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