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