| /* 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 |