at v4.16 5.5 kB view raw
1/* AFS caching stuff 2 * 3 * Copyright (C) 2008 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#include <linux/sched.h> 13#include "internal.h" 14 15static uint16_t afs_cell_cache_get_key(const void *cookie_netfs_data, 16 void *buffer, uint16_t buflen); 17static uint16_t afs_volume_cache_get_key(const void *cookie_netfs_data, 18 void *buffer, uint16_t buflen); 19 20static uint16_t afs_vnode_cache_get_key(const void *cookie_netfs_data, 21 void *buffer, uint16_t buflen); 22static void afs_vnode_cache_get_attr(const void *cookie_netfs_data, 23 uint64_t *size); 24static uint16_t afs_vnode_cache_get_aux(const void *cookie_netfs_data, 25 void *buffer, uint16_t buflen); 26static enum fscache_checkaux afs_vnode_cache_check_aux(void *cookie_netfs_data, 27 const void *buffer, 28 uint16_t buflen); 29 30struct fscache_netfs afs_cache_netfs = { 31 .name = "afs", 32 .version = 1, 33}; 34 35struct fscache_cookie_def afs_cell_cache_index_def = { 36 .name = "AFS.cell", 37 .type = FSCACHE_COOKIE_TYPE_INDEX, 38 .get_key = afs_cell_cache_get_key, 39}; 40 41struct fscache_cookie_def afs_volume_cache_index_def = { 42 .name = "AFS.volume", 43 .type = FSCACHE_COOKIE_TYPE_INDEX, 44 .get_key = afs_volume_cache_get_key, 45}; 46 47struct fscache_cookie_def afs_vnode_cache_index_def = { 48 .name = "AFS.vnode", 49 .type = FSCACHE_COOKIE_TYPE_DATAFILE, 50 .get_key = afs_vnode_cache_get_key, 51 .get_attr = afs_vnode_cache_get_attr, 52 .get_aux = afs_vnode_cache_get_aux, 53 .check_aux = afs_vnode_cache_check_aux, 54}; 55 56/* 57 * set the key for the index entry 58 */ 59static uint16_t afs_cell_cache_get_key(const void *cookie_netfs_data, 60 void *buffer, uint16_t bufmax) 61{ 62 const struct afs_cell *cell = cookie_netfs_data; 63 uint16_t klen; 64 65 _enter("%p,%p,%u", cell, buffer, bufmax); 66 67 klen = strlen(cell->name); 68 if (klen > bufmax) 69 return 0; 70 71 memcpy(buffer, cell->name, klen); 72 return klen; 73} 74 75/*****************************************************************************/ 76/* 77 * set the key for the volume index entry 78 */ 79static uint16_t afs_volume_cache_get_key(const void *cookie_netfs_data, 80 void *buffer, uint16_t bufmax) 81{ 82 const struct afs_volume *volume = cookie_netfs_data; 83 struct { 84 u64 volid; 85 } __packed key; 86 87 _enter("{%u},%p,%u", volume->type, buffer, bufmax); 88 89 if (bufmax < sizeof(key)) 90 return 0; 91 92 key.volid = volume->vid; 93 memcpy(buffer, &key, sizeof(key)); 94 return sizeof(key); 95} 96 97/*****************************************************************************/ 98/* 99 * set the key for the index entry 100 */ 101static uint16_t afs_vnode_cache_get_key(const void *cookie_netfs_data, 102 void *buffer, uint16_t bufmax) 103{ 104 const struct afs_vnode *vnode = cookie_netfs_data; 105 struct { 106 u32 vnode_id[3]; 107 } __packed key; 108 109 _enter("{%x,%x,%llx},%p,%u", 110 vnode->fid.vnode, vnode->fid.unique, vnode->status.data_version, 111 buffer, bufmax); 112 113 /* Allow for a 96-bit key */ 114 memset(&key, 0, sizeof(key)); 115 key.vnode_id[0] = vnode->fid.vnode; 116 key.vnode_id[1] = 0; 117 key.vnode_id[2] = 0; 118 119 if (sizeof(key) > bufmax) 120 return 0; 121 122 memcpy(buffer, &key, sizeof(key)); 123 return sizeof(key); 124} 125 126/* 127 * provide updated file attributes 128 */ 129static void afs_vnode_cache_get_attr(const void *cookie_netfs_data, 130 uint64_t *size) 131{ 132 const struct afs_vnode *vnode = cookie_netfs_data; 133 134 _enter("{%x,%x,%llx},", 135 vnode->fid.vnode, vnode->fid.unique, 136 vnode->status.data_version); 137 138 *size = vnode->status.size; 139} 140 141struct afs_vnode_cache_aux { 142 u64 data_version; 143 u32 fid_unique; 144} __packed; 145 146/* 147 * provide new auxiliary cache data 148 */ 149static uint16_t afs_vnode_cache_get_aux(const void *cookie_netfs_data, 150 void *buffer, uint16_t bufmax) 151{ 152 const struct afs_vnode *vnode = cookie_netfs_data; 153 struct afs_vnode_cache_aux aux; 154 155 _enter("{%x,%x,%Lx},%p,%u", 156 vnode->fid.vnode, vnode->fid.unique, vnode->status.data_version, 157 buffer, bufmax); 158 159 memset(&aux, 0, sizeof(aux)); 160 aux.data_version = vnode->status.data_version; 161 aux.fid_unique = vnode->fid.unique; 162 163 if (bufmax < sizeof(aux)) 164 return 0; 165 166 memcpy(buffer, &aux, sizeof(aux)); 167 return sizeof(aux); 168} 169 170/* 171 * check that the auxiliary data indicates that the entry is still valid 172 */ 173static enum fscache_checkaux afs_vnode_cache_check_aux(void *cookie_netfs_data, 174 const void *buffer, 175 uint16_t buflen) 176{ 177 struct afs_vnode *vnode = cookie_netfs_data; 178 struct afs_vnode_cache_aux aux; 179 180 _enter("{%x,%x,%llx},%p,%u", 181 vnode->fid.vnode, vnode->fid.unique, vnode->status.data_version, 182 buffer, buflen); 183 184 memcpy(&aux, buffer, sizeof(aux)); 185 186 /* check the size of the data is what we're expecting */ 187 if (buflen != sizeof(aux)) { 188 _leave(" = OBSOLETE [len %hx != %zx]", buflen, sizeof(aux)); 189 return FSCACHE_CHECKAUX_OBSOLETE; 190 } 191 192 if (vnode->fid.unique != aux.fid_unique) { 193 _leave(" = OBSOLETE [uniq %x != %x]", 194 aux.fid_unique, vnode->fid.unique); 195 return FSCACHE_CHECKAUX_OBSOLETE; 196 } 197 198 if (vnode->status.data_version != aux.data_version) { 199 _leave(" = OBSOLETE [vers %llx != %llx]", 200 aux.data_version, vnode->status.data_version); 201 return FSCACHE_CHECKAUX_OBSOLETE; 202 } 203 204 _leave(" = SUCCESS"); 205 return FSCACHE_CHECKAUX_OKAY; 206}