Use the correct API for msleep() in FBSD's afs_osi_TimedSleep()
[openafs.git] / src / afs / FBSD / osi_inode.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  * FreeBSD inode operations
12  *
13  * Implements:
14  *
15  */
16 #include <afsconfig.h>
17 #include "afs/param.h"
18
19
20 #include "afs/sysincludes.h"    /* Standard vendor system headers */
21 #include "afsincludes.h"        /* Afs-based standard headers */
22 #include "afs/osi_inode.h"
23 #include "afs/afs_stats.h"      /* statistics stuff */
24 #include <sys/queue.h>
25 #include <sys/lock.h>
26 #include <ufs/ufs/dinode.h>
27 #if defined(AFS_FBSD50_ENV)
28 #include <ufs/ufs/extattr.h>
29 #endif
30 #include <ufs/ufsmount.h>
31
32 int
33 getinode(fs, dev, inode, ipp, perror)
34      struct mount *fs;
35      struct inode **ipp;
36      dev_t dev;
37      ino_t inode;
38      int *perror;
39 {
40     struct vnode *vp;
41     int code;
42
43     *ipp = 0;
44     *perror = 0;
45     if (!fs) {
46         register struct ufsmount *ump;
47         register struct mount *mp;
48
49 #if defined(AFS_FBSD50_ENV)
50         mtx_lock(&mountlist_mtx);
51 #else
52         simple_lock(&mountlist_slock);
53 #endif
54         if ((mp = TAILQ_FIRST(&mountlist)) != NULL)
55             do {
56                 /*
57                  * XXX Also do the test for MFS
58                  */
59 #undef m_data
60 #undef m_next
61                 if (!strcmp(mp->mnt_stat.f_fstypename, MOUNT_UFS)) {
62                     ump = VFSTOUFS(mp);
63                     if (ump->um_fs == NULL)
64                         break;
65                     if (ump->um_dev == dev) {
66                         fs = ump->um_mountp;
67                     }
68                 }
69                 mp = TAILQ_NEXT(mp, mnt_list);
70             } while (mp != TAILQ_FIRST(&mountlist));
71 #if defined(AFS_FBSD50_ENV)
72         mtx_unlock(&mountlist_mtx);
73 #else
74         simple_unlock(&mountlist_slock);
75 #endif
76         if (!fs)
77             return (ENXIO);
78     }
79 #if defined(AFS_FBSD50_ENV)
80     code = VFS_VGET(fs, inode, 0, &vp);
81 #else
82     code = VFS_VGET(fs, inode, &vp);
83 #endif
84     if (code != 0) {
85         *perror = BAD_IGET;
86         return code;
87     } else {
88         *ipp = VTOI(vp);
89         return (0);
90     }
91 }
92
93 int
94 igetinode(vfsp, dev, inode, ipp, perror)
95      struct inode **ipp;
96      struct mount *vfsp;
97      dev_t dev;
98      ino_t inode;
99      int *perror;
100 {
101     struct inode *ip;
102     register int code = 0;
103
104     *perror = 0;
105
106     AFS_STATCNT(igetinode);
107
108     if ((code = getinode(vfsp, dev, inode, &ip, perror)) != 0) {
109         return (code);
110     }
111
112     if (ip->i_mode == 0) {
113         /* Not an allocated inode */
114         vput(ITOV(ip));
115         return (ENOENT);
116     }
117
118     if (ip->i_nlink == 0 || (ip->i_mode & IFMT) != IFREG) {
119         vput(ITOV(ip));
120         return (ENOENT);
121     }
122
123     *ipp = ip;
124     return (0);
125 }
126
127 #if 0
128 /*
129  * icreate system call -- create an inode
130  */
131 afs_syscall_icreate(dev, near_inode, param1, param2, param3, param4, retval)
132      long *retval;
133      long dev, near_inode, param1, param2, param3, param4;
134 {
135     int dummy, err = 0;
136     struct inode *ip, *newip;
137     register int code;
138     struct vnode *vp;
139
140     AFS_STATCNT(afs_syscall_icreate);
141
142     if (!afs_suser(NULL))
143         return (EPERM);
144
145     code = getinode(0, (dev_t) dev, 2, &ip, &dummy);
146     if (code) {
147         return (ENOENT);
148     }
149     code = ialloc(ip, (ino_t) near_inode, 0, &newip);
150     iput(ip);
151     if (code) {
152         return (code);
153     }
154     IN_LOCK(newip);
155     newip->i_flag |= IACC | IUPD | ICHG;
156
157     newip->i_nlink = 1;
158
159     newip->i_mode = IFREG;
160
161     IN_UNLOCK(newip);
162     vp = ITOV(newip);
163     VN_LOCK(vp);
164     vp->v_type = VREG;
165     VN_UNLOCK(vp);
166
167     /*
168      * if ( !vp->v_object)
169      * {
170      * extern struct vfs_ubcops ufs_ubcops;
171      * extern struct vm_ubc_object* ubc_object_allocate();
172      * struct vm_ubc_object* vop;
173      * vop = ubc_object_allocate(&vp, &ufs_ubcops,
174      * vp->v_mount->m_funnel);
175      * VN_LOCK(vp);
176      * vp->v_object = vop;
177      * VN_UNLOCK(vp);
178      * }
179      */
180
181     IN_LOCK(newip);
182     /*    newip->i_flags |= IC_XUID|IC_XGID; */
183     /*    newip->i_flags &= ~IC_PROPLIST; */
184     newip->i_vicep1 = param1;
185     if (param2 == 0x1fffffff /*INODESPECIAL*/) {
186         newip->i_vicep2 = ((0x1fffffff << 3) + (param4 & 0x3));
187         newip->i_vicep3a = (u_short) (param3 >> 16);
188         newip->i_vicep3b = (u_short) param3;
189     } else {
190         newip->i_vicep2 =
191             (((param2 >> 16) & 0x1f) << 27) +
192             (((param4 >> 16) & 0x1f) << 22) + (param3 & 0x3fffff);
193         newip->i_vicep3a = (u_short) param4;
194         newip->i_vicep3b = (u_short) param2;
195     }
196     newip->i_vicemagic = VICEMAGIC;
197
198     *retval = newip->i_number;
199     IN_UNLOCK(newip);
200     iput(newip);
201     return (code);
202 }
203
204
205 int
206 afs_syscall_iopen(dev, inode, usrmod, retval)
207      long *retval;
208      int dev, inode, usrmod;
209 {
210     struct file *fp;
211     struct inode *ip;
212     struct vnode *vp = NULL;
213     int dummy;
214     int fd;
215     extern struct fileops vnops;
216     register int code;
217
218     AFS_STATCNT(afs_syscall_iopen);
219
220     if (!afs_suser(NULL))
221         return (EPERM);
222
223     code = igetinode(0, (dev_t) dev, (ino_t) inode, &ip, &dummy);
224     if (code) {
225         return (code);
226     }
227     if ((code = falloc(curproc, &fp, &fd)) != 0) {
228         iput(ip);
229         return (code);
230     }
231     IN_UNLOCK(ip);
232
233     /* FreeBSD doesn't do much mp stuff yet :( */
234     /* FP_LOCK(fp); */
235     fp->f_flag = (usrmod) & FMASK;
236     fp->f_type = DTYPE_VNODE;
237     fp->f_ops = &vnops;
238     fp->f_data = (caddr_t) ITOV(ip);
239
240     /* FP_UNLOCK(fp); */
241     return (0);
242 }
243
244
245 /*
246  * Support for iinc() and idec() system calls--increment or decrement
247  * count on inode.
248  * Restricted to super user.
249  * Only VICEMAGIC type inodes.
250  */
251 int
252 afs_syscall_iincdec(dev, inode, inode_p1, amount)
253      int dev, inode, inode_p1, amount;
254 {
255     int dummy;
256     struct inode *ip;
257     register int code;
258
259     if (!afs_suser(NULL))
260         return (EPERM);
261
262     code = igetinode(0, (dev_t) dev, (ino_t) inode, &ip, &dummy);
263     if (code) {
264         return (code);
265     }
266     if (!IS_VICEMAGIC(ip)) {
267         return (EPERM);
268     } else if (ip->i_vicep1 != inode_p1) {
269         return (ENXIO);
270     }
271     ip->i_nlink += amount;
272     if (ip->i_nlink == 0) {
273         CLEAR_VICEMAGIC(ip);
274     }
275     ip->i_flag |= ICHG;
276     iput(ip);
277     return (0);
278 }
279 #else
280 int
281 afs_syscall_icreate(dev, near_inode, param1, param2, param3, param4, retval)
282      long *retval;
283      long dev, near_inode, param1, param2, param3, param4;
284 {
285     return EOPNOTSUPP;
286 }
287
288 int
289 afs_syscall_iopen(dev, inode, usrmod, retval)
290      long *retval;
291      int dev, inode, usrmod;
292 {
293     return EOPNOTSUPP;
294 }
295
296 int
297 afs_syscall_iincdec(dev, inode, inode_p1, amount)
298      int dev, inode, inode_p1, amount;
299 {
300     return EOPNOTSUPP;
301 }
302 #endif