cache.c 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256
  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. #ifdef AFS_CACHING_SUPPORT
  12. static cachefs_match_val_t afs_cell_cache_match(void *target,
  13. const void *entry);
  14. static void afs_cell_cache_update(void *source, void *entry);
  15. struct cachefs_index_def afs_cache_cell_index_def = {
  16. .name = "cell_ix",
  17. .data_size = sizeof(struct afs_cache_cell),
  18. .keys[0] = { CACHEFS_INDEX_KEYS_ASCIIZ, 64 },
  19. .match = afs_cell_cache_match,
  20. .update = afs_cell_cache_update,
  21. };
  22. #endif
  23. /*
  24. * match a cell record obtained from the cache
  25. */
  26. #ifdef AFS_CACHING_SUPPORT
  27. static cachefs_match_val_t afs_cell_cache_match(void *target,
  28. const void *entry)
  29. {
  30. const struct afs_cache_cell *ccell = entry;
  31. struct afs_cell *cell = target;
  32. _enter("{%s},{%s}", ccell->name, cell->name);
  33. if (strncmp(ccell->name, cell->name, sizeof(ccell->name)) == 0) {
  34. _leave(" = SUCCESS");
  35. return CACHEFS_MATCH_SUCCESS;
  36. }
  37. _leave(" = FAILED");
  38. return CACHEFS_MATCH_FAILED;
  39. }
  40. #endif
  41. /*
  42. * update a cell record in the cache
  43. */
  44. #ifdef AFS_CACHING_SUPPORT
  45. static void afs_cell_cache_update(void *source, void *entry)
  46. {
  47. struct afs_cache_cell *ccell = entry;
  48. struct afs_cell *cell = source;
  49. _enter("%p,%p", source, entry);
  50. strncpy(ccell->name, cell->name, sizeof(ccell->name));
  51. memcpy(ccell->vl_servers,
  52. cell->vl_addrs,
  53. min(sizeof(ccell->vl_servers), sizeof(cell->vl_addrs)));
  54. }
  55. #endif
  56. #ifdef AFS_CACHING_SUPPORT
  57. static cachefs_match_val_t afs_vlocation_cache_match(void *target,
  58. const void *entry);
  59. static void afs_vlocation_cache_update(void *source, void *entry);
  60. struct cachefs_index_def afs_vlocation_cache_index_def = {
  61. .name = "vldb",
  62. .data_size = sizeof(struct afs_cache_vlocation),
  63. .keys[0] = { CACHEFS_INDEX_KEYS_ASCIIZ, 64 },
  64. .match = afs_vlocation_cache_match,
  65. .update = afs_vlocation_cache_update,
  66. };
  67. #endif
  68. /*
  69. * match a VLDB record stored in the cache
  70. * - may also load target from entry
  71. */
  72. #ifdef AFS_CACHING_SUPPORT
  73. static cachefs_match_val_t afs_vlocation_cache_match(void *target,
  74. const void *entry)
  75. {
  76. const struct afs_cache_vlocation *vldb = entry;
  77. struct afs_vlocation *vlocation = target;
  78. _enter("{%s},{%s}", vlocation->vldb.name, vldb->name);
  79. if (strncmp(vlocation->vldb.name, vldb->name, sizeof(vldb->name)) == 0
  80. ) {
  81. if (!vlocation->valid ||
  82. vlocation->vldb.rtime == vldb->rtime
  83. ) {
  84. vlocation->vldb = *vldb;
  85. vlocation->valid = 1;
  86. _leave(" = SUCCESS [c->m]");
  87. return CACHEFS_MATCH_SUCCESS;
  88. } else if (memcmp(&vlocation->vldb, vldb, sizeof(*vldb)) != 0) {
  89. /* delete if VIDs for this name differ */
  90. if (memcmp(&vlocation->vldb.vid,
  91. &vldb->vid,
  92. sizeof(vldb->vid)) != 0) {
  93. _leave(" = DELETE");
  94. return CACHEFS_MATCH_SUCCESS_DELETE;
  95. }
  96. _leave(" = UPDATE");
  97. return CACHEFS_MATCH_SUCCESS_UPDATE;
  98. } else {
  99. _leave(" = SUCCESS");
  100. return CACHEFS_MATCH_SUCCESS;
  101. }
  102. }
  103. _leave(" = FAILED");
  104. return CACHEFS_MATCH_FAILED;
  105. }
  106. #endif
  107. /*
  108. * update a VLDB record stored in the cache
  109. */
  110. #ifdef AFS_CACHING_SUPPORT
  111. static void afs_vlocation_cache_update(void *source, void *entry)
  112. {
  113. struct afs_cache_vlocation *vldb = entry;
  114. struct afs_vlocation *vlocation = source;
  115. _enter("");
  116. *vldb = vlocation->vldb;
  117. }
  118. #endif
  119. #ifdef AFS_CACHING_SUPPORT
  120. static cachefs_match_val_t afs_volume_cache_match(void *target,
  121. const void *entry);
  122. static void afs_volume_cache_update(void *source, void *entry);
  123. struct cachefs_index_def afs_volume_cache_index_def = {
  124. .name = "volume",
  125. .data_size = sizeof(struct afs_cache_vhash),
  126. .keys[0] = { CACHEFS_INDEX_KEYS_BIN, 1 },
  127. .keys[1] = { CACHEFS_INDEX_KEYS_BIN, 1 },
  128. .match = afs_volume_cache_match,
  129. .update = afs_volume_cache_update,
  130. };
  131. #endif
  132. /*
  133. * match a volume hash record stored in the cache
  134. */
  135. #ifdef AFS_CACHING_SUPPORT
  136. static cachefs_match_val_t afs_volume_cache_match(void *target,
  137. const void *entry)
  138. {
  139. const struct afs_cache_vhash *vhash = entry;
  140. struct afs_volume *volume = target;
  141. _enter("{%u},{%u}", volume->type, vhash->vtype);
  142. if (volume->type == vhash->vtype) {
  143. _leave(" = SUCCESS");
  144. return CACHEFS_MATCH_SUCCESS;
  145. }
  146. _leave(" = FAILED");
  147. return CACHEFS_MATCH_FAILED;
  148. }
  149. #endif
  150. /*
  151. * update a volume hash record stored in the cache
  152. */
  153. #ifdef AFS_CACHING_SUPPORT
  154. static void afs_volume_cache_update(void *source, void *entry)
  155. {
  156. struct afs_cache_vhash *vhash = entry;
  157. struct afs_volume *volume = source;
  158. _enter("");
  159. vhash->vtype = volume->type;
  160. }
  161. #endif
  162. #ifdef AFS_CACHING_SUPPORT
  163. static cachefs_match_val_t afs_vnode_cache_match(void *target,
  164. const void *entry);
  165. static void afs_vnode_cache_update(void *source, void *entry);
  166. struct cachefs_index_def afs_vnode_cache_index_def = {
  167. .name = "vnode",
  168. .data_size = sizeof(struct afs_cache_vnode),
  169. .keys[0] = { CACHEFS_INDEX_KEYS_BIN, 4 },
  170. .match = afs_vnode_cache_match,
  171. .update = afs_vnode_cache_update,
  172. };
  173. #endif
  174. /*
  175. * match a vnode record stored in the cache
  176. */
  177. #ifdef AFS_CACHING_SUPPORT
  178. static cachefs_match_val_t afs_vnode_cache_match(void *target,
  179. const void *entry)
  180. {
  181. const struct afs_cache_vnode *cvnode = entry;
  182. struct afs_vnode *vnode = target;
  183. _enter("{%x,%x,%Lx},{%x,%x,%Lx}",
  184. vnode->fid.vnode,
  185. vnode->fid.unique,
  186. vnode->status.version,
  187. cvnode->vnode_id,
  188. cvnode->vnode_unique,
  189. cvnode->data_version);
  190. if (vnode->fid.vnode != cvnode->vnode_id) {
  191. _leave(" = FAILED");
  192. return CACHEFS_MATCH_FAILED;
  193. }
  194. if (vnode->fid.unique != cvnode->vnode_unique ||
  195. vnode->status.version != cvnode->data_version) {
  196. _leave(" = DELETE");
  197. return CACHEFS_MATCH_SUCCESS_DELETE;
  198. }
  199. _leave(" = SUCCESS");
  200. return CACHEFS_MATCH_SUCCESS;
  201. }
  202. #endif
  203. /*
  204. * update a vnode record stored in the cache
  205. */
  206. #ifdef AFS_CACHING_SUPPORT
  207. static void afs_vnode_cache_update(void *source, void *entry)
  208. {
  209. struct afs_cache_vnode *cvnode = entry;
  210. struct afs_vnode *vnode = source;
  211. _enter("");
  212. cvnode->vnode_id = vnode->fid.vnode;
  213. cvnode->vnode_unique = vnode->fid.unique;
  214. cvnode->data_version = vnode->status.version;
  215. }
  216. #endif