| /* AFS caching stuff | |
| * | |
| * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. | |
| * Written by David Howells (dhowells@redhat.com) | |
| * | |
| * This program is free software; you can redistribute it and/or | |
| * modify it under the terms of the GNU General Public License | |
| * as published by the Free Software Foundation; either version | |
| * 2 of the License, or (at your option) any later version. | |
| */ | |
| #ifdef AFS_CACHING_SUPPORT | |
| static cachefs_match_val_t afs_cell_cache_match(void *target, | |
| const void *entry); | |
| static void afs_cell_cache_update(void *source, void *entry); | |
| struct cachefs_index_def afs_cache_cell_index_def = { | |
| .name = "cell_ix", | |
| .data_size = sizeof(struct afs_cache_cell), | |
| .keys[0] = { CACHEFS_INDEX_KEYS_ASCIIZ, 64 }, | |
| .match = afs_cell_cache_match, | |
| .update = afs_cell_cache_update, | |
| }; | |
| #endif | |
| /* | |
| * match a cell record obtained from the cache | |
| */ | |
| #ifdef AFS_CACHING_SUPPORT | |
| static cachefs_match_val_t afs_cell_cache_match(void *target, | |
| const void *entry) | |
| { | |
| const struct afs_cache_cell *ccell = entry; | |
| struct afs_cell *cell = target; | |
| _enter("{%s},{%s}", ccell->name, cell->name); | |
| if (strncmp(ccell->name, cell->name, sizeof(ccell->name)) == 0) { | |
| _leave(" = SUCCESS"); | |
| return CACHEFS_MATCH_SUCCESS; | |
| } | |
| _leave(" = FAILED"); | |
| return CACHEFS_MATCH_FAILED; | |
| } | |
| #endif | |
| /* | |
| * update a cell record in the cache | |
| */ | |
| #ifdef AFS_CACHING_SUPPORT | |
| static void afs_cell_cache_update(void *source, void *entry) | |
| { | |
| struct afs_cache_cell *ccell = entry; | |
| struct afs_cell *cell = source; | |
| _enter("%p,%p", source, entry); | |
| strncpy(ccell->name, cell->name, sizeof(ccell->name)); | |
| memcpy(ccell->vl_servers, | |
| cell->vl_addrs, | |
| min(sizeof(ccell->vl_servers), sizeof(cell->vl_addrs))); | |
| } | |
| #endif | |
| #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, | |
| }; | |
| #endif | |
| /* | |
| * match a VLDB record stored in the cache | |
| * - may also load target from entry | |
| */ | |
| #ifdef AFS_CACHING_SUPPORT | |
| static cachefs_match_val_t afs_vlocation_cache_match(void *target, | |
| const void *entry) | |
| { | |
| const struct afs_cache_vlocation *vldb = entry; | |
| struct afs_vlocation *vlocation = target; | |
| _enter("{%s},{%s}", vlocation->vldb.name, vldb->name); | |
| 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; | |
| } 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; | |
| } | |
| _leave(" = UPDATE"); | |
| return CACHEFS_MATCH_SUCCESS_UPDATE; | |
| } else { | |
| _leave(" = SUCCESS"); | |
| return CACHEFS_MATCH_SUCCESS; | |
| } | |
| } | |
| _leave(" = FAILED"); | |
| return CACHEFS_MATCH_FAILED; | |
| } | |
| #endif | |
| /* | |
| * update a VLDB record stored in the cache | |
| */ | |
| #ifdef AFS_CACHING_SUPPORT | |
| static void afs_vlocation_cache_update(void *source, void *entry) | |
| { | |
| struct afs_cache_vlocation *vldb = entry; | |
| struct afs_vlocation *vlocation = source; | |
| _enter(""); | |
| *vldb = vlocation->vldb; | |
| } | |
| #endif | |
| #ifdef AFS_CACHING_SUPPORT | |
| static cachefs_match_val_t afs_volume_cache_match(void *target, | |
| const void *entry); | |
| static void afs_volume_cache_update(void *source, void *entry); | |
| struct cachefs_index_def afs_volume_cache_index_def = { | |
| .name = "volume", | |
| .data_size = sizeof(struct afs_cache_vhash), | |
| .keys[0] = { CACHEFS_INDEX_KEYS_BIN, 1 }, | |
| .keys[1] = { CACHEFS_INDEX_KEYS_BIN, 1 }, | |
| .match = afs_volume_cache_match, | |
| .update = afs_volume_cache_update, | |
| }; | |
| #endif | |
| /* | |
| * match a volume hash record stored in the cache | |
| */ | |
| #ifdef AFS_CACHING_SUPPORT | |
| static cachefs_match_val_t afs_volume_cache_match(void *target, | |
| const void *entry) | |
| { | |
| const struct afs_cache_vhash *vhash = entry; | |
| struct afs_volume *volume = target; | |
| _enter("{%u},{%u}", volume->type, vhash->vtype); | |
| if (volume->type == vhash->vtype) { | |
| _leave(" = SUCCESS"); | |
| return CACHEFS_MATCH_SUCCESS; | |
| } | |
| _leave(" = FAILED"); | |
| return CACHEFS_MATCH_FAILED; | |
| } | |
| #endif | |
| /* | |
| * update a volume hash record stored in the cache | |
| */ | |
| #ifdef AFS_CACHING_SUPPORT | |
| static void afs_volume_cache_update(void *source, void *entry) | |
| { | |
| struct afs_cache_vhash *vhash = entry; | |
| struct afs_volume *volume = source; | |
| _enter(""); | |
| vhash->vtype = volume->type; | |
| } | |
| #endif | |
| #ifdef AFS_CACHING_SUPPORT | |
| static cachefs_match_val_t afs_vnode_cache_match(void *target, | |
| const void *entry); | |
| static void afs_vnode_cache_update(void *source, void *entry); | |
| struct cachefs_index_def afs_vnode_cache_index_def = { | |
| .name = "vnode", | |
| .data_size = sizeof(struct afs_cache_vnode), | |
| .keys[0] = { CACHEFS_INDEX_KEYS_BIN, 4 }, | |
| .match = afs_vnode_cache_match, | |
| .update = afs_vnode_cache_update, | |
| }; | |
| #endif | |
| /* | |
| * match a vnode record stored in the cache | |
| */ | |
| #ifdef AFS_CACHING_SUPPORT | |
| static cachefs_match_val_t afs_vnode_cache_match(void *target, | |
| const void *entry) | |
| { | |
| const struct afs_cache_vnode *cvnode = entry; | |
| struct afs_vnode *vnode = target; | |
| _enter("{%x,%x,%Lx},{%x,%x,%Lx}", | |
| vnode->fid.vnode, | |
| vnode->fid.unique, | |
| vnode->status.version, | |
| cvnode->vnode_id, | |
| cvnode->vnode_unique, | |
| cvnode->data_version); | |
| if (vnode->fid.vnode != cvnode->vnode_id) { | |
| _leave(" = FAILED"); | |
| return CACHEFS_MATCH_FAILED; | |
| } | |
| if (vnode->fid.unique != cvnode->vnode_unique || | |
| vnode->status.version != cvnode->data_version) { | |
| _leave(" = DELETE"); | |
| return CACHEFS_MATCH_SUCCESS_DELETE; | |
| } | |
| _leave(" = SUCCESS"); | |
| return CACHEFS_MATCH_SUCCESS; | |
| } | |
| #endif | |
| /* | |
| * update a vnode record stored in the cache | |
| */ | |
| #ifdef AFS_CACHING_SUPPORT | |
| static void afs_vnode_cache_update(void *source, void *entry) | |
| { | |
| struct afs_cache_vnode *cvnode = entry; | |
| struct afs_vnode *vnode = source; | |
| _enter(""); | |
| cvnode->vnode_id = vnode->fid.vnode; | |
| cvnode->vnode_unique = vnode->fid.unique; | |
| cvnode->data_version = vnode->status.version; | |
| } | |
| #endif |