Standardize License information
[openafs.git] / src / afs / IRIX / osi_vfsops.c
1 /*
2  * Copyright 2000, International Business Machines Corporation and others.
3  * All Rights Reserved.
4  * 
5  * This software has been released under the terms of the IBM Public
6  * License.  For details, see the LICENSE file in the top-level source
7  * directory or online at http://www.openafs.org/dl/license10.html
8  */
9
10 /*
11  * osi_vfsops.c for IRIX
12  */
13 #include "../afs/param.h"       /* Should be always first */
14 #include "../afs/sysincludes.h" /* Standard vendor system headers */
15 #include "../afs/afsincludes.h" /* Afs-based standard headers */
16 #include "../afs/afs_stats.h"   /* statistics stuff */
17 #include "sys/syssgi.h"
18
19
20 struct vfs *afs_globalVFS = 0;
21 struct vcache *afs_globalVp = 0;
22
23 #ifdef AFS_SGI_VNODE_GLUE
24 #include <sys/invent.h>
25 int afs_is_numa_arch;
26 mutex_t afs_init_kern_lock;
27 #endif
28
29
30 #define SYS_setgroups SGI_SETGROUPS
31
32 int (*nfs_rfsdisptab_v2)() = NULL;
33
34 int afs_fstype;
35 lock_t afs_rxlock;
36
37 #include "sys/mload.h"
38 char *Afs_mversion = M_VERSION;
39
40 extern int (*setgroupsp)(int, gid_t *);
41 extern struct afs_lock afs_xvcache;
42 extern int idbg_afsuser();
43 extern void afs_mpservice(void *);
44
45 /*
46  * AFS fs initialization - we also plug system calls here
47  */
48 #define NewSystemCall(n,f,a) \
49         syscallsw[ABI_IRIX5].sc_sysent[(n)-1000].sy_narg = a; \
50         syscallsw[ABI_IRIX5].sc_sysent[(n)-1000].sy_call = f; \
51         syscallsw[ABI_IRIX5].sc_sysent[(n)-1000].sy_flags = 0;
52 extern struct vfsops Afs_vfsops, *afs_vfsopsp;
53 extern struct vnodeops Afs_vnodeops, *afs_vnodeopsp;
54 extern void (*afsidestroyp)(struct inode *);
55 extern void (*afsdptoipp)(struct efs_dinode *, struct inode *);
56 extern void (*afsiptodpp)(struct inode *, struct efs_dinode *);
57 extern void afsidestroy(struct inode *);
58 extern void afsdptoip(struct efs_dinode *, struct inode *);
59 extern void afsiptodp(struct inode *, struct efs_dinode *);
60 extern int (*idbg_prafsnodep)(vnode_t *);
61 extern int (*idbg_afsvfslistp)(void);
62 extern int idbg_prafsnode(vnode_t *);
63 extern int idbg_afsvfslist(void);
64
65
66 int
67 Afs_init(struct vfssw *vswp, int fstype)
68 {
69     extern int Afs_syscall(), Afs_xsetgroups(), afs_pioctl(), afs_setpag();
70     extern int icreate(), iopen(), iinc(), idec();
71 #ifdef AFS_SGI_XFS_IOPS_ENV
72     extern int iopen64();
73 #else
74     extern int iread(), iwrite();
75 #endif
76
77     AFS_STATCNT(afsinit);
78     osi_Init();
79     afs_fstype = fstype;
80
81 #ifdef AFS_SGI_VNODE_GLUE
82     /* Synchronize doing NUMA test. */
83     mutex_init(&afs_init_kern_lock, MUTEX_DEFAULT, "init_kern_lock");
84 #endif
85     /*
86      * set up pointers from main kernel into us
87      */
88     afs_vnodeopsp = &Afs_vnodeops;
89     afs_vfsopsp = &Afs_vfsops;
90     afsidestroyp = afsidestroy;
91     afsiptodpp = afsiptodp;
92     afsdptoipp = afsdptoip;
93     idbg_prafsnodep = idbg_prafsnode;
94     idbg_afsvfslistp = idbg_afsvfslist;
95     NewSystemCall (AFS_SYSCALL, Afs_syscall, 6);
96     NewSystemCall (AFS_PIOCTL, afs_pioctl, 4);
97     NewSystemCall (AFS_SETPAG, afs_setpag, 0);
98     NewSystemCall (AFS_IOPEN, iopen, 3);
99     NewSystemCall (AFS_ICREATE, icreate, 6);
100     NewSystemCall (AFS_IINC, iinc, 3);
101     NewSystemCall (AFS_IDEC, idec, 3);
102 #ifdef AFS_SGI_XFS_IOPS_ENV
103     NewSystemCall (AFS_IOPEN64, iopen64, 4);
104 #else
105     NewSystemCall (AFS_IREAD, iread, 6);
106     NewSystemCall (AFS_IWRITE, iwrite, 6);
107 #endif
108
109     /* last replace these */
110     setgroupsp = Afs_xsetgroups;
111
112     idbg_addfunc("afsuser", idbg_afsuser);
113     return (0);
114 }
115
116
117 extern int afs_mount(), afs_unmount(), afs_root(), afs_statfs();
118 #ifdef AFS_SGI65_ENV
119 extern int afs_sync(OSI_VFS_DECL(afsp), int flags, struct cred *cr);
120 #else
121 extern int afs_sync(OSI_VFS_DECL(afsp), short flags, struct cred *cr);
122 #endif
123 extern int afs_vget(OSI_VFS_DECL(afsp), vnode_t **vpp, struct fid *afidp);
124 #ifdef MP
125 struct vfsops afs_lockedvfsops =
126 #else
127 struct vfsops Afs_vfsops =
128 #endif
129 {
130 #ifdef AFS_SGI64_ENV
131 #ifdef AFS_SGI65_ENV
132     BHV_IDENTITY_INIT_POSITION(VFS_POSITION_BASE),
133 #else
134     VFS_POSITION_BASE,
135 #endif
136 #endif
137     afs_mount,
138 #ifdef AFS_SGI64_ENV
139     fs_nosys, /* rootinit */
140     fs_nosys, /* mntupdate */
141     fs_dounmount,
142 #endif
143     afs_unmount,
144     afs_root,
145     afs_statfs,
146     afs_sync,
147     afs_vget,
148     fs_nosys, /* mountroot */
149 #ifdef AFS_SGI65_ENV
150     fs_nosys,   /* realvfsops */
151     fs_import,  /* import */
152     fs_nosys,   /* quotactl */
153 #else
154     fs_nosys, /* swapvp */
155 #endif
156 };
157 extern struct afs_q VLRU;                       /*vcache LRU*/
158
159 #ifdef AFS_SGI64_ENV
160 static bhv_desc_t afs_vfs_bhv;
161 #endif
162 afs_mount(struct vfs *afsp, vnode_t *mvp, struct mounta *uap,
163 #ifdef AFS_SGI65_ENV
164           char *attrs,
165 #endif
166           cred_t *cr)
167 {
168     AFS_STATCNT(afs_mount);
169
170     if (!suser())
171         return EPERM;
172
173     if (mvp->v_type != VDIR)
174         return ENOTDIR;
175
176     if (afs_globalVFS) { /* Don't allow remounts. */
177         return EBUSY;
178     }
179
180     afs_globalVFS = afsp;
181     afsp->vfs_bsize = 8192;
182     afsp->vfs_fsid.val[0] = AFS_VFSMAGIC; /* magic */
183     afsp->vfs_fsid.val[1] = afs_fstype; 
184 #ifdef AFS_SGI64_ENV
185     vfs_insertbhv(afsp, &afs_vfs_bhv, &Afs_vfsops, &afs_vfs_bhv);
186 #else
187     afsp->vfs_data = NULL;
188 #endif
189     afsp->vfs_fstype = afs_fstype;
190     afsp->vfs_dev = 0xbabebabe; /* XXX this should be unique */
191
192 #ifndef AFS_NONFSTRANS
193     if (nfs_rfsdisptab_v2)
194         afs_xlatorinit_v2(nfs_rfsdisptab_v2);
195     afs_xlatorinit_v3();
196 #endif
197     return 0;
198 }
199
200 afs_unmount(OSI_VFS_ARG(afsp), flags, cr)
201 OSI_VFS_DECL(afsp);
202 int flags;
203 cred_t *cr;
204 {
205     extern int afs_afs_cold_shutdown;
206     struct vcache *tvc;
207     vnode_t *vp, *rootvp = NULL;
208     register struct afs_q *tq;
209     struct afs_q *uq;
210     int error, fv_slept;
211     OSI_VFS_CONVERT(afsp)
212
213     AFS_STATCNT(afs_unmount);
214
215     if (!suser())
216         return EPERM;
217
218     /*
219      * flush all pages from inactive vnodes - return
220      * EBUSY if any still in use
221      */
222     ObtainWriteLock(&afs_xvcache,172);
223     for (tq = VLRU.prev; tq != &VLRU; tq = uq) {
224         tvc = QTOV(tq);
225         uq = QPrev(tq);
226         vp = (vnode_t *)tvc;
227         if (error = afs_FlushVCache(tvc, &fv_slept))
228                 if (vp->v_flag & VROOT) {
229                         rootvp = vp;
230                         continue;
231                 } else {
232                         ReleaseWriteLock(&afs_xvcache);
233                         return error;
234                 }
235     }
236
237     /*
238      * rootvp gets lots of ref counts
239      */
240     if (rootvp) {
241         tvc = (struct vcache *)rootvp;
242         if (tvc->opens || CheckLock(&tvc->lock) || LockWaiters(&tvc->lock)) {
243             ReleaseWriteLock(&afs_xvcache);
244             return EBUSY;
245         }
246         ReleaseWriteLock(&afs_xvcache);
247         rootvp->v_count = 1;
248         AFS_RELE(rootvp);
249         ObtainWriteLock(&afs_xvcache,173);
250         afs_FlushVCache(tvc, &fv_slept);
251     }
252     ReleaseWriteLock(&afs_xvcache);
253     afs_globalVFS = 0;
254     afs_shutdown();
255 #ifdef AFS_SGI65_ENV
256     VFS_REMOVEBHV(afsp, &afs_vfs_bhv);
257 #endif
258     return 0;
259 }
260
261
262
263 afs_root (OSI_VFS_ARG(afsp), avpp)
264     OSI_VFS_DECL(afsp);
265     struct vnode **avpp;
266 {
267     register afs_int32 code = 0;
268     struct vrequest treq;
269     register struct vcache *tvp=0;
270     OSI_VFS_CONVERT(afsp)
271
272     AFS_STATCNT(afs_root);
273     if (afs_globalVp && (afs_globalVp->states & CStatd)) {
274         tvp = afs_globalVp;
275     } else {
276         if (!(code = afs_InitReq(&treq, OSI_GET_CURRENT_CRED())) &&
277             !(code = afs_CheckInit())) {
278             tvp = afs_GetVCache(&afs_rootFid, &treq, (afs_int32 *)0,
279                                 (struct vcache*)0, WRITE_LOCK);
280             /* we really want this to stay around */
281             if (tvp) {
282                 afs_globalVp = tvp;
283             } else
284                 code = ENOENT;
285         }
286     }
287     if (tvp) {
288         int s;
289         VN_HOLD((struct vnode *)tvp);
290         s = VN_LOCK((struct vnode *)tvp);
291         tvp->v.v_flag |= VROOT; 
292         VN_UNLOCK((struct vnode *)tvp, s);
293
294         afs_globalVFS = afsp;
295         *avpp = (struct vnode *) tvp;
296     }
297
298     afs_Trace2(afs_iclSetp, CM_TRACE_VFSROOT, ICL_TYPE_POINTER, *avpp,
299                ICL_TYPE_INT32, code);
300     return code;
301 }
302
303 afs_statfs(OSI_VFS_ARG(afsp), abp, avp)
304 OSI_VFS_DECL(afsp);
305 struct statvfs *abp;
306 struct vnode *avp; /* unused */
307 {
308     OSI_VFS_CONVERT(afsp)
309
310         AFS_STATCNT(afs_statfs);
311         abp->f_bsize = afsp->vfs_bsize;
312         abp->f_frsize = afsp->vfs_bsize;
313         /* Fake a high number below to satisfy programs that use the statfs
314          * call to make sure that there's enough space in the device partition
315          * before storing something there.
316          */
317         abp->f_blocks = abp->f_bfree = abp->f_bavail = abp->f_files =
318             abp->f_ffree  = abp->f_favail = 900000;
319
320         abp->f_fsid = AFS_VFSMAGIC; /* magic */
321         strcpy(abp->f_basetype, AFS_MOUNT_AFS);
322         abp->f_flag = 0;
323         abp->f_namemax = 256;
324         return 0;
325 }
326
327
328
329 /*
330  * sync's responsibilities include pushing back DELWRI pages
331  * Things to watch out for:
332  *      1) don't want to hold off new vnodes in the file system
333  *              while pushing back pages
334  *      2) since we can deal with un-referenced vndoes need to watch
335  *              races with folks who recycle vnodes
336  * Flags:
337  *      SYNC_BDFLUSH - do NOT sleep waiting for an inode - also, when
338  *                      when pushing DELWRI - only push old ones.
339  *      SYNC_PDFLUSH - push v_dpages.
340  *      SYNC_ATTR    - sync attributes - note that ordering considerations
341  *                      dictate that we also flush dirty pages
342  *      SYNC_WAIT    - do synchronouse writes - inode & delwri
343  *      SYNC_NOWAIT  - start delayed writes.
344  *      SYNC_DELWRI  - look at inodes w/ delwri pages. Other flags
345  *                      decide how to deal with them.
346  *      SYNC_CLOSE   - flush delwri and invalidate others.
347  *      SYNC_FSDATA  - push fs data (e.g. superblocks)
348  */
349
350 extern afs_int32 vcachegen;
351 #define PREEMPT_MASK    0x7f
352 #ifdef AFS_SGI64_ENV
353 #define PREEMPT()
354 #endif
355
356 int
357 afs_sync(OSI_VFS_DECL(afsp),
358 #ifdef AFS_SGI65_ENV
359          int flags,
360 #else
361          short flags,
362 #endif
363          struct cred *cr)
364 {
365     /* Why enable the vfs sync operation?? */
366         int error, lasterr, preempt;
367         struct vcache *tvc;
368         struct vnode *vp;
369         afs_uint32 lvcachegen;
370         register struct afs_q *tq;
371         struct afs_q *uq;
372         int s;
373         OSI_VFS_CONVERT(afsp)
374
375         error = lasterr = 0;
376         /*
377          * if not interested in vnodes, skip all this
378          */
379 #ifdef AFS_SGI61_ENV
380         if ((flags & (SYNC_CLOSE|SYNC_DELWRI|SYNC_PDFLUSH)) == 0)
381                 goto end;
382 #else /* AFS_SGI61_ENV */
383         if ((flags & (SYNC_CLOSE|SYNC_DELWRI|SYNC_ATTR)) == 0)
384                 goto end;
385 #endif /* AFS_SGI61_ENV */
386 loop:
387         ObtainReadLock(&afs_xvcache);
388         for (tq = VLRU.prev; tq != &VLRU; tq = uq) {
389                 tvc = QTOV(tq);
390                 uq = QPrev(tq);
391                 vp = (vnode_t *)tvc;
392                 /*
393                  * Since we push all dirty pages on last close/VOP_INACTIVE
394                  * we are only concerned with vnodes with
395                  * active reference counts.
396                  */
397                 s = VN_LOCK(vp);
398                 if (vp->v_count == 0) {
399                         VN_UNLOCK(vp, s);
400                         continue;
401                 }
402                 if ((flags & SYNC_CLOSE) == 0 && !AFS_VN_DIRTY(vp)) {
403                         VN_UNLOCK(vp, s);
404                         continue;
405                 }
406                 
407                 /*
408                  * ignore vnodes which need no flushing
409                  */
410                 if (flags & SYNC_DELWRI) {
411                     if (!AFS_VN_DIRTY(vp)) {
412                         VN_UNLOCK(vp, s);
413                         continue;
414                     }
415                 }
416 #ifdef AFS_SGI61_ENV
417                 else if (flags & SYNC_PDFLUSH) {
418                     if (!VN_GET_DPAGES(vp)) {
419                         VN_UNLOCK(vp, s);
420                         continue;
421                     }
422                 }
423 #endif /* AFS_SGI61_ENV */
424
425                 vp->v_count++;
426                 VN_UNLOCK(vp, s);
427                 lvcachegen = vcachegen;
428                 ReleaseReadLock(&afs_xvcache);
429
430                 /*
431                  * Try to lock rwlock without sleeping.  If we can't, we must
432                  * sleep for rwlock.
433                  */
434                 if (afs_rwlock_nowait(vp, 1) == 0) {
435 #ifdef AFS_SGI61_ENV
436                         if (flags & (SYNC_BDFLUSH | SYNC_PDFLUSH))
437 #else /* AFS_SGI61_ENV */
438                         if (flags & SYNC_BDFLUSH)
439 #endif /* AFS_SGI61_ENV */
440                             {
441                                 AFS_RELE(vp);
442                                 ObtainReadLock(&afs_xvcache);
443                                 if (vcachegen != lvcachegen) {
444                                         ReleaseReadLock(&afs_xvcache);
445                                         goto loop;
446                                 }
447                                 continue;
448                             }
449                         AFS_RWLOCK(vp, VRWLOCK_WRITE);
450                 }
451
452                 AFS_GUNLOCK();
453                 if (flags & SYNC_CLOSE) {
454                     PFLUSHINVALVP(vp, (off_t)0, (off_t)tvc->m.Length);
455                 }
456 #ifdef AFS_SGI61_ENV
457                 else if (flags & SYNC_PDFLUSH) {
458                         if (VN_GET_DPAGES(vp)) {
459                                 pdflush(vp, B_ASYNC);
460                         }
461                 }
462 #endif /* AFS_SGI61_ENV */
463
464
465                 if ((flags & SYNC_DELWRI) && AFS_VN_DIRTY(vp)) {
466 #ifdef AFS_SGI61_ENV
467                         PFLUSHVP(vp, (off_t)tvc->m.Length,
468                                  (flags & SYNC_WAIT) ? 0 : B_ASYNC, error);
469 #else /* AFS_SGI61_ENV */
470                         if (flags & SYNC_WAIT)
471                             /* push all and wait */
472                             PFLUSHVP(vp, (off_t)tvc->m.Length,
473                                      (off_t)0, error);
474                         else if (flags & SYNC_BDFLUSH) {
475                             /* push oldest */
476                             error = pdflush(vp, B_ASYNC);
477                         }
478                         else {
479                             /* push all but don't wait */
480                             PFLUSHVP(vp, (off_t)tvc->m.Length,
481                                      (off_t)B_ASYNC, error);
482                         }
483 #endif /* AFS_SGI61_ENV */
484                 }
485
486                 /*
487                  * Release vp, check error and whether to preempt, and if
488                  * we let go of xvcache lock and someone has changed the
489                  * VLRU, restart the loop
490                  */
491                 AFS_GLOCK();
492                 AFS_RWUNLOCK(vp, VRWLOCK_WRITE);
493                 AFS_RELE(vp);
494                 if (error)
495                         lasterr = error;
496                 if ((++preempt & PREEMPT_MASK) == 0) {
497                         AFS_GUNLOCK();
498                         PREEMPT();
499                         AFS_GLOCK();
500                 }
501                 ObtainReadLock(&afs_xvcache);
502                 if (vcachegen != lvcachegen) {
503                         ReleaseReadLock(&afs_xvcache);
504                         goto loop;
505                 }
506         }
507         ReleaseReadLock(&afs_xvcache);
508 end:
509         return lasterr;
510 }
511
512
513 afs_vget(OSI_VFS_DECL(afsp), vnode_t **avcp, struct fid *fidp)
514 {
515     struct VenusFid vfid;
516     struct vrequest treq;
517     extern struct cell *afs_GetCellByIndex();
518     register struct cell *tcell;
519     register afs_int32 code = 0;
520     afs_int32 ret;
521
522 #if defined(AFS_SGI64_ENV) && defined(CKPT)
523     afs_fid2_t *afid2;
524 #endif    
525
526     OSI_VFS_CONVERT(afsp)
527
528     AFS_STATCNT(afs_vget);
529
530     *avcp = NULL;
531
532 #if defined(AFS_SGI64_ENV) && defined(CKPT)
533     afid2 = (afs_fid2_t*)fidp;
534     if (afid2->af_len == sizeof(afs_fid2_t) - sizeof(afid2->af_len)) {
535         /* It's a checkpoint restart fid. */
536         tcell = afs_GetCellByIndex(afid2->af_cell, READ_LOCK);
537         if (!tcell) {
538             code = ENOENT;
539             goto out;
540         }
541         vfid.Cell = tcell->cell;
542         afs_PutCell(tcell, WRITE_LOCK);
543         vfid.Fid.Volume = afid2->af_volid;
544         vfid.Fid.Vnode = afid2->af_vno;
545         vfid.Fid.Unique = afid2->af_uniq;
546
547         if (code = afs_InitReq(&treq, OSI_GET_CURRENT_CRED()))
548             goto out;
549         *avcp = (vnode_t*) afs_GetVCache(&vfid, &treq, (afs_int32 *)0,
550                                          (struct vcache*)0, 0);
551         if (! *avcp) {
552             code = ENOENT;
553         }
554         goto out;
555     }
556 #endif
557
558     if (code = afs_InitReq(&treq, OSI_GET_CURRENT_CRED())) goto out;
559     code = afs_osi_vget((struct vcache**)avcp, fidp, &treq);
560
561  out:
562     afs_Trace3(afs_iclSetp, CM_TRACE_VGET, ICL_TYPE_POINTER, *avcp,
563                ICL_TYPE_INT32, treq.uid, ICL_TYPE_FID, &vfid);
564     code = afs_CheckCode(code, &treq, 42);
565     return code;
566 }
567
568
569 #ifdef MP /* locked versions of vfs operations. */
570
571 /* wrappers for vfs calls */
572 #ifdef AFS_SGI64_ENV
573 #define AFS_MP_VFS_ARG(A) bhv_desc_t A
574 #else
575 #define AFS_MP_VFS_ARG(A) struct vfs A
576 #endif
577
578 int mp_afs_mount(struct vfs *a, struct vnode *b, struct mounta *c,
579 #ifdef AFS_SGI65_ENV
580                  char *d,
581 #endif
582                  struct cred *e)
583 {
584         int rv;
585         AFS_GLOCK();
586         rv = afs_lockedvfsops.vfs_mount(a, b, c, d
587 #ifdef AFS_SGI65_ENV
588                                         , e
589 #endif
590                                         );
591         AFS_GUNLOCK();
592         return rv;
593 }
594
595 int mp_afs_unmount(AFS_MP_VFS_ARG(*a), int b, struct cred *c)
596 {
597         int rv;
598         AFS_GLOCK();
599         rv = afs_lockedvfsops.vfs_unmount(a, b, c);
600         AFS_GUNLOCK();
601         return rv;
602 }
603
604 int mp_afs_root(AFS_MP_VFS_ARG(*a), struct vnode **b)
605 {
606         int rv;
607         AFS_GLOCK();
608         rv = afs_lockedvfsops.vfs_root(a, b);
609         AFS_GUNLOCK();
610         return rv;
611 }
612
613 int mp_afs_statvfs(AFS_MP_VFS_ARG(*a), struct statvfs *b, struct vnode *c)
614 {
615         int rv;
616         AFS_GLOCK();
617         rv = afs_lockedvfsops.vfs_statvfs(a, b, c);
618         AFS_GUNLOCK();
619         return rv;
620 }
621 int mp_afs_sync(AFS_MP_VFS_ARG(*a),
622 #ifdef AFS_SGI65_ENV
623                 int b,
624 #else
625                 short b,
626 #endif
627                 struct cred *c)
628 {
629         int rv;
630         AFS_GLOCK();
631         rv = afs_lockedvfsops.vfs_sync(a, b, c);
632         AFS_GUNLOCK();
633         return rv;
634 }
635 int mp_afs_vget(AFS_MP_VFS_ARG(*a), struct vnode **b, struct fid *c)
636 {
637         int rv;
638         AFS_GLOCK();
639         rv = afs_lockedvfsops.vfs_vget(a, b, c);
640         AFS_GUNLOCK();
641         return rv;
642 }
643
644 struct vfsops Afs_vfsops = {
645 #ifdef AFS_SGI64_ENV
646 #ifdef AFS_SGI65_ENV
647     BHV_IDENTITY_INIT_POSITION(VFS_POSITION_BASE),
648 #else
649     VFS_POSITION_BASE,
650 #endif
651 #endif
652     mp_afs_mount,
653 #ifdef AFS_SGI64_ENV
654     fs_nosys, /* rootinit */
655     fs_nosys, /* mntupdate */
656     fs_dounmount,
657 #endif
658     mp_afs_unmount,
659     mp_afs_root,
660     mp_afs_statvfs,
661     mp_afs_sync,
662     mp_afs_vget,
663     fs_nosys, /* mountroot */
664 #ifdef AFS_SGI65_ENV
665     fs_nosys,   /* realvfsops */
666     fs_import,  /* import */
667     fs_nosys,   /* quotactl */
668 #else
669     fs_nosys, /* swapvp */
670 #endif
671 };
672
673 #endif /* MP */