pull-prototypes-to-head-20020821
[openafs.git] / src / afs / DARWIN / 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  * MACOS inode operations
11  *
12  * Implements:
13  *
14  */
15 #include <afsconfig.h>
16 #include "../afs/param.h"
17
18 RCSID("$Header$");
19
20 #include "../afs/sysincludes.h" /* Standard vendor system headers */
21 #include "../afs/afsincludes.h" /* Afs-based standard headers */
22 #include "../afs/osi_inode.h"
23 #include "../afs/afs_stats.h" /* statistics stuff */
24 #include <ufs/ufs/ufsmount.h>
25 extern struct ucred afs_osi_cred;
26
27 getinode(fs, dev, inode, vpp, perror)
28      struct mount *fs;
29      struct vnode **vpp;
30      dev_t dev;
31      ino_t inode;
32      int *perror;
33 {
34     struct vnode *vp;
35     int code;
36
37     *vpp = 0;
38     *perror = 0;
39     if (!fs) {
40         register struct ufsmount *ump;
41 #ifdef VFSTOHFS
42         register struct hfsmount *hmp;
43 #endif
44         register struct vnode *vp;
45         register struct mount *mp;
46         extern struct mount *rootfs;
47         if (mp = rootfs) do {
48             /*
49              * XXX Also do the test for MFS 
50              */
51             if (!strcmp(mp->mnt_vfc->vfc_name, "ufs")) {        
52                 ump = VFSTOUFS(mp);
53                 if (ump->um_fs == NULL)
54                     break;
55                 if (ump->um_dev == dev) {
56                     fs = ump->um_mountp;
57                 }
58             }
59 #ifdef VFSTOHFS
60             if (!strcmp(mp->mnt_vfc->vfc_name, "hfs")) {
61                 hmp = VFSTOHFS(mp);
62 #if 0
63                 if (hmp->hfs_mp == NULL)
64                     break;
65 #endif
66                 if (hmp->hfs_raw_dev == dev) {
67                     fs = hmp->hfs_mp;
68                 }
69             }   
70 #endif
71
72             mp = CIRCLEQ_NEXT(mp, mnt_list);
73         } while (mp != rootfs);
74         if (!fs)
75             return(ENXIO);
76     }
77     code=VFS_VGET(fs, (void *)inode, &vp);
78     if (code) {
79         *perror = BAD_IGET;
80         return code;
81     } else { 
82         *vpp = vp;
83         return(0);
84     }
85 }
86 extern int afs_CacheFSType;
87 igetinode(vfsp, dev, inode, vpp, va, perror)
88      struct vnode **vpp;
89      struct mount *vfsp;
90      dev_t dev;
91      ino_t inode;
92      struct vattr *va;
93      int *perror;
94 {
95     struct vnode *pvp, *vp;
96     extern struct osi_dev cacheDev;
97     register int code = 0;
98
99     *perror = 0;
100
101     AFS_STATCNT(igetinode);
102     if ((code = getinode(vfsp, dev, inode, &vp, perror)) != 0) {
103         return(code);
104     }
105     if (vp->v_type != VREG && vp->v_type != VDIR && vp->v_type != VLNK) {
106         printf("igetinode: bad type %d\n", vp->v_type);
107         iforget(vp);        
108         return(ENOENT);
109     }
110     VOP_GETATTR(vp, va, &afs_osi_cred, current_proc());
111     if (va->va_mode == 0) {
112         /* Not an allocated inode */
113         iforget(vp);        
114         return(ENOENT);
115     }
116     if (vfsp && afs_CacheFSType == AFS_APPL_HFS_CACHE && va->va_nlink == 0) {
117         printf("igetinode: hfs nlink 0\n");
118     }
119     if (va->va_nlink == 0) {
120         vput(vp);
121         return(ENOENT);
122     }
123
124     VOP_UNLOCK(vp, 0, current_proc());
125     *vpp = vp;
126     return(0);
127 }
128
129 iforget(vp)
130 struct vnode *vp;
131 {
132
133     AFS_STATCNT(iforget);
134     /* XXX could sleep */
135     vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, current_proc());
136     /* this whole thing is too wierd.  Why??? XXX */
137     if (vp->v_usecount == 1) {
138         vp->v_usecount=0;
139         VOP_UNLOCK(vp,0, current_proc());
140 #if 0
141         simple_lock(&vnode_free_list_slock);
142         TAILQ_INSERT_TAIL(&vnode_free_list, vp, v_freelist);
143         freevnodes++;
144         simple_unlock(&vnode_free_list_slock);
145 #else
146         printf("iforget: leaking vnode\n");
147 #endif
148     } else {
149         vput(vp);
150     }
151 }
152
153 #if 0
154 /*
155  * icreate system call -- create an inode
156  */
157 afs_syscall_icreate(dev, near_inode, param1, param2, param3, param4, retval)
158      long *retval;
159      long dev, near_inode, param1, param2, param3, param4;
160 {
161     int dummy, err=0;
162     struct inode *ip, *newip;
163     register int code;
164     struct vnode *vp;
165     
166     AFS_STATCNT(afs_syscall_icreate);
167     
168     if (!afs_suser())
169         return(EPERM);
170
171     code = getinode(0, (dev_t)dev, 2, &ip, &dummy);
172     if (code) {
173         return(ENOENT);
174     }
175     code = ialloc(ip, (ino_t)near_inode, 0, &newip);
176     iput(ip);
177     if (code) {
178         return(code);
179     }
180     IN_LOCK(newip);
181     newip->i_flag |= IACC|IUPD|ICHG;
182     
183     newip->i_nlink = 1;
184
185     newip->i_mode = IFREG;
186     
187     IN_UNLOCK(newip);
188     vp = ITOV(newip);
189     VN_LOCK(vp);
190     vp->v_type = VREG;
191     VN_UNLOCK(vp);
192     
193     if ( !vp->v_object)
194         {
195             extern struct vfs_ubcops ufs_ubcops;
196             extern struct vm_ubc_object* ubc_object_allocate();
197             struct vm_ubc_object* vop;
198             vop = ubc_object_allocate(&vp, &ufs_ubcops,
199                                       vp->v_mount->m_funnel);
200             VN_LOCK(vp);
201             vp->v_object = vop;
202             VN_UNLOCK(vp);
203         }
204     
205     
206     IN_LOCK(newip);
207     newip->i_flags |= IC_XUID|IC_XGID;
208     newip->i_flags &= ~IC_PROPLIST;
209     newip->i_vicep1 = param1;
210     if (param2 == 0x1fffffff/*INODESPECIAL*/)   {
211         newip->i_vicep2 = ((0x1fffffff << 3) + (param4 & 0x3));
212         newip->i_vicep3a = (u_short)(param3 >> 16);
213         newip->i_vicep3b = (u_short)param3;
214     } else {
215         newip->i_vicep2 = (((param2 >> 16) & 0x1f) << 27) +
216             (((param4 >> 16) & 0x1f) << 22) + 
217                 (param3 & 0x3fffff);        
218         newip->i_vicep3a = (u_short)param4;
219         newip->i_vicep3b = (u_short)param2;
220     }
221     newip->i_vicemagic = VICEMAGIC;
222     
223     *retval = newip->i_number;
224     IN_UNLOCK(newip);
225     iput(newip);
226     return(code);
227 }
228
229
230 afs_syscall_iopen(dev, inode, usrmod, retval)
231      long *retval;
232      int dev, inode, usrmod;
233 {
234     struct file *fp;
235     struct inode *ip;
236     struct vnode *vp = NULL;
237     int dummy;
238     int fd;
239     extern struct fileops vnops;
240     register int code;
241     
242     AFS_STATCNT(afs_syscall_iopen);
243     
244     if (!afs_suser())
245         return(EPERM);
246
247     code = igetinode(0, (dev_t)dev, (ino_t)inode, &ip, &dummy);
248     if (code) {
249         return(code);
250     }
251     if ((code = falloc(&fp, &fd)) != 0) {
252         iput(ip);
253         return(code);
254     }
255     IN_UNLOCK(ip);
256     
257     FP_LOCK(fp);
258     fp->f_flag = (usrmod-FOPEN) & FMASK;
259     fp->f_type = DTYPE_VNODE;
260     fp->f_ops = &vnops;
261     fp->f_data = (caddr_t)ITOV(ip);
262     
263     FP_UNLOCK(fp);
264     U_FD_SET(fd, fp, &u.u_file_state);
265     *retval = fd;
266     return(0);
267 }
268
269
270 /*
271  * Support for iinc() and idec() system calls--increment or decrement
272  * count on inode.
273  * Restricted to super user.
274  * Only VICEMAGIC type inodes.
275  */
276 afs_syscall_iincdec(dev, inode, inode_p1, amount)
277      int dev, inode, inode_p1, amount;
278 {
279     int dummy;
280     struct inode *ip;
281     register int code;
282     
283     if (!afs_suser())
284         return(EPERM);
285
286     code = igetinode(0, (dev_t)dev, (ino_t)inode, &ip, &dummy);
287     if (code) {
288         return(code);
289     }
290     if (!IS_VICEMAGIC(ip)) {
291         return(EPERM);
292     } else if (ip->i_vicep1 != inode_p1) {
293         return(ENXIO);
294     }
295     ip->i_nlink += amount;
296     if (ip->i_nlink == 0) {
297         CLEAR_VICEMAGIC(ip);
298     }
299     ip->i_flag |= ICHG;
300     iput(ip);
301     return(0);
302 }
303 #else
304 afs_syscall_icreate(dev, near_inode, param1, param2, param3, param4, retval)
305      long *retval;
306      long dev, near_inode, param1, param2, param3, param4;
307 {
308      return EOPNOTSUPP;
309 }
310 afs_syscall_iopen(dev, inode, usrmod, retval)
311      long *retval;
312      int dev, inode, usrmod;
313 {
314      return EOPNOTSUPP;
315 }
316 afs_syscall_iincdec(dev, inode, inode_p1, amount)
317      int dev, inode, inode_p1, amount;
318 {
319      return EOPNOTSUPP;
320 }
321 #endif