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