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