Deleted Added
sdiff udiff text old ( 116173 ) new ( 119832 )
full compact
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 ---