LINUX: Use struct vfs_path on RHEL5
[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 #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;
68     code = ENOENT;
69
70     if (followlink)
71        flags |= LOOKUP_FOLLOW;
72     code = afs_kern_path(aname, flags, &path_data);
73
74     if (!code)
75         afs_get_dentry_ref(&path_data, mnt, dpp);
76
77     return code;
78 }
79
80 int
81 osi_lookupname(char *aname, uio_seg_t seg, int followlink, 
82                struct dentry **dpp)
83 {
84     int code;
85     char *tname;
86     code = ENOENT;
87     if (seg == AFS_UIOUSER) {
88         tname = getname(aname);
89         if (IS_ERR(tname)) 
90             return PTR_ERR(tname);
91     } else {
92         tname = aname;
93     }
94     code = osi_lookupname_internal(tname, followlink, NULL, dpp);   
95     if (seg == AFS_UIOUSER) {
96         putname(tname);
97     }
98     return code;
99 }
100
101 int osi_abspath(char *aname, char *buf, int buflen,
102                 int followlink, char **pathp)
103 {
104     struct dentry *dp = NULL;
105     struct vfsmount *mnt = NULL;
106     char *tname, *path;
107     int code;
108
109     code = ENOENT;
110     tname = getname(aname);
111     if (IS_ERR(tname)) 
112         return -PTR_ERR(tname);
113     code = osi_lookupname_internal(tname, followlink, &mnt, &dp);   
114     if (!code) {
115 #if defined(D_PATH_TAKES_STRUCT_PATH)
116         afs_linux_path_t p = { mnt, dp };
117         path = d_path(&p, buf, buflen);
118 #else
119         path = d_path(dp, mnt, buf, buflen);
120 #endif
121
122         if (IS_ERR(path)) {
123             code = -PTR_ERR(path);
124         } else {
125             *pathp = path;
126         }
127
128         dput(dp);
129         mntput(mnt);
130     }
131
132     putname(tname);
133     return code;
134 }
135
136
137 /* This could use some work, and support on more platforms. */
138 int afs_thread_wrapper(void *rock)
139 {
140     void (*proc)(void) = rock;
141     __module_get(THIS_MODULE);
142     AFS_GLOCK();
143     (*proc)();
144     AFS_GUNLOCK();
145     module_put(THIS_MODULE);
146     return 0;
147 }
148
149 void afs_start_thread(void (*proc)(void), char *name)
150 {
151     kthread_run(afs_thread_wrapper, proc, "%s", name);
152 }