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, NULL, NULL);
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_type = MOUNT_AFS;
364 abp->f_blocks = abp->f_bfree = abp->f_bavail = abp->f_files =
365 abp->f_ffree = AFS_VFS_FAKEFREE;
367 if (abp != sysstat) {
368 abp->f_fsid.val[0] = sysstat->f_fsid.val[0];
369 abp->f_fsid.val[1] = sysstat->f_fsid.val[1];
370 #ifndef AFS_DARWIN80_ENV
371 abp->f_type = vfs_typenum(mp);
373 memcpy((caddr_t) & abp->f_mntonname[0],
374 (caddr_t) sysstat->f_mntonname, MNAMELEN);
375 memcpy((caddr_t) & abp->f_mntfromname[0],
376 (caddr_t) sysstat->f_mntfromname, MNAMELEN);
383 #ifdef AFS_DARWIN80_ENV
385 afs_vfs_getattr(struct mount *mp, struct vfs_attr *outattrs,
386 vfs_context_t context)
388 VFSATTR_RETURN(outattrs, f_bsize, vfs_devblocksize(mp));
389 VFSATTR_RETURN(outattrs, f_iosize, vfs_devblocksize(mp));
390 VFSATTR_RETURN(outattrs, f_blocks, 2000000);
391 VFSATTR_RETURN(outattrs, f_bfree, 2000000);
392 VFSATTR_RETURN(outattrs, f_bavail, 2000000);
393 VFSATTR_RETURN(outattrs, f_files, 2000000);
394 VFSATTR_RETURN(outattrs, f_ffree, 2000000);
395 if ( VFSATTR_IS_ACTIVE(outattrs, f_capabilities) )
397 vol_capabilities_attr_t *vcapattrptr;
398 vcapattrptr = &outattrs->f_capabilities;
399 vcapattrptr->capabilities[VOL_CAPABILITIES_FORMAT] =
400 VOL_CAP_FMT_SYMBOLICLINKS |
401 VOL_CAP_FMT_HARDLINKS |
402 VOL_CAP_FMT_ZERO_RUNS |
403 VOL_CAP_FMT_CASE_SENSITIVE |
404 VOL_CAP_FMT_CASE_PRESERVING |
405 VOL_CAP_FMT_PERSISTENTOBJECTIDS |
406 VOL_CAP_FMT_2TB_FILESIZE |
407 VOL_CAP_FMT_FAST_STATFS;
408 vcapattrptr->capabilities[VOL_CAPABILITIES_INTERFACES] =
409 VOL_CAP_INT_ADVLOCK |
411 vcapattrptr->capabilities[VOL_CAPABILITIES_RESERVED1] = 0;
412 vcapattrptr->capabilities[VOL_CAPABILITIES_RESERVED2] = 0;
414 /* Capabilities we know about: */
415 vcapattrptr->valid[VOL_CAPABILITIES_FORMAT] =
416 VOL_CAP_FMT_PERSISTENTOBJECTIDS |
417 VOL_CAP_FMT_SYMBOLICLINKS |
418 VOL_CAP_FMT_HARDLINKS |
419 VOL_CAP_FMT_JOURNAL |
420 VOL_CAP_FMT_JOURNAL_ACTIVE |
421 VOL_CAP_FMT_NO_ROOT_TIMES |
422 VOL_CAP_FMT_SPARSE_FILES |
423 VOL_CAP_FMT_ZERO_RUNS |
424 VOL_CAP_FMT_CASE_SENSITIVE |
425 VOL_CAP_FMT_CASE_PRESERVING |
426 VOL_CAP_FMT_PERSISTENTOBJECTIDS |
427 VOL_CAP_FMT_2TB_FILESIZE |
428 VOL_CAP_FMT_FAST_STATFS;
429 vcapattrptr->valid[VOL_CAPABILITIES_INTERFACES] =
430 VOL_CAP_INT_SEARCHFS |
431 VOL_CAP_INT_ATTRLIST |
432 VOL_CAP_INT_NFSEXPORT |
433 VOL_CAP_INT_READDIRATTR |
434 VOL_CAP_INT_EXCHANGEDATA |
435 VOL_CAP_INT_COPYFILE |
436 VOL_CAP_INT_ALLOCATE |
437 VOL_CAP_INT_VOL_RENAME |
438 VOL_CAP_INT_ADVLOCK |
440 vcapattrptr->valid[VOL_CAPABILITIES_RESERVED1] = 0;
441 vcapattrptr->valid[VOL_CAPABILITIES_RESERVED2] = 0;
443 VFSATTR_SET_SUPPORTED(outattrs, f_capabilities);
449 #ifdef AFS_DARWIN80_ENV
451 afs_sync(struct mount *mp, int waitfor, CTX_TYPE ctx)
454 afs_sync(struct mount *mp, int waitfor, struct ucred *cred, struct proc *p)
460 u_int32_t afs_darwin_realmodes = 0;
461 u_int32_t afs_darwin_fsevents = 0;
462 extern int AFSDOBULK;
465 afs_sysctl_int(int *name, u_int namelen, user_addr_t oldp, size_t *oldlenp,
466 user_addr_t newp, size_t newlen, u_int32_t *object)
468 #ifdef AFS_DARWIN80_ENV
471 if (oldp != USER_ADDR_NULL && oldlenp == NULL)
473 if (oldp && *oldlenp < sizeof(u_int32_t))
475 if (newp && newlen != sizeof(u_int32_t))
477 *oldlenp = sizeof(u_int32_t);
479 if ((error = copyout(object,
480 oldp, sizeof(u_int32_t)))) {
485 return copyin(newp, object, sizeof(u_int32_t));
488 return sysctl_int(oldp, oldlenp, newp, newlen,
493 #ifdef AFS_DARWIN80_ENV
495 afs_sysctl(int *name, u_int namelen, user_addr_t oldp, size_t *oldlenp,
496 user_addr_t newp, size_t newlen, vfs_context_t context)
499 afs_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp,
500 void *newp, size_t newlen, struct proc *p)
505 /* nothing defined */
511 case AFS_SC_DARWIN_ALL:
513 case AFS_SC_DARWIN_ALL_REALMODES:
514 return afs_sysctl_int(name, namelen, oldp, oldlenp,
515 newp, newlen, &afs_darwin_realmodes);
516 case AFS_SC_DARWIN_ALL_FSEVENTS:
517 return afs_sysctl_int(name, namelen, oldp, oldlenp,
518 newp, newlen, &afs_darwin_fsevents);
519 case AFS_SC_DARWIN_ALL_BULKSTAT:
520 return afs_sysctl_int(name, namelen, oldp, oldlenp,
521 newp, newlen, &AFSDOBULK);
524 /* darwin version specific sysctl's goes here */
532 extern int vfs_opv_numops; /* The total number of defined vnode operations */
533 extern struct vnodeopv_desc afs_vnodeop_opv_desc;
535 afs_init(struct vfsconf *vfc)
537 #ifndef AFS_DARWIN80_ENV /* vfs_fsadd does all this junk */
539 int (**opv_desc_vector) ();
540 struct vnodeopv_entry_desc *opve_descp;
544 MALLOC(afs_vnodeop_p, PFI *, vfs_opv_numops * sizeof(PFI), M_TEMP,
547 memset(afs_vnodeop_p, 0, vfs_opv_numops * sizeof(PFI));
549 opv_desc_vector = afs_vnodeop_p;
550 for (j = 0; afs_vnodeop_opv_desc.opv_desc_ops[j].opve_op; j++) {
551 opve_descp = &(afs_vnodeop_opv_desc.opv_desc_ops[j]);
554 * Sanity check: is this operation listed
555 * in the list of operations? We check this
556 * by seeing if its offest is zero. Since
557 * the default routine should always be listed
558 * first, it should be the only one with a zero
559 * offset. Any other operation with a zero
560 * offset is probably not listed in
561 * vfs_op_descs, and so is probably an error.
563 * A panic here means the layer programmer
564 * has committed the all-too common bug
565 * of adding a new operation to the layer's
566 * list of vnode operations but
567 * not adding the operation to the system-wide
568 * list of supported operations.
570 if (opve_descp->opve_op->vdesc_offset == 0
571 && opve_descp->opve_op->vdesc_offset != VOFFSET(vop_default)) {
572 printf("afs_init: operation %s not listed in %s.\n",
573 opve_descp->opve_op->vdesc_name, "vfs_op_descs");
574 panic("load_afs: bad operation");
577 * Fill in this entry.
579 opv_desc_vector[opve_descp->opve_op->vdesc_offset] =
580 opve_descp->opve_impl;
584 * Finally, go back and replace unfilled routines
585 * with their default. (Sigh, an O(n^3) algorithm. I
586 * could make it better, but that'd be work, and n is small.)
590 * Force every operations vector to have a default routine.
592 opv_desc_vector = afs_vnodeop_p;
593 if (opv_desc_vector[VOFFSET(vop_default)] == NULL) {
594 panic("afs_init: operation vector without default routine.");
596 for (j = 0; j < vfs_opv_numops; j++)
597 if (opv_desc_vector[j] == NULL)
598 opv_desc_vector[j] = opv_desc_vector[VOFFSET(vop_default)];
603 struct vfsops afs_vfsops = {
608 #ifdef AFS_DARWIN80_ENV
616 #ifdef AFS_DARWIN80_ENV
625 #ifdef AFS_DARWIN80_ENV