coda_vfsops.c revision 39650
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 * @(#) src/sys/cfs/coda_vfsops.c,v 1.1.1.1 1998/08/29 21:14:52 rvb Exp $ 30 * $Id: coda_vfsops.c,v 1.5 1998/09/13 13:57:59 rvb Exp $ 31 * 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.5 1998/09/13 13:57:59 rvb 51 * Finish conversion of cfs -> coda 52 * 53 * Revision 1.4 1998/09/11 18:50:17 rvb 54 * All the references to cfs, in symbols, structs, and strings 55 * have been changed to coda. (Same for CFS.) 56 * 57 * Revision 1.2 1998/09/02 19:09:53 rvb 58 * Pass2 complete 59 * 60 * Revision 1.1.1.1 1998/08/29 21:14:52 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#ifdef ACTUALLY_LKM_NOT_KERNEL 189#define NVCODA 4 190#else 191#include <vcoda.h> 192#endif 193 194#include <sys/param.h> 195#include <sys/systm.h> 196#include <sys/kernel.h> 197#include <sys/proc.h> 198#include <sys/malloc.h> 199#include <sys/conf.h> 200#include <sys/namei.h> 201#include <sys/mount.h> 202#include <sys/select.h> 203 204#include <coda/coda.h> 205#include <coda/cnode.h> 206#include <coda/coda_vfsops.h> 207#include <coda/coda_venus.h> 208#include <coda/coda_subr.h> 209#include <coda/coda_opstats.h> 210 211#include <miscfs/specfs/specdev.h> 212 213MALLOC_DEFINE(M_CODA, "CODA storage", "Various Coda Structures"); 214 215int codadebug = 0; 216int coda_vfsop_print_entry = 0; 217#define ENTRY if(coda_vfsop_print_entry) myprintf(("Entered %s\n",__FUNCTION__)) 218 219struct vnode *coda_ctlvp; 220struct coda_mntinfo coda_mnttbl[NVCODA]; /* indexed by minor device number */ 221 222/* structure to keep statistics of internally generated/satisfied calls */ 223 224struct coda_op_stats coda_vfsopstats[CODA_VFSOPS_SIZE]; 225 226#define MARK_ENTRY(op) (coda_vfsopstats[op].entries++) 227#define MARK_INT_SAT(op) (coda_vfsopstats[op].sat_intrn++) 228#define MARK_INT_FAIL(op) (coda_vfsopstats[op].unsat_intrn++) 229#define MRAK_INT_GEN(op) (coda_vfsopstats[op].gen_intrn++) 230 231extern int coda_nc_initialized; /* Set if cache has been initialized */ 232extern int vc_nb_open __P((dev_t, int, int, struct proc *)); 233 234int 235coda_vfsopstats_init(void) 236{ 237 register int i; 238 239 for (i=0;i<CODA_VFSOPS_SIZE;i++) { 240 coda_vfsopstats[i].opcode = i; 241 coda_vfsopstats[i].entries = 0; 242 coda_vfsopstats[i].sat_intrn = 0; 243 coda_vfsopstats[i].unsat_intrn = 0; 244 coda_vfsopstats[i].gen_intrn = 0; 245 } 246 247 return 0; 248} 249 250/* 251 * cfs mount vfsop 252 * Set up mount info record and attach it to vfs struct. 253 */ 254/*ARGSUSED*/ 255int 256coda_mount(vfsp, path, data, ndp, p) 257 struct mount *vfsp; /* Allocated and initialized by mount(2) */ 258 char *path; /* path covered: ignored by the fs-layer */ 259 caddr_t data; /* Need to define a data type for this in netbsd? */ 260 struct nameidata *ndp; /* Clobber this to lookup the device name */ 261 struct proc *p; /* The ever-famous proc pointer */ 262{ 263 struct vnode *dvp; 264 struct cnode *cp; 265 dev_t dev; 266 struct coda_mntinfo *mi; 267 struct vnode *rootvp; 268 ViceFid rootfid; 269 ViceFid ctlfid; 270 int error; 271 272 ENTRY; 273 274 coda_vfsopstats_init(); 275 coda_vnodeopstats_init(); 276 277 MARK_ENTRY(CODA_MOUNT_STATS); 278 if (CODA_MOUNTED(vfsp)) { 279 MARK_INT_FAIL(CODA_MOUNT_STATS); 280 return(EBUSY); 281 } 282 283 /* Validate mount device. Similar to getmdev(). */ 284 285 NDINIT(ndp, LOOKUP, FOLLOW, UIO_USERSPACE, data, p); 286 error = namei(ndp); 287 dvp = ndp->ni_vp; 288 289 if (error) { 290 MARK_INT_FAIL(CODA_MOUNT_STATS); 291 return (error); 292 } 293 if (dvp->v_type != VCHR) { 294 MARK_INT_FAIL(CODA_MOUNT_STATS); 295 vrele(dvp); 296 return(ENXIO); 297 } 298 dev = dvp->v_specinfo->si_rdev; 299 vrele(dvp); 300 if (major(dev) >= nchrdev || major(dev) < 0) { 301 MARK_INT_FAIL(CODA_MOUNT_STATS); 302 return(ENXIO); 303 } 304 305 /* 306 * See if the device table matches our expectations. 307 */ 308 if (cdevsw[major(dev)]->d_open != vc_nb_open) 309 { 310 MARK_INT_FAIL(CODA_MOUNT_STATS); 311 return(ENXIO); 312 } 313 314 if (minor(dev) >= NVCODA || minor(dev) < 0) { 315 MARK_INT_FAIL(CODA_MOUNT_STATS); 316 return(ENXIO); 317 } 318 319 /* 320 * Initialize the mount record and link it to the vfs struct 321 */ 322 mi = &coda_mnttbl[minor(dev)]; 323 324 if (!VC_OPEN(&mi->mi_vcomm)) { 325 MARK_INT_FAIL(CODA_MOUNT_STATS); 326 return(ENODEV); 327 } 328 329 /* No initialization (here) of mi_vcomm! */ 330 vfsp->mnt_data = (qaddr_t)mi; 331 vfs_getnewfsid (vfsp); 332 333 mi->mi_vfsp = vfsp; 334 335 /* 336 * Make a root vnode to placate the Vnode interface, but don't 337 * actually make the CODA_ROOT call to venus until the first call 338 * to coda_root in case a server is down while venus is starting. 339 */ 340 rootfid.Volume = 0; 341 rootfid.Vnode = 0; 342 rootfid.Unique = 0; 343 cp = make_coda_node(&rootfid, vfsp, VDIR); 344 rootvp = CTOV(cp); 345 rootvp->v_flag |= VROOT; 346 347 ctlfid.Volume = CTL_VOL; 348 ctlfid.Vnode = CTL_VNO; 349 ctlfid.Unique = CTL_UNI; 350/* cp = make_coda_node(&ctlfid, vfsp, VCHR); 351 The above code seems to cause a loop in the cnode links. 352 I don't totally understand when it happens, it is caught 353 when closing down the system. 354 */ 355 cp = make_coda_node(&ctlfid, 0, VCHR); 356 357 coda_ctlvp = CTOV(cp); 358 359 /* Add vfs and rootvp to chain of vfs hanging off mntinfo */ 360 mi->mi_vfsp = vfsp; 361 mi->mi_rootvp = rootvp; 362 363 /* set filesystem block size */ 364 vfsp->mnt_stat.f_bsize = 8192; /* XXX -JJK */ 365 366 /* Set f_iosize. XXX -- inamura@isl.ntt.co.jp. 367 For vnode_pager_haspage() references. The value should be obtained 368 from underlying UFS. */ 369 /* Checked UFS. iosize is set as 8192 */ 370 vfsp->mnt_stat.f_iosize = 8192; 371 372 /* error is currently guaranteed to be zero, but in case some 373 code changes... */ 374 CODADEBUG(1, 375 myprintf(("coda_mount returned %d\n",error));); 376 if (error) 377 MARK_INT_FAIL(CODA_MOUNT_STATS); 378 else 379 MARK_INT_SAT(CODA_MOUNT_STATS); 380 381 return(error); 382} 383 384int 385coda_start(vfsp, flags, p) 386 struct mount *vfsp; 387 int flags; 388 struct proc *p; 389{ 390 ENTRY; 391 return (0); 392} 393 394int 395coda_unmount(vfsp, mntflags, p) 396 struct mount *vfsp; 397 int mntflags; 398 struct proc *p; 399{ 400 struct coda_mntinfo *mi = vftomi(vfsp); 401 int active, error = 0; 402 403 ENTRY; 404 MARK_ENTRY(CODA_UMOUNT_STATS); 405 if (!CODA_MOUNTED(vfsp)) { 406 MARK_INT_FAIL(CODA_UMOUNT_STATS); 407 return(EINVAL); 408 } 409 410 if (mi->mi_vfsp == vfsp) { /* We found the victim */ 411 if (!IS_UNMOUNTING(VTOC(mi->mi_rootvp))) 412 return (EBUSY); /* Venus is still running */ 413 414#ifdef DEBUG 415 printf("coda_unmount: ROOT: vp %p, cp %p\n", mi->mi_rootvp, VTOC(mi->mi_rootvp)); 416#endif 417 vrele(mi->mi_rootvp); 418 419 active = coda_kill(vfsp, NOT_DOWNCALL); 420 error = vflush(mi->mi_vfsp, NULLVP, FORCECLOSE); 421 printf("coda_unmount: active = %d, vflush active %d\n", active, error); 422 error = 0; 423 /* I'm going to take this out to allow lookups to go through. I'm 424 * not sure it's important anyway. -- DCS 2/2/94 425 */ 426 /* vfsp->VFS_DATA = NULL; */ 427 428 /* No more vfsp's to hold onto */ 429 mi->mi_vfsp = NULL; 430 mi->mi_rootvp = NULL; 431 432 if (error) 433 MARK_INT_FAIL(CODA_UMOUNT_STATS); 434 else 435 MARK_INT_SAT(CODA_UMOUNT_STATS); 436 437 return(error); 438 } 439 return (EINVAL); 440} 441 442/* 443 * find root of cfs 444 */ 445int 446coda_root(vfsp, vpp) 447 struct mount *vfsp; 448 struct vnode **vpp; 449{ 450 struct coda_mntinfo *mi = vftomi(vfsp); 451 struct vnode **result; 452 int error; 453 struct proc *p = curproc; /* XXX - bnoble */ 454 ViceFid VFid; 455 456 ENTRY; 457 MARK_ENTRY(CODA_ROOT_STATS); 458 result = NULL; 459 460 if (vfsp == mi->mi_vfsp) { 461 if ((VTOC(mi->mi_rootvp)->c_fid.Volume != 0) || 462 (VTOC(mi->mi_rootvp)->c_fid.Vnode != 0) || 463 (VTOC(mi->mi_rootvp)->c_fid.Unique != 0)) 464 { /* Found valid root. */ 465 *vpp = mi->mi_rootvp; 466 /* On Mach, this is vref. On NetBSD, VOP_LOCK */ 467#if 1 468 vref(*vpp); 469 vn_lock(*vpp, LK_EXCLUSIVE, p); 470#else 471 vget(*vpp, LK_EXCLUSIVE, p); 472#endif 473 MARK_INT_SAT(CODA_ROOT_STATS); 474 return(0); 475 } 476 } 477 478 error = venus_root(vftomi(vfsp), p->p_cred->pc_ucred, p, &VFid); 479 480 if (!error) { 481 /* 482 * Save the new rootfid in the cnode, and rehash the cnode into the 483 * cnode hash with the new fid key. 484 */ 485 coda_unsave(VTOC(mi->mi_rootvp)); 486 VTOC(mi->mi_rootvp)->c_fid = VFid; 487 coda_save(VTOC(mi->mi_rootvp)); 488 489 *vpp = mi->mi_rootvp; 490#if 1 491 vref(*vpp); 492 vn_lock(*vpp, LK_EXCLUSIVE, p); 493#else 494 vget(*vpp, LK_EXCLUSIVE, p); 495#endif 496 497 MARK_INT_SAT(CODA_ROOT_STATS); 498 goto exit; 499 } else if (error == ENODEV) { 500 /* Gross hack here! */ 501 /* 502 * If Venus fails to respond to the CODA_ROOT call, coda_call returns 503 * ENODEV. Return the uninitialized root vnode to allow vfs 504 * operations such as unmount to continue. Without this hack, 505 * there is no way to do an unmount if Venus dies before a 506 * successful CODA_ROOT call is done. All vnode operations 507 * will fail. 508 */ 509 *vpp = mi->mi_rootvp; 510#if 1 511 vref(*vpp); 512 vn_lock(*vpp, LK_EXCLUSIVE, p); 513#else 514 vget(*vpp, LK_EXCLUSIVE, p); 515#endif 516 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 527 exit: 528 return(error); 529} 530 531int 532coda_quotactl(vfsp, cmd, uid, arg, p) 533 struct mount *vfsp; 534 int cmd; 535 uid_t uid; 536 caddr_t arg; 537 struct proc *p; 538{ 539 ENTRY; 540 return (EOPNOTSUPP); 541} 542 543/* 544 * Get file system statistics. 545 */ 546int 547coda_nb_statfs(vfsp, sbp, p) 548 register struct mount *vfsp; 549 struct statfs *sbp; 550 struct proc *p; 551{ 552 ENTRY; 553/* MARK_ENTRY(CODA_STATFS_STATS); */ 554 if (!CODA_MOUNTED(vfsp)) { 555/* MARK_INT_FAIL(CODA_STATFS_STATS);*/ 556 return(EINVAL); 557 } 558 559 bzero(sbp, sizeof(struct statfs)); 560 /* XXX - what to do about f_flags, others? --bnoble */ 561 /* Below This is what AFS does 562 #define NB_SFS_SIZ 0x895440 563 */ 564 /* Note: Normal fs's have a bsize of 0x400 == 1024 */ 565 sbp->f_type = vfsp->mnt_vfc->vfc_typenum; 566 sbp->f_bsize = 8192; /* XXX */ 567 sbp->f_iosize = 8192; /* XXX */ 568#define NB_SFS_SIZ 0x8AB75D 569 sbp->f_blocks = NB_SFS_SIZ; 570 sbp->f_bfree = NB_SFS_SIZ; 571 sbp->f_bavail = NB_SFS_SIZ; 572 sbp->f_files = NB_SFS_SIZ; 573 sbp->f_ffree = NB_SFS_SIZ; 574 bcopy((caddr_t)&(vfsp->mnt_stat.f_fsid), (caddr_t)&(sbp->f_fsid), sizeof (fsid_t)); 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 */ 584int 585coda_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 597int 598coda_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 */ 612int 613coda_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 655int 656coda_vptofh(vnp, fidp) 657 struct vnode *vnp; 658 struct fid *fidp; 659{ 660 ENTRY; 661 return (EOPNOTSUPP); 662} 663 664int 665coda_init(struct vfsconf *vfsp) 666{ 667 ENTRY; 668 return 0; 669} 670 671/* 672 * To allow for greater ease of use, some vnodes may be orphaned when 673 * Venus dies. Certain operations should still be allowed to go 674 * through, but without propagating ophan-ness. So this function will 675 * get a new vnode for the file from the current run of Venus. */ 676 677int 678getNewVnode(vpp) 679 struct vnode **vpp; 680{ 681 struct cfid cfid; 682 struct coda_mntinfo *mi = vftomi((*vpp)->v_mount); 683 684 ENTRY; 685 686 cfid.cfid_len = (short)sizeof(ViceFid); 687 cfid.cfid_fid = VTOC(*vpp)->c_fid; /* Structure assignment. */ 688 /* XXX ? */ 689 690 /* We're guessing that if set, the 1st element on the list is a 691 * valid vnode to use. If not, return ENODEV as venus is dead. 692 */ 693 if (mi->mi_vfsp == NULL) 694 return ENODEV; 695 696 return coda_fhtovp(mi->mi_vfsp, (struct fid*)&cfid, NULL, vpp, 697 NULL, NULL); 698} 699 700#include <ufs/ufs/quota.h> 701#include <ufs/ufs/ufsmount.h> 702/* get the mount structure corresponding to a given device. Assume 703 * device corresponds to a UFS. Return NULL if no device is found. 704 */ 705struct mount *devtomp(dev) 706 dev_t dev; 707{ 708 struct mount *mp, *nmp; 709 710 for (mp = mountlist.cqh_first; mp != (void*)&mountlist; mp = nmp) { 711 nmp = mp->mnt_list.cqe_next; 712 if (((VFSTOUFS(mp))->um_dev == (dev_t) dev)) { 713 /* mount corresponds to UFS and the device matches one we want */ 714 return(mp); 715 } 716 } 717 /* mount structure wasn't found */ 718 return(NULL); 719} 720 721struct vfsops coda_vfsops = { 722 coda_mount, 723 coda_start, 724 coda_unmount, 725 coda_root, 726 coda_quotactl, 727 coda_nb_statfs, 728 coda_sync, 729 coda_vget, 730 (int (*) (struct mount *, struct fid *, struct sockaddr *, struct vnode **, 731 int *, struct ucred **)) 732 eopnotsupp, 733 (int (*) (struct vnode *, struct fid *)) eopnotsupp, 734 coda_init, 735}; 736 737#ifdef ACTUALLY_LKM_NOT_KERNEL 738/* 739 * This case is being handled in coda_fbsd.c 740 * What we want is too hairy for VFS_SET to get right! 741 */ 742#else 743VFS_SET(coda_vfsops, coda, VFCF_NETWORK); 744#endif 745