initial-darwin-support-20010327
[openafs.git] / src / afs / DARWIN / osi_vfsops.c
1 #include <afs/param.h>  /* Should be always first */
2 #include <afs/sysincludes.h>            /* Standard vendor system headers */
3 #include <afs/afsincludes.h>            /* Afs-based standard headers */
4 #include <afs/afs_stats.h>              /* statistics */
5 #include <sys/malloc.h>
6 #include <sys/namei.h>
7 #include <sys/conf.h>
8 #include <sys/syscall.h>
9
10 struct vcache *afs_globalVp = 0;
11 struct mount *afs_globalVFS = 0;
12
13 int
14 afs_quotactl()
15 {
16         return EOPNOTSUPP;
17 }
18
19 int
20 afs_fhtovp(mp, fhp, vpp)
21 struct mount *mp;
22 struct fid *fhp;
23 struct vnode **vpp;
24 {
25
26         return (EINVAL);
27 }
28
29 int
30 afs_vptofh(vp, fhp)
31 struct vnode *vp;
32 struct fid *fhp;
33 {
34
35         return (EINVAL);
36 }
37
38 int
39 afs_start(mp, flags, p)
40 struct mount *mp;
41 int flags;
42 struct proc *p;
43 {
44     return (0);                         /* nothing to do. ? */
45 }
46
47 int
48 afs_mount(mp, path, data, ndp, p)
49 register struct mount *mp;
50 char *path;
51 caddr_t data;
52 struct nameidata *ndp;
53 struct proc *p;
54 {
55     /* ndp contains the mounted-from device.  Just ignore it.
56        we also don't care about our proc struct. */
57     size_t size;
58     int error;
59
60     if (mp->mnt_flag & MNT_UPDATE)
61         return EINVAL;
62
63     AFS_GLOCK();
64     AFS_STATCNT(afs_mount);
65
66     if (afs_globalVFS) { /* Don't allow remounts. */
67         AFS_GUNLOCK();
68         return (EBUSY);
69     }
70
71     afs_globalVFS = mp;
72     mp->vfs_bsize = 8192;
73     vfs_getnewfsid(mp);
74     mp->mnt_stat.f_iosize=8192;
75     
76     (void) copyinstr(path, mp->mnt_stat.f_mntonname, MNAMELEN-1, &size);
77     bzero(mp->mnt_stat.f_mntonname + size, MNAMELEN - size);
78     bzero(mp->mnt_stat.f_mntfromname, MNAMELEN);
79     strcpy(mp->mnt_stat.f_mntfromname, "AFS");
80     /* null terminated string "AFS" will fit, just leave it be. */
81     strcpy(mp->mnt_stat.f_fstypename, "afs");
82     AFS_GUNLOCK();
83     (void) afs_statfs(mp, &mp->mnt_stat, p);
84     return 0;
85 }
86
87 int
88 afs_unmount(mp, flags, p)
89 struct mount *mp;
90 int flags;
91 struct proc *p;
92 {
93     
94     AFS_GLOCK();
95     AFS_STATCNT(afs_unmount);
96     afs_globalVFS = 0;
97     afs_shutdown();
98     AFS_GUNLOCK();
99
100     return 0;
101 }
102
103 int
104 afs_root(struct mount *mp,
105               struct vnode **vpp)
106 {
107     int error;
108     struct vrequest treq;
109     register struct vcache *tvp=0;
110     struct proc *p=current_proc();
111     struct ucred cr;
112
113     pcred_readlock(p);
114     cr=*p->p_cred->pc_ucred;
115     pcred_unlock(p);
116     AFS_GLOCK();
117     AFS_STATCNT(afs_root);
118     if (afs_globalVp && (afs_globalVp->states & CStatd)) {
119         tvp = afs_globalVp;
120         error=0;
121     } else {
122         
123         if (!(error = afs_InitReq(&treq, &cr)) &&
124             !(error = afs_CheckInit())) {
125             tvp = afs_GetVCache(&afs_rootFid, &treq, (afs_int32 *)0,
126                                 (struct vcache*)0, WRITE_LOCK);
127             /* we really want this to stay around */
128             if (tvp) {
129                 afs_globalVp = tvp;
130             } else
131                 error = ENOENT;
132         }
133     }
134     if (tvp) {
135         osi_vnhold(tvp,0);
136     AFS_GUNLOCK();
137         vn_lock((struct vnode *)tvp, LK_EXCLUSIVE | LK_RETRY, p);
138     AFS_GLOCK();
139         afs_globalVFS = mp;
140         *vpp = (struct vnode *) tvp;
141         tvp->v.v_flag |= VROOT;
142     }
143
144     afs_Trace2(afs_iclSetp, CM_TRACE_VFSROOT, ICL_TYPE_POINTER, *vpp,
145                ICL_TYPE_INT32, error);
146     AFS_GUNLOCK();
147     return error;
148 }
149
150 int
151 afs_vget(mp, lfl, vp)
152 struct mount *mp;
153 struct vnode *vp;
154 int lfl;
155 {
156     int error;
157     printf("vget called. help!\n");
158     if (vp->v_usecount < 0) {
159         vprint("bad usecount", vp);
160         panic("afs_vget");
161     }
162     error = vget(vp, lfl, current_proc());
163     if (!error)
164         insmntque(vp, afs_globalVFS);   /* take off free list */
165     return error;
166 }
167
168 int afs_statfs(struct mount *mp, struct statfs *abp, struct proc *p)
169 {
170     AFS_GLOCK();
171     AFS_STATCNT(afs_statfs);
172
173 #if 0
174     abp->f_type = MOUNT_AFS;
175 #endif
176     abp->f_bsize = mp->vfs_bsize;
177     abp->f_iosize = mp->vfs_bsize;
178
179     /* Fake a high number below to satisfy programs that use the statfs call
180      * to make sure that there's enough space in the device partition before
181      * storing something there.
182      */
183     abp->f_blocks = abp->f_bfree = abp->f_bavail = abp->f_files =
184         abp->f_ffree  = 2000000;
185
186     abp->f_fsid.val[0] = mp->mnt_stat.f_fsid.val[0];
187     abp->f_fsid.val[1] = mp->mnt_stat.f_fsid.val[1];
188     if (abp != &mp->mnt_stat) {
189         abp->f_type = mp->mnt_vfc->vfc_typenum;
190         bcopy((caddr_t)mp->mnt_stat.f_mntonname,
191               (caddr_t)&abp->f_mntonname[0], MNAMELEN);
192         bcopy((caddr_t)mp->mnt_stat.f_mntfromname,
193               (caddr_t)&abp->f_mntfromname[0], MNAMELEN);
194     }
195
196     AFS_GUNLOCK();
197     return 0;
198 }
199
200 int afs_sync(mp, waitfor, cred, p) 
201 struct mount *mp;
202 int waitfor;
203 struct ucred *cred;
204 struct prioc *p;
205 {
206 return 0;
207 }
208
209 int afs_sysctl() {
210    return EOPNOTSUPP;
211 }
212
213
214 typedef (*PFI)();
215 extern int vfs_opv_numops; /* The total number of defined vnode operations */
216 extern struct vnodeopv_desc afs_vnodeop_opv_desc;
217 int afs_init(struct vfsconf *vfc) {
218         int j;
219         int (**opv_desc_vector)();
220         struct vnodeopv_entry_desc *opve_descp;
221  
222
223
224         MALLOC(afs_vnodeop_p, PFI *, vfs_opv_numops*sizeof(PFI), M_TEMP, M_WAITOK);
225
226         bzero (afs_vnodeop_p, vfs_opv_numops*sizeof(PFI));
227
228         opv_desc_vector = afs_vnodeop_p;
229         for (j=0; afs_vnodeop_opv_desc.opv_desc_ops[j].opve_op; j++) {
230             opve_descp = &(afs_vnodeop_opv_desc.opv_desc_ops[j]);
231
232             /*
233              * Sanity check:  is this operation listed
234              * in the list of operations?  We check this
235              * by seeing if its offest is zero.  Since
236              * the default routine should always be listed
237              * first, it should be the only one with a zero
238              * offset.  Any other operation with a zero
239              * offset is probably not listed in
240              * vfs_op_descs, and so is probably an error.
241              *
242              * A panic here means the layer programmer
243              * has committed the all-too common bug
244              * of adding a new operation to the layer's
245              * list of vnode operations but
246              * not adding the operation to the system-wide
247              * list of supported operations.
248              */
249             if (opve_descp->opve_op->vdesc_offset == 0 &&
250                 opve_descp->opve_op->vdesc_offset != VOFFSET(vop_default)) {
251                 printf("afs_init: operation %s not listed in %s.\n",
252                        opve_descp->opve_op->vdesc_name,
253                        "vfs_op_descs");
254                panic ("load_afs: bad operation");
255                 }
256             /*
257              * Fill in this entry.
258              */
259             opv_desc_vector[opve_descp->opve_op->vdesc_offset] =
260                 opve_descp->opve_impl;
261             }
262
263         /*
264          * Finally, go back and replace unfilled routines
265          * with their default.  (Sigh, an O(n^3) algorithm.  I
266                                  * could make it better, but that'd be work, and n is small.)
267          */
268
269         /*
270          * Force every operations vector to have a default routine.
271          */
272         opv_desc_vector = afs_vnodeop_p;
273         if (opv_desc_vector[VOFFSET(vop_default)]==NULL) {
274             panic("afs_init: operation vector without default routine.");
275             }
276         for (j = 0;j<vfs_opv_numops; j++)
277             if (opv_desc_vector[j] == NULL)
278                 opv_desc_vector[j] =
279                     opv_desc_vector[VOFFSET(vop_default)];
280 }
281
282 struct vfsops afs_vfsops = {
283   afs_mount,
284   afs_start,
285   afs_unmount,
286   afs_root,
287   afs_quotactl,
288   afs_statfs,
289   afs_sync,
290   afs_vget,
291   afs_fhtovp,
292   afs_vptofh,
293   afs_init,
294   afs_sysctl
295 };