coda_vfsops.c revision 1.1 1 /*
2
3 Coda: an Experimental Distributed File System
4 Release 3.1
5
6 Copyright (c) 1987-1998 Carnegie Mellon University
7 All Rights Reserved
8
9 Permission to use, copy, modify and distribute this software and its
10 documentation is hereby granted, provided that both the copyright
11 notice and this permission notice appear in all copies of the
12 software, derivative works or modified versions, and any portions
13 thereof, and that both notices appear in supporting documentation, and
14 that credit is given to Carnegie Mellon University in all documents
15 and publicity pertaining to direct or indirect use of this code or its
16 derivatives.
17
18 CODA IS AN EXPERIMENTAL SOFTWARE SYSTEM AND IS KNOWN TO HAVE BUGS,
19 SOME OF WHICH MAY HAVE SERIOUS CONSEQUENCES. CARNEGIE MELLON ALLOWS
20 FREE USE OF THIS SOFTWARE IN ITS "AS IS" CONDITION. CARNEGIE MELLON
21 DISCLAIMS ANY LIABILITY OF ANY KIND FOR ANY DAMAGES WHATSOEVER
22 RESULTING DIRECTLY OR INDIRECTLY FROM THE USE OF THIS SOFTWARE OR OF
23 ANY DERIVATIVE WORK.
24
25 Carnegie Mellon encourages users of this software to return any
26 improvements or extensions that they make, and to grant Carnegie
27 Mellon the rights to redistribute these changes without encumbrance.
28 */
29
30 /* $Header: /tank/opengrok/rsync2/NetBSD/src/sys/coda/coda_vfsops.c,v 1.1 1998/08/29 21:26:45 rvb Exp $ */
31
32 /*
33 * Mach Operating System
34 * Copyright (c) 1989 Carnegie-Mellon University
35 * All rights reserved. The CMU software License Agreement specifies
36 * the terms and conditions for use and redistribution.
37 */
38
39 /*
40 * This code was written for the Coda file system at Carnegie Mellon
41 * University. Contributers include David Steere, James Kistler, and
42 * M. Satyanarayanan.
43 */
44
45 /*
46 * HISTORY
47 * $Log: coda_vfsops.c,v $
48 * Revision 1.1 1998/08/29 21:26:45 rvb
49 * Initial revision
50 *
51 * Revision 1.11 1998/08/28 18:12:22 rvb
52 * Now it also works on FreeBSD -current. This code will be
53 * committed to the FreeBSD -current and NetBSD -current
54 * trees. It will then be tailored to the particular platform
55 * by flushing conditional code.
56 *
57 * Revision 1.10 1998/08/18 17:05:19 rvb
58 * Don't use __RCSID now
59 *
60 * Revision 1.9 1998/08/18 16:31:44 rvb
61 * Sync the code for NetBSD -current; test on 1.3 later
62 *
63 * Revision 1.8 98/02/24 22:22:48 rvb
64 * Fixes up mainly to flush iopen and friends
65 *
66 * Revision 1.7 98/01/23 11:53:45 rvb
67 * Bring RVB_CFS1_1 to HEAD
68 *
69 * Revision 1.6.2.6 98/01/23 11:21:07 rvb
70 * Sync with 2.2.5
71 *
72 * Revision 1.6.2.5 98/01/22 13:05:33 rvb
73 * Move makecfsnode ctlfid later so vfsp is known
74 *
75 * Revision 1.6.2.4 97/12/19 14:26:05 rvb
76 * session id
77 *
78 * Revision 1.6.2.3 97/12/16 12:40:11 rvb
79 * Sync with 1.3
80 *
81 * Revision 1.6.2.2 97/12/10 11:40:25 rvb
82 * No more ody
83 *
84 * Revision 1.6.2.1 97/12/06 17:41:24 rvb
85 * Sync with peters coda.h
86 *
87 * Revision 1.6 97/12/05 10:39:21 rvb
88 * Read CHANGES
89 *
90 * Revision 1.5.14.8 97/11/24 15:44:46 rvb
91 * Final cfs_venus.c w/o macros, but one locking bug
92 *
93 * Revision 1.5.14.7 97/11/21 13:22:03 rvb
94 * Catch a few cfscalls in cfs_vfsops.c
95 *
96 * Revision 1.5.14.6 97/11/20 11:46:48 rvb
97 * Capture current cfs_venus
98 *
99 * Revision 1.5.14.5 97/11/18 10:27:17 rvb
100 * cfs_nbsd.c is DEAD!!!; integrated into cfs_vf/vnops.c
101 * cfs_nb_foo and cfs_foo are joined
102 *
103 * Revision 1.5.14.4 97/11/13 22:03:01 rvb
104 * pass2 cfs_NetBSD.h mt
105 *
106 * Revision 1.5.14.3 97/11/12 12:09:40 rvb
107 * reorg pass1
108 *
109 * Revision 1.5.14.2 97/10/29 16:06:28 rvb
110 * Kill DYING
111 *
112 * Revision 1.5.14.1 1997/10/28 23:10:17 rvb
113 * >64Meg; venus can be killed!
114 *
115 * Revision 1.5 1997/01/13 17:11:07 bnoble
116 * Coda statfs needs to return something other than -1 for blocks avail. and
117 * files available for wabi (and other windowsish) programs to install
118 * there correctly.
119 *
120 * Revision 1.4 1996/12/12 22:11:00 bnoble
121 * Fixed the "downcall invokes venus operation" deadlock in all known cases.
122 * There may be more
123 *
124 * Revision 1.3 1996/11/08 18:06:12 bnoble
125 * Minor changes in vnode operation signature, VOP_UPDATE signature, and
126 * some newly defined bits in the include files.
127 *
128 * Revision 1.2 1996/01/02 16:57:04 bnoble
129 * Added support for Coda MiniCache and raw inode calls (final commit)
130 *
131 * Revision 1.1.2.1 1995/12/20 01:57:32 bnoble
132 * Added CFS-specific files
133 *
134 * Revision 3.1.1.1 1995/03/04 19:08:02 bnoble
135 * Branch for NetBSD port revisions
136 *
137 * Revision 3.1 1995/03/04 19:08:01 bnoble
138 * Bump to major revision 3 to prepare for NetBSD port
139 *
140 * Revision 2.4 1995/02/17 16:25:22 dcs
141 * These versions represent several changes:
142 * 1. Allow venus to restart even if outstanding references exist.
143 * 2. Have only one ctlvp per client, as opposed to one per mounted cfs device.d
144 * 3. Allow ody_expand to return many members, not just one.
145 *
146 * Revision 2.3 94/10/14 09:58:21 dcs
147 * Made changes 'cause sun4s have braindead compilers
148 *
149 * Revision 2.2 94/10/12 16:46:33 dcs
150 * Cleaned kernel/venus interface by removing XDR junk, plus
151 * so cleanup to allow this code to be more easily ported.
152 *
153 * Revision 1.3 93/05/28 16:24:29 bnoble
154 * *** empty log message ***
155 *
156 * Revision 1.2 92/10/27 17:58:24 lily
157 * merge kernel/latest and alpha/src/cfs
158 *
159 * Revision 2.3 92/09/30 14:16:32 mja
160 * Added call to cfs_flush to cfs_unmount.
161 * [90/12/15 dcs]
162 *
163 * Added contributors blurb.
164 * [90/12/13 jjk]
165 *
166 * Revision 2.2 90/07/05 11:26:40 mrt
167 * Created for the Coda File System.
168 * [90/05/23 dcs]
169 *
170 * Revision 1.3 90/05/31 17:01:42 dcs
171 * Prepare for merge with facilities kernel.
172 *
173 *
174 */
175 #include <vcfs.h>
176
177 #include <sys/param.h>
178 #include <sys/systm.h>
179 #include <sys/malloc.h>
180 #include <sys/conf.h>
181 #include <sys/namei.h>
182 #include <sys/mount.h>
183 #include <sys/proc.h>
184 #include <sys/select.h>
185
186 #include <cfs/coda.h>
187 #include <cfs/cnode.h>
188 #include <cfs/cfs_vfsops.h>
189 #include <cfs/cfs_venus.h>
190 #include <cfs/cfs_subr.h>
191 #include <cfs/coda_opstats.h>
192 /* for VN_RDEV */
193 #include <miscfs/specfs/specdev.h>
194
195 #ifdef __FreeBSD__
196 #ifdef __FreeBSD_version
197 MALLOC_DEFINE(M_CFS, "CFS storage", "Various Coda Structures");
198 #endif
199 #endif
200
201 int cfsdebug = 0;
202
203 int cfs_vfsop_print_entry = 0;
204 #ifdef __GNUC__
205 #define ENTRY \
206 if(cfs_vfsop_print_entry) myprintf(("Entered %s\n",__FUNCTION__))
207 #else
208 #define ENTRY
209 #endif
210
211
212 struct vnode *cfs_ctlvp;
213 struct cfs_mntinfo cfs_mnttbl[NVCFS]; /* indexed by minor device number */
214
215 /* structure to keep statistics of internally generated/satisfied calls */
216
217 struct cfs_op_stats cfs_vfsopstats[CFS_VFSOPS_SIZE];
218
219 #define MARK_ENTRY(op) (cfs_vfsopstats[op].entries++)
220 #define MARK_INT_SAT(op) (cfs_vfsopstats[op].sat_intrn++)
221 #define MARK_INT_FAIL(op) (cfs_vfsopstats[op].unsat_intrn++)
222 #define MRAK_INT_GEN(op) (cfs_vfsopstats[op].gen_intrn++)
223
224 extern int cfsnc_initialized; /* Set if cache has been initialized */
225 extern int vc_nb_open __P((dev_t, int, int, struct proc *));
226 #ifdef __NetBSD__
227 extern struct cdevsw cdevsw[]; /* For sanity check in cfs_mount */
228 #endif
229 /* NetBSD interface to statfs */
230
231 #if defined(__NetBSD__) && defined(NetBSD1_3) && (NetBSD1_3 >= 5)
232 extern struct vnodeopv_desc cfs_vnodeop_opv_desc;
233
234 struct vnodeopv_desc *cfs_vnodeopv_descs[] = {
235 &cfs_vnodeop_opv_desc,
236 NULL,
237 };
238
239 struct vfsops cfs_vfsops = {
240 MOUNT_CFS,
241 cfs_mount,
242 cfs_start,
243 cfs_unmount,
244 cfs_root,
245 cfs_quotactl,
246 cfs_nb_statfs,
247 cfs_sync,
248 cfs_vget,
249 (int (*) (struct mount *, struct fid *, struct mbuf *, struct vnode **,
250 int *, struct ucred **))
251 eopnotsupp,
252 (int (*) (struct vnode *, struct fid *)) eopnotsupp,
253 cfs_init,
254 #if (NetBSD1_3 >= 7)
255 cfs_sysctl,
256 #endif
257 (int (*)(void)) eopnotsupp,
258 cfs_vnodeopv_descs,
259 0
260 };
261 #elif defined(__NetBSD__)
262 struct vfsops cfs_vfsops = {
263 MOUNT_CFS,
264 cfs_mount,
265 cfs_start,
266 cfs_unmount,
267 cfs_root,
268 cfs_quotactl,
269 cfs_nb_statfs,
270 cfs_sync,
271 cfs_vget,
272 (int (*) (struct mount *, struct fid *, struct mbuf *, struct vnode **,
273 int *, struct ucred **))
274 eopnotsupp,
275 (int (*) (struct vnode *, struct fid *)) eopnotsupp,
276 cfs_init,
277 #ifdef NetBSD1_3
278 (int (*)(void)) eopnotsupp,
279 #endif
280 0
281 };
282
283 #elif defined(__FreeBSD__)
284 #ifdef __FreeBSD_version
285 struct vfsops cfs_vfsops = {
286 cfs_mount,
287 cfs_start,
288 cfs_unmount,
289 cfs_root,
290 cfs_quotactl,
291 cfs_nb_statfs,
292 cfs_sync,
293 cfs_vget,
294 (int (*) (struct mount *, struct fid *, struct sockaddr *, struct vnode **,
295 int *, struct ucred **))
296 eopnotsupp,
297 (int (*) (struct vnode *, struct fid *)) eopnotsupp,
298 cfs_init,
299 };
300
301 #else
302 struct vfsops cfs_vfsops = {
303 cfs_mount,
304 cfs_start,
305 cfs_unmount,
306 cfs_root,
307 cfs_quotactl,
308 cfs_nb_statfs,
309 cfs_sync,
310 cfs_vget,
311 (int (*) (struct mount *, struct fid *, struct mbuf *, struct vnode **,
312 int *, struct ucred **))
313 eopnotsupp,
314 (int (*) (struct vnode *, struct fid *)) eopnotsupp,
315 cfs_init,
316 };
317
318 #endif
319
320
321 #include <sys/kernel.h>
322 VFS_SET(cfs_vfsops, cfs, MOUNT_CFS, VFCF_NETWORK);
323 #endif
324
325 int
326 cfs_vfsopstats_init(void)
327 {
328 register int i;
329
330 for (i=0;i<CFS_VFSOPS_SIZE;i++) {
331 cfs_vfsopstats[i].opcode = i;
332 cfs_vfsopstats[i].entries = 0;
333 cfs_vfsopstats[i].sat_intrn = 0;
334 cfs_vfsopstats[i].unsat_intrn = 0;
335 cfs_vfsopstats[i].gen_intrn = 0;
336 }
337
338 return 0;
339 }
340
341
342 /*
343 * cfs mount vfsop
344 * Set up mount info record and attach it to vfs struct.
345 */
346 /*ARGSUSED*/
347 int
348 cfs_mount(vfsp, path, data, ndp, p)
349 struct mount *vfsp; /* Allocated and initialized by mount(2) */
350 #ifdef NetBSD1_3
351 const char *path; /* path covered: ignored by the fs-layer */
352 void *data; /* Need to define a data type for this in netbsd? */
353 #else
354 char *path; /* path covered: ignored by the fs-layer */
355 caddr_t data; /* Need to define a data type for this in netbsd? */
356 #endif
357 struct nameidata *ndp; /* Clobber this to lookup the device name */
358 struct proc *p; /* The ever-famous proc pointer */
359 {
360 struct vnode *dvp;
361 struct cnode *cp;
362 dev_t dev;
363 struct cfs_mntinfo *mi;
364 struct vnode *rootvp;
365 ViceFid rootfid;
366 ViceFid ctlfid;
367 int error;
368
369 ENTRY;
370
371 cfs_vfsopstats_init();
372 cfs_vnodeopstats_init();
373
374 MARK_ENTRY(CFS_MOUNT_STATS);
375 if (CFS_MOUNTED(vfsp)) {
376 MARK_INT_FAIL(CFS_MOUNT_STATS);
377 return(EBUSY);
378 }
379
380 /* Validate mount device. Similar to getmdev(). */
381
382 NDINIT(ndp, LOOKUP, FOLLOW, UIO_USERSPACE, data, p);
383 error = namei(ndp);
384 dvp = ndp->ni_vp;
385
386 if (error) {
387 MARK_INT_FAIL(CFS_MOUNT_STATS);
388 return (error);
389 }
390 if (dvp->v_type != VCHR) {
391 MARK_INT_FAIL(CFS_MOUNT_STATS);
392 vrele(dvp);
393 return(ENXIO);
394 }
395 dev = dvp->v_specinfo->si_rdev;
396 vrele(dvp);
397 if (major(dev) >= nchrdev || major(dev) < 0) {
398 MARK_INT_FAIL(CFS_MOUNT_STATS);
399 return(ENXIO);
400 }
401
402 /*
403 * See if the device table matches our expectations.
404 */
405 #ifdef __NetBSD__
406 if (cdevsw[major(dev)].d_open != vc_nb_open)
407 #elif defined(__FreeBSD__)
408 if (cdevsw[major(dev)]->d_open != vc_nb_open)
409 #endif
410 {
411 MARK_INT_FAIL(CFS_MOUNT_STATS);
412 return(ENXIO);
413 }
414
415 if (minor(dev) >= NVCFS || minor(dev) < 0) {
416 MARK_INT_FAIL(CFS_MOUNT_STATS);
417 return(ENXIO);
418 }
419
420 /*
421 * Initialize the mount record and link it to the vfs struct
422 */
423 mi = &cfs_mnttbl[minor(dev)];
424
425 if (!VC_OPEN(&mi->mi_vcomm)) {
426 MARK_INT_FAIL(CFS_MOUNT_STATS);
427 return(ENODEV);
428 }
429
430 /* No initialization (here) of mi_vcomm! */
431 vfsp->mnt_data = (qaddr_t)mi;
432 #ifdef __NetBSD__
433 vfsp->mnt_stat.f_fsid.val[0] = 0;
434 vfsp->mnt_stat.f_fsid.val[1] = makefstype(MOUNT_CFS);
435 #elif defined(__FreeBSD__) && defined(__FreeBSD_version)
436
437 vfs_getnewfsid (vfsp);
438
439 #elif defined(__FreeBSD__)
440 /* Seems a bit overkill, since usualy /coda is the only mount point
441 * for cfs.
442 */
443 getnewfsid (vfsp, MOUNT_CFS);
444 #endif
445 mi->mi_vfsp = vfsp;
446
447 /*
448 * Make a root vnode to placate the Vnode interface, but don't
449 * actually make the CFS_ROOT call to venus until the first call
450 * to cfs_root in case a server is down while venus is starting.
451 */
452 rootfid.Volume = 0;
453 rootfid.Vnode = 0;
454 rootfid.Unique = 0;
455 cp = makecfsnode(&rootfid, vfsp, VDIR);
456 rootvp = CTOV(cp);
457 rootvp->v_flag |= VROOT;
458
459 ctlfid.Volume = CTL_VOL;
460 ctlfid.Vnode = CTL_VNO;
461 ctlfid.Unique = CTL_UNI;
462 /* cp = makecfsnode(&ctlfid, vfsp, VCHR);
463 The above code seems to cause a loop in the cnode links.
464 I don't totally understand when it happens, it is caught
465 when closing down the system.
466 */
467 cp = makecfsnode(&ctlfid, 0, VCHR);
468
469 cfs_ctlvp = CTOV(cp);
470
471 /* Add vfs and rootvp to chain of vfs hanging off mntinfo */
472 mi->mi_vfsp = vfsp;
473 mi->mi_rootvp = rootvp;
474
475 /* set filesystem block size */
476 vfsp->mnt_stat.f_bsize = 8192; /* XXX -JJK */
477 #ifdef __FreeBSD__
478 /* Set f_iosize. XXX -- inamura (at) isl.ntt.co.jp.
479 For vnode_pager_haspage() references. The value should be obtained
480 from underlying UFS. */
481 /* Checked UFS. iosize is set as 8192 */
482 vfsp->mnt_stat.f_iosize = 8192;
483 #endif
484
485 /* error is currently guaranteed to be zero, but in case some
486 code changes... */
487 CFSDEBUG(1,
488 myprintf(("cfs_mount returned %d\n",error)););
489 if (error)
490 MARK_INT_FAIL(CFS_MOUNT_STATS);
491 else
492 MARK_INT_SAT(CFS_MOUNT_STATS);
493
494 return(error);
495 }
496
497 int
498 cfs_start(vfsp, flags, p)
499 struct mount *vfsp;
500 int flags;
501 struct proc *p;
502 {
503 ENTRY;
504 return (0);
505 }
506
507 int
508 cfs_unmount(vfsp, mntflags, p)
509 struct mount *vfsp;
510 int mntflags;
511 struct proc *p;
512 {
513 struct cfs_mntinfo *mi = vftomi(vfsp);
514 int active, error = 0;
515
516 ENTRY;
517 MARK_ENTRY(CFS_UMOUNT_STATS);
518 if (!CFS_MOUNTED(vfsp)) {
519 MARK_INT_FAIL(CFS_UMOUNT_STATS);
520 return(EINVAL);
521 }
522
523 if (mi->mi_vfsp == vfsp) { /* We found the victim */
524 if (!IS_UNMOUNTING(VTOC(mi->mi_rootvp)))
525 return (EBUSY); /* Venus is still running */
526
527 #ifdef DEBUG
528 printf("cfs_unmount: ROOT: vp %p, cp %p\n", mi->mi_rootvp, VTOC(mi->mi_rootvp));
529 #endif
530 vrele(mi->mi_rootvp);
531
532 #ifdef NetBSD1_3
533 active = cfs_kill(vfsp, NOT_DOWNCALL);
534
535 #if defined(__NetBSD__) && defined(NetBSD1_3) && (NetBSD1_3 >= 7)
536 if (1)
537 #else
538 if ((error = vfs_busy(mi->mi_vfsp)) == 0)
539 #endif
540 {
541 error = vflush(mi->mi_vfsp, NULLVP, FORCECLOSE);
542 printf("cfs_unmount: active = %d, vflush active %d\n", active, error);
543 error = 0;
544 } else {
545 printf("cfs_unmount: busy\n");
546 }
547 #else /* FreeBSD I guess */
548 active = cfs_kill(vfsp, NOT_DOWNCALL);
549 error = vflush(mi->mi_vfsp, NULLVP, FORCECLOSE);
550 printf("cfs_unmount: active = %d, vflush active %d\n", active, error);
551 error = 0;
552 #endif
553 /* I'm going to take this out to allow lookups to go through. I'm
554 * not sure it's important anyway. -- DCS 2/2/94
555 */
556 /* vfsp->VFS_DATA = NULL; */
557
558 /* No more vfsp's to hold onto */
559 mi->mi_vfsp = NULL;
560 mi->mi_rootvp = NULL;
561
562 if (error)
563 MARK_INT_FAIL(CFS_UMOUNT_STATS);
564 else
565 MARK_INT_SAT(CFS_UMOUNT_STATS);
566
567 return(error);
568 }
569 return (EINVAL);
570 }
571
572 /*
573 * find root of cfs
574 */
575 int
576 cfs_root(vfsp, vpp)
577 struct mount *vfsp;
578 struct vnode **vpp;
579 {
580 struct cfs_mntinfo *mi = vftomi(vfsp);
581 struct vnode **result;
582 int error;
583 struct proc *p = curproc; /* XXX - bnoble */
584 ViceFid VFid;
585
586 ENTRY;
587 MARK_ENTRY(CFS_ROOT_STATS);
588 result = NULL;
589
590 if (vfsp == mi->mi_vfsp) {
591 if ((VTOC(mi->mi_rootvp)->c_fid.Volume != 0) ||
592 (VTOC(mi->mi_rootvp)->c_fid.Vnode != 0) ||
593 (VTOC(mi->mi_rootvp)->c_fid.Unique != 0))
594 { /* Found valid root. */
595 *vpp = mi->mi_rootvp;
596 /* On Mach, this is vref. On NetBSD, VOP_LOCK */
597 vref(*vpp);
598 VOP_X_LOCK(*vpp, LK_EXCLUSIVE);
599 MARK_INT_SAT(CFS_ROOT_STATS);
600 return(0);
601 }
602 }
603
604 error = venus_root(vftomi(vfsp), p->p_cred->pc_ucred, p, &VFid);
605
606 if (!error) {
607 /*
608 * Save the new rootfid in the cnode, and rehash the cnode into the
609 * cnode hash with the new fid key.
610 */
611 cfs_unsave(VTOC(mi->mi_rootvp));
612 VTOC(mi->mi_rootvp)->c_fid = VFid;
613 cfs_save(VTOC(mi->mi_rootvp));
614
615 *vpp = mi->mi_rootvp;
616 vref(*vpp);
617 VOP_X_LOCK(*vpp, LK_EXCLUSIVE);
618 MARK_INT_SAT(CFS_ROOT_STATS);
619 goto exit;
620 } else if (error == ENODEV) {
621 /* Gross hack here! */
622 /*
623 * If Venus fails to respond to the CFS_ROOT call, cfscall returns
624 * ENODEV. Return the uninitialized root vnode to allow vfs
625 * operations such as unmount to continue. Without this hack,
626 * there is no way to do an unmount if Venus dies before a
627 * successful CFS_ROOT call is done. All vnode operations
628 * will fail.
629 */
630 *vpp = mi->mi_rootvp;
631 vref(*vpp);
632 VOP_X_LOCK(*vpp, LK_EXCLUSIVE);
633 MARK_INT_FAIL(CFS_ROOT_STATS);
634 error = 0;
635 goto exit;
636 } else {
637 CFSDEBUG( CFS_ROOT, myprintf(("error %d in CFS_ROOT\n", error)); );
638 MARK_INT_FAIL(CFS_ROOT_STATS);
639
640 goto exit;
641 }
642 exit:
643 return(error);
644 }
645
646 int
647 cfs_quotactl(vfsp, cmd, uid, arg, p)
648 struct mount *vfsp;
649 int cmd;
650 uid_t uid;
651 caddr_t arg;
652 struct proc *p;
653 {
654 ENTRY;
655 return (EOPNOTSUPP);
656 }
657
658 /*
659 * Get file system statistics.
660 */
661 int
662 cfs_nb_statfs(vfsp, sbp, p)
663 register struct mount *vfsp;
664 struct statfs *sbp;
665 struct proc *p;
666 {
667 ENTRY;
668 /* MARK_ENTRY(CFS_STATFS_STATS); */
669 if (!CFS_MOUNTED(vfsp)) {
670 /* MARK_INT_FAIL(CFS_STATFS_STATS);*/
671 return(EINVAL);
672 }
673
674 bzero(sbp, sizeof(struct statfs));
675 /* XXX - what to do about f_flags, others? --bnoble */
676 /* Below This is what AFS does
677 #define NB_SFS_SIZ 0x895440
678 */
679 /* Note: Normal fs's have a bsize of 0x400 == 1024 */
680 #ifdef __NetBSD__
681 sbp->f_type = 0;
682 #elif defined(__FreeBSD__)
683 sbp->f_type = MOUNT_CFS;
684 #endif
685 sbp->f_bsize = 8192; /* XXX */
686 sbp->f_iosize = 8192; /* XXX */
687 #define NB_SFS_SIZ 0x8AB75D
688 sbp->f_blocks = NB_SFS_SIZ;
689 sbp->f_bfree = NB_SFS_SIZ;
690 sbp->f_bavail = NB_SFS_SIZ;
691 sbp->f_files = NB_SFS_SIZ;
692 sbp->f_ffree = NB_SFS_SIZ;
693 bcopy((caddr_t)&(vfsp->mnt_stat.f_fsid), (caddr_t)&(sbp->f_fsid), sizeof (fsid_t));
694 #ifdef __NetBSD__
695 strncpy(sbp->f_fstypename, MOUNT_CFS, MFSNAMELEN-1);
696 #endif
697 strcpy(sbp->f_mntonname, "/coda");
698 strcpy(sbp->f_mntfromname, "CFS");
699 /* MARK_INT_SAT(CFS_STATFS_STATS); */
700 return(0);
701 }
702
703 /*
704 * Flush any pending I/O.
705 */
706 int
707 cfs_sync(vfsp, waitfor, cred, p)
708 struct mount *vfsp;
709 int waitfor;
710 struct ucred *cred;
711 struct proc *p;
712 {
713 ENTRY;
714 MARK_ENTRY(CFS_SYNC_STATS);
715 MARK_INT_SAT(CFS_SYNC_STATS);
716 return(0);
717 }
718
719 int
720 cfs_vget(vfsp, ino, vpp)
721 struct mount *vfsp;
722 ino_t ino;
723 struct vnode **vpp;
724 {
725 ENTRY;
726 return (EOPNOTSUPP);
727 }
728
729 /*
730 * fhtovp is now what vget used to be in 4.3-derived systems. For
731 * some silly reason, vget is now keyed by a 32 bit ino_t, rather than
732 * a type-specific fid.
733 */
734 int
735 cfs_fhtovp(vfsp, fhp, nam, vpp, exflagsp, creadanonp)
736 register struct mount *vfsp;
737 struct fid *fhp;
738 struct mbuf *nam;
739 struct vnode **vpp;
740 int *exflagsp;
741 struct ucred **creadanonp;
742 {
743 struct cfid *cfid = (struct cfid *)fhp;
744 struct cnode *cp = 0;
745 int error;
746 struct proc *p = curproc; /* XXX -mach */
747 ViceFid VFid;
748 int vtype;
749
750 ENTRY;
751
752 MARK_ENTRY(CFS_VGET_STATS);
753 /* Check for vget of control object. */
754 if (IS_CTL_FID(&cfid->cfid_fid)) {
755 *vpp = cfs_ctlvp;
756 vref(cfs_ctlvp);
757 MARK_INT_SAT(CFS_VGET_STATS);
758 return(0);
759 }
760
761 error = venus_fhtovp(vftomi(vfsp), &cfid->cfid_fid, p->p_cred->pc_ucred, p, &VFid, &vtype);
762
763 if (error) {
764 CFSDEBUG(CFS_VGET, myprintf(("vget error %d\n",error));)
765 *vpp = (struct vnode *)0;
766 } else {
767 CFSDEBUG(CFS_VGET,
768 myprintf(("vget: vol %lx vno %lx uni %lx type %d result %d\n",
769 VFid.Volume, VFid.Vnode, VFid.Unique, vtype, error)); )
770
771 cp = makecfsnode(&VFid, vfsp, vtype);
772 *vpp = CTOV(cp);
773 }
774 return(error);
775 }
776
777 int
778 cfs_vptofh(vnp, fidp)
779 struct vnode *vnp;
780 struct fid *fidp;
781 {
782 ENTRY;
783 return (EOPNOTSUPP);
784 }
785
786 #ifdef __NetBSD__
787 void
788 cfs_init(void)
789 {
790 ENTRY;
791 }
792 #elif defined(__FreeBSD__)
793 #ifdef __FreeBSD_version
794 int
795 cfs_init(struct vfsconf *vfsp)
796 {
797 ENTRY;
798 return 0;
799 }
800 #else
801 int
802 cfs_init(void)
803 {
804 ENTRY;
805 return 0;
806 }
807 #endif
808 #endif
809
810 #if defined(__NetBSD__) && defined(NetBSD1_3) && (NetBSD1_3 >= 7)
811 int
812 cfs_sysctl(name, namelen, oldp, oldlp, newp, newl, p)
813 int *name;
814 u_int namelen;
815 void *oldp;
816 size_t *oldlp;
817 void *newp;
818 size_t newl;
819 struct proc *p;
820 {
821
822 /* all sysctl names at this level are terminal */
823 if (namelen != 1)
824 return (ENOTDIR); /* overloaded */
825
826 switch (name[0]) {
827 /*
828 case FFS_CLUSTERREAD:
829 return (sysctl_int(oldp, oldlp, newp, newl, &doclusterread));
830 */
831 default:
832 return (EOPNOTSUPP);
833 }
834 /* NOTREACHED */
835 }
836 #endif
837
838 /*
839 * To allow for greater ease of use, some vnodes may be orphaned when
840 * Venus dies. Certain operations should still be allowed to go
841 * through, but without propagating ophan-ness. So this function will
842 * get a new vnode for the file from the current run of Venus. */
843
844 int
845 getNewVnode(vpp)
846 struct vnode **vpp;
847 {
848 struct cfid cfid;
849 struct cfs_mntinfo *mi = vftomi((*vpp)->v_mount);
850
851 ENTRY;
852
853 cfid.cfid_len = (short)sizeof(ViceFid);
854 cfid.cfid_fid = VTOC(*vpp)->c_fid; /* Structure assignment. */
855 /* XXX ? */
856
857 /* We're guessing that if set, the 1st element on the list is a
858 * valid vnode to use. If not, return ENODEV as venus is dead.
859 */
860 if (mi->mi_vfsp == NULL)
861 return ENODEV;
862
863 return cfs_fhtovp(mi->mi_vfsp, (struct fid*)&cfid, NULL, vpp,
864 NULL, NULL);
865 }
866
867 #include <ufs/ufs/quota.h>
868 #include <ufs/ufs/ufsmount.h>
869 /* get the mount structure corresponding to a given device. Assume
870 * device corresponds to a UFS. Return NULL if no device is found.
871 */
872 struct mount *devtomp(dev)
873 dev_t dev;
874 {
875 struct mount *mp, *nmp;
876
877 for (mp = mountlist.cqh_first; mp != (void*)&mountlist; mp = nmp) {
878 nmp = mp->mnt_list.cqe_next;
879 if (
880 #ifdef __NetBSD__
881 (!strcmp(mp->mnt_op->vfs_name, MOUNT_UFS)) &&
882 #endif
883 ((VFSTOUFS(mp))->um_dev == (dev_t) dev)) {
884 /* mount corresponds to UFS and the device matches one we want */
885 return(mp);
886 }
887 }
888 /* mount structure wasn't found */
889 return(NULL);
890 }
891