2 * Portions Copyright (c) 2003 Apple Computer, Inc. All rights reserved.
8 #include <afs/sysincludes.h> /* Standard vendor system headers */
9 #include <afsincludes.h> /* Afs-based standard headers */
10 #include <afs/afs_stats.h> /* statistics */
11 #include <sys/malloc.h>
12 #include <sys/namei.h>
14 #ifndef AFS_DARWIN80_ENV
15 #include <sys/syscall.h>
17 #include <sys/sysctl.h>
18 #include "../afs/sysctl.h"
21 #define M_UFSMNT M_TEMP /* DARWIN80 MALLOC doesn't look at the type anyway */
24 struct vcache *afs_globalVp = 0;
25 struct mount *afs_globalVFS = 0;
35 afs_fhtovp(mp, fhp, vpp)
53 #ifdef AFS_DARWIN80_ENV
54 #define CTX_TYPE vfs_context_t
55 #define CTX_PROC_CONVERT(C) vfs_context_proc((C))
56 #define STATFS_TYPE struct vfsstatfs
58 #define CTX_TYPE struct proc *
59 #define CTX_PROC_CONVERT(C) (C)
60 #define STATFS_TYPE struct statfs
61 #define vfs_statfs(VFS) &(VFS)->mnt_stat
63 #define PROC_DECL(out,in) struct proc *out = CTX_PROC_CONVERT(in)
66 afs_start(mp, flags, p)
71 return (0); /* nothing to do. ? */
75 afs_statfs(struct mount *mp, STATFS_TYPE *abp, CTX_TYPE ctx);
76 #ifdef AFS_DARWIN80_ENV
78 afs_mount(mp, devvp, data, ctx)
79 register struct mount *mp;
85 afs_mount(mp, path, data, ndp, ctx)
86 register struct mount *mp;
89 struct nameidata *ndp;
93 /* ndp contains the mounted-from device. Just ignore it.
94 * we also don't care about our proc struct. */
97 #ifdef AFS_DARWIN80_ENV
98 struct vfsioattr ioattr;
99 /* vfs_statfs advertised as RO, but isn't */
100 /* new api will be needed to initialize this information (nfs needs to
101 set mntfromname too) */
103 STATFS_TYPE *mnt_stat = vfs_statfs(mp);
105 if (vfs_isupdate(mp))
109 AFS_STATCNT(afs_mount);
111 if (data == 0 && afs_globalVFS) { /* Don't allow remounts. */
117 #ifdef AFS_DARWIN80_ENV
118 vfs_ioattr(mp, &ioattr);
119 ioattr.io_devblocksize = (16 * 32768);
120 vfs_setioattr(mp, &ioattr);
121 /* f_iosize is handled in VFS_GETATTR */
123 mp->vfs_bsize = 8192;
124 mp->mnt_stat.f_iosize = 8192;
128 #ifndef AFS_DARWIN80_ENV
129 (void)copyinstr(path, mp->mnt_stat.f_mntonname, MNAMELEN - 1, &size);
130 memset(mp->mnt_stat.f_mntonname + size, 0, MNAMELEN - size);
132 memset(mnt_stat->f_mntfromname, 0, MNAMELEN);
135 strcpy(mnt_stat->f_mntfromname, "AFS");
136 /* null terminated string "AFS" will fit, just leave it be. */
137 vfs_setfsprivate(mp, NULL);
139 struct VenusFid *rootFid = NULL;
141 char volName[MNAMELEN];
143 (void)copyinstr(data, volName, MNAMELEN - 1, &size);
144 memset(volName + size, 0, MNAMELEN - size);
146 if (volName[0] == 0) {
147 strcpy(mnt_stat->f_mntfromname, "AFS");
148 vfs_setfsprivate(mp, &afs_rootFid);
150 struct cell *localcell = afs_GetPrimaryCell(READ_LOCK);
151 if (localcell == NULL) {
156 /* Set the volume identifier to "AFS:volume.name" */
157 snprintf(mnt_stat->f_mntfromname, MNAMELEN - 1, "AFS:%s",
160 afs_GetVolumeByName(volName, localcell->cellNum, 1,
161 (struct vrequest *)0, READ_LOCK);
164 int volid = (tvp->roVol ? tvp->roVol : tvp->volume);
165 MALLOC(rootFid, struct VenusFid *, sizeof(*rootFid), M_UFSMNT,
167 rootFid->Cell = localcell->cellNum;
168 rootFid->Fid.Volume = volid;
169 rootFid->Fid.Vnode = 1;
170 rootFid->Fid.Unique = 1;
176 vfs_setfsprivate(mp, &rootFid);
179 #ifdef AFS_DARWIN80_ENV
180 afs_vfs_typenum=vfs_typenum(mp);
181 vfs_setauthopaque(mp);
182 vfs_setauthopaqueaccess(mp);
184 strcpy(mp->mnt_stat.f_fstypename, "afs");
187 (void)afs_statfs(mp, mnt_stat, ctx);
192 afs_unmount(mp, flags, ctx)
197 void *mdata = vfs_fsprivate(mp);
199 AFS_STATCNT(afs_unmount);
201 if (mdata != (qaddr_t) - 1) {
203 vfs_setfsprivate(mp, (qaddr_t) - 1);
204 FREE(mdata, M_UFSMNT);
206 if (flags & MNT_FORCE) {
208 #ifdef AFS_DARWIN80_ENV
209 afs_PutVCache(afs_globalVp);
212 vrele(AFSTOV(afs_globalVp));
218 vflush(mp, NULLVP, FORCECLOSE/*0*/);
227 vfs_clearflags(mp, MNT_LOCAL);
235 #ifdef AFS_DARWIN80_ENV
237 afs_root(struct mount *mp, struct vnode **vpp, vfs_context_t ctx)
240 afs_root(struct mount *mp, struct vnode **vpp)
243 void *mdata = vfs_fsprivate(mp);
245 struct vrequest treq;
246 register struct vcache *tvp = 0;
247 #ifdef AFS_DARWIN80_ENV
248 struct ucred *cr = vfs_context_ucred(ctx);
251 struct proc *p = current_proc();
253 struct ucred *cr = &_cr;
256 _cr = *p->p_cred->pc_ucred;
260 AFS_STATCNT(afs_root);
261 if (mdata == NULL && afs_globalVp
262 && (afs_globalVp->f.states & CStatd)) {
265 #ifdef AFS_DARWIN80_ENV
268 } else if (mdata == (qaddr_t) - 1) {
271 struct VenusFid *rootFid = (mdata == NULL)
272 ? &afs_rootFid : (struct VenusFid *)mdata;
274 if (!(error = afs_InitReq(&treq, cr)) && !(error = afs_CheckInit())) {
275 tvp = afs_GetVCache(rootFid, &treq, NULL, NULL);
276 #ifdef AFS_DARWIN80_ENV
279 error = afs_darwin_finalizevnode(tvp, NULL, NULL, 1, 0);
284 /* re-acquire the usecount that finalizevnode disposed of */
285 vnode_ref(AFSTOV(tvp));
288 /* we really want this to stay around */
292 afs_PutVCache(afs_globalVp);
296 #ifdef AFS_DARWIN80_ENV
305 #ifndef AFS_DARWIN80_ENV /* DARWIN80 caller does not need a usecount reference */
308 vn_lock(AFSTOV(tvp), LK_EXCLUSIVE | LK_RETRY, p);
311 #ifdef AFS_DARWIN80_ENV
312 if (needref) /* this iocount is for the caller. the initial iocount
313 is for the eventual afs_PutVCache. for mdata != null,
314 there will not be a PutVCache, so the caller gets the
315 initial (from GetVCache or finalizevnode) iocount*/
316 vnode_get(AFSTOV(tvp));
322 #ifndef AFS_DARWIN80_ENV
323 AFSTOV(tvp)->v_flag |= VROOT;
324 AFSTOV(tvp)->v_vfsp = mp;
328 afs_Trace2(afs_iclSetp, CM_TRACE_VFSROOT, ICL_TYPE_POINTER, *vpp,
329 ICL_TYPE_INT32, error);
334 #ifndef AFS_DARWIN80_ENV /* vget vfsop never had this prototype AFAIK */
336 afs_vget(mp, lfl, vp)
342 //printf("vget called. help!\n");
343 if (vp->v_usecount < 0) {
344 vprint("bad usecount", vp);
347 error = vget(vp, lfl, current_proc());
349 insmntque(vp, mp); /* take off free list */
353 int afs_vfs_vget(struct mount *mp, void *ino, struct vnode **vpp)
355 return ENOENT; /* cannot implement */
361 afs_statfs(struct mount *mp, STATFS_TYPE *abp, CTX_TYPE ctx)
363 STATFS_TYPE *sysstat = vfs_statfs(mp);
365 AFS_STATCNT(afs_statfs);
367 #ifdef AFS_DARWIN80_ENV
368 abp->f_iosize = (256 * 1024);
369 abp->f_bsize = vfs_devblocksize(mp);
371 abp->f_bsize = mp->vfs_bsize;
372 abp->f_iosize = mp->vfs_bsize;
375 abp->f_type = MOUNT_AFS;
378 /* Fake a high number below to satisfy programs that use the statfs call
379 * to make sure that there's enough space in the device partition before
380 * storing something there.
382 abp->f_blocks = abp->f_bfree = abp->f_bavail = abp->f_files =
383 abp->f_ffree = 0x7fffffff;
385 if (abp != sysstat) {
386 abp->f_fsid.val[0] = sysstat->f_fsid.val[0];
387 abp->f_fsid.val[1] = sysstat->f_fsid.val[1];
388 #ifndef AFS_DARWIN80_ENV
389 abp->f_type = vfs_typenum(mp);
391 memcpy((caddr_t) & abp->f_mntonname[0],
392 (caddr_t) sysstat->f_mntonname, MNAMELEN);
393 memcpy((caddr_t) & abp->f_mntfromname[0],
394 (caddr_t) sysstat->f_mntfromname, MNAMELEN);
401 #ifdef AFS_DARWIN80_ENV
403 afs_vfs_getattr(struct mount *mp, struct vfs_attr *outattrs,
404 vfs_context_t context)
406 VFSATTR_RETURN(outattrs, f_bsize, vfs_devblocksize(mp));
407 VFSATTR_RETURN(outattrs, f_iosize, vfs_devblocksize(mp));
408 VFSATTR_RETURN(outattrs, f_blocks, 2000000);
409 VFSATTR_RETURN(outattrs, f_bfree, 2000000);
410 VFSATTR_RETURN(outattrs, f_bavail, 2000000);
411 VFSATTR_RETURN(outattrs, f_files, 2000000);
412 VFSATTR_RETURN(outattrs, f_ffree, 2000000);
413 if ( VFSATTR_IS_ACTIVE(outattrs, f_capabilities) )
415 vol_capabilities_attr_t *vcapattrptr;
416 vcapattrptr = &outattrs->f_capabilities;
417 vcapattrptr->capabilities[VOL_CAPABILITIES_FORMAT] =
418 VOL_CAP_FMT_SYMBOLICLINKS |
419 VOL_CAP_FMT_HARDLINKS |
420 VOL_CAP_FMT_ZERO_RUNS |
421 VOL_CAP_FMT_CASE_SENSITIVE |
422 VOL_CAP_FMT_CASE_PRESERVING |
423 VOL_CAP_FMT_FAST_STATFS;
424 vcapattrptr->capabilities[VOL_CAPABILITIES_INTERFACES] =
425 VOL_CAP_INT_ADVLOCK |
427 vcapattrptr->capabilities[VOL_CAPABILITIES_RESERVED1] = 0;
428 vcapattrptr->capabilities[VOL_CAPABILITIES_RESERVED2] = 0;
430 /* Capabilities we know about: */
431 vcapattrptr->valid[VOL_CAPABILITIES_FORMAT] =
432 VOL_CAP_FMT_PERSISTENTOBJECTIDS |
433 VOL_CAP_FMT_SYMBOLICLINKS |
434 VOL_CAP_FMT_HARDLINKS |
435 VOL_CAP_FMT_JOURNAL |
436 VOL_CAP_FMT_JOURNAL_ACTIVE |
437 VOL_CAP_FMT_NO_ROOT_TIMES |
438 VOL_CAP_FMT_SPARSE_FILES |
439 VOL_CAP_FMT_ZERO_RUNS |
440 VOL_CAP_FMT_CASE_SENSITIVE |
441 VOL_CAP_FMT_CASE_PRESERVING |
442 VOL_CAP_FMT_FAST_STATFS;
443 vcapattrptr->valid[VOL_CAPABILITIES_INTERFACES] =
444 VOL_CAP_INT_SEARCHFS |
445 VOL_CAP_INT_ATTRLIST |
446 VOL_CAP_INT_NFSEXPORT |
447 VOL_CAP_INT_READDIRATTR |
448 VOL_CAP_INT_EXCHANGEDATA |
449 VOL_CAP_INT_COPYFILE |
450 VOL_CAP_INT_ALLOCATE |
451 VOL_CAP_INT_VOL_RENAME |
452 VOL_CAP_INT_ADVLOCK |
454 vcapattrptr->valid[VOL_CAPABILITIES_RESERVED1] = 0;
455 vcapattrptr->valid[VOL_CAPABILITIES_RESERVED2] = 0;
457 VFSATTR_SET_SUPPORTED(outattrs, f_capabilities);
463 #ifdef AFS_DARWIN80_ENV
465 afs_sync(mp, waitfor, ctx)
471 afs_sync(mp, waitfor, cred, p)
481 u_int32_t afs_darwin_realmodes = 0;
483 #ifdef AFS_DARWIN80_ENV
484 int afs_sysctl(int *name, u_int namelen, user_addr_t oldp, size_t *oldlenp,
485 user_addr_t newp, size_t newlen, vfs_context_t context)
487 int afs_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp,
488 void *newp, size_t newlen, struct proc *p)
495 /* nothing defined */
501 case AFS_SC_DARWIN_ALL:
503 case AFS_SC_DARWIN_ALL_REALMODES:
504 #ifdef AFS_DARWIN80_ENV
505 if (oldp != USER_ADDR_NULL && oldlenp == NULL)
507 if (oldp && *oldlenp < sizeof(u_int32_t))
509 if (newp && newlen != sizeof(u_int32_t))
511 *oldlenp = sizeof(u_int32_t);
513 if ((error = copyout(&afs_darwin_realmodes,
514 oldp, sizeof(u_int32_t)))) {
519 return copyin(newp, &afs_darwin_realmodes,
523 return sysctl_int(oldp, oldlenp, newp, newlen,
524 &afs_darwin_realmodes);
528 /* darwin version specific sysctl's goes here */
536 extern int vfs_opv_numops; /* The total number of defined vnode operations */
537 extern struct vnodeopv_desc afs_vnodeop_opv_desc;
539 afs_init(struct vfsconf *vfc)
541 #ifndef AFS_DARWIN80_ENV /* vfs_fsadd does all this junk */
543 int (**opv_desc_vector) ();
544 struct vnodeopv_entry_desc *opve_descp;
548 MALLOC(afs_vnodeop_p, PFI *, vfs_opv_numops * sizeof(PFI), M_TEMP,
551 memset(afs_vnodeop_p, 0, vfs_opv_numops * sizeof(PFI));
553 opv_desc_vector = afs_vnodeop_p;
554 for (j = 0; afs_vnodeop_opv_desc.opv_desc_ops[j].opve_op; j++) {
555 opve_descp = &(afs_vnodeop_opv_desc.opv_desc_ops[j]);
558 * Sanity check: is this operation listed
559 * in the list of operations? We check this
560 * by seeing if its offest is zero. Since
561 * the default routine should always be listed
562 * first, it should be the only one with a zero
563 * offset. Any other operation with a zero
564 * offset is probably not listed in
565 * vfs_op_descs, and so is probably an error.
567 * A panic here means the layer programmer
568 * has committed the all-too common bug
569 * of adding a new operation to the layer's
570 * list of vnode operations but
571 * not adding the operation to the system-wide
572 * list of supported operations.
574 if (opve_descp->opve_op->vdesc_offset == 0
575 && opve_descp->opve_op->vdesc_offset != VOFFSET(vop_default)) {
576 printf("afs_init: operation %s not listed in %s.\n",
577 opve_descp->opve_op->vdesc_name, "vfs_op_descs");
578 panic("load_afs: bad operation");
581 * Fill in this entry.
583 opv_desc_vector[opve_descp->opve_op->vdesc_offset] =
584 opve_descp->opve_impl;
588 * Finally, go back and replace unfilled routines
589 * with their default. (Sigh, an O(n^3) algorithm. I
590 * could make it better, but that'd be work, and n is small.)
594 * Force every operations vector to have a default routine.
596 opv_desc_vector = afs_vnodeop_p;
597 if (opv_desc_vector[VOFFSET(vop_default)] == NULL) {
598 panic("afs_init: operation vector without default routine.");
600 for (j = 0; j < vfs_opv_numops; j++)
601 if (opv_desc_vector[j] == NULL)
602 opv_desc_vector[j] = opv_desc_vector[VOFFSET(vop_default)];
607 struct vfsops afs_vfsops = {
612 #ifdef AFS_DARWIN80_ENV
620 #ifdef AFS_DARWIN80_ENV
629 #ifdef AFS_DARWIN80_ENV