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(struct mount *mp, struct fid *fhp, struct vnode **vpp)
41 afs_vptofh(struct vnode *vp, struct fid *fhp)
46 #ifdef AFS_DARWIN80_ENV
47 #define CTX_TYPE vfs_context_t
48 #define CTX_PROC_CONVERT(C) vfs_context_proc((C))
49 #define STATFS_TYPE struct vfsstatfs
51 #define CTX_TYPE struct proc *
52 #define CTX_PROC_CONVERT(C) (C)
53 #define STATFS_TYPE struct statfs
54 #define vfs_statfs(VFS) &(VFS)->mnt_stat
56 #define PROC_DECL(out,in) struct proc *out = CTX_PROC_CONVERT(in)
59 afs_start(struct mount *mp, int flags, CTX_TYPE p)
61 return (0); /* nothing to do. ? */
65 afs_statfs(struct mount *mp, STATFS_TYPE *abp, CTX_TYPE ctx);
66 #ifdef AFS_DARWIN80_ENV
68 afs_mount(struct mount *mp, vnode_t *devvp, user_addr_t data, vfs_context_t ctx)
71 afs_mount(struct mount *mp, char *path, caddr_t data, struct nameidata *ndp, CTX_TYPE ctx)
74 /* ndp contains the mounted-from device. Just ignore it.
75 * we also don't care about our proc struct. */
78 #ifdef AFS_DARWIN80_ENV
79 struct vfsioattr ioattr;
80 /* vfs_statfs advertised as RO, but isn't */
81 /* new api will be needed to initialize this information (nfs needs to
82 set mntfromname too) */
84 STATFS_TYPE *mnt_stat = vfs_statfs(mp);
90 AFS_STATCNT(afs_mount);
92 if (data == 0 && afs_globalVFS) { /* Don't allow remounts. */
98 #ifdef AFS_DARWIN80_ENV
99 vfs_ioattr(mp, &ioattr);
100 ioattr.io_devblocksize = (16 * 32768);
101 vfs_setioattr(mp, &ioattr);
102 /* f_iosize is handled in VFS_GETATTR */
104 mp->vfs_bsize = 8192;
105 mp->mnt_stat.f_iosize = 8192;
109 #ifndef AFS_DARWIN80_ENV
110 (void)copyinstr(path, mp->mnt_stat.f_mntonname, MNAMELEN - 1, &size);
111 memset(mp->mnt_stat.f_mntonname + size, 0, MNAMELEN - size);
113 memset(mnt_stat->f_mntfromname, 0, MNAMELEN);
116 strcpy(mnt_stat->f_mntfromname, "AFS");
117 /* null terminated string "AFS" will fit, just leave it be. */
118 vfs_setfsprivate(mp, NULL);
120 struct VenusFid *rootFid = NULL;
122 char volName[MNAMELEN];
124 (void)copyinstr(data, volName, MNAMELEN - 1, &size);
125 memset(volName + size, 0, MNAMELEN - size);
127 if (volName[0] == 0) {
128 strcpy(mnt_stat->f_mntfromname, "AFS");
129 vfs_setfsprivate(mp, &afs_rootFid);
131 struct cell *localcell = afs_GetPrimaryCell(READ_LOCK);
132 if (localcell == NULL) {
137 /* Set the volume identifier to "AFS:volume.name" */
138 snprintf(mnt_stat->f_mntfromname, MNAMELEN - 1, "AFS:%s",
141 afs_GetVolumeByName(volName, localcell->cellNum, 1,
142 (struct vrequest *)0, READ_LOCK);
145 int volid = (tvp->roVol ? tvp->roVol : tvp->volume);
146 MALLOC(rootFid, struct VenusFid *, sizeof(*rootFid), M_UFSMNT,
148 rootFid->Cell = localcell->cellNum;
149 rootFid->Fid.Volume = volid;
150 rootFid->Fid.Vnode = 1;
151 rootFid->Fid.Unique = 1;
157 vfs_setfsprivate(mp, &rootFid);
160 #ifdef AFS_DARWIN80_ENV
161 afs_vfs_typenum=vfs_typenum(mp);
162 vfs_setauthopaque(mp);
163 vfs_setauthopaqueaccess(mp);
165 strcpy(mp->mnt_stat.f_fstypename, "afs");
168 (void)afs_statfs(mp, mnt_stat, ctx);
173 afs_unmount(struct mount *mp, int flags, CTX_TYPE ctx)
175 void *mdata = vfs_fsprivate(mp);
177 AFS_STATCNT(afs_unmount);
179 if (mdata != (qaddr_t) - 1) {
181 vfs_setfsprivate(mp, (qaddr_t) - 1);
182 FREE(mdata, M_UFSMNT);
184 if (flags & MNT_FORCE) {
186 #ifdef AFS_DARWIN80_ENV
187 afs_PutVCache(afs_globalVp);
190 vrele(AFSTOV(afs_globalVp));
196 vflush(mp, NULLVP, FORCECLOSE/*0*/);
205 vfs_clearflags(mp, MNT_LOCAL);
213 #ifdef AFS_DARWIN80_ENV
215 afs_root(struct mount *mp, struct vnode **vpp, vfs_context_t ctx)
218 afs_root(struct mount *mp, struct vnode **vpp)
221 void *mdata = vfs_fsprivate(mp);
223 struct vrequest treq;
224 struct vcache *tvp = 0;
225 #ifdef AFS_DARWIN80_ENV
226 struct ucred *cr = vfs_context_ucred(ctx);
229 struct proc *p = current_proc();
231 struct ucred *cr = &_cr;
234 _cr = *p->p_cred->pc_ucred;
238 AFS_STATCNT(afs_root);
239 if (mdata == NULL && afs_globalVp
240 && (afs_globalVp->f.states & CStatd)) {
243 #ifdef AFS_DARWIN80_ENV
246 } else if (mdata == (qaddr_t) - 1) {
249 struct VenusFid *rootFid = (mdata == NULL)
250 ? &afs_rootFid : (struct VenusFid *)mdata;
252 if (!(error = afs_InitReq(&treq, cr)) && !(error = afs_CheckInit())) {
253 tvp = afs_GetVCache(rootFid, &treq, NULL, NULL);
254 #ifdef AFS_DARWIN80_ENV
257 error = afs_darwin_finalizevnode(tvp, NULL, NULL, 1, 0);
262 /* re-acquire the usecount that finalizevnode disposed of */
263 vnode_ref(AFSTOV(tvp));
266 /* we really want this to stay around */
270 afs_PutVCache(afs_globalVp);
274 #ifdef AFS_DARWIN80_ENV
283 #ifndef AFS_DARWIN80_ENV /* DARWIN80 caller does not need a usecount reference */
286 vn_lock(AFSTOV(tvp), LK_EXCLUSIVE | LK_RETRY, p);
289 #ifdef AFS_DARWIN80_ENV
290 if (needref) /* this iocount is for the caller. the initial iocount
291 is for the eventual afs_PutVCache. for mdata != null,
292 there will not be a PutVCache, so the caller gets the
293 initial (from GetVCache or finalizevnode) iocount*/
294 vnode_get(AFSTOV(tvp));
300 #ifndef AFS_DARWIN80_ENV
301 AFSTOV(tvp)->v_flag |= VROOT;
302 AFSTOV(tvp)->v_vfsp = mp;
306 afs_Trace2(afs_iclSetp, CM_TRACE_VFSROOT, ICL_TYPE_POINTER, *vpp,
307 ICL_TYPE_INT32, error);
312 #ifndef AFS_DARWIN80_ENV /* vget vfsop never had this prototype AFAIK */
314 afs_vget(struct mount *mp, int lfl, struct vnode *vp)
317 //printf("vget called. help!\n");
318 if (vp->v_usecount < 0) {
319 vprint("bad usecount", vp);
322 error = vget(vp, lfl, current_proc());
324 insmntque(vp, mp); /* take off free list */
328 int afs_vfs_vget(struct mount *mp, void *ino, struct vnode **vpp)
330 return ENOENT; /* cannot implement */
336 afs_statfs(struct mount *mp, STATFS_TYPE *abp, CTX_TYPE ctx)
338 STATFS_TYPE *sysstat = vfs_statfs(mp);
340 AFS_STATCNT(afs_statfs);
342 #ifdef AFS_DARWIN80_ENV
343 abp->f_iosize = (256 * 1024);
344 abp->f_bsize = vfs_devblocksize(mp);
346 abp->f_bsize = mp->vfs_bsize;
347 abp->f_iosize = mp->vfs_bsize;
350 abp->f_type = MOUNT_AFS;
353 /* Fake a high number below to satisfy programs that use the statfs call
354 * to make sure that there's enough space in the device partition before
355 * storing something there.
357 abp->f_blocks = abp->f_bfree = abp->f_bavail = abp->f_files =
358 abp->f_ffree = 0x7fffffff;
360 if (abp != sysstat) {
361 abp->f_fsid.val[0] = sysstat->f_fsid.val[0];
362 abp->f_fsid.val[1] = sysstat->f_fsid.val[1];
363 #ifndef AFS_DARWIN80_ENV
364 abp->f_type = vfs_typenum(mp);
366 memcpy((caddr_t) & abp->f_mntonname[0],
367 (caddr_t) sysstat->f_mntonname, MNAMELEN);
368 memcpy((caddr_t) & abp->f_mntfromname[0],
369 (caddr_t) sysstat->f_mntfromname, MNAMELEN);
376 #ifdef AFS_DARWIN80_ENV
378 afs_vfs_getattr(struct mount *mp, struct vfs_attr *outattrs,
379 vfs_context_t context)
381 VFSATTR_RETURN(outattrs, f_bsize, vfs_devblocksize(mp));
382 VFSATTR_RETURN(outattrs, f_iosize, vfs_devblocksize(mp));
383 VFSATTR_RETURN(outattrs, f_blocks, 2000000);
384 VFSATTR_RETURN(outattrs, f_bfree, 2000000);
385 VFSATTR_RETURN(outattrs, f_bavail, 2000000);
386 VFSATTR_RETURN(outattrs, f_files, 2000000);
387 VFSATTR_RETURN(outattrs, f_ffree, 2000000);
388 if ( VFSATTR_IS_ACTIVE(outattrs, f_capabilities) )
390 vol_capabilities_attr_t *vcapattrptr;
391 vcapattrptr = &outattrs->f_capabilities;
392 vcapattrptr->capabilities[VOL_CAPABILITIES_FORMAT] =
393 VOL_CAP_FMT_SYMBOLICLINKS |
394 VOL_CAP_FMT_HARDLINKS |
395 VOL_CAP_FMT_ZERO_RUNS |
396 VOL_CAP_FMT_CASE_SENSITIVE |
397 VOL_CAP_FMT_CASE_PRESERVING |
398 VOL_CAP_FMT_FAST_STATFS;
399 vcapattrptr->capabilities[VOL_CAPABILITIES_INTERFACES] =
400 VOL_CAP_INT_ADVLOCK |
402 vcapattrptr->capabilities[VOL_CAPABILITIES_RESERVED1] = 0;
403 vcapattrptr->capabilities[VOL_CAPABILITIES_RESERVED2] = 0;
405 /* Capabilities we know about: */
406 vcapattrptr->valid[VOL_CAPABILITIES_FORMAT] =
407 VOL_CAP_FMT_PERSISTENTOBJECTIDS |
408 VOL_CAP_FMT_SYMBOLICLINKS |
409 VOL_CAP_FMT_HARDLINKS |
410 VOL_CAP_FMT_JOURNAL |
411 VOL_CAP_FMT_JOURNAL_ACTIVE |
412 VOL_CAP_FMT_NO_ROOT_TIMES |
413 VOL_CAP_FMT_SPARSE_FILES |
414 VOL_CAP_FMT_ZERO_RUNS |
415 VOL_CAP_FMT_CASE_SENSITIVE |
416 VOL_CAP_FMT_CASE_PRESERVING |
417 VOL_CAP_FMT_FAST_STATFS;
418 vcapattrptr->valid[VOL_CAPABILITIES_INTERFACES] =
419 VOL_CAP_INT_SEARCHFS |
420 VOL_CAP_INT_ATTRLIST |
421 VOL_CAP_INT_NFSEXPORT |
422 VOL_CAP_INT_READDIRATTR |
423 VOL_CAP_INT_EXCHANGEDATA |
424 VOL_CAP_INT_COPYFILE |
425 VOL_CAP_INT_ALLOCATE |
426 VOL_CAP_INT_VOL_RENAME |
427 VOL_CAP_INT_ADVLOCK |
429 vcapattrptr->valid[VOL_CAPABILITIES_RESERVED1] = 0;
430 vcapattrptr->valid[VOL_CAPABILITIES_RESERVED2] = 0;
432 VFSATTR_SET_SUPPORTED(outattrs, f_capabilities);
438 #ifdef AFS_DARWIN80_ENV
440 afs_sync(struct mount *mp, int waitfor, CTX_TYPE ctx)
443 afs_sync(struct mount *mp, int waitfor, struct ucred *cred, struct proc *p)
449 u_int32_t afs_darwin_realmodes = 0;
450 u_int32_t afs_darwin_fsevents = 0;
451 extern int AFSDOBULK;
454 afs_sysctl_int(int *name, u_int namelen, user_addr_t oldp, size_t *oldlenp,
455 user_addr_t newp, size_t newlen, u_int32_t *object)
457 #ifdef AFS_DARWIN80_ENV
460 if (oldp != USER_ADDR_NULL && oldlenp == NULL)
462 if (oldp && *oldlenp < sizeof(u_int32_t))
464 if (newp && newlen != sizeof(u_int32_t))
466 *oldlenp = sizeof(u_int32_t);
468 if ((error = copyout(object,
469 oldp, sizeof(u_int32_t)))) {
474 return copyin(newp, object, sizeof(u_int32_t));
477 return sysctl_int(oldp, oldlenp, newp, newlen,
482 #ifdef AFS_DARWIN80_ENV
484 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)
488 afs_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp,
489 void *newp, size_t newlen, struct proc *p)
494 /* nothing defined */
500 case AFS_SC_DARWIN_ALL:
502 case AFS_SC_DARWIN_ALL_REALMODES:
503 return afs_sysctl_int(name, namelen, oldp, oldlenp,
504 newp, newlen, &afs_darwin_realmodes);
505 case AFS_SC_DARWIN_ALL_FSEVENTS:
506 return afs_sysctl_int(name, namelen, oldp, oldlenp,
507 newp, newlen, &afs_darwin_fsevents);
508 case AFS_SC_DARWIN_ALL_BULKSTAT:
509 return afs_sysctl_int(name, namelen, oldp, oldlenp,
510 newp, newlen, &AFSDOBULK);
513 /* darwin version specific sysctl's goes here */
521 extern int vfs_opv_numops; /* The total number of defined vnode operations */
522 extern struct vnodeopv_desc afs_vnodeop_opv_desc;
524 afs_init(struct vfsconf *vfc)
526 #ifndef AFS_DARWIN80_ENV /* vfs_fsadd does all this junk */
528 int (**opv_desc_vector) ();
529 struct vnodeopv_entry_desc *opve_descp;
533 MALLOC(afs_vnodeop_p, PFI *, vfs_opv_numops * sizeof(PFI), M_TEMP,
536 memset(afs_vnodeop_p, 0, vfs_opv_numops * sizeof(PFI));
538 opv_desc_vector = afs_vnodeop_p;
539 for (j = 0; afs_vnodeop_opv_desc.opv_desc_ops[j].opve_op; j++) {
540 opve_descp = &(afs_vnodeop_opv_desc.opv_desc_ops[j]);
543 * Sanity check: is this operation listed
544 * in the list of operations? We check this
545 * by seeing if its offest is zero. Since
546 * the default routine should always be listed
547 * first, it should be the only one with a zero
548 * offset. Any other operation with a zero
549 * offset is probably not listed in
550 * vfs_op_descs, and so is probably an error.
552 * A panic here means the layer programmer
553 * has committed the all-too common bug
554 * of adding a new operation to the layer's
555 * list of vnode operations but
556 * not adding the operation to the system-wide
557 * list of supported operations.
559 if (opve_descp->opve_op->vdesc_offset == 0
560 && opve_descp->opve_op->vdesc_offset != VOFFSET(vop_default)) {
561 printf("afs_init: operation %s not listed in %s.\n",
562 opve_descp->opve_op->vdesc_name, "vfs_op_descs");
563 panic("load_afs: bad operation");
566 * Fill in this entry.
568 opv_desc_vector[opve_descp->opve_op->vdesc_offset] =
569 opve_descp->opve_impl;
573 * Finally, go back and replace unfilled routines
574 * with their default. (Sigh, an O(n^3) algorithm. I
575 * could make it better, but that'd be work, and n is small.)
579 * Force every operations vector to have a default routine.
581 opv_desc_vector = afs_vnodeop_p;
582 if (opv_desc_vector[VOFFSET(vop_default)] == NULL) {
583 panic("afs_init: operation vector without default routine.");
585 for (j = 0; j < vfs_opv_numops; j++)
586 if (opv_desc_vector[j] == NULL)
587 opv_desc_vector[j] = opv_desc_vector[VOFFSET(vop_default)];
592 struct vfsops afs_vfsops = {
597 #ifdef AFS_DARWIN80_ENV
605 #ifdef AFS_DARWIN80_ENV
614 #ifdef AFS_DARWIN80_ENV