1*9f3ba01bSAlexander von Gluck IV /* 2*9f3ba01bSAlexander von Gluck IV Copyright 1999-2001, Be Incorporated. All Rights Reserved. 3*9f3ba01bSAlexander von Gluck IV This file may be used under the terms of the Be Sample Code License. 4*9f3ba01bSAlexander von Gluck IV */ 5*9f3ba01bSAlexander von Gluck IV /* 6*9f3ba01bSAlexander von Gluck IV The FAT file system has no good way of assigning unique persistent values to 7*9f3ba01bSAlexander von Gluck IV nodes. The only obvious choice, storing the starting cluster number of the 8*9f3ba01bSAlexander von Gluck IV file, is unusable because 0 byte files exist as directory entries only. 9*9f3ba01bSAlexander von Gluck IV Further, even if it were usable, it would potentially require a full directory 10*9f3ba01bSAlexander von Gluck IV tree traversal to locate an arbitrary node. We must resort to some ickiness 11*9f3ba01bSAlexander von Gluck IV in order to make persistent vnode id's (at least across a given mount) work. 12*9f3ba01bSAlexander von Gluck IV 13*9f3ba01bSAlexander von Gluck IV There are three ways to encode a vnode id: 14*9f3ba01bSAlexander von Gluck IV 15*9f3ba01bSAlexander von Gluck IV 1. Combine the starting cluster of the entry with the starting cluster of the 16*9f3ba01bSAlexander von Gluck IV directory it appears in. This is used for files with data. 17*9f3ba01bSAlexander von Gluck IV 2. Combine the starting cluster of the directory the entry appears in with the 18*9f3ba01bSAlexander von Gluck IV index of the entry in the directory. This is used for 0-byte files. 19*9f3ba01bSAlexander von Gluck IV 3. A unique number that doesn't match any possible values from encodings 1 or 20*9f3ba01bSAlexander von Gluck IV 2. 21*9f3ba01bSAlexander von Gluck IV 22*9f3ba01bSAlexander von Gluck IV With the first encoding, the vnode id is invalidated (i.e. no longer describes 23*9f3ba01bSAlexander von Gluck IV the file's location) when the file moves to a different directory or when 24*9f3ba01bSAlexander von Gluck IV its starting cluster changes (this can occur if the file is truncated and data 25*9f3ba01bSAlexander von Gluck IV is subsequently written to it). 26*9f3ba01bSAlexander von Gluck IV 27*9f3ba01bSAlexander von Gluck IV With the second encoding, the vnode id is invalidated when the file position 28*9f3ba01bSAlexander von Gluck IV is moved within a directory (as a result of a renaming), when it's moved to a 29*9f3ba01bSAlexander von Gluck IV different directory, or when data is written to it. 30*9f3ba01bSAlexander von Gluck IV 31*9f3ba01bSAlexander von Gluck IV The third encoding doesn't describe the file's location on disk, and so it is 32*9f3ba01bSAlexander von Gluck IV invalid from the start. 33*9f3ba01bSAlexander von Gluck IV 34*9f3ba01bSAlexander von Gluck IV Since we can't change vnode id's once they are assigned, we have to create a 35*9f3ba01bSAlexander von Gluck IV mapping table to translate vnode id's to locations. This file serves this 36*9f3ba01bSAlexander von Gluck IV purpose. 37*9f3ba01bSAlexander von Gluck IV */ 38*9f3ba01bSAlexander von Gluck IV 39*9f3ba01bSAlexander von Gluck IV 40*9f3ba01bSAlexander von Gluck IV #include "vcache.h" 41*9f3ba01bSAlexander von Gluck IV 42*9f3ba01bSAlexander von Gluck IV #include "system_dependencies.h" 43*9f3ba01bSAlexander von Gluck IV 44*9f3ba01bSAlexander von Gluck IV #include "dosfs.h" 45*9f3ba01bSAlexander von Gluck IV #include "util.h" 46*9f3ba01bSAlexander von Gluck IV 47*9f3ba01bSAlexander von Gluck IV 48*9f3ba01bSAlexander von Gluck IV #define DPRINTF(a,b) if (debug_vcache > (a)) dprintf b 49*9f3ba01bSAlexander von Gluck IV 50*9f3ba01bSAlexander von Gluck IV #define LOCK_CACHE_R \ 51*9f3ba01bSAlexander von Gluck IV rw_lock_read_lock(&vol->vcache.lock) 52*9f3ba01bSAlexander von Gluck IV 53*9f3ba01bSAlexander von Gluck IV #define LOCK_CACHE_W \ 54*9f3ba01bSAlexander von Gluck IV rw_lock_write_lock(&vol->vcache.lock) 55*9f3ba01bSAlexander von Gluck IV 56*9f3ba01bSAlexander von Gluck IV #define UNLOCK_CACHE_R \ 57*9f3ba01bSAlexander von Gluck IV rw_lock_read_unlock(&vol->vcache.lock) 58*9f3ba01bSAlexander von Gluck IV 59*9f3ba01bSAlexander von Gluck IV #define UNLOCK_CACHE_W \ 60*9f3ba01bSAlexander von Gluck IV rw_lock_write_unlock(&vol->vcache.lock) 61*9f3ba01bSAlexander von Gluck IV 62*9f3ba01bSAlexander von Gluck IV #define hash(v) ((v) & (vol->vcache.cache_size-1)) 63*9f3ba01bSAlexander von Gluck IV 64*9f3ba01bSAlexander von Gluck IV 65*9f3ba01bSAlexander von Gluck IV struct vcache_entry { 66*9f3ba01bSAlexander von Gluck IV ino_t vnid; /* originally reported vnid */ 67*9f3ba01bSAlexander von Gluck IV ino_t loc; /* where the file is now */ 68*9f3ba01bSAlexander von Gluck IV struct vcache_entry *next_vnid; /* next entry in vnid hash table */ 69*9f3ba01bSAlexander von Gluck IV struct vcache_entry *next_loc; /* next entry in location hash table */ 70*9f3ba01bSAlexander von Gluck IV }; 71*9f3ba01bSAlexander von Gluck IV 72*9f3ba01bSAlexander von Gluck IV 73*9f3ba01bSAlexander von Gluck IV void 74*9f3ba01bSAlexander von Gluck IV dump_vcache(nspace *vol) 75*9f3ba01bSAlexander von Gluck IV { 76*9f3ba01bSAlexander von Gluck IV uint32 i; 77*9f3ba01bSAlexander von Gluck IV struct vcache_entry *c; 78*9f3ba01bSAlexander von Gluck IV kprintf("vnid cache size %" B_PRIu32 ", cur vnid = %" B_PRIdINO "\n" 79*9f3ba01bSAlexander von Gluck IV "vnid loc\n", vol->vcache.cache_size, vol->vcache.cur_vnid); 80*9f3ba01bSAlexander von Gluck IV for (i = 0; i < vol->vcache.cache_size; i++) { 81*9f3ba01bSAlexander von Gluck IV for (c = vol->vcache.by_vnid[i]; c ; c = c->next_vnid) 82*9f3ba01bSAlexander von Gluck IV kprintf("%16" B_PRIdINO " %16" B_PRIdINO "\n", c->vnid, c->loc); 83*9f3ba01bSAlexander von Gluck IV } 84*9f3ba01bSAlexander von Gluck IV } 85*9f3ba01bSAlexander von Gluck IV 86*9f3ba01bSAlexander von Gluck IV 87*9f3ba01bSAlexander von Gluck IV status_t 88*9f3ba01bSAlexander von Gluck IV init_vcache(nspace *vol) 89*9f3ba01bSAlexander von Gluck IV { 90*9f3ba01bSAlexander von Gluck IV char name[16]; 91*9f3ba01bSAlexander von Gluck IV DPRINTF(0, ("init_vcache called\n")); 92*9f3ba01bSAlexander von Gluck IV 93*9f3ba01bSAlexander von Gluck IV vol->vcache.cur_vnid = ARTIFICIAL_VNID_BITS; 94*9f3ba01bSAlexander von Gluck IV #if DEBUG 95*9f3ba01bSAlexander von Gluck IV vol->vcache.cache_size = 1; 96*9f3ba01bSAlexander von Gluck IV #else 97*9f3ba01bSAlexander von Gluck IV vol->vcache.cache_size = 512; /* must be power of 2 */ 98*9f3ba01bSAlexander von Gluck IV #endif 99*9f3ba01bSAlexander von Gluck IV 100*9f3ba01bSAlexander von Gluck IV vol->vcache.by_vnid = (vcache_entry**)calloc(sizeof(struct vache_entry *), 101*9f3ba01bSAlexander von Gluck IV vol->vcache.cache_size); 102*9f3ba01bSAlexander von Gluck IV if (vol->vcache.by_vnid == NULL) { 103*9f3ba01bSAlexander von Gluck IV dprintf("init_vcache: out of memory\n"); 104*9f3ba01bSAlexander von Gluck IV return ENOMEM; 105*9f3ba01bSAlexander von Gluck IV } 106*9f3ba01bSAlexander von Gluck IV 107*9f3ba01bSAlexander von Gluck IV vol->vcache.by_loc = (vcache_entry**)calloc(sizeof(struct vache_entry *), 108*9f3ba01bSAlexander von Gluck IV vol->vcache.cache_size); 109*9f3ba01bSAlexander von Gluck IV if (vol->vcache.by_loc == NULL) { 110*9f3ba01bSAlexander von Gluck IV dprintf("init_vcache: out of memory\n"); 111*9f3ba01bSAlexander von Gluck IV free(vol->vcache.by_vnid); 112*9f3ba01bSAlexander von Gluck IV vol->vcache.by_vnid = NULL; 113*9f3ba01bSAlexander von Gluck IV return ENOMEM; 114*9f3ba01bSAlexander von Gluck IV } 115*9f3ba01bSAlexander von Gluck IV 116*9f3ba01bSAlexander von Gluck IV sprintf(name, "fat cache %" B_PRIdDEV, vol->id); 117*9f3ba01bSAlexander von Gluck IV rw_lock_init(&vol->vcache.lock, "fat cache"); 118*9f3ba01bSAlexander von Gluck IV 119*9f3ba01bSAlexander von Gluck IV DPRINTF(0, ("init_vcache: initialized vnid cache with %" B_PRIu32 120*9f3ba01bSAlexander von Gluck IV " entries\n", vol->vcache.cache_size)); 121*9f3ba01bSAlexander von Gluck IV 122*9f3ba01bSAlexander von Gluck IV return 0; 123*9f3ba01bSAlexander von Gluck IV } 124*9f3ba01bSAlexander von Gluck IV 125*9f3ba01bSAlexander von Gluck IV 126*9f3ba01bSAlexander von Gluck IV status_t 127*9f3ba01bSAlexander von Gluck IV uninit_vcache(nspace *vol) 128*9f3ba01bSAlexander von Gluck IV { 129*9f3ba01bSAlexander von Gluck IV uint32 i, count = 0; 130*9f3ba01bSAlexander von Gluck IV struct vcache_entry *c, *n; 131*9f3ba01bSAlexander von Gluck IV DPRINTF(0, ("uninit_vcache called\n")); 132*9f3ba01bSAlexander von Gluck IV 133*9f3ba01bSAlexander von Gluck IV LOCK_CACHE_W; 134*9f3ba01bSAlexander von Gluck IV 135*9f3ba01bSAlexander von Gluck IV /* free entries */ 136*9f3ba01bSAlexander von Gluck IV for (i = 0; i < vol->vcache.cache_size; i++) { 137*9f3ba01bSAlexander von Gluck IV c = vol->vcache.by_vnid[i]; 138*9f3ba01bSAlexander von Gluck IV while (c) { 139*9f3ba01bSAlexander von Gluck IV count++; 140*9f3ba01bSAlexander von Gluck IV n = c->next_vnid; 141*9f3ba01bSAlexander von Gluck IV free(c); 142*9f3ba01bSAlexander von Gluck IV c = n; 143*9f3ba01bSAlexander von Gluck IV } 144*9f3ba01bSAlexander von Gluck IV } 145*9f3ba01bSAlexander von Gluck IV 146*9f3ba01bSAlexander von Gluck IV DPRINTF(0, ("%" B_PRIu32 " vcache entries removed\n", count)); 147*9f3ba01bSAlexander von Gluck IV 148*9f3ba01bSAlexander von Gluck IV free(vol->vcache.by_vnid); vol->vcache.by_vnid = NULL; 149*9f3ba01bSAlexander von Gluck IV free(vol->vcache.by_loc); vol->vcache.by_loc = NULL; 150*9f3ba01bSAlexander von Gluck IV 151*9f3ba01bSAlexander von Gluck IV rw_lock_destroy(&vol->vcache.lock); 152*9f3ba01bSAlexander von Gluck IV return B_OK; 153*9f3ba01bSAlexander von Gluck IV } 154*9f3ba01bSAlexander von Gluck IV 155*9f3ba01bSAlexander von Gluck IV 156*9f3ba01bSAlexander von Gluck IV ino_t 157*9f3ba01bSAlexander von Gluck IV generate_unique_vnid(nspace *vol) 158*9f3ba01bSAlexander von Gluck IV { 159*9f3ba01bSAlexander von Gluck IV DPRINTF(0, ("generate_unique_vnid\n")); 160*9f3ba01bSAlexander von Gluck IV /* only one thread per volume will be in here at any given time anyway 161*9f3ba01bSAlexander von Gluck IV * due to volume locking */ 162*9f3ba01bSAlexander von Gluck IV return vol->vcache.cur_vnid++; 163*9f3ba01bSAlexander von Gluck IV } 164*9f3ba01bSAlexander von Gluck IV 165*9f3ba01bSAlexander von Gluck IV 166*9f3ba01bSAlexander von Gluck IV static status_t 167*9f3ba01bSAlexander von Gluck IV _add_to_vcache_(nspace *vol, ino_t vnid, ino_t loc) 168*9f3ba01bSAlexander von Gluck IV { 169*9f3ba01bSAlexander von Gluck IV int hash1 = hash(vnid), hash2 = hash(loc); 170*9f3ba01bSAlexander von Gluck IV struct vcache_entry *e, *c, *p; 171*9f3ba01bSAlexander von Gluck IV 172*9f3ba01bSAlexander von Gluck IV DPRINTF(0, ("add_to_vcache %" B_PRIdINO "/%" B_PRIdINO "\n", vnid, loc)); 173*9f3ba01bSAlexander von Gluck IV 174*9f3ba01bSAlexander von Gluck IV ASSERT(vnid != loc); 175*9f3ba01bSAlexander von Gluck IV 176*9f3ba01bSAlexander von Gluck IV e = (vcache_entry*)malloc(sizeof(struct vcache_entry)); 177*9f3ba01bSAlexander von Gluck IV if (e == NULL) 178*9f3ba01bSAlexander von Gluck IV return ENOMEM; 179*9f3ba01bSAlexander von Gluck IV 180*9f3ba01bSAlexander von Gluck IV e->vnid = vnid; e->loc = loc; e->next_vnid = NULL; e->next_loc = NULL; 181*9f3ba01bSAlexander von Gluck IV 182*9f3ba01bSAlexander von Gluck IV c = p = vol->vcache.by_vnid[hash1]; 183*9f3ba01bSAlexander von Gluck IV while (c) { 184*9f3ba01bSAlexander von Gluck IV if (vnid < c->vnid) 185*9f3ba01bSAlexander von Gluck IV break; 186*9f3ba01bSAlexander von Gluck IV ASSERT(vnid != c->vnid); ASSERT(loc != c->loc); 187*9f3ba01bSAlexander von Gluck IV p = c; 188*9f3ba01bSAlexander von Gluck IV c = c->next_vnid; 189*9f3ba01bSAlexander von Gluck IV } 190*9f3ba01bSAlexander von Gluck IV ASSERT(!c || (vnid != c->vnid)); 191*9f3ba01bSAlexander von Gluck IV 192*9f3ba01bSAlexander von Gluck IV e->next_vnid = c; 193*9f3ba01bSAlexander von Gluck IV if (p == c) 194*9f3ba01bSAlexander von Gluck IV vol->vcache.by_vnid[hash1] = e; 195*9f3ba01bSAlexander von Gluck IV else 196*9f3ba01bSAlexander von Gluck IV p->next_vnid = e; 197*9f3ba01bSAlexander von Gluck IV 198*9f3ba01bSAlexander von Gluck IV c = p = vol->vcache.by_loc[hash2]; 199*9f3ba01bSAlexander von Gluck IV while (c) { 200*9f3ba01bSAlexander von Gluck IV if (loc < c->loc) 201*9f3ba01bSAlexander von Gluck IV break; 202*9f3ba01bSAlexander von Gluck IV ASSERT(vnid != c->vnid); ASSERT(loc != c->loc); 203*9f3ba01bSAlexander von Gluck IV p = c; 204*9f3ba01bSAlexander von Gluck IV c = c->next_loc; 205*9f3ba01bSAlexander von Gluck IV } 206*9f3ba01bSAlexander von Gluck IV ASSERT(!c || (loc != c->loc)); 207*9f3ba01bSAlexander von Gluck IV 208*9f3ba01bSAlexander von Gluck IV e->next_loc = c; 209*9f3ba01bSAlexander von Gluck IV if (p == c) 210*9f3ba01bSAlexander von Gluck IV vol->vcache.by_loc[hash2] = e; 211*9f3ba01bSAlexander von Gluck IV else 212*9f3ba01bSAlexander von Gluck IV p->next_loc = e; 213*9f3ba01bSAlexander von Gluck IV 214*9f3ba01bSAlexander von Gluck IV return B_OK; 215*9f3ba01bSAlexander von Gluck IV } 216*9f3ba01bSAlexander von Gluck IV 217*9f3ba01bSAlexander von Gluck IV 218*9f3ba01bSAlexander von Gluck IV static status_t 219*9f3ba01bSAlexander von Gluck IV _remove_from_vcache_(nspace *vol, ino_t vnid) 220*9f3ba01bSAlexander von Gluck IV { 221*9f3ba01bSAlexander von Gluck IV int hash1 = hash(vnid), hash2; 222*9f3ba01bSAlexander von Gluck IV struct vcache_entry *c, *p, *e; 223*9f3ba01bSAlexander von Gluck IV 224*9f3ba01bSAlexander von Gluck IV DPRINTF(0, ("remove_from_vcache %" B_PRIdINO "\n", vnid)); 225*9f3ba01bSAlexander von Gluck IV 226*9f3ba01bSAlexander von Gluck IV c = p = vol->vcache.by_vnid[hash1]; 227*9f3ba01bSAlexander von Gluck IV while (c) { 228*9f3ba01bSAlexander von Gluck IV if (vnid == c->vnid) 229*9f3ba01bSAlexander von Gluck IV break; 230*9f3ba01bSAlexander von Gluck IV ASSERT(c->vnid < vnid); 231*9f3ba01bSAlexander von Gluck IV p = c; 232*9f3ba01bSAlexander von Gluck IV c = c->next_vnid; 233*9f3ba01bSAlexander von Gluck IV } 234*9f3ba01bSAlexander von Gluck IV ASSERT(c); 235*9f3ba01bSAlexander von Gluck IV if (!c) return ENOENT; 236*9f3ba01bSAlexander von Gluck IV 237*9f3ba01bSAlexander von Gluck IV if (p == c) 238*9f3ba01bSAlexander von Gluck IV vol->vcache.by_vnid[hash1] = c->next_vnid; 239*9f3ba01bSAlexander von Gluck IV else 240*9f3ba01bSAlexander von Gluck IV p->next_vnid = c->next_vnid; 241*9f3ba01bSAlexander von Gluck IV 242*9f3ba01bSAlexander von Gluck IV e = c; 243*9f3ba01bSAlexander von Gluck IV 244*9f3ba01bSAlexander von Gluck IV hash2 = hash(c->loc); 245*9f3ba01bSAlexander von Gluck IV c = p = vol->vcache.by_loc[hash2]; 246*9f3ba01bSAlexander von Gluck IV 247*9f3ba01bSAlexander von Gluck IV while (c) { 248*9f3ba01bSAlexander von Gluck IV if (vnid == c->vnid) 249*9f3ba01bSAlexander von Gluck IV break; 250*9f3ba01bSAlexander von Gluck IV ASSERT(c->loc < e->loc); 251*9f3ba01bSAlexander von Gluck IV p = c; 252*9f3ba01bSAlexander von Gluck IV c = c->next_loc; 253*9f3ba01bSAlexander von Gluck IV } 254*9f3ba01bSAlexander von Gluck IV ASSERT(c); 255*9f3ba01bSAlexander von Gluck IV if (!c) return ENOENT; 256*9f3ba01bSAlexander von Gluck IV if (p == c) 257*9f3ba01bSAlexander von Gluck IV vol->vcache.by_loc[hash2] = c->next_loc; 258*9f3ba01bSAlexander von Gluck IV else 259*9f3ba01bSAlexander von Gluck IV p->next_loc = c->next_loc; 260*9f3ba01bSAlexander von Gluck IV 261*9f3ba01bSAlexander von Gluck IV free(c); 262*9f3ba01bSAlexander von Gluck IV 263*9f3ba01bSAlexander von Gluck IV return 0; 264*9f3ba01bSAlexander von Gluck IV } 265*9f3ba01bSAlexander von Gluck IV 266*9f3ba01bSAlexander von Gluck IV 267*9f3ba01bSAlexander von Gluck IV static struct vcache_entry * 268*9f3ba01bSAlexander von Gluck IV _find_vnid_in_vcache_(nspace *vol, ino_t vnid) 269*9f3ba01bSAlexander von Gluck IV { 270*9f3ba01bSAlexander von Gluck IV int hash1 = hash(vnid); 271*9f3ba01bSAlexander von Gluck IV struct vcache_entry *c; 272*9f3ba01bSAlexander von Gluck IV c = vol->vcache.by_vnid[hash1]; 273*9f3ba01bSAlexander von Gluck IV while (c) { 274*9f3ba01bSAlexander von Gluck IV if (c->vnid == vnid) 275*9f3ba01bSAlexander von Gluck IV break; 276*9f3ba01bSAlexander von Gluck IV if (c->vnid > vnid) 277*9f3ba01bSAlexander von Gluck IV return NULL; 278*9f3ba01bSAlexander von Gluck IV c = c->next_vnid; 279*9f3ba01bSAlexander von Gluck IV } 280*9f3ba01bSAlexander von Gluck IV 281*9f3ba01bSAlexander von Gluck IV return c; 282*9f3ba01bSAlexander von Gluck IV } 283*9f3ba01bSAlexander von Gluck IV 284*9f3ba01bSAlexander von Gluck IV 285*9f3ba01bSAlexander von Gluck IV static struct vcache_entry * 286*9f3ba01bSAlexander von Gluck IV _find_loc_in_vcache_(nspace *vol, ino_t loc) 287*9f3ba01bSAlexander von Gluck IV { 288*9f3ba01bSAlexander von Gluck IV int hash2 = hash(loc); 289*9f3ba01bSAlexander von Gluck IV struct vcache_entry *c; 290*9f3ba01bSAlexander von Gluck IV c = vol->vcache.by_loc[hash2]; 291*9f3ba01bSAlexander von Gluck IV while (c) { 292*9f3ba01bSAlexander von Gluck IV if (c->loc == loc) 293*9f3ba01bSAlexander von Gluck IV break; 294*9f3ba01bSAlexander von Gluck IV if (c->loc > loc) 295*9f3ba01bSAlexander von Gluck IV return NULL; 296*9f3ba01bSAlexander von Gluck IV c = c->next_loc; 297*9f3ba01bSAlexander von Gluck IV } 298*9f3ba01bSAlexander von Gluck IV 299*9f3ba01bSAlexander von Gluck IV return c; 300*9f3ba01bSAlexander von Gluck IV } 301*9f3ba01bSAlexander von Gluck IV 302*9f3ba01bSAlexander von Gluck IV 303*9f3ba01bSAlexander von Gluck IV status_t 304*9f3ba01bSAlexander von Gluck IV add_to_vcache(nspace *vol, ino_t vnid, ino_t loc) 305*9f3ba01bSAlexander von Gluck IV { 306*9f3ba01bSAlexander von Gluck IV status_t result; 307*9f3ba01bSAlexander von Gluck IV 308*9f3ba01bSAlexander von Gluck IV LOCK_CACHE_W; 309*9f3ba01bSAlexander von Gluck IV result = _add_to_vcache_(vol,vnid,loc); 310*9f3ba01bSAlexander von Gluck IV UNLOCK_CACHE_W; 311*9f3ba01bSAlexander von Gluck IV 312*9f3ba01bSAlexander von Gluck IV if (result < 0) DPRINTF(0, ("add_to_vcache failed (%s)\n", strerror(result))); 313*9f3ba01bSAlexander von Gluck IV return result; 314*9f3ba01bSAlexander von Gluck IV } 315*9f3ba01bSAlexander von Gluck IV 316*9f3ba01bSAlexander von Gluck IV 317*9f3ba01bSAlexander von Gluck IV /* XXX: do this in a smarter fashion */ 318*9f3ba01bSAlexander von Gluck IV static status_t 319*9f3ba01bSAlexander von Gluck IV _update_loc_in_vcache_(nspace *vol, ino_t vnid, ino_t loc) 320*9f3ba01bSAlexander von Gluck IV { 321*9f3ba01bSAlexander von Gluck IV status_t result; 322*9f3ba01bSAlexander von Gluck IV 323*9f3ba01bSAlexander von Gluck IV result = _remove_from_vcache_(vol, vnid); 324*9f3ba01bSAlexander von Gluck IV if (result == 0) 325*9f3ba01bSAlexander von Gluck IV result = _add_to_vcache_(vol, vnid, loc); 326*9f3ba01bSAlexander von Gluck IV 327*9f3ba01bSAlexander von Gluck IV return result; 328*9f3ba01bSAlexander von Gluck IV } 329*9f3ba01bSAlexander von Gluck IV 330*9f3ba01bSAlexander von Gluck IV 331*9f3ba01bSAlexander von Gluck IV status_t 332*9f3ba01bSAlexander von Gluck IV remove_from_vcache(nspace *vol, ino_t vnid) 333*9f3ba01bSAlexander von Gluck IV { 334*9f3ba01bSAlexander von Gluck IV status_t result; 335*9f3ba01bSAlexander von Gluck IV 336*9f3ba01bSAlexander von Gluck IV LOCK_CACHE_W; 337*9f3ba01bSAlexander von Gluck IV result = _remove_from_vcache_(vol, vnid); 338*9f3ba01bSAlexander von Gluck IV UNLOCK_CACHE_W; 339*9f3ba01bSAlexander von Gluck IV 340*9f3ba01bSAlexander von Gluck IV if (result < 0) DPRINTF(0, ("remove_from_vcache failed (%s)\n", strerror(result))); 341*9f3ba01bSAlexander von Gluck IV return result; 342*9f3ba01bSAlexander von Gluck IV } 343*9f3ba01bSAlexander von Gluck IV 344*9f3ba01bSAlexander von Gluck IV 345*9f3ba01bSAlexander von Gluck IV status_t 346*9f3ba01bSAlexander von Gluck IV vcache_vnid_to_loc(nspace *vol, ino_t vnid, ino_t *loc) 347*9f3ba01bSAlexander von Gluck IV { 348*9f3ba01bSAlexander von Gluck IV struct vcache_entry *e; 349*9f3ba01bSAlexander von Gluck IV 350*9f3ba01bSAlexander von Gluck IV DPRINTF(1, ("vcache_vnid_to_loc %" B_PRIdINO " %p\n", vnid, 351*9f3ba01bSAlexander von Gluck IV loc)); 352*9f3ba01bSAlexander von Gluck IV 353*9f3ba01bSAlexander von Gluck IV LOCK_CACHE_R; 354*9f3ba01bSAlexander von Gluck IV e = _find_vnid_in_vcache_(vol, vnid); 355*9f3ba01bSAlexander von Gluck IV if (loc && e) 356*9f3ba01bSAlexander von Gluck IV *loc = e->loc; 357*9f3ba01bSAlexander von Gluck IV UNLOCK_CACHE_R; 358*9f3ba01bSAlexander von Gluck IV 359*9f3ba01bSAlexander von Gluck IV return (e) ? B_OK : ENOENT; 360*9f3ba01bSAlexander von Gluck IV } 361*9f3ba01bSAlexander von Gluck IV 362*9f3ba01bSAlexander von Gluck IV 363*9f3ba01bSAlexander von Gluck IV status_t 364*9f3ba01bSAlexander von Gluck IV vcache_loc_to_vnid(nspace *vol, ino_t loc, ino_t *vnid) 365*9f3ba01bSAlexander von Gluck IV { 366*9f3ba01bSAlexander von Gluck IV struct vcache_entry *e; 367*9f3ba01bSAlexander von Gluck IV 368*9f3ba01bSAlexander von Gluck IV DPRINTF(1, ("vcache_loc_to_vnid %" B_PRIdINO " %p\n", loc, 369*9f3ba01bSAlexander von Gluck IV vnid)); 370*9f3ba01bSAlexander von Gluck IV 371*9f3ba01bSAlexander von Gluck IV LOCK_CACHE_R; 372*9f3ba01bSAlexander von Gluck IV e = _find_loc_in_vcache_(vol, loc); 373*9f3ba01bSAlexander von Gluck IV if (vnid && e) 374*9f3ba01bSAlexander von Gluck IV *vnid = e->vnid; 375*9f3ba01bSAlexander von Gluck IV UNLOCK_CACHE_R; 376*9f3ba01bSAlexander von Gluck IV 377*9f3ba01bSAlexander von Gluck IV return (e) ? B_OK : ENOENT; 378*9f3ba01bSAlexander von Gluck IV } 379*9f3ba01bSAlexander von Gluck IV 380*9f3ba01bSAlexander von Gluck IV 381*9f3ba01bSAlexander von Gluck IV status_t 382*9f3ba01bSAlexander von Gluck IV vcache_set_entry(nspace *vol, ino_t vnid, ino_t loc) 383*9f3ba01bSAlexander von Gluck IV { 384*9f3ba01bSAlexander von Gluck IV struct vcache_entry *e; 385*9f3ba01bSAlexander von Gluck IV status_t result = B_OK; 386*9f3ba01bSAlexander von Gluck IV 387*9f3ba01bSAlexander von Gluck IV DPRINTF(0, ("vcache_set_entry: %" B_PRIdINO " -> %" B_PRIdINO "\n", vnid, 388*9f3ba01bSAlexander von Gluck IV loc)); 389*9f3ba01bSAlexander von Gluck IV 390*9f3ba01bSAlexander von Gluck IV /*if (is_vnode_removed(vol->id, vnid) > 0) { 391*9f3ba01bSAlexander von Gluck IV if (!IS_ARTIFICIAL_VNID(loc)) 392*9f3ba01bSAlexander von Gluck IV return B_OK; 393*9f3ba01bSAlexander von Gluck IV } else { 394*9f3ba01bSAlexander von Gluck IV ASSERT(is_vnode_removed(vol->id, vnid) == 0); 395*9f3ba01bSAlexander von Gluck IV }*/ 396*9f3ba01bSAlexander von Gluck IV 397*9f3ba01bSAlexander von Gluck IV LOCK_CACHE_W; 398*9f3ba01bSAlexander von Gluck IV 399*9f3ba01bSAlexander von Gluck IV e = _find_vnid_in_vcache_(vol, vnid); 400*9f3ba01bSAlexander von Gluck IV 401*9f3ba01bSAlexander von Gluck IV if (e) { 402*9f3ba01bSAlexander von Gluck IV if (e->vnid == loc) 403*9f3ba01bSAlexander von Gluck IV result = _remove_from_vcache_(vol, vnid); 404*9f3ba01bSAlexander von Gluck IV else 405*9f3ba01bSAlexander von Gluck IV result = _update_loc_in_vcache_(vol, vnid, loc); 406*9f3ba01bSAlexander von Gluck IV } else { 407*9f3ba01bSAlexander von Gluck IV if (vnid != loc) 408*9f3ba01bSAlexander von Gluck IV result = _add_to_vcache_(vol,vnid,loc); 409*9f3ba01bSAlexander von Gluck IV } 410*9f3ba01bSAlexander von Gluck IV 411*9f3ba01bSAlexander von Gluck IV UNLOCK_CACHE_W; 412*9f3ba01bSAlexander von Gluck IV 413*9f3ba01bSAlexander von Gluck IV return result; 414*9f3ba01bSAlexander von Gluck IV } 415*9f3ba01bSAlexander von Gluck IV 416*9f3ba01bSAlexander von Gluck IV #if DEBUG 417*9f3ba01bSAlexander von Gluck IV 418*9f3ba01bSAlexander von Gluck IV int 419*9f3ba01bSAlexander von Gluck IV debug_dfvnid(int argc, char **argv) 420*9f3ba01bSAlexander von Gluck IV { 421*9f3ba01bSAlexander von Gluck IV int i; 422*9f3ba01bSAlexander von Gluck IV nspace *vol; 423*9f3ba01bSAlexander von Gluck IV 424*9f3ba01bSAlexander von Gluck IV if (argc < 3) { 425*9f3ba01bSAlexander von Gluck IV kprintf("dfvnid nspace vnid\n"); 426*9f3ba01bSAlexander von Gluck IV return B_OK; 427*9f3ba01bSAlexander von Gluck IV } 428*9f3ba01bSAlexander von Gluck IV 429*9f3ba01bSAlexander von Gluck IV vol = (nspace *)strtoul(argv[1], NULL, 0); 430*9f3ba01bSAlexander von Gluck IV if (vol == NULL) 431*9f3ba01bSAlexander von Gluck IV return B_OK; 432*9f3ba01bSAlexander von Gluck IV 433*9f3ba01bSAlexander von Gluck IV for (i = 2; i < argc; i++) { 434*9f3ba01bSAlexander von Gluck IV ino_t vnid = strtoull(argv[i], NULL, 0); 435*9f3ba01bSAlexander von Gluck IV struct vcache_entry *e; 436*9f3ba01bSAlexander von Gluck IV if ((e = _find_vnid_in_vcache_(vol, vnid)) != NULL) { 437*9f3ba01bSAlexander von Gluck IV kprintf("vnid %" B_PRIdINO " -> loc %" B_PRIdINO " @ %p\n", vnid, 438*9f3ba01bSAlexander von Gluck IV e->loc, e); 439*9f3ba01bSAlexander von Gluck IV } else { 440*9f3ba01bSAlexander von Gluck IV kprintf("vnid %" B_PRIdINO " not found in vnid cache\n", vnid); 441*9f3ba01bSAlexander von Gluck IV } 442*9f3ba01bSAlexander von Gluck IV } 443*9f3ba01bSAlexander von Gluck IV 444*9f3ba01bSAlexander von Gluck IV return B_OK; 445*9f3ba01bSAlexander von Gluck IV } 446*9f3ba01bSAlexander von Gluck IV 447*9f3ba01bSAlexander von Gluck IV 448*9f3ba01bSAlexander von Gluck IV int 449*9f3ba01bSAlexander von Gluck IV debug_dfloc(int argc, char **argv) 450*9f3ba01bSAlexander von Gluck IV { 451*9f3ba01bSAlexander von Gluck IV int i; 452*9f3ba01bSAlexander von Gluck IV nspace *vol; 453*9f3ba01bSAlexander von Gluck IV 454*9f3ba01bSAlexander von Gluck IV if (argc < 3) { 455*9f3ba01bSAlexander von Gluck IV kprintf("dfloc nspace vnid\n"); 456*9f3ba01bSAlexander von Gluck IV return B_OK; 457*9f3ba01bSAlexander von Gluck IV } 458*9f3ba01bSAlexander von Gluck IV 459*9f3ba01bSAlexander von Gluck IV vol = (nspace *)strtoul(argv[1], NULL, 0); 460*9f3ba01bSAlexander von Gluck IV if (vol == NULL) 461*9f3ba01bSAlexander von Gluck IV return B_OK; 462*9f3ba01bSAlexander von Gluck IV 463*9f3ba01bSAlexander von Gluck IV for (i = 2; i < argc; i++) { 464*9f3ba01bSAlexander von Gluck IV ino_t loc = strtoull(argv[i], NULL, 0); 465*9f3ba01bSAlexander von Gluck IV struct vcache_entry *e; 466*9f3ba01bSAlexander von Gluck IV if ((e = _find_loc_in_vcache_(vol, loc)) != NULL) { 467*9f3ba01bSAlexander von Gluck IV kprintf("loc %" B_PRIdINO " -> vnid %" B_PRIdINO " @ %p\n", loc, 468*9f3ba01bSAlexander von Gluck IV e->vnid, e); 469*9f3ba01bSAlexander von Gluck IV } else { 470*9f3ba01bSAlexander von Gluck IV kprintf("loc %" B_PRIdINO " not found in vnid cache\n", loc); 471*9f3ba01bSAlexander von Gluck IV } 472*9f3ba01bSAlexander von Gluck IV } 473*9f3ba01bSAlexander von Gluck IV 474*9f3ba01bSAlexander von Gluck IV return B_OK; 475*9f3ba01bSAlexander von Gluck IV } 476*9f3ba01bSAlexander von Gluck IV 477*9f3ba01bSAlexander von Gluck IV #endif 478