1/* Filesystem index definition 2 * 3 * Copyright (C) 2004-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#define FSCACHE_DEBUG_LEVEL CACHE 13#include <linux/module.h> 14#include "internal.h" 15 16static uint16_t fscache_fsdef_netfs_get_key(const void *cookie_netfs_data, 17 void *buffer, uint16_t bufmax); 18 19static uint16_t fscache_fsdef_netfs_get_aux(const void *cookie_netfs_data, 20 void *buffer, uint16_t bufmax); 21 22static 23enum fscache_checkaux fscache_fsdef_netfs_check_aux(void *cookie_netfs_data, 24 const void *data, 25 uint16_t datalen); 26 27/* 28 * The root index is owned by FS-Cache itself. 29 * 30 * When a netfs requests caching facilities, FS-Cache will, if one doesn't 31 * already exist, create an entry in the root index with the key being the name 32 * of the netfs ("AFS" for example), and the auxiliary data holding the index 33 * structure version supplied by the netfs: 34 * 35 * FSDEF 36 * | 37 * +-----------+ 38 * | | 39 * NFS AFS 40 * [v=1] [v=1] 41 * 42 * If an entry with the appropriate name does already exist, the version is 43 * compared. If the version is different, the entire subtree from that entry 44 * will be discarded and a new entry created. 45 * 46 * The new entry will be an index, and a cookie referring to it will be passed 47 * to the netfs. This is then the root handle by which the netfs accesses the 48 * cache. It can create whatever objects it likes in that index, including 49 * further indices. 50 */ 51static struct fscache_cookie_def fscache_fsdef_index_def = { 52 .name = ".FS-Cache", 53 .type = FSCACHE_COOKIE_TYPE_INDEX, 54}; 55 56struct fscache_cookie fscache_fsdef_index = { 57 .usage = ATOMIC_INIT(1), 58 .n_active = ATOMIC_INIT(1), 59 .lock = __SPIN_LOCK_UNLOCKED(fscache_fsdef_index.lock), 60 .backing_objects = HLIST_HEAD_INIT, 61 .def = &fscache_fsdef_index_def, 62 .flags = 1 << FSCACHE_COOKIE_ENABLED, 63}; 64EXPORT_SYMBOL(fscache_fsdef_index); 65 66/* 67 * Definition of an entry in the root index. Each entry is an index, keyed to 68 * a specific netfs and only applicable to a particular version of the index 69 * structure used by that netfs. 70 */ 71struct fscache_cookie_def fscache_fsdef_netfs_def = { 72 .name = "FSDEF.netfs", 73 .type = FSCACHE_COOKIE_TYPE_INDEX, 74 .get_key = fscache_fsdef_netfs_get_key, 75 .get_aux = fscache_fsdef_netfs_get_aux, 76 .check_aux = fscache_fsdef_netfs_check_aux, 77}; 78 79/* 80 * get the key data for an FSDEF index record - this is the name of the netfs 81 * for which this entry is created 82 */ 83static uint16_t fscache_fsdef_netfs_get_key(const void *cookie_netfs_data, 84 void *buffer, uint16_t bufmax) 85{ 86 const struct fscache_netfs *netfs = cookie_netfs_data; 87 unsigned klen; 88 89 _enter("{%s.%u},", netfs->name, netfs->version); 90 91 klen = strlen(netfs->name); 92 if (klen > bufmax) 93 return 0; 94 95 memcpy(buffer, netfs->name, klen); 96 return klen; 97} 98 99/* 100 * get the auxiliary data for an FSDEF index record - this is the index 101 * structure version number of the netfs for which this version is created 102 */ 103static uint16_t fscache_fsdef_netfs_get_aux(const void *cookie_netfs_data, 104 void *buffer, uint16_t bufmax) 105{ 106 const struct fscache_netfs *netfs = cookie_netfs_data; 107 unsigned dlen; 108 109 _enter("{%s.%u},", netfs->name, netfs->version); 110 111 dlen = sizeof(uint32_t); 112 if (dlen > bufmax) 113 return 0; 114 115 memcpy(buffer, &netfs->version, dlen); 116 return dlen; 117} 118 119/* 120 * check that the index structure version number stored in the auxiliary data 121 * matches the one the netfs gave us 122 */ 123static enum fscache_checkaux fscache_fsdef_netfs_check_aux( 124 void *cookie_netfs_data, 125 const void *data, 126 uint16_t datalen) 127{ 128 struct fscache_netfs *netfs = cookie_netfs_data; 129 uint32_t version; 130 131 _enter("{%s},,%hu", netfs->name, datalen); 132 133 if (datalen != sizeof(version)) { 134 _leave(" = OBSOLETE [dl=%d v=%zu]", datalen, sizeof(version)); 135 return FSCACHE_CHECKAUX_OBSOLETE; 136 } 137 138 memcpy(&version, data, sizeof(version)); 139 if (version != netfs->version) { 140 _leave(" = OBSOLETE [ver=%x net=%x]", version, netfs->version); 141 return FSCACHE_CHECKAUX_OBSOLETE; 142 } 143 144 _leave(" = OKAY"); 145 return FSCACHE_CHECKAUX_OKAY; 146} 147