Remove struct from AFS_UCRED instantiations (opaque credential type support)
[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 #if defined(AFS_LINUX26_ENV)
20 #include "h/dcache.h"
21 #include "h/namei.h"
22 #include "h/kthread.h"
23 #endif
24 #include "afs/sysincludes.h"
25 #include "afsincludes.h"
26 #include "afs/afs_stats.h"
27 #if defined(AFS_LINUX24_ENV)
28 #include "h/smp_lock.h"
29 #endif
30
31 int afs_osicred_initialized = 0;
32 AFS_UCRED afs_osi_cred;
33
34 void
35 afs_osi_SetTime(osi_timeval_t * tvp)
36 {
37 #if defined(AFS_LINUX24_ENV)
38
39 #if defined(AFS_LINUX26_ENV)
40     struct timespec tv;
41     tv.tv_sec = tvp->tv_sec;
42     tv.tv_nsec = tvp->tv_usec * NSEC_PER_USEC;
43 #else
44     struct timeval tv;
45     tv.tv_sec = tvp->tv_sec;
46     tv.tv_usec = tvp->tv_usec;
47 #endif
48
49     AFS_STATCNT(osi_SetTime);
50
51     do_settimeofday(&tv);
52 #else
53     extern int (*sys_settimeofdayp) (struct timeval * tv,
54                                      struct timezone * tz);
55
56     KERNEL_SPACE_DECL;
57
58     AFS_STATCNT(osi_SetTime);
59
60     TO_USER_SPACE();
61     if (sys_settimeofdayp)
62         (void)(*sys_settimeofdayp) (tvp, NULL);
63     TO_KERNEL_SPACE();
64 #endif
65 }
66
67 void
68 osi_linux_mask(void)
69 {
70     SIG_LOCK(current);
71     sigfillset(&current->blocked);
72     RECALC_SIGPENDING(current);
73     SIG_UNLOCK(current);
74 }
75
76 #if defined(AFS_LINUX24_ENV)
77 /* LOOKUP_POSITIVE is becoming the default */
78 #ifndef LOOKUP_POSITIVE
79 #define LOOKUP_POSITIVE 0
80 #endif
81 /* Lookup name and return vnode for same. */
82 int
83 osi_lookupname_internal(char *aname, int followlink, struct vfsmount **mnt,
84                         struct dentry **dpp)
85 {
86     int code;
87     struct nameidata nd;
88     int flags = LOOKUP_POSITIVE;
89     code = ENOENT;
90
91     if (followlink)
92        flags |= LOOKUP_FOLLOW;
93 #if defined(AFS_LINUX26_ENV)
94     code = path_lookup(aname, flags, &nd);
95 #else
96     if (path_init(aname, flags, &nd))
97         code = path_walk(aname, &nd);
98 #endif
99
100     if (!code) {
101 #if defined(STRUCT_NAMEIDATA_HAS_PATH)
102         *dpp = dget(nd.path.dentry);
103         if (mnt)
104             *mnt = mntget(nd.path.mnt);
105         path_put(&nd.path);
106 #else
107         *dpp = dget(nd.dentry);
108         if (mnt)
109            *mnt = mntget(nd.mnt);
110         path_release(&nd);
111 #endif
112     }
113     return code;
114 }
115
116 int
117 osi_lookupname(char *aname, uio_seg_t seg, int followlink, 
118                struct dentry **dpp)
119 {
120     int code;
121     char *tname;
122     code = ENOENT;
123     if (seg == AFS_UIOUSER) {
124         tname = getname(aname);
125         if (IS_ERR(tname)) 
126             return PTR_ERR(tname);
127     } else {
128         tname = aname;
129     }
130     code = osi_lookupname_internal(tname, followlink, NULL, dpp);   
131     if (seg == AFS_UIOUSER) {
132         putname(tname);
133     }
134     return code;
135 }
136 #else
137 int
138 osi_lookupname(char *aname, uio_seg_t seg, int followlink, struct dentry **dpp)
139 {
140     struct dentry *dp = NULL;
141     int code;
142
143     code = ENOENT;
144     if (seg == AFS_UIOUSER) {
145         dp = followlink ? namei(aname) : lnamei(aname);
146     } else {
147         dp = lookup_dentry(aname, NULL, followlink ? 1 : 0);
148     }
149
150     if (dp && !IS_ERR(dp)) {
151         if (dp->d_inode) {
152             *dpp = dp;
153             code = 0;
154         } else
155             dput(dp);
156     }
157
158     return code;
159 }
160 #endif
161
162
163 #ifdef AFS_LINUX26_ENV
164 /* This is right even for Linux 2.4, but on that version d_path is inline
165  * and implemented in terms of __d_path, which is not exported.
166  */
167 int osi_abspath(char *aname, char *buf, int buflen,
168                 int followlink, char **pathp)
169 {
170     struct dentry *dp = NULL;
171     struct vfsmount *mnt = NULL;
172     char *tname, *path;
173     int code;
174
175     code = ENOENT;
176     tname = getname(aname);
177     if (IS_ERR(tname)) 
178         return -PTR_ERR(tname);
179     code = osi_lookupname_internal(tname, followlink, &mnt, &dp);   
180     if (!code) {
181 #if defined(D_PATH_TAKES_STRUCT_PATH)
182         struct path p = { mnt, dp };
183         path = d_path(&p, buf, buflen);
184 #else
185         path = d_path(dp, mnt, buf, buflen);
186 #endif
187
188         if (IS_ERR(path)) {
189             code = -PTR_ERR(path);
190         } else {
191             *pathp = path;
192         }
193
194         dput(dp);
195         mntput(mnt);
196     }
197
198     putname(tname);
199     return code;
200 }
201
202
203 /* This could use some work, and support on more platforms. */
204 int afs_thread_wrapper(void *rock)
205 {
206     void (*proc)(void) = rock;
207     __module_get(THIS_MODULE);
208     AFS_GLOCK();
209     (*proc)();
210     AFS_GUNLOCK();
211     module_put(THIS_MODULE);
212     return 0;
213 }
214
215 void afs_start_thread(void (*proc)(void), char *name)
216 {
217     kthread_run(afs_thread_wrapper, proc, "%s", name);
218 }
219 #endif