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;
227 #ifdef AFS_DARWIN80_ENV
228 struct ucred *cr = vfs_context_ucred(ctx);
230 struct proc *p = current_proc();
232 struct ucred *cr = &_cr;
235 _cr = *p->p_cred->pc_ucred;
239 AFS_STATCNT(afs_root);
242 if (mdata == NULL && afs_globalVp
243 && (afs_globalVp->f.states & CStatd)) {
247 } else if (mdata == (qaddr_t) - 1) {
250 struct VenusFid *rootFid = (mdata == NULL)
251 ? &afs_rootFid : (struct VenusFid *)mdata;
253 if (!(error = afs_InitReq(&treq, cr)) && !(error = afs_CheckInit())) {
254 tvp = afs_GetVCache(rootFid, &treq);
255 #ifdef AFS_DARWIN80_ENV
258 error = afs_darwin_finalizevnode(tvp, NULL, NULL, 1, 0);
263 /* re-acquire the usecount that finalizevnode disposed of */
264 vnode_ref(AFSTOV(tvp));
267 /* we really want this to stay around */
274 if (tvp != afs_globalVp) {
275 /* someone else got there before us! */
288 #ifndef AFS_DARWIN80_ENV /* KPI callers don't need a usecount reference */
291 vn_lock(AFSTOV(tvp), LK_EXCLUSIVE | LK_RETRY, p);
296 #ifdef AFS_DARWIN80_ENV
297 /* This iocount is for the caller. the initial iocount
298 * is for the eventual afs_PutVCache. for mdata != null,
299 * there will not be a PutVCache, so the caller gets the
300 * initial (from GetVCache or finalizevnode) iocount
302 vnode_get(AFSTOV(tvp));
311 #ifndef AFS_DARWIN80_ENV
312 AFSTOV(tvp)->v_flag |= VROOT;
313 AFSTOV(tvp)->v_vfsp = mp;
317 afs_Trace2(afs_iclSetp, CM_TRACE_VFSROOT, ICL_TYPE_POINTER, *vpp,
318 ICL_TYPE_INT32, error);
323 #ifndef AFS_DARWIN80_ENV /* vget vfsop never had this prototype AFAIK */
325 afs_vget(struct mount *mp, int lfl, struct vnode *vp)
328 //printf("vget called. help!\n");
329 if (vp->v_usecount < 0) {
330 vprint("bad usecount", vp);
333 error = vget(vp, lfl, current_proc());
335 insmntque(vp, mp); /* take off free list */
339 int afs_vfs_vget(struct mount *mp, void *ino, struct vnode **vpp)
341 return ENOENT; /* cannot implement */
347 afs_statfs(struct mount *mp, STATFS_TYPE *abp, CTX_TYPE ctx)
349 STATFS_TYPE *sysstat = vfs_statfs(mp);
351 AFS_STATCNT(afs_statfs);
353 #ifdef AFS_DARWIN80_ENV
354 abp->f_iosize = (256 * 1024);
355 abp->f_bsize = vfs_devblocksize(mp);
357 abp->f_bsize = mp->vfs_bsize;
358 abp->f_iosize = mp->vfs_bsize;
361 abp->f_blocks = abp->f_bfree = abp->f_bavail = abp->f_files =
362 abp->f_ffree = AFS_VFS_FAKEFREE;
364 if (abp != sysstat) {
365 abp->f_fsid.val[0] = sysstat->f_fsid.val[0];
366 abp->f_fsid.val[1] = sysstat->f_fsid.val[1];
367 #ifndef AFS_DARWIN80_ENV
368 abp->f_type = vfs_typenum(mp);
370 memcpy((caddr_t) & abp->f_mntonname[0],
371 (caddr_t) sysstat->f_mntonname, MNAMELEN);
372 memcpy((caddr_t) & abp->f_mntfromname[0],
373 (caddr_t) sysstat->f_mntfromname, MNAMELEN);
380 #ifdef AFS_DARWIN80_ENV
382 afs_vfs_getattr(struct mount *mp, struct vfs_attr *outattrs,
383 vfs_context_t context)
385 VFSATTR_RETURN(outattrs, f_bsize, vfs_devblocksize(mp));
386 VFSATTR_RETURN(outattrs, f_iosize, vfs_devblocksize(mp));
387 VFSATTR_RETURN(outattrs, f_blocks, 2000000);
388 VFSATTR_RETURN(outattrs, f_bfree, 2000000);
389 VFSATTR_RETURN(outattrs, f_bavail, 2000000);
390 VFSATTR_RETURN(outattrs, f_files, 2000000);
391 VFSATTR_RETURN(outattrs, f_ffree, 2000000);
392 if ( VFSATTR_IS_ACTIVE(outattrs, f_capabilities) )
394 vol_capabilities_attr_t *vcapattrptr;
395 vcapattrptr = &outattrs->f_capabilities;
396 vcapattrptr->capabilities[VOL_CAPABILITIES_FORMAT] =
397 VOL_CAP_FMT_SYMBOLICLINKS |
398 VOL_CAP_FMT_HARDLINKS |
399 VOL_CAP_FMT_ZERO_RUNS |
400 VOL_CAP_FMT_CASE_SENSITIVE |
401 VOL_CAP_FMT_CASE_PRESERVING |
402 VOL_CAP_FMT_PERSISTENTOBJECTIDS |
403 VOL_CAP_FMT_2TB_FILESIZE |
404 VOL_CAP_FMT_FAST_STATFS;
405 vcapattrptr->capabilities[VOL_CAPABILITIES_INTERFACES] =
406 VOL_CAP_INT_ADVLOCK |
408 vcapattrptr->capabilities[VOL_CAPABILITIES_RESERVED1] = 0;
409 vcapattrptr->capabilities[VOL_CAPABILITIES_RESERVED2] = 0;
411 /* Capabilities we know about: */
412 vcapattrptr->valid[VOL_CAPABILITIES_FORMAT] =
413 VOL_CAP_FMT_PERSISTENTOBJECTIDS |
414 VOL_CAP_FMT_SYMBOLICLINKS |
415 VOL_CAP_FMT_HARDLINKS |
416 VOL_CAP_FMT_JOURNAL |
417 VOL_CAP_FMT_JOURNAL_ACTIVE |
418 VOL_CAP_FMT_NO_ROOT_TIMES |
419 VOL_CAP_FMT_SPARSE_FILES |
420 VOL_CAP_FMT_ZERO_RUNS |
421 VOL_CAP_FMT_CASE_SENSITIVE |
422 VOL_CAP_FMT_CASE_PRESERVING |
423 VOL_CAP_FMT_PERSISTENTOBJECTIDS |
424 VOL_CAP_FMT_2TB_FILESIZE |
425 VOL_CAP_FMT_FAST_STATFS;
426 vcapattrptr->valid[VOL_CAPABILITIES_INTERFACES] =
427 VOL_CAP_INT_SEARCHFS |
428 VOL_CAP_INT_ATTRLIST |
429 VOL_CAP_INT_NFSEXPORT |
430 VOL_CAP_INT_READDIRATTR |
431 VOL_CAP_INT_EXCHANGEDATA |
432 VOL_CAP_INT_COPYFILE |
433 VOL_CAP_INT_ALLOCATE |
434 VOL_CAP_INT_VOL_RENAME |
435 VOL_CAP_INT_ADVLOCK |
437 vcapattrptr->valid[VOL_CAPABILITIES_RESERVED1] = 0;
438 vcapattrptr->valid[VOL_CAPABILITIES_RESERVED2] = 0;
440 VFSATTR_SET_SUPPORTED(outattrs, f_capabilities);
446 #ifdef AFS_DARWIN80_ENV
448 afs_sync(struct mount *mp, int waitfor, CTX_TYPE ctx)
451 afs_sync(struct mount *mp, int waitfor, struct ucred *cred, struct proc *p)
457 u_int32_t afs_darwin_realmodes = 0;
458 u_int32_t afs_darwin_fsevents = 0;
459 extern int AFSDOBULK;
462 afs_sysctl_int(int *name, u_int namelen, user_addr_t oldp, size_t *oldlenp,
463 user_addr_t newp, size_t newlen, u_int32_t *object)
465 #ifdef AFS_DARWIN80_ENV
468 if (oldp != USER_ADDR_NULL && oldlenp == NULL)
470 if (oldp && *oldlenp < sizeof(u_int32_t))
472 if (newp && newlen != sizeof(u_int32_t))
474 *oldlenp = sizeof(u_int32_t);
476 if ((error = copyout(object,
477 oldp, sizeof(u_int32_t)))) {
482 return copyin(newp, object, sizeof(u_int32_t));
485 return sysctl_int(oldp, oldlenp, newp, newlen,
490 #ifdef AFS_DARWIN80_ENV
492 afs_sysctl(int *name, u_int namelen, user_addr_t oldp, size_t *oldlenp,
493 user_addr_t newp, size_t newlen, vfs_context_t context)
496 afs_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp,
497 void *newp, size_t newlen, struct proc *p)
502 /* nothing defined */
508 case AFS_SC_DARWIN_ALL:
510 case AFS_SC_DARWIN_ALL_REALMODES:
511 return afs_sysctl_int(name, namelen, oldp, oldlenp,
512 newp, newlen, &afs_darwin_realmodes);
513 case AFS_SC_DARWIN_ALL_FSEVENTS:
514 return afs_sysctl_int(name, namelen, oldp, oldlenp,
515 newp, newlen, &afs_darwin_fsevents);
516 case AFS_SC_DARWIN_ALL_BULKSTAT:
517 return afs_sysctl_int(name, namelen, oldp, oldlenp,
518 newp, newlen, &AFSDOBULK);
521 /* darwin version specific sysctl's goes here */
529 extern int vfs_opv_numops; /* The total number of defined vnode operations */
530 extern struct vnodeopv_desc afs_vnodeop_opv_desc;
532 afs_init(struct vfsconf *vfc)
534 #ifndef AFS_DARWIN80_ENV /* vfs_fsadd does all this junk */
536 int (**opv_desc_vector) ();
537 struct vnodeopv_entry_desc *opve_descp;
541 MALLOC(afs_vnodeop_p, PFI *, vfs_opv_numops * sizeof(PFI), M_TEMP,
544 memset(afs_vnodeop_p, 0, vfs_opv_numops * sizeof(PFI));
546 opv_desc_vector = afs_vnodeop_p;
547 for (j = 0; afs_vnodeop_opv_desc.opv_desc_ops[j].opve_op; j++) {
548 opve_descp = &(afs_vnodeop_opv_desc.opv_desc_ops[j]);
551 * Sanity check: is this operation listed
552 * in the list of operations? We check this
553 * by seeing if its offest is zero. Since
554 * the default routine should always be listed
555 * first, it should be the only one with a zero
556 * offset. Any other operation with a zero
557 * offset is probably not listed in
558 * vfs_op_descs, and so is probably an error.
560 * A panic here means the layer programmer
561 * has committed the all-too common bug
562 * of adding a new operation to the layer's
563 * list of vnode operations but
564 * not adding the operation to the system-wide
565 * list of supported operations.
567 if (opve_descp->opve_op->vdesc_offset == 0
568 && opve_descp->opve_op->vdesc_offset != VOFFSET(vop_default)) {
569 printf("afs_init: operation %s not listed in %s.\n",
570 opve_descp->opve_op->vdesc_name, "vfs_op_descs");
571 panic("load_afs: bad operation");
574 * Fill in this entry.
576 opv_desc_vector[opve_descp->opve_op->vdesc_offset] =
577 opve_descp->opve_impl;
581 * Finally, go back and replace unfilled routines
582 * with their default. (Sigh, an O(n^3) algorithm. I
583 * could make it better, but that'd be work, and n is small.)
587 * Force every operations vector to have a default routine.
589 opv_desc_vector = afs_vnodeop_p;
590 if (opv_desc_vector[VOFFSET(vop_default)] == NULL) {
591 panic("afs_init: operation vector without default routine.");
593 for (j = 0; j < vfs_opv_numops; j++)
594 if (opv_desc_vector[j] == NULL)
595 opv_desc_vector[j] = opv_desc_vector[VOFFSET(vop_default)];
600 struct vfsops afs_vfsops = {
605 #ifdef AFS_DARWIN80_ENV
613 #ifdef AFS_DARWIN80_ENV
622 #ifdef AFS_DARWIN80_ENV