81f9dbfe5741a9eff9e4d3b8574d955b715a44c6
[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
19 #include "afs/sysincludes.h"    /* Standard vendor system headers */
20 #include "afsincludes.h"        /* Afs-based standard headers */
21 #include "afs/osi_inode.h"
22 #include "afs/afs_stats.h"      /* statistics stuff */
23 #ifndef AFS_DARWIN80_ENV
24 #include <ufs/ufs/ufsmount.h>
25 #endif
26 extern struct ucred afs_osi_cred;
27 extern int afs_CacheFSType;
28
29 #ifdef AFS_DARWIN80_ENV
30 getinode(fs, dev, inode, vpp, perror)
31     mount_t fs;
32     vnode_t *vpp;
33     dev_t dev;
34     ino_t inode;
35     int *perror;
36 {
37     struct vnode *vp;
38     int code;
39     vfs_context_t ctx;
40     char volfspath[64];
41     
42     *vpp = 0;
43     *perror = 0;
44     sprintf(volfspath, "/.vol/%d/%d", dev, inode);
45     code = vnode_open(volfspath, O_RDWR, 0, 0, &vp, afs_osi_ctxtp);
46     if (code) {
47         *perror = BAD_IGET;
48         return code;
49     } else {
50         *vpp = vp;
51         return (0);
52     }
53 }    
54     
55   
56 igetinode(vfsp, dev, inode, vpp, va, perror)
57     vnode_t *vpp;
58     mount_t vfsp;
59     dev_t dev;
60     ino_t inode;
61     struct vattr *va;
62     int *perror;
63 {
64     vnode_t pvp, vp;
65     extern struct osi_dev cacheDev;
66     int code = 0;
67     
68     *perror = 0;
69     
70     AFS_STATCNT(igetinode);
71     if ((code = getinode(vfsp, dev, inode, &vp, perror)) != 0) {
72         return (code);
73     }
74     if (vnode_vtype(vp) != VREG && vnode_vtype(vp) != VDIR && vnode_vtype(vp) != VLNK) {
75         vnode_close(vp, O_RDWR, afs_osi_ctxtp);
76         printf("igetinode: bad type %d\n", vnode_vtype(vp));
77         return (ENOENT);
78     }
79     VATTR_INIT(va);
80     VATTR_WANTED(va, va_mode);
81     VATTR_WANTED(va, va_nlink);
82     VATTR_WANTED(va, va_size);
83     code = vnode_getattr(vp, va, afs_osi_ctxtp);
84     if (code) {
85         vnode_close(vp, O_RDWR, afs_osi_ctxtp);
86         return code;
87     }
88     if (!VATTR_ALL_SUPPORTED(va)) {
89         vnode_close(vp, O_RDWR, afs_osi_ctxtp);
90         return ENOENT;
91     }
92     if (va->va_mode == 0) {
93         vnode_close(vp, O_RDWR, afs_osi_ctxtp);
94         /* Not an allocated inode */
95         return (ENOENT);
96     }
97     if (va->va_nlink == 0) {
98         vnode_close(vp, O_RDWR, afs_osi_ctxtp);
99         return (ENOENT);
100     }
101     
102     *vpp = vp;
103     return (0);
104 }
105 #else
106 getinode(fs, dev, inode, vpp, perror)
107      struct mount *fs;
108      struct vnode **vpp;
109      dev_t dev;
110      ino_t inode;
111      int *perror;
112 {
113     struct vnode *vp;
114     int code;
115
116     *vpp = 0;
117     *perror = 0;
118     if (!fs) {
119         struct ufsmount *ump;
120 #ifdef VFSTOHFS
121         struct hfsmount *hmp;
122 #endif
123         struct vnode *vp;
124         struct mount *mp;
125         extern struct mount *rootfs;
126         if (mp = rootfs)
127             do {
128                 /*
129                  * XXX Also do the test for MFS 
130                  */
131                 if (!strcmp(mp->mnt_vfc->vfc_name, "ufs")) {
132                     ump = VFSTOUFS(mp);
133                     if (ump->um_fs == NULL)
134                         break;
135                     if (ump->um_dev == dev) {
136                         fs = ump->um_mountp;
137                     }
138                 }
139 #ifdef VFSTOHFS
140                 if (!strcmp(mp->mnt_vfc->vfc_name, "hfs")) {
141                     hmp = VFSTOHFS(mp);
142 #if 0
143                     if (hmp->hfs_mp == NULL)
144                         break;
145 #endif
146                     if (hmp->hfs_raw_dev == dev) {
147                         fs = hmp->hfs_mp;
148                     }
149                 }
150 #endif
151
152                 mp = CIRCLEQ_NEXT(mp, mnt_list);
153             } while (mp != rootfs);
154         if (!fs)
155             return (ENXIO);
156     }
157     code = VFS_VGET(fs, (void *)inode, &vp);
158     if (code) {
159         *perror = BAD_IGET;
160         return code;
161     } else {
162         *vpp = vp;
163         return (0);
164     }
165 }
166
167 igetinode(vfsp, dev, inode, vpp, va, perror)
168      struct vnode **vpp;
169      struct mount *vfsp;
170      dev_t dev;
171      ino_t inode;
172      struct vattr *va;
173      int *perror;
174 {
175     struct vnode *pvp, *vp;
176     extern struct osi_dev cacheDev;
177     int code = 0;
178
179     *perror = 0;
180
181     AFS_STATCNT(igetinode);
182     if ((code = getinode(vfsp, dev, inode, &vp, perror)) != 0) {
183         return (code);
184     }
185     if (vp->v_type != VREG && vp->v_type != VDIR && vp->v_type != VLNK) {
186         printf("igetinode: bad type %d\n", vp->v_type);
187         iforget(vp);
188         return (ENOENT);
189     }
190     VOP_GETATTR(vp, va, &afs_osi_cred, current_proc());
191     if (va->va_mode == 0) {
192         /* Not an allocated inode */
193         iforget(vp);
194         return (ENOENT);
195     }
196     if (vfsp && afs_CacheFSType == AFS_APPL_HFS_CACHE && va->va_nlink == 0) {
197         printf("igetinode: hfs nlink 0\n");
198     }
199     if (va->va_nlink == 0) {
200         vput(vp);
201         return (ENOENT);
202     }
203
204     VOP_UNLOCK(vp, 0, current_proc());
205     *vpp = vp;
206     return (0);
207 }
208
209 iforget(vp)
210      struct vnode *vp;
211 {
212
213     AFS_STATCNT(iforget);
214     /* XXX could sleep */
215     vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, current_proc());
216     /* this whole thing is too wierd.  Why??? XXX */
217     if (vp->v_usecount == 1) {
218         vp->v_usecount = 0;
219         VOP_UNLOCK(vp, 0, current_proc());
220 #if 0
221         simple_lock(&vnode_free_list_slock);
222         TAILQ_INSERT_TAIL(&vnode_free_list, vp, v_freelist);
223         freevnodes++;
224         simple_unlock(&vnode_free_list_slock);
225 #else
226         printf("iforget: leaking vnode\n");
227 #endif
228     } else {
229         vput(vp);
230     }
231 }
232 #endif
233
234 int
235 afs_syscall_icreate(long dev, long near_inode, long param1, long param2, 
236                     long param3, long param4, long *retval)
237 {
238     return EOPNOTSUPP;
239 }
240
241 int
242 afs_syscall_iopen(int dev, int inode, int usrmod, long *retval)
243 {
244     return EOPNOTSUPP;
245 }
246
247 int
248 afs_syscall_iincdec(int dev, int inode, int inode_p1, int amount)
249 {
250     return EOPNOTSUPP;
251 }