1 /* SPDX-License-Identifier: GPL-2.0-or-later */ 2 /* General filesystem caching interface 3 * 4 * Copyright (C) 2021 Red Hat, Inc. All Rights Reserved. 5 * Written by David Howells ([email protected]) 6 * 7 * NOTE!!! See: 8 * 9 * Documentation/filesystems/caching/netfs-api.rst 10 * 11 * for a description of the network filesystem interface declared here. 12 */ 13 14 #ifndef _LINUX_FSCACHE_H 15 #define _LINUX_FSCACHE_H 16 17 #include <linux/fs.h> 18 #include <linux/netfs.h> 19 20 #if defined(CONFIG_FSCACHE) || defined(CONFIG_FSCACHE_MODULE) 21 #define __fscache_available (1) 22 #define fscache_available() (1) 23 #define fscache_volume_valid(volume) (volume) 24 #define fscache_cookie_valid(cookie) (cookie) 25 #define fscache_resources_valid(cres) ((cres)->cache_priv) 26 #define fscache_cookie_enabled(cookie) (cookie && !test_bit(FSCACHE_COOKIE_DISABLED, &cookie->flags)) 27 #else 28 #define __fscache_available (0) 29 #define fscache_available() (0) 30 #define fscache_volume_valid(volume) (0) 31 #define fscache_cookie_valid(cookie) (0) 32 #define fscache_resources_valid(cres) (false) 33 #define fscache_cookie_enabled(cookie) (0) 34 #endif 35 36 struct fscache_cookie; 37 38 #define FSCACHE_ADV_SINGLE_CHUNK 0x01 /* The object is a single chunk of data */ 39 #define FSCACHE_ADV_WRITE_CACHE 0x00 /* Do cache if written to locally */ 40 #define FSCACHE_ADV_WRITE_NOCACHE 0x02 /* Don't cache if written to locally */ 41 42 #define FSCACHE_INVAL_DIO_WRITE 0x01 /* Invalidate due to DIO write */ 43 44 enum fscache_want_state { 45 FSCACHE_WANT_PARAMS, 46 FSCACHE_WANT_WRITE, 47 FSCACHE_WANT_READ, 48 }; 49 50 /* 51 * Data object state. 52 */ 53 enum fscache_cookie_state { 54 FSCACHE_COOKIE_STATE_QUIESCENT, /* The cookie is uncached */ 55 FSCACHE_COOKIE_STATE_LOOKING_UP, /* The cache object is being looked up */ 56 FSCACHE_COOKIE_STATE_CREATING, /* The cache object is being created */ 57 FSCACHE_COOKIE_STATE_ACTIVE, /* The cache is active, readable and writable */ 58 FSCACHE_COOKIE_STATE_INVALIDATING, /* The cache is being invalidated */ 59 FSCACHE_COOKIE_STATE_FAILED, /* The cache failed, withdraw to clear */ 60 FSCACHE_COOKIE_STATE_LRU_DISCARDING, /* The cookie is being discarded by the LRU */ 61 FSCACHE_COOKIE_STATE_WITHDRAWING, /* The cookie is being withdrawn */ 62 FSCACHE_COOKIE_STATE_RELINQUISHING, /* The cookie is being relinquished */ 63 FSCACHE_COOKIE_STATE_DROPPED, /* The cookie has been dropped */ 64 #define FSCACHE_COOKIE_STATE__NR (FSCACHE_COOKIE_STATE_DROPPED + 1) 65 } __attribute__((mode(byte))); 66 67 /* 68 * Volume representation cookie. 69 */ 70 struct fscache_volume { 71 refcount_t ref; 72 atomic_t n_cookies; /* Number of data cookies in volume */ 73 atomic_t n_accesses; /* Number of cache accesses in progress */ 74 unsigned int debug_id; 75 unsigned int key_hash; /* Hash of key string */ 76 char *key; /* Volume ID, eg. "[email protected]@1234" */ 77 struct list_head proc_link; /* Link in /proc/fs/fscache/volumes */ 78 struct hlist_bl_node hash_link; /* Link in hash table */ 79 struct work_struct work; 80 struct fscache_cache *cache; /* The cache in which this resides */ 81 void *cache_priv; /* Cache private data */ 82 spinlock_t lock; 83 unsigned long flags; 84 #define FSCACHE_VOLUME_RELINQUISHED 0 /* Volume is being cleaned up */ 85 #define FSCACHE_VOLUME_INVALIDATE 1 /* Volume was invalidated */ 86 #define FSCACHE_VOLUME_COLLIDED_WITH 2 /* Volume was collided with */ 87 #define FSCACHE_VOLUME_ACQUIRE_PENDING 3 /* Volume is waiting to complete acquisition */ 88 #define FSCACHE_VOLUME_CREATING 4 /* Volume is being created on disk */ 89 }; 90 91 /* 92 * Data file representation cookie. 93 * - a file will only appear in one cache 94 * - a request to cache a file may or may not be honoured, subject to 95 * constraints such as disk space 96 * - indices are created on disk just-in-time 97 */ 98 struct fscache_cookie { 99 refcount_t ref; 100 atomic_t n_active; /* number of active users of cookie */ 101 atomic_t n_accesses; /* Number of cache accesses in progress */ 102 unsigned int debug_id; 103 unsigned int inval_counter; /* Number of invalidations made */ 104 spinlock_t lock; 105 struct fscache_volume *volume; /* Parent volume of this file. */ 106 void *cache_priv; /* Cache-side representation */ 107 struct hlist_bl_node hash_link; /* Link in hash table */ 108 struct list_head proc_link; /* Link in proc list */ 109 struct list_head commit_link; /* Link in commit queue */ 110 struct work_struct work; /* Commit/relinq/withdraw work */ 111 loff_t object_size; /* Size of the netfs object */ 112 unsigned long unused_at; /* Time at which unused (jiffies) */ 113 unsigned long flags; 114 #define FSCACHE_COOKIE_RELINQUISHED 0 /* T if cookie has been relinquished */ 115 #define FSCACHE_COOKIE_RETIRED 1 /* T if this cookie has retired on relinq */ 116 #define FSCACHE_COOKIE_IS_CACHING 2 /* T if this cookie is cached */ 117 #define FSCACHE_COOKIE_NO_DATA_TO_READ 3 /* T if this cookie has nothing to read */ 118 #define FSCACHE_COOKIE_NEEDS_UPDATE 4 /* T if attrs have been updated */ 119 #define FSCACHE_COOKIE_HAS_BEEN_CACHED 5 /* T if cookie needs withdraw-on-relinq */ 120 #define FSCACHE_COOKIE_DISABLED 6 /* T if cookie has been disabled */ 121 #define FSCACHE_COOKIE_LOCAL_WRITE 7 /* T if cookie has been modified locally */ 122 #define FSCACHE_COOKIE_NO_ACCESS_WAKE 8 /* T if no wake when n_accesses goes 0 */ 123 #define FSCACHE_COOKIE_DO_RELINQUISH 9 /* T if this cookie needs relinquishment */ 124 #define FSCACHE_COOKIE_DO_WITHDRAW 10 /* T if this cookie needs withdrawing */ 125 #define FSCACHE_COOKIE_DO_LRU_DISCARD 11 /* T if this cookie needs LRU discard */ 126 #define FSCACHE_COOKIE_DO_PREP_TO_WRITE 12 /* T if cookie needs write preparation */ 127 #define FSCACHE_COOKIE_HAVE_DATA 13 /* T if this cookie has data stored */ 128 #define FSCACHE_COOKIE_IS_HASHED 14 /* T if this cookie is hashed */ 129 130 enum fscache_cookie_state state; 131 u8 advice; /* FSCACHE_ADV_* */ 132 u8 key_len; /* Length of index key */ 133 u8 aux_len; /* Length of auxiliary data */ 134 u32 key_hash; /* Hash of volume, key, len */ 135 union { 136 void *key; /* Index key */ 137 u8 inline_key[16]; /* - If the key is short enough */ 138 }; 139 union { 140 void *aux; /* Auxiliary data */ 141 u8 inline_aux[8]; /* - If the aux data is short enough */ 142 }; 143 }; 144 145 /* 146 * slow-path functions for when there is actually caching available, and the 147 * netfs does actually have a valid token 148 * - these are not to be called directly 149 * - these are undefined symbols when FS-Cache is not configured and the 150 * optimiser takes care of not using them 151 */ 152 extern struct fscache_volume *__fscache_acquire_volume(const char *, const char *, 153 const void *, size_t); 154 extern void __fscache_relinquish_volume(struct fscache_volume *, const void *, bool); 155 156 extern struct fscache_cookie *__fscache_acquire_cookie( 157 struct fscache_volume *, 158 u8, 159 const void *, size_t, 160 const void *, size_t, 161 loff_t); 162 extern void __fscache_use_cookie(struct fscache_cookie *, bool); 163 extern void __fscache_unuse_cookie(struct fscache_cookie *, const void *, const loff_t *); 164 extern void __fscache_relinquish_cookie(struct fscache_cookie *, bool); 165 extern void __fscache_invalidate(struct fscache_cookie *, const void *, loff_t, unsigned int); 166 extern int __fscache_begin_read_operation(struct netfs_cache_resources *, struct fscache_cookie *); 167 168 /** 169 * fscache_acquire_volume - Register a volume as desiring caching services 170 * @volume_key: An identification string for the volume 171 * @cache_name: The name of the cache to use (or NULL for the default) 172 * @coherency_data: Piece of arbitrary coherency data to check (or NULL) 173 * @coherency_len: The size of the coherency data 174 * 175 * Register a volume as desiring caching services if they're available. The 176 * caller must provide an identifier for the volume and may also indicate which 177 * cache it should be in. If a preexisting volume entry is found in the cache, 178 * the coherency data must match otherwise the entry will be invalidated. 179 * 180 * Returns a cookie pointer on success, -ENOMEM if out of memory or -EBUSY if a 181 * cache volume of that name is already acquired. Note that "NULL" is a valid 182 * cookie pointer and can be returned if caching is refused. 183 */ 184 static inline 185 struct fscache_volume *fscache_acquire_volume(const char *volume_key, 186 const char *cache_name, 187 const void *coherency_data, 188 size_t coherency_len) 189 { 190 if (!fscache_available()) 191 return NULL; 192 return __fscache_acquire_volume(volume_key, cache_name, 193 coherency_data, coherency_len); 194 } 195 196 /** 197 * fscache_relinquish_volume - Cease caching a volume 198 * @volume: The volume cookie 199 * @coherency_data: Piece of arbitrary coherency data to set (or NULL) 200 * @invalidate: True if the volume should be invalidated 201 * 202 * Indicate that a filesystem no longer desires caching services for a volume. 203 * The caller must have relinquished all file cookies prior to calling this. 204 * The stored coherency data is updated. 205 */ 206 static inline 207 void fscache_relinquish_volume(struct fscache_volume *volume, 208 const void *coherency_data, 209 bool invalidate) 210 { 211 if (fscache_volume_valid(volume)) 212 __fscache_relinquish_volume(volume, coherency_data, invalidate); 213 } 214 215 /** 216 * fscache_acquire_cookie - Acquire a cookie to represent a cache object 217 * @volume: The volume in which to locate/create this cookie 218 * @advice: Advice flags (FSCACHE_COOKIE_ADV_*) 219 * @index_key: The index key for this cookie 220 * @index_key_len: Size of the index key 221 * @aux_data: The auxiliary data for the cookie (may be NULL) 222 * @aux_data_len: Size of the auxiliary data buffer 223 * @object_size: The initial size of object 224 * 225 * Acquire a cookie to represent a data file within the given cache volume. 226 * 227 * See Documentation/filesystems/caching/netfs-api.rst for a complete 228 * description. 229 */ 230 static inline 231 struct fscache_cookie *fscache_acquire_cookie(struct fscache_volume *volume, 232 u8 advice, 233 const void *index_key, 234 size_t index_key_len, 235 const void *aux_data, 236 size_t aux_data_len, 237 loff_t object_size) 238 { 239 if (!fscache_volume_valid(volume)) 240 return NULL; 241 return __fscache_acquire_cookie(volume, advice, 242 index_key, index_key_len, 243 aux_data, aux_data_len, 244 object_size); 245 } 246 247 /** 248 * fscache_use_cookie - Request usage of cookie attached to an object 249 * @object: Object description 250 * @will_modify: If cache is expected to be modified locally 251 * 252 * Request usage of the cookie attached to an object. The caller should tell 253 * the cache if the object's contents are about to be modified locally and then 254 * the cache can apply the policy that has been set to handle this case. 255 */ 256 static inline void fscache_use_cookie(struct fscache_cookie *cookie, 257 bool will_modify) 258 { 259 if (fscache_cookie_valid(cookie)) 260 __fscache_use_cookie(cookie, will_modify); 261 } 262 263 /** 264 * fscache_unuse_cookie - Cease usage of cookie attached to an object 265 * @object: Object description 266 * @aux_data: Updated auxiliary data (or NULL) 267 * @object_size: Revised size of the object (or NULL) 268 * 269 * Cease usage of the cookie attached to an object. When the users count 270 * reaches zero then the cookie relinquishment will be permitted to proceed. 271 */ 272 static inline void fscache_unuse_cookie(struct fscache_cookie *cookie, 273 const void *aux_data, 274 const loff_t *object_size) 275 { 276 if (fscache_cookie_valid(cookie)) 277 __fscache_unuse_cookie(cookie, aux_data, object_size); 278 } 279 280 /** 281 * fscache_relinquish_cookie - Return the cookie to the cache, maybe discarding 282 * it 283 * @cookie: The cookie being returned 284 * @retire: True if the cache object the cookie represents is to be discarded 285 * 286 * This function returns a cookie to the cache, forcibly discarding the 287 * associated cache object if retire is set to true. 288 * 289 * See Documentation/filesystems/caching/netfs-api.rst for a complete 290 * description. 291 */ 292 static inline 293 void fscache_relinquish_cookie(struct fscache_cookie *cookie, bool retire) 294 { 295 if (fscache_cookie_valid(cookie)) 296 __fscache_relinquish_cookie(cookie, retire); 297 } 298 299 /* 300 * Find the auxiliary data on a cookie. 301 */ 302 static inline void *fscache_get_aux(struct fscache_cookie *cookie) 303 { 304 if (cookie->aux_len <= sizeof(cookie->inline_aux)) 305 return cookie->inline_aux; 306 else 307 return cookie->aux; 308 } 309 310 /* 311 * Update the auxiliary data on a cookie. 312 */ 313 static inline 314 void fscache_update_aux(struct fscache_cookie *cookie, 315 const void *aux_data, const loff_t *object_size) 316 { 317 void *p = fscache_get_aux(cookie); 318 319 if (aux_data && p) 320 memcpy(p, aux_data, cookie->aux_len); 321 if (object_size) 322 cookie->object_size = *object_size; 323 } 324 325 #ifdef CONFIG_FSCACHE_STATS 326 extern atomic_t fscache_n_updates; 327 #endif 328 329 static inline 330 void __fscache_update_cookie(struct fscache_cookie *cookie, const void *aux_data, 331 const loff_t *object_size) 332 { 333 #ifdef CONFIG_FSCACHE_STATS 334 atomic_inc(&fscache_n_updates); 335 #endif 336 fscache_update_aux(cookie, aux_data, object_size); 337 smp_wmb(); 338 set_bit(FSCACHE_COOKIE_NEEDS_UPDATE, &cookie->flags); 339 } 340 341 /** 342 * fscache_invalidate - Notify cache that an object needs invalidation 343 * @cookie: The cookie representing the cache object 344 * @aux_data: The updated auxiliary data for the cookie (may be NULL) 345 * @size: The revised size of the object. 346 * @flags: Invalidation flags (FSCACHE_INVAL_*) 347 * 348 * Notify the cache that an object is needs to be invalidated and that it 349 * should abort any retrievals or stores it is doing on the cache. This 350 * increments inval_counter on the cookie which can be used by the caller to 351 * reconsider I/O requests as they complete. 352 * 353 * If @flags has FSCACHE_INVAL_DIO_WRITE set, this indicates that this is due 354 * to a direct I/O write and will cause caching to be disabled on this cookie 355 * until it is completely unused. 356 * 357 * See Documentation/filesystems/caching/netfs-api.rst for a complete 358 * description. 359 */ 360 static inline 361 void fscache_invalidate(struct fscache_cookie *cookie, 362 const void *aux_data, loff_t size, unsigned int flags) 363 { 364 if (fscache_cookie_enabled(cookie)) 365 __fscache_invalidate(cookie, aux_data, size, flags); 366 } 367 368 /** 369 * fscache_operation_valid - Return true if operations resources are usable 370 * @cres: The resources to check. 371 * 372 * Returns a pointer to the operations table if usable or NULL if not. 373 */ 374 static inline 375 const struct netfs_cache_ops *fscache_operation_valid(const struct netfs_cache_resources *cres) 376 { 377 return fscache_resources_valid(cres) ? cres->ops : NULL; 378 } 379 380 /** 381 * fscache_begin_read_operation - Begin a read operation for the netfs lib 382 * @cres: The cache resources for the read being performed 383 * @cookie: The cookie representing the cache object 384 * 385 * Begin a read operation on behalf of the netfs helper library. @cres 386 * indicates the cache resources to which the operation state should be 387 * attached; @cookie indicates the cache object that will be accessed. 388 * 389 * This is intended to be called from the ->begin_cache_operation() netfs lib 390 * operation as implemented by the network filesystem. 391 * 392 * @cres->inval_counter is set from @cookie->inval_counter for comparison at 393 * the end of the operation. This allows invalidation during the operation to 394 * be detected by the caller. 395 * 396 * Returns: 397 * * 0 - Success 398 * * -ENOBUFS - No caching available 399 * * Other error code from the cache, such as -ENOMEM. 400 */ 401 static inline 402 int fscache_begin_read_operation(struct netfs_cache_resources *cres, 403 struct fscache_cookie *cookie) 404 { 405 if (fscache_cookie_enabled(cookie)) 406 return __fscache_begin_read_operation(cres, cookie); 407 return -ENOBUFS; 408 } 409 410 #endif /* _LINUX_FSCACHE_H */ 411