1/* AFS caching stuff 2 * 3 * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. 4 * Written by David Howells (dhowells@redhat.com) 5 * 6 * This program is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU General Public License 8 * as published by the Free Software Foundation; either version 9 * 2 of the License, or (at your option) any later version. 10 */ 11 12#ifdef AFS_CACHING_SUPPORT 13static cachefs_match_val_t afs_cell_cache_match(void *target, 14 const void *entry); 15static void afs_cell_cache_update(void *source, void *entry); 16 17struct cachefs_index_def afs_cache_cell_index_def = { 18 .name = "cell_ix", 19 .data_size = sizeof(struct afs_cache_cell), 20 .keys[0] = { CACHEFS_INDEX_KEYS_ASCIIZ, 64 }, 21 .match = afs_cell_cache_match, 22 .update = afs_cell_cache_update, 23}; 24#endif 25 26/* 27 * match a cell record obtained from the cache 28 */ 29#ifdef AFS_CACHING_SUPPORT 30static cachefs_match_val_t afs_cell_cache_match(void *target, 31 const void *entry) 32{ 33 const struct afs_cache_cell *ccell = entry; 34 struct afs_cell *cell = target; 35 36 _enter("{%s},{%s}", ccell->name, cell->name); 37 38 if (strncmp(ccell->name, cell->name, sizeof(ccell->name)) == 0) { 39 _leave(" = SUCCESS"); 40 return CACHEFS_MATCH_SUCCESS; 41 } 42 43 _leave(" = FAILED"); 44 return CACHEFS_MATCH_FAILED; 45} 46#endif 47 48/* 49 * update a cell record in the cache 50 */ 51#ifdef AFS_CACHING_SUPPORT 52static void afs_cell_cache_update(void *source, void *entry) 53{ 54 struct afs_cache_cell *ccell = entry; 55 struct afs_cell *cell = source; 56 57 _enter("%p,%p", source, entry); 58 59 strncpy(ccell->name, cell->name, sizeof(ccell->name)); 60 61 memcpy(ccell->vl_servers, 62 cell->vl_addrs, 63 min(sizeof(ccell->vl_servers), sizeof(cell->vl_addrs))); 64 65} 66#endif 67 68#ifdef AFS_CACHING_SUPPORT 69static cachefs_match_val_t afs_vlocation_cache_match(void *target, 70 const void *entry); 71static void afs_vlocation_cache_update(void *source, void *entry); 72 73struct cachefs_index_def afs_vlocation_cache_index_def = { 74 .name = "vldb", 75 .data_size = sizeof(struct afs_cache_vlocation), 76 .keys[0] = { CACHEFS_INDEX_KEYS_ASCIIZ, 64 }, 77 .match = afs_vlocation_cache_match, 78 .update = afs_vlocation_cache_update, 79}; 80#endif 81 82/* 83 * match a VLDB record stored in the cache 84 * - may also load target from entry 85 */ 86#ifdef AFS_CACHING_SUPPORT 87static cachefs_match_val_t afs_vlocation_cache_match(void *target, 88 const void *entry) 89{ 90 const struct afs_cache_vlocation *vldb = entry; 91 struct afs_vlocation *vlocation = target; 92 93 _enter("{%s},{%s}", vlocation->vldb.name, vldb->name); 94 95 if (strncmp(vlocation->vldb.name, vldb->name, sizeof(vldb->name)) == 0 96 ) { 97 if (!vlocation->valid || 98 vlocation->vldb.rtime == vldb->rtime 99 ) { 100 vlocation->vldb = *vldb; 101 vlocation->valid = 1; 102 _leave(" = SUCCESS [c->m]"); 103 return CACHEFS_MATCH_SUCCESS; 104 } else if (memcmp(&vlocation->vldb, vldb, sizeof(*vldb)) != 0) { 105 /* delete if VIDs for this name differ */ 106 if (memcmp(&vlocation->vldb.vid, 107 &vldb->vid, 108 sizeof(vldb->vid)) != 0) { 109 _leave(" = DELETE"); 110 return CACHEFS_MATCH_SUCCESS_DELETE; 111 } 112 113 _leave(" = UPDATE"); 114 return CACHEFS_MATCH_SUCCESS_UPDATE; 115 } else { 116 _leave(" = SUCCESS"); 117 return CACHEFS_MATCH_SUCCESS; 118 } 119 } 120 121 _leave(" = FAILED"); 122 return CACHEFS_MATCH_FAILED; 123} 124#endif 125 126/* 127 * update a VLDB record stored in the cache 128 */ 129#ifdef AFS_CACHING_SUPPORT 130static void afs_vlocation_cache_update(void *source, void *entry) 131{ 132 struct afs_cache_vlocation *vldb = entry; 133 struct afs_vlocation *vlocation = source; 134 135 _enter(""); 136 137 *vldb = vlocation->vldb; 138} 139#endif 140 141#ifdef AFS_CACHING_SUPPORT 142static cachefs_match_val_t afs_volume_cache_match(void *target, 143 const void *entry); 144static void afs_volume_cache_update(void *source, void *entry); 145 146struct cachefs_index_def afs_volume_cache_index_def = { 147 .name = "volume", 148 .data_size = sizeof(struct afs_cache_vhash), 149 .keys[0] = { CACHEFS_INDEX_KEYS_BIN, 1 }, 150 .keys[1] = { CACHEFS_INDEX_KEYS_BIN, 1 }, 151 .match = afs_volume_cache_match, 152 .update = afs_volume_cache_update, 153}; 154#endif 155 156/* 157 * match a volume hash record stored in the cache 158 */ 159#ifdef AFS_CACHING_SUPPORT 160static cachefs_match_val_t afs_volume_cache_match(void *target, 161 const void *entry) 162{ 163 const struct afs_cache_vhash *vhash = entry; 164 struct afs_volume *volume = target; 165 166 _enter("{%u},{%u}", volume->type, vhash->vtype); 167 168 if (volume->type == vhash->vtype) { 169 _leave(" = SUCCESS"); 170 return CACHEFS_MATCH_SUCCESS; 171 } 172 173 _leave(" = FAILED"); 174 return CACHEFS_MATCH_FAILED; 175} 176#endif 177 178/* 179 * update a volume hash record stored in the cache 180 */ 181#ifdef AFS_CACHING_SUPPORT 182static void afs_volume_cache_update(void *source, void *entry) 183{ 184 struct afs_cache_vhash *vhash = entry; 185 struct afs_volume *volume = source; 186 187 _enter(""); 188 189 vhash->vtype = volume->type; 190} 191#endif 192 193#ifdef AFS_CACHING_SUPPORT 194static cachefs_match_val_t afs_vnode_cache_match(void *target, 195 const void *entry); 196static void afs_vnode_cache_update(void *source, void *entry); 197 198struct cachefs_index_def afs_vnode_cache_index_def = { 199 .name = "vnode", 200 .data_size = sizeof(struct afs_cache_vnode), 201 .keys[0] = { CACHEFS_INDEX_KEYS_BIN, 4 }, 202 .match = afs_vnode_cache_match, 203 .update = afs_vnode_cache_update, 204}; 205#endif 206 207/* 208 * match a vnode record stored in the cache 209 */ 210#ifdef AFS_CACHING_SUPPORT 211static cachefs_match_val_t afs_vnode_cache_match(void *target, 212 const void *entry) 213{ 214 const struct afs_cache_vnode *cvnode = entry; 215 struct afs_vnode *vnode = target; 216 217 _enter("{%x,%x,%Lx},{%x,%x,%Lx}", 218 vnode->fid.vnode, 219 vnode->fid.unique, 220 vnode->status.version, 221 cvnode->vnode_id, 222 cvnode->vnode_unique, 223 cvnode->data_version); 224 225 if (vnode->fid.vnode != cvnode->vnode_id) { 226 _leave(" = FAILED"); 227 return CACHEFS_MATCH_FAILED; 228 } 229 230 if (vnode->fid.unique != cvnode->vnode_unique || 231 vnode->status.version != cvnode->data_version) { 232 _leave(" = DELETE"); 233 return CACHEFS_MATCH_SUCCESS_DELETE; 234 } 235 236 _leave(" = SUCCESS"); 237 return CACHEFS_MATCH_SUCCESS; 238} 239#endif 240 241/* 242 * update a vnode record stored in the cache 243 */ 244#ifdef AFS_CACHING_SUPPORT 245static void afs_vnode_cache_update(void *source, void *entry) 246{ 247 struct afs_cache_vnode *cvnode = entry; 248 struct afs_vnode *vnode = source; 249 250 _enter(""); 251 252 cvnode->vnode_id = vnode->fid.vnode; 253 cvnode->vnode_unique = vnode->fid.unique; 254 cvnode->data_version = vnode->status.version; 255} 256#endif 257