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