Linux: 2.6.39: replace path_lookup with kern_path
[openafs.git] / src / afs / LINUX / osi_misc.c
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  */
9
10 /*
11  * Linux support routines.
12  *
13  */
14 #include <afsconfig.h>
15 #include "afs/param.h"
16
17
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"
25
26 #include "osi_compat.h"
27
28 int afs_osicred_initialized = 0;
29 afs_ucred_t afs_osi_cred;
30
31 void
32 afs_osi_SetTime(osi_timeval_t * tvp)
33 {
34     struct timespec tv;
35     tv.tv_sec = tvp->tv_sec;
36     tv.tv_nsec = tvp->tv_usec * NSEC_PER_USEC;
37
38     AFS_STATCNT(osi_SetTime);
39
40     do_settimeofday(&tv);
41 }
42
43 void
44 osi_linux_mask(void)
45 {
46     SIG_LOCK(current);
47     sigfillset(&current->blocked);
48     RECALC_SIGPENDING(current);
49     SIG_UNLOCK(current);
50 }
51
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)
60 {
61     int code;
62     struct nameidata nd;
63     struct path path;
64     int flags = LOOKUP_POSITIVE;
65     code = ENOENT;
66
67     if (followlink)
68        flags |= LOOKUP_FOLLOW;
69     code = afs_kern_path(aname, flags, &nd, &path);
70
71     if (!code)
72         afs_get_dentry_ref(&nd, &path, mnt, dpp);
73
74     return code;
75 }
76
77 int
78 osi_lookupname(char *aname, uio_seg_t seg, int followlink, 
79                struct dentry **dpp)
80 {
81     int code;
82     char *tname;
83     code = ENOENT;
84     if (seg == AFS_UIOUSER) {
85         tname = getname(aname);
86         if (IS_ERR(tname)) 
87             return PTR_ERR(tname);
88     } else {
89         tname = aname;
90     }
91     code = osi_lookupname_internal(tname, followlink, NULL, dpp);   
92     if (seg == AFS_UIOUSER) {
93         putname(tname);
94     }
95     return code;
96 }
97
98 int osi_abspath(char *aname, char *buf, int buflen,
99                 int followlink, char **pathp)
100 {
101     struct dentry *dp = NULL;
102     struct vfsmount *mnt = NULL;
103     char *tname, *path;
104     int code;
105
106     code = ENOENT;
107     tname = getname(aname);
108     if (IS_ERR(tname)) 
109         return -PTR_ERR(tname);
110     code = osi_lookupname_internal(tname, followlink, &mnt, &dp);   
111     if (!code) {
112 #if defined(D_PATH_TAKES_STRUCT_PATH)
113         struct path p = { mnt, dp };
114         path = d_path(&p, buf, buflen);
115 #else
116         path = d_path(dp, mnt, buf, buflen);
117 #endif
118
119         if (IS_ERR(path)) {
120             code = -PTR_ERR(path);
121         } else {
122             *pathp = path;
123         }
124
125         dput(dp);
126         mntput(mnt);
127     }
128
129     putname(tname);
130     return code;
131 }
132
133
134 /* This could use some work, and support on more platforms. */
135 int afs_thread_wrapper(void *rock)
136 {
137     void (*proc)(void) = rock;
138     __module_get(THIS_MODULE);
139     AFS_GLOCK();
140     (*proc)();
141     AFS_GUNLOCK();
142     module_put(THIS_MODULE);
143     return 0;
144 }
145
146 void afs_start_thread(void (*proc)(void), char *name)
147 {
148     kthread_run(afs_thread_wrapper, proc, "%s", name);
149 }