Merge 1.8.0~pre4 packaging into master
[pkg-k5-afs_openafs.git] / src / afs / LINUX / osi_misc.c
blob077d4edfb840ec28f62453450ab41d4a0a94476d
1 /*
2 * Copyright 2000, International Business Machines Corporation and others.
3 * All Rights Reserved.
4 *
5 * This software has been released under the terms of the IBM Public
6 * License. For details, see the LICENSE file in the top-level source
7 * directory or online at http://www.openafs.org/dl/license10.html
8 */
11 * Linux support routines.
14 #include <afsconfig.h>
15 #include "afs/param.h"
18 #include <linux/module.h> /* early to avoid printf->printk mapping */
19 #include <linux/dcache.h>
20 #include <linux/namei.h>
21 #include <linux/kthread.h>
22 #include "afs/sysincludes.h"
23 #include "afsincludes.h"
24 #include "afs/afs_stats.h"
26 #include "osi_compat.h"
28 int afs_osicred_initialized = 0;
29 afs_ucred_t afs_osi_cred;
31 void
32 afs_osi_SetTime(osi_timeval_t * tvp)
34 struct timespec tv;
35 tv.tv_sec = tvp->tv_sec;
36 tv.tv_nsec = tvp->tv_usec * NSEC_PER_USEC;
38 AFS_STATCNT(osi_SetTime);
40 do_settimeofday(&tv);
43 void
44 osi_linux_mask(void)
46 SIG_LOCK(current);
47 sigfillset(&current->blocked);
48 RECALC_SIGPENDING(current);
49 SIG_UNLOCK(current);
52 /* LOOKUP_POSITIVE is becoming the default */
53 #ifndef LOOKUP_POSITIVE
54 #define LOOKUP_POSITIVE 0
55 #endif
56 /* Lookup name and return vnode for same. */
57 int
58 osi_lookupname_internal(char *aname, int followlink, struct vfsmount **mnt,
59 struct dentry **dpp)
61 int code;
62 #if defined(HAVE_LINUX_PATH_LOOKUP)
63 struct nameidata path_data;
64 #else
65 afs_linux_path_t path_data;
66 #endif
67 int flags = LOOKUP_POSITIVE;
69 if (followlink)
70 flags |= LOOKUP_FOLLOW;
71 code = afs_kern_path(aname, flags, &path_data);
73 if (!code)
74 afs_get_dentry_ref(&path_data, mnt, dpp);
76 return code;
79 static char *
80 afs_getname(char *aname)
82 int len;
83 char *name = kmem_cache_alloc(names_cachep, GFP_KERNEL);
85 if (!name)
86 return ERR_PTR(-ENOMEM);
88 len = strncpy_from_user(name, aname, PATH_MAX);
89 if (len < 0)
90 goto error;
91 if (len >= PATH_MAX) {
92 len = -ENAMETOOLONG;
93 goto error;
95 return name;
97 error:
98 kmem_cache_free(names_cachep, name);
99 return ERR_PTR(len);
102 static void
103 afs_putname(char *name)
105 kmem_cache_free(names_cachep, name);
109 osi_lookupname(char *aname, uio_seg_t seg, int followlink,
110 struct dentry **dpp)
112 int code;
113 char *name;
115 if (seg == AFS_UIOUSER) {
116 name = afs_getname(aname);
117 if (IS_ERR(name))
118 return -PTR_ERR(name);
119 } else {
120 name = aname;
122 code = osi_lookupname_internal(name, followlink, NULL, dpp);
123 if (seg == AFS_UIOUSER) {
124 afs_putname(name);
126 return code;
129 int osi_abspath(char *aname, char *buf, int buflen,
130 int followlink, char **pathp)
132 struct dentry *dp = NULL;
133 struct vfsmount *mnt = NULL;
134 char *name, *path;
135 int code;
137 name = afs_getname(aname);
138 if (IS_ERR(name))
139 return -PTR_ERR(name);
140 code = osi_lookupname_internal(name, followlink, &mnt, &dp);
141 if (!code) {
142 #if defined(D_PATH_TAKES_STRUCT_PATH)
143 afs_linux_path_t p = { .mnt = mnt, .dentry = dp };
144 path = d_path(&p, buf, buflen);
145 #else
146 path = d_path(dp, mnt, buf, buflen);
147 #endif
149 if (IS_ERR(path)) {
150 code = -PTR_ERR(path);
151 } else {
152 *pathp = path;
155 dput(dp);
156 mntput(mnt);
159 afs_putname(name);
160 return code;
164 /* This could use some work, and support on more platforms. */
165 int afs_thread_wrapper(void *rock)
167 void (*proc)(void) = rock;
168 __module_get(THIS_MODULE);
169 AFS_GLOCK();
170 (*proc)();
171 AFS_GUNLOCK();
172 module_put(THIS_MODULE);
173 return 0;
176 void afs_start_thread(void (*proc)(void), char *name)
178 kthread_run(afs_thread_wrapper, proc, "%s", name);