X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=fs%2Fafs%2Fvlocation.c;fp=fs%2Fafs%2Fvlocation.c;h=20148bc8c4f464e7ffb6e942048bfa26271eee1e;hb=16c70f8c1b54b61c3b951b6fb220df250fe09b32;hp=eced20618eccf2bfc23a1bc7d9b3abefc2ded9a1;hpb=4e76c8a9fa413ccc09d3f7f664183dcce3555d57;p=linux-2.6.git diff --git a/fs/afs/vlocation.c b/fs/afs/vlocation.c index eced20618..20148bc8c 100644 --- a/fs/afs/vlocation.c +++ b/fs/afs/vlocation.c @@ -59,17 +59,21 @@ static LIST_HEAD(afs_vlocation_update_pendq); /* queue of VLs awaiting update */ static struct afs_vlocation *afs_vlocation_update; /* VL currently being updated */ static DEFINE_SPINLOCK(afs_vlocation_update_lock); /* lock guarding update queue */ -#ifdef AFS_CACHING_SUPPORT -static cachefs_match_val_t afs_vlocation_cache_match(void *target, - const void *entry); -static void afs_vlocation_cache_update(void *source, void *entry); - -struct cachefs_index_def afs_vlocation_cache_index_def = { - .name = "vldb", - .data_size = sizeof(struct afs_cache_vlocation), - .keys[0] = { CACHEFS_INDEX_KEYS_ASCIIZ, 64 }, - .match = afs_vlocation_cache_match, - .update = afs_vlocation_cache_update, +#ifdef CONFIG_AFS_FSCACHE +static uint16_t afs_vlocation_cache_get_key(const void *cookie_netfs_data, + void *buffer, uint16_t buflen); +static uint16_t afs_vlocation_cache_get_aux(const void *cookie_netfs_data, + void *buffer, uint16_t buflen); +static fscache_checkaux_t afs_vlocation_cache_check_aux(void *cookie_netfs_data, + const void *buffer, + uint16_t buflen); + +static struct fscache_cookie_def afs_vlocation_cache_index_def = { + .name = "AFS.vldb", + .type = FSCACHE_COOKIE_TYPE_INDEX, + .get_key = afs_vlocation_cache_get_key, + .get_aux = afs_vlocation_cache_get_aux, + .check_aux = afs_vlocation_cache_check_aux, }; #endif @@ -300,13 +304,12 @@ int afs_vlocation_lookup(struct afs_cell *cell, list_add_tail(&vlocation->link, &cell->vl_list); -#ifdef AFS_CACHING_SUPPORT +#ifdef CONFIG_AFS_FSCACHE /* we want to store it in the cache, plus it might already be * encached */ - cachefs_acquire_cookie(cell->cache, - &afs_volume_cache_index_def, - vlocation, - &vlocation->cache); + vlocation->cache = fscache_acquire_cookie(cell->cache, + &afs_vlocation_cache_index_def, + vlocation); if (vlocation->valid) goto found_in_cache; @@ -326,8 +329,7 @@ int afs_vlocation_lookup(struct afs_cell *cell, /* found in the graveyard - resurrect */ _debug("found in graveyard"); atomic_inc(&vlocation->usage); - list_del(&vlocation->link); - list_add_tail(&vlocation->link, &cell->vl_list); + list_move_tail(&vlocation->link, &cell->vl_list); spin_unlock(&cell->vl_gylock); afs_kafstimod_del_timer(&vlocation->timeout); @@ -341,7 +343,7 @@ int afs_vlocation_lookup(struct afs_cell *cell, active: active = 1; -#ifdef AFS_CACHING_SUPPORT +#ifdef CONFIG_AFS_FSCACHE found_in_cache: #endif /* try to look up a cached volume in the cell VL databases by ID */ @@ -423,9 +425,9 @@ int afs_vlocation_lookup(struct afs_cell *cell, afs_kafstimod_add_timer(&vlocation->upd_timer, 10 * HZ); -#ifdef AFS_CACHING_SUPPORT +#ifdef CONFIG_AFS_FSCACHE /* update volume entry in local cache */ - cachefs_update_cookie(vlocation->cache); + fscache_update_cookie(vlocation->cache); #endif *_vlocation = vlocation; @@ -439,8 +441,8 @@ int afs_vlocation_lookup(struct afs_cell *cell, } else { list_del(&vlocation->link); -#ifdef AFS_CACHING_SUPPORT - cachefs_relinquish_cookie(vlocation->cache, 0); +#ifdef CONFIG_AFS_FSCACHE + fscache_relinquish_cookie(vlocation->cache, 0); #endif afs_put_cell(vlocation->cell); kfree(vlocation); @@ -478,8 +480,7 @@ static void __afs_put_vlocation(struct afs_vlocation *vlocation) } /* move to graveyard queue */ - list_del(&vlocation->link); - list_add_tail(&vlocation->link,&cell->vl_graveyard); + list_move_tail(&vlocation->link,&cell->vl_graveyard); /* remove from pending timeout queue (refcounted if actually being * updated) */ @@ -538,8 +539,8 @@ void afs_vlocation_do_timeout(struct afs_vlocation *vlocation) } /* we can now destroy it properly */ -#ifdef AFS_CACHING_SUPPORT - cachefs_relinquish_cookie(vlocation->cache, 0); +#ifdef CONFIG_AFS_FSCACHE + fscache_relinquish_cookie(vlocation->cache, 0); #endif afs_put_cell(cell); @@ -890,65 +891,103 @@ static void afs_vlocation_update_discard(struct afs_async_op *op) /*****************************************************************************/ /* - * match a VLDB record stored in the cache - * - may also load target from entry + * set the key for the index entry */ -#ifdef AFS_CACHING_SUPPORT -static cachefs_match_val_t afs_vlocation_cache_match(void *target, - const void *entry) +#ifdef CONFIG_AFS_FSCACHE +static uint16_t afs_vlocation_cache_get_key(const void *cookie_netfs_data, + void *buffer, uint16_t bufmax) { - const struct afs_cache_vlocation *vldb = entry; - struct afs_vlocation *vlocation = target; + const struct afs_vlocation *vlocation = cookie_netfs_data; + uint16_t klen; - _enter("{%s},{%s}", vlocation->vldb.name, vldb->name); + _enter("{%s},%p,%u", vlocation->vldb.name, buffer, bufmax); - if (strncmp(vlocation->vldb.name, vldb->name, sizeof(vldb->name)) == 0 - ) { - if (!vlocation->valid || - vlocation->vldb.rtime == vldb->rtime - ) { - vlocation->vldb = *vldb; - vlocation->valid = 1; - _leave(" = SUCCESS [c->m]"); - return CACHEFS_MATCH_SUCCESS; - } - /* need to update cache if cached info differs */ - else if (memcmp(&vlocation->vldb, vldb, sizeof(*vldb)) != 0) { - /* delete if VIDs for this name differ */ - if (memcmp(&vlocation->vldb.vid, - &vldb->vid, - sizeof(vldb->vid)) != 0) { - _leave(" = DELETE"); - return CACHEFS_MATCH_SUCCESS_DELETE; - } + klen = strnlen(vlocation->vldb.name, sizeof(vlocation->vldb.name)); + if (klen > bufmax) + return 0; - _leave(" = UPDATE"); - return CACHEFS_MATCH_SUCCESS_UPDATE; - } - else { - _leave(" = SUCCESS"); - return CACHEFS_MATCH_SUCCESS; - } - } + memcpy(buffer, vlocation->vldb.name, klen); + + _leave(" = %u", klen); + return klen; + +} /* end afs_vlocation_cache_get_key() */ +#endif + +/*****************************************************************************/ +/* + * provide new auxilliary cache data + */ +#ifdef CONFIG_AFS_FSCACHE +static uint16_t afs_vlocation_cache_get_aux(const void *cookie_netfs_data, + void *buffer, uint16_t bufmax) +{ + const struct afs_vlocation *vlocation = cookie_netfs_data; + uint16_t dlen; + + _enter("{%s},%p,%u", vlocation->vldb.name, buffer, bufmax); + + dlen = sizeof(struct afs_cache_vlocation); + dlen -= offsetof(struct afs_cache_vlocation, nservers); + if (dlen > bufmax) + return 0; + + memcpy(buffer, (uint8_t *)&vlocation->vldb.nservers, dlen); - _leave(" = FAILED"); - return CACHEFS_MATCH_FAILED; -} /* end afs_vlocation_cache_match() */ + _leave(" = %u", dlen); + return dlen; + +} /* end afs_vlocation_cache_get_aux() */ #endif /*****************************************************************************/ /* - * update a VLDB record stored in the cache + * check that the auxilliary data indicates that the entry is still valid */ -#ifdef AFS_CACHING_SUPPORT -static void afs_vlocation_cache_update(void *source, void *entry) +#ifdef CONFIG_AFS_FSCACHE +static fscache_checkaux_t afs_vlocation_cache_check_aux(void *cookie_netfs_data, + const void *buffer, + uint16_t buflen) { - struct afs_cache_vlocation *vldb = entry; - struct afs_vlocation *vlocation = source; + const struct afs_cache_vlocation *cvldb; + struct afs_vlocation *vlocation = cookie_netfs_data; + uint16_t dlen; + + _enter("{%s},%p,%u", vlocation->vldb.name, buffer, buflen); + + /* check the size of the data is what we're expecting */ + dlen = sizeof(struct afs_cache_vlocation); + dlen -= offsetof(struct afs_cache_vlocation, nservers); + if (dlen != buflen) + return FSCACHE_CHECKAUX_OBSOLETE; + + cvldb = container_of(buffer, struct afs_cache_vlocation, nservers); - _enter(""); + /* if what's on disk is more valid than what's in memory, then use the + * VL record from the cache */ + if (!vlocation->valid || vlocation->vldb.rtime == cvldb->rtime) { + memcpy((uint8_t *)&vlocation->vldb.nservers, buffer, dlen); + vlocation->valid = 1; + _leave(" = SUCCESS [c->m]"); + return FSCACHE_CHECKAUX_OKAY; + } + + /* need to update the cache if the cached info differs */ + if (memcmp(&vlocation->vldb, buffer, dlen) != 0) { + /* delete if the volume IDs for this name differ */ + if (memcmp(&vlocation->vldb.vid, &cvldb->vid, + sizeof(cvldb->vid)) != 0 + ) { + _leave(" = OBSOLETE"); + return FSCACHE_CHECKAUX_OBSOLETE; + } + + _leave(" = UPDATE"); + return FSCACHE_CHECKAUX_NEEDS_UPDATE; + } - *vldb = vlocation->vldb; + _leave(" = OKAY"); + return FSCACHE_CHECKAUX_OKAY; -} /* end afs_vlocation_cache_update() */ +} /* end afs_vlocation_cache_check_aux() */ #endif