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