1/* 2 * Coda: an Experimental Distributed File System 3 * Release 3.1 4 * 5 * Copyright (c) 1987-1998 Carnegie Mellon University 6 * All Rights Reserved 7 * 8 * Permission to use, copy, modify and distribute this software and its --- 38 unchanged lines hidden (view full) --- 47 * The vnode pager does this. 48 * 2. coda_unmounting marks all cnodes scanning coda_cache. 49 * 3. cfs_checkunmounting (under DEBUG) checks all cnodes by chasing the vnodes 50 * under the /coda mount point. 51 * 4. coda_cacheprint (under DEBUG) prints names with vnode/cnode address 52 */ 53 54#include <sys/cdefs.h> |
55__FBSDID("$FreeBSD: head/sys/fs/coda/coda_subr.c 119832 2003-09-07 07:43:10Z tjr $"); |
56 57#include <vcoda.h> 58 59#include <sys/param.h> 60#include <sys/systm.h> 61#include <sys/lock.h> 62#include <sys/malloc.h> 63#include <sys/mount.h> --- 5 unchanged lines hidden (view full) --- 69 70int coda_active = 0; 71int coda_reuse = 0; 72int coda_new = 0; 73 74struct cnode *coda_freelist = NULL; 75struct cnode *coda_cache[CODA_CACHESIZE]; 76 |
77#define CNODE_NEXT(cp) ((cp)->c_next) |
78 |
79#ifdef CODA_COMPAT_5 80#define coda_hash(fid) \ 81 (((fid)->Volume + (fid)->Vnode) & (CODA_CACHESIZE-1)) 82#define IS_DIR(cnode) (cnode.Vnode & 0x1) 83#else 84#define coda_hash(fid) (coda_f2i(fid) & (CODA_CACHESIZE-1)) 85#define IS_DIR(cnode) (cnode.opaque[2] & 0x1) 86#endif 87 |
88/* 89 * Allocate a cnode. 90 */ 91struct cnode * 92coda_alloc(void) 93{ 94 struct cnode *cp; 95 --- 67 unchanged lines hidden (view full) --- 163} 164 165/* 166 * Lookup a cnode by fid. If the cnode is dying, it is bogus so skip it. 167 * NOTE: this allows multiple cnodes with same fid -- dcs 1/25/95 168 */ 169struct cnode * 170coda_find(fid) |
171 CodaFid *fid; |
172{ 173 struct cnode *cp; 174 175 cp = coda_cache[coda_hash(fid)]; 176 while (cp) { |
177 if (coda_fid_eq(&(cp->c_fid), fid) && |
178 (!IS_UNMOUNTING(cp))) 179 { 180 coda_active++; 181 return(cp); 182 } 183 cp = CNODE_NEXT(cp); 184 } 185 return(NULL); --- 32 unchanged lines hidden (view full) --- 218 for (hash = 0; hash < CODA_CACHESIZE; hash++) { 219 for (cp = coda_cache[hash]; cp != NULL; cp = CNODE_NEXT(cp)) { 220 if (CTOV(cp)->v_mount == whoIam) { 221#ifdef DEBUG 222 printf("coda_kill: vp %p, cp %p\n", CTOV(cp), cp); 223#endif 224 count++; 225 CODADEBUG(CODA_FLUSH, |
226 myprintf(("Live cnode fid %s flags %d count %d\n", 227 coda_f2s(&cp->c_fid), 228 cp->c_flags, 229 vrefcnt(CTOV(cp)))); ); |
230 } 231 } 232 } 233 return count; 234} 235 236/* 237 * There are two reasons why a cnode may be in use, it may be in the --- 8 unchanged lines hidden (view full) --- 246 247 coda_clstat.ncalls++; 248 coda_clstat.reqs[CODA_FLUSH]++; 249 250 coda_nc_flush(dcstat); /* flush files from the name cache */ 251 252 for (hash = 0; hash < CODA_CACHESIZE; hash++) { 253 for (cp = coda_cache[hash]; cp != NULL; cp = CNODE_NEXT(cp)) { |
254 if (!IS_DIR(cp->c_fid)) /* only files can be executed */ |
255 coda_vmflush(cp); 256 } 257 } 258} 259 260/* 261 * As a debugging measure, print out any cnodes that lived through a 262 * name cache flush. 263 */ 264void 265coda_testflush(void) 266{ 267 int hash; 268 struct cnode *cp; 269 270 for (hash = 0; hash < CODA_CACHESIZE; hash++) { 271 for (cp = coda_cache[hash]; 272 cp != NULL; 273 cp = CNODE_NEXT(cp)) { |
274 myprintf(("Live cnode fid %s count %d\n", 275 coda_f2s(&cp->c_fid), CTOV(cp)->v_usecount)); |
276 } 277 } 278} 279 280/* 281 * First, step through all cnodes and mark them unmounting. 282 * NetBSD kernels may try to fsync them now that venus 283 * is dead, which would be a bad thing. --- 86 unchanged lines hidden (view full) --- 370 * CODA_PURGEFID -- flush the attribute for the file 371 * If it is a dir (odd vnode), purge its 372 * children from the namecache 373 * remove the file from the namecache. 374 * 375 * The sixth allows Venus to replace local fids with global ones 376 * during reintegration. 377 * |
378 * CODA_REPLACE -- replace one CodaFid with another throughout the name cache |
379 */ 380 381int handleDownCall(opcode, out) 382 int opcode; union outputArgs *out; 383{ 384 int error; 385 386 /* Handle invalidate requests. */ --- 6 unchanged lines hidden (view full) --- 393 return(0); 394 } 395 396 case CODA_PURGEUSER : { 397 coda_clstat.ncalls++; 398 coda_clstat.reqs[CODA_PURGEUSER]++; 399 400 /* XXX - need to prevent fsync's */ |
401#ifdef CODA_COMPAT_5 |
402 coda_nc_purge_user(out->coda_purgeuser.cred.cr_uid, IS_DOWNCALL); |
403#else 404 coda_nc_purge_user(out->coda_purgeuser.uid, IS_DOWNCALL); 405#endif |
406 return(0); 407 } 408 409 case CODA_ZAPFILE : { 410 struct cnode *cp; 411 412 error = 0; 413 coda_clstat.ncalls++; 414 coda_clstat.reqs[CODA_ZAPFILE]++; 415 |
416 cp = coda_find(&out->coda_zapfile.Fid); |
417 if (cp != NULL) { 418 vref(CTOV(cp)); 419 420 cp->c_flags &= ~C_VATTR; 421 ASSERT_VOP_LOCKED(CTOV(cp), "coda HandleDownCall"); 422 if (CTOV(cp)->v_vflag & VV_TEXT) 423 error = coda_vmflush(cp); |
424 CODADEBUG(CODA_ZAPFILE, 425 myprintf(("zapfile: fid = %s, refcnt = %d, error = %d\n", 426 coda_f2s(&cp->c_fid), CTOV(cp)->v_usecount - 1, error));); 427 if (vrefcnt(CTOV(cp)) == 1) { |
428 cp->c_flags |= C_PURGING; 429 } 430 vrele(CTOV(cp)); 431 } 432 433 return(error); 434 } 435 436 case CODA_ZAPDIR : { 437 struct cnode *cp; 438 439 coda_clstat.ncalls++; 440 coda_clstat.reqs[CODA_ZAPDIR]++; 441 |
442 cp = coda_find(&out->coda_zapdir.Fid); |
443 if (cp != NULL) { 444 vref(CTOV(cp)); 445 446 cp->c_flags &= ~C_VATTR; |
447 coda_nc_zapParentfid(&out->coda_zapdir.Fid, IS_DOWNCALL); |
448 449 CODADEBUG(CODA_ZAPDIR, myprintf(( |
450 "zapdir: fid = %s, refcnt = %d\n", 451 coda_f2s(&cp->c_fid), CTOV(cp)->v_usecount - 1));); |
452 if (vrefcnt(CTOV(cp)) == 1) { 453 cp->c_flags |= C_PURGING; 454 } 455 vrele(CTOV(cp)); 456 } 457 458 return(0); 459 } 460 461 case CODA_PURGEFID : { 462 struct cnode *cp; 463 464 error = 0; 465 coda_clstat.ncalls++; 466 coda_clstat.reqs[CODA_PURGEFID]++; 467 |
468 cp = coda_find(&out->coda_purgefid.Fid); |
469 if (cp != NULL) { 470 vref(CTOV(cp)); |
471 if (IS_DIR(out->coda_purgefid.Fid)) { /* Vnode is a directory */ 472 coda_nc_zapParentfid(&out->coda_purgefid.Fid,IS_DOWNCALL); |
473 } 474 cp->c_flags &= ~C_VATTR; |
475 coda_nc_zapfid(&out->coda_purgefid.Fid, IS_DOWNCALL); |
476 ASSERT_VOP_LOCKED(CTOV(cp), "coda HandleDownCall"); |
477 if (!(IS_DIR(out->coda_purgefid.Fid)) |
478 && (CTOV(cp)->v_vflag & VV_TEXT)) { 479 480 error = coda_vmflush(cp); 481 } |
482 CODADEBUG(CODA_PURGEFID, myprintf(( 483 "purgefid: fid = %s, refcnt = %d, error = %d\n", 484 coda_f2s(&cp->c_fid), CTOV(cp)->v_usecount - 1, error));); |
485 if (vrefcnt(CTOV(cp)) == 1) { 486 cp->c_flags |= C_PURGING; 487 } 488 vrele(CTOV(cp)); 489 } 490 return(error); 491 } 492 --- 6 unchanged lines hidden (view full) --- 499 cp = coda_find(&out->coda_replace.OldFid); 500 if (cp != NULL) { 501 /* remove the cnode from the hash table, replace the fid, and reinsert */ 502 vref(CTOV(cp)); 503 coda_unsave(cp); 504 cp->c_fid = out->coda_replace.NewFid; 505 coda_save(cp); 506 |
507 CODADEBUG(CODA_REPLACE, myprintf(( 508 "replace: oldfid = %s, newfid = %s, cp = %p\n", 509 coda_f2s(&out->coda_replace.OldFid), 510 coda_f2s(&cp->c_fid), cp));) vrele(CTOV(cp)); |
511 } 512 return (0); 513 } 514 default: 515 myprintf(("handleDownCall: unknown opcode %d\n", opcode)); 516 return (EINVAL); 517 } 518} --- 51 unchanged lines hidden --- |