| 1 | |
| 2 | *
|
| 3 | * Copyright (C) 2004-2007 Red Hat, Inc. All Rights Reserved.
|
| 4 | * Written by David Howells ([email protected])
|
| 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 | * NOTE!!! See:
|
| 12 | *
|
| 13 | * Documentation/filesystems/caching/backend-api.txt
|
| 14 | *
|
| 15 | * for a description of the cache backend interface declared here.
|
| 16 |
|
| 17 |
|
| 18 | #ifndef _LINUX_FSCACHE_CACHE_H
|
| 19 | #define _LINUX_FSCACHE_CACHE_H
|
| 20 |
|
| 21 | #include <linux/fscache.h>
|
| 22 | #include <linux/sched.h>
|
| 23 | #include <linux/workqueue.h>
|
| 24 |
|
| 25 | #define NR_MAXCACHES BITS_PER_LONG
|
| 26 |
|
| 27 | struct fscache_cache;
|
| 28 | struct fscache_cache_ops;
|
| 29 | struct fscache_object;
|
| 30 | struct fscache_operation;
|
| 31 |
|
| 32 | |
| 33 | * cache tag definition
|
| 34 |
|
| 35 | struct fscache_cache_tag {
|
| 36 | struct list_head link;
|
| 37 | struct fscache_cache *cache;
|
| 38 | unsigned long flags;
|
| 39 | #define FSCACHE_TAG_RESERVED 0
|
| 40 | atomic_t usage;
|
| 41 | char name[0];
|
| 42 | };
|
| 43 |
|
| 44 | |
| 45 | * cache definition
|
| 46 |
|
| 47 | struct fscache_cache {
|
| 48 | const struct fscache_cache_ops *ops;
|
| 49 | struct fscache_cache_tag *tag;
|
| 50 | struct kobject *kobj;
|
| 51 | struct list_head link;
|
| 52 | size_t max_index_size;
|
| 53 | char identifier[36];
|
| 54 |
|
| 55 |
|
| 56 | struct work_struct op_gc;
|
| 57 | struct list_head object_list;
|
| 58 | struct list_head op_gc_list;
|
| 59 | spinlock_t object_list_lock;
|
| 60 | spinlock_t op_gc_list_lock;
|
| 61 | atomic_t object_count;
|
| 62 | struct fscache_object *fsdef;
|
| 63 | unsigned long flags;
|
| 64 | #define FSCACHE_IOERROR 0
|
| 65 | #define FSCACHE_CACHE_WITHDRAWN 1
|
| 66 | };
|
| 67 |
|
| 68 | extern wait_queue_head_t fscache_cache_cleared_wq;
|
| 69 |
|
| 70 | |
| 71 | * operation to be applied to a cache object
|
| 72 | * - retrieval initiation operations are done in the context of the process
|
| 73 | * that issued them, and not in an async thread pool
|
| 74 |
|
| 75 | typedef void (*fscache_operation_release_t)(struct fscache_operation *op);
|
| 76 | typedef void (*fscache_operation_processor_t)(struct fscache_operation *op);
|
| 77 | typedef void (*fscache_operation_cancel_t)(struct fscache_operation *op);
|
| 78 |
|
| 79 | enum fscache_operation_state {
|
| 80 | FSCACHE_OP_ST_BLANK,
|
| 81 | FSCACHE_OP_ST_INITIALISED,
|
| 82 | FSCACHE_OP_ST_PENDING,
|
| 83 | FSCACHE_OP_ST_IN_PROGRESS,
|
| 84 | FSCACHE_OP_ST_COMPLETE,
|
| 85 | FSCACHE_OP_ST_CANCELLED,
|
| 86 | FSCACHE_OP_ST_DEAD
|
| 87 | };
|
| 88 |
|
| 89 | struct fscache_operation {
|
| 90 | struct work_struct work;
|
| 91 | struct list_head pend_link;
|
| 92 | struct fscache_object *object;
|
| 93 |
|
| 94 | unsigned long flags;
|
| 95 | #define FSCACHE_OP_TYPE 0x000f
|
| 96 | #define FSCACHE_OP_ASYNC 0x0001
|
| 97 | #define FSCACHE_OP_MYTHREAD 0x0002
|
| 98 | #define FSCACHE_OP_WAITING 4
|
| 99 | #define FSCACHE_OP_EXCLUSIVE 5
|
| 100 | #define FSCACHE_OP_DEC_READ_CNT 6
|
| 101 | #define FSCACHE_OP_UNUSE_COOKIE 7
|
| 102 | #define FSCACHE_OP_KEEP_FLAGS 0x00f0
|
| 103 |
|
| 104 | enum fscache_operation_state state;
|
| 105 | atomic_t usage;
|
| 106 | unsigned debug_id;
|
| 107 |
|
| 108 | |
| 109 | * - can be NULL if FSCACHE_OP_WAITING is going to be used to perform
|
| 110 | * the op in a non-pool thread
|
| 111 | fscache_operation_processor_t processor;
|
| 112 |
|
| 113 |
|
| 114 | fscache_operation_cancel_t cancel;
|
| 115 |
|
| 116 |
|
| 117 | fscache_operation_release_t release;
|
| 118 | };
|
| 119 |
|
| 120 | extern atomic_t fscache_op_debug_id;
|
| 121 | extern void fscache_op_work_func(struct work_struct *work);
|
| 122 |
|
| 123 | extern void fscache_enqueue_operation(struct fscache_operation *);
|
| 124 | extern void fscache_op_complete(struct fscache_operation *, bool);
|
| 125 | extern void fscache_put_operation(struct fscache_operation *);
|
| 126 | extern void fscache_operation_init(struct fscache_operation *,
|
| 127 | fscache_operation_processor_t,
|
| 128 | fscache_operation_cancel_t,
|
| 129 | fscache_operation_release_t);
|
| 130 |
|
| 131 | |
| 132 | * data read operation
|
| 133 |
|
| 134 | struct fscache_retrieval {
|
| 135 | struct fscache_operation op;
|
| 136 | struct fscache_cookie *cookie;
|
| 137 | struct address_space *mapping;
|
| 138 | fscache_rw_complete_t end_io_func;
|
| 139 | void *context;
|
| 140 | struct list_head to_do;
|
| 141 | unsigned long start_time;
|
| 142 | atomic_t n_pages;
|
| 143 | };
|
| 144 |
|
| 145 | typedef int (*fscache_page_retrieval_func_t)(struct fscache_retrieval *op,
|
| 146 | struct page *page,
|
| 147 | gfp_t gfp);
|
| 148 |
|
| 149 | typedef int (*fscache_pages_retrieval_func_t)(struct fscache_retrieval *op,
|
| 150 | struct list_head *pages,
|
| 151 | unsigned *nr_pages,
|
| 152 | gfp_t gfp);
|
| 153 |
|
| 154 | |
| 155 | * fscache_get_retrieval - Get an extra reference on a retrieval operation
|
| 156 | * @op: The retrieval operation to get a reference on
|
| 157 | *
|
| 158 | * Get an extra reference on a retrieval operation.
|
| 159 |
|
| 160 | static inline
|
| 161 | struct fscache_retrieval *fscache_get_retrieval(struct fscache_retrieval *op)
|
| 162 | {
|
| 163 | atomic_inc(&op->op.usage);
|
| 164 | return op;
|
| 165 | }
|
| 166 |
|
| 167 | |
| 168 | * fscache_enqueue_retrieval - Enqueue a retrieval operation for processing
|
| 169 | * @op: The retrieval operation affected
|
| 170 | *
|
| 171 | * Enqueue a retrieval operation for processing by the FS-Cache thread pool.
|
| 172 |
|
| 173 | static inline void fscache_enqueue_retrieval(struct fscache_retrieval *op)
|
| 174 | {
|
| 175 | fscache_enqueue_operation(&op->op);
|
| 176 | }
|
| 177 |
|
| 178 | |
| 179 | * fscache_retrieval_complete - Record (partial) completion of a retrieval
|
| 180 | * @op: The retrieval operation affected
|
| 181 | * @n_pages: The number of pages to account for
|
| 182 |
|
| 183 | static inline void fscache_retrieval_complete(struct fscache_retrieval *op,
|
| 184 | int n_pages)
|
| 185 | {
|
| 186 | atomic_sub(n_pages, &op->n_pages);
|
| 187 | if (atomic_read(&op->n_pages) <= 0)
|
| 188 | fscache_op_complete(&op->op, true);
|
| 189 | }
|
| 190 |
|
| 191 | |
| 192 | * fscache_put_retrieval - Drop a reference to a retrieval operation
|
| 193 | * @op: The retrieval operation affected
|
| 194 | *
|
| 195 | * Drop a reference to a retrieval operation.
|
| 196 |
|
| 197 | static inline void fscache_put_retrieval(struct fscache_retrieval *op)
|
| 198 | {
|
| 199 | fscache_put_operation(&op->op);
|
| 200 | }
|
| 201 |
|
| 202 | |
| 203 | * cached page storage work item
|
| 204 | * - used to do three things:
|
| 205 | * - batch writes to the cache
|
| 206 | * - do cache writes asynchronously
|
| 207 | * - defer writes until cache object lookup completion
|
| 208 |
|
| 209 | struct fscache_storage {
|
| 210 | struct fscache_operation op;
|
| 211 | pgoff_t store_limit;
|
| 212 | };
|
| 213 |
|
| 214 | |
| 215 | * cache operations
|
| 216 |
|
| 217 | struct fscache_cache_ops {
|
| 218 |
|
| 219 | const char *name;
|
| 220 |
|
| 221 |
|
| 222 | struct fscache_object *(*alloc_object)(struct fscache_cache *cache,
|
| 223 | struct fscache_cookie *cookie);
|
| 224 |
|
| 225 | |
| 226 | * - return -ETIMEDOUT to be requeued
|
| 227 |
|
| 228 | int (*lookup_object)(struct fscache_object *object);
|
| 229 |
|
| 230 |
|
| 231 | void (*lookup_complete)(struct fscache_object *object);
|
| 232 |
|
| 233 |
|
| 234 | struct fscache_object *(*grab_object)(struct fscache_object *object);
|
| 235 |
|
| 236 |
|
| 237 | int (*pin_object)(struct fscache_object *object);
|
| 238 |
|
| 239 |
|
| 240 | void (*unpin_object)(struct fscache_object *object);
|
| 241 |
|
| 242 | |
| 243 | * cookie
|
| 244 | int (*check_consistency)(struct fscache_operation *op);
|
| 245 |
|
| 246 |
|
| 247 | void (*update_object)(struct fscache_object *object);
|
| 248 |
|
| 249 |
|
| 250 | void (*invalidate_object)(struct fscache_operation *op);
|
| 251 |
|
| 252 | |
| 253 | * necessary
|
| 254 | void (*drop_object)(struct fscache_object *object);
|
| 255 |
|
| 256 |
|
| 257 | void (*put_object)(struct fscache_object *object);
|
| 258 |
|
| 259 |
|
| 260 | void (*sync_cache)(struct fscache_cache *cache);
|
| 261 |
|
| 262 | |
| 263 | * i_size) have changed
|
| 264 | int (*attr_changed)(struct fscache_object *object);
|
| 265 |
|
| 266 |
|
| 267 | int (*reserve_space)(struct fscache_object *object, loff_t i_size);
|
| 268 |
|
| 269 | |
| 270 | * cache
|
| 271 | fscache_page_retrieval_func_t read_or_alloc_page;
|
| 272 |
|
| 273 | |
| 274 | * the cache
|
| 275 | fscache_pages_retrieval_func_t read_or_alloc_pages;
|
| 276 |
|
| 277 | |
| 278 | * it can be written directly
|
| 279 | fscache_page_retrieval_func_t allocate_page;
|
| 280 |
|
| 281 | |
| 282 | * they can be written directly
|
| 283 | fscache_pages_retrieval_func_t allocate_pages;
|
| 284 |
|
| 285 |
|
| 286 | int (*write_page)(struct fscache_storage *op, struct page *page);
|
| 287 |
|
| 288 | |
| 289 | * - must release the cookie lock before returning
|
| 290 | * - may sleep
|
| 291 |
|
| 292 | void (*uncache_page)(struct fscache_object *object,
|
| 293 | struct page *page);
|
| 294 |
|
| 295 |
|
| 296 | void (*dissociate_pages)(struct fscache_cache *cache);
|
| 297 | };
|
| 298 |
|
| 299 | extern struct fscache_cookie fscache_fsdef_index;
|
| 300 |
|
| 301 | |
| 302 | * Event list for fscache_object::{event_mask,events}
|
| 303 |
|
| 304 | enum {
|
| 305 | FSCACHE_OBJECT_EV_NEW_CHILD,
|
| 306 | FSCACHE_OBJECT_EV_PARENT_READY,
|
| 307 | FSCACHE_OBJECT_EV_UPDATE,
|
| 308 | FSCACHE_OBJECT_EV_INVALIDATE,
|
| 309 | FSCACHE_OBJECT_EV_CLEARED,
|
| 310 | FSCACHE_OBJECT_EV_ERROR,
|
| 311 | FSCACHE_OBJECT_EV_KILL,
|
| 312 | NR_FSCACHE_OBJECT_EVENTS
|
| 313 | };
|
| 314 |
|
| 315 | #define FSCACHE_OBJECT_EVENTS_MASK ((1UL << NR_FSCACHE_OBJECT_EVENTS) - 1)
|
| 316 |
|
| 317 | |
| 318 | * States for object state machine.
|
| 319 |
|
| 320 | struct fscache_transition {
|
| 321 | unsigned long events;
|
| 322 | const struct fscache_state *transit_to;
|
| 323 | };
|
| 324 |
|
| 325 | struct fscache_state {
|
| 326 | char name[24];
|
| 327 | char short_name[8];
|
| 328 | const struct fscache_state *(*work)(struct fscache_object *object,
|
| 329 | int event);
|
| 330 | const struct fscache_transition transitions[];
|
| 331 | };
|
| 332 |
|
| 333 | |
| 334 | * on-disk cache file or index handle
|
| 335 |
|
| 336 | struct fscache_object {
|
| 337 | const struct fscache_state *state;
|
| 338 | const struct fscache_transition *oob_table;
|
| 339 | int debug_id;
|
| 340 | int n_children;
|
| 341 | int n_ops;
|
| 342 | int n_obj_ops;
|
| 343 | int n_in_progress;
|
| 344 | int n_exclusive;
|
| 345 | atomic_t n_reads;
|
| 346 | spinlock_t lock;
|
| 347 |
|
| 348 | unsigned long lookup_jif;
|
| 349 | unsigned long oob_event_mask;
|
| 350 | unsigned long event_mask;
|
| 351 | unsigned long events; |
| 352 | * (order is important - using fls)
|
| 353 |
|
| 354 | unsigned long flags;
|
| 355 | #define FSCACHE_OBJECT_LOCK 0
|
| 356 | #define FSCACHE_OBJECT_PENDING_WRITE 1
|
| 357 | #define FSCACHE_OBJECT_WAITING 2
|
| 358 | #define FSCACHE_OBJECT_IS_LIVE 3
|
| 359 | #define FSCACHE_OBJECT_IS_LOOKED_UP 4
|
| 360 | #define FSCACHE_OBJECT_IS_AVAILABLE 5
|
| 361 | #define FSCACHE_OBJECT_RETIRED 6
|
| 362 | #define FSCACHE_OBJECT_KILLED_BY_CACHE 7
|
| 363 | #define FSCACHE_OBJECT_RUN_AFTER_DEAD 8
|
| 364 |
|
| 365 | struct list_head cache_link;
|
| 366 | struct hlist_node cookie_link;
|
| 367 | struct fscache_cache *cache;
|
| 368 | struct fscache_cookie *cookie;
|
| 369 | struct fscache_object *parent;
|
| 370 | struct work_struct work;
|
| 371 | struct list_head dependents;
|
| 372 | struct list_head dep_link;
|
| 373 | struct list_head pending_ops;
|
| 374 | #ifdef CONFIG_FSCACHE_OBJECT_LIST
|
| 375 | struct rb_node objlist_link;
|
| 376 | #endif
|
| 377 | pgoff_t store_limit;
|
| 378 | loff_t store_limit_l;
|
| 379 | };
|
| 380 |
|
| 381 | extern void fscache_object_init(struct fscache_object *, struct fscache_cookie *,
|
| 382 | struct fscache_cache *);
|
| 383 | extern void fscache_object_destroy(struct fscache_object *);
|
| 384 |
|
| 385 | extern void fscache_object_lookup_negative(struct fscache_object *object);
|
| 386 | extern void fscache_obtained_object(struct fscache_object *object);
|
| 387 |
|
| 388 | static inline bool fscache_object_is_live(struct fscache_object *object)
|
| 389 | {
|
| 390 | return test_bit(FSCACHE_OBJECT_IS_LIVE, &object->flags);
|
| 391 | }
|
| 392 |
|
| 393 | static inline bool fscache_object_is_dying(struct fscache_object *object)
|
| 394 | {
|
| 395 | return !fscache_object_is_live(object);
|
| 396 | }
|
| 397 |
|
| 398 | static inline bool fscache_object_is_available(struct fscache_object *object)
|
| 399 | {
|
| 400 | return test_bit(FSCACHE_OBJECT_IS_AVAILABLE, &object->flags);
|
| 401 | }
|
| 402 |
|
| 403 | static inline bool fscache_cache_is_broken(struct fscache_object *object)
|
| 404 | {
|
| 405 | return test_bit(FSCACHE_IOERROR, &object->cache->flags);
|
| 406 | }
|
| 407 |
|
| 408 | static inline bool fscache_object_is_active(struct fscache_object *object)
|
| 409 | {
|
| 410 | return fscache_object_is_available(object) &&
|
| 411 | fscache_object_is_live(object) &&
|
| 412 | !fscache_cache_is_broken(object);
|
| 413 | }
|
| 414 |
|
| 415 | |
| 416 | * fscache_object_destroyed - Note destruction of an object in a cache
|
| 417 | * @cache: The cache from which the object came
|
| 418 | *
|
| 419 | * Note the destruction and deallocation of an object record in a cache.
|
| 420 |
|
| 421 | static inline void fscache_object_destroyed(struct fscache_cache *cache)
|
| 422 | {
|
| 423 | if (atomic_dec_and_test(&cache->object_count))
|
| 424 | wake_up_all(&fscache_cache_cleared_wq);
|
| 425 | }
|
| 426 |
|
| 427 | |
| 428 | * fscache_object_lookup_error - Note an object encountered an error
|
| 429 | * @object: The object on which the error was encountered
|
| 430 | *
|
| 431 | * Note that an object encountered a fatal error (usually an I/O error) and
|
| 432 | * that it should be withdrawn as soon as possible.
|
| 433 |
|
| 434 | static inline void fscache_object_lookup_error(struct fscache_object *object)
|
| 435 | {
|
| 436 | set_bit(FSCACHE_OBJECT_EV_ERROR, &object->events);
|
| 437 | }
|
| 438 |
|
| 439 | |
| 440 | * fscache_set_store_limit - Set the maximum size to be stored in an object
|
| 441 | * @object: The object to set the maximum on
|
| 442 | * @i_size: The limit to set in bytes
|
| 443 | *
|
| 444 | * Set the maximum size an object is permitted to reach, implying the highest
|
| 445 | * byte that may be written. Intended to be called by the attr_changed() op.
|
| 446 | *
|
| 447 | * See Documentation/filesystems/caching/backend-api.txt for a complete
|
| 448 | * description.
|
| 449 |
|
| 450 | static inline
|
| 451 | void fscache_set_store_limit(struct fscache_object *object, loff_t i_size)
|
| 452 | {
|
| 453 | object->store_limit_l = i_size;
|
| 454 | object->store_limit = i_size >> PAGE_SHIFT;
|
| 455 | if (i_size & ~PAGE_MASK)
|
| 456 | object->store_limit++;
|
| 457 | }
|
| 458 |
|
| 459 | |
| 460 | * fscache_end_io - End a retrieval operation on a page
|
| 461 | * @op: The FS-Cache operation covering the retrieval
|
| 462 | * @page: The page that was to be fetched
|
| 463 | * @error: The error code (0 if successful)
|
| 464 | *
|
| 465 | * Note the end of an operation to retrieve a page, as covered by a particular
|
| 466 | * operation record.
|
| 467 |
|
| 468 | static inline void fscache_end_io(struct fscache_retrieval *op,
|
| 469 | struct page *page, int error)
|
| 470 | {
|
| 471 | op->end_io_func(page, op->context, error);
|
| 472 | }
|
| 473 |
|
| 474 | static inline void __fscache_use_cookie(struct fscache_cookie *cookie)
|
| 475 | {
|
| 476 | atomic_inc(&cookie->n_active);
|
| 477 | }
|
| 478 |
|
| 479 | |
| 480 | * fscache_use_cookie - Request usage of cookie attached to an object
|
| 481 | * @object: Object description
|
| 482 | *
|
| 483 | * Request usage of the cookie attached to an object. NULL is returned if the
|
| 484 | * relinquishment had reduced the cookie usage count to 0.
|
| 485 |
|
| 486 | static inline bool fscache_use_cookie(struct fscache_object *object)
|
| 487 | {
|
| 488 | struct fscache_cookie *cookie = object->cookie;
|
| 489 | return atomic_inc_not_zero(&cookie->n_active) != 0;
|
| 490 | }
|
| 491 |
|
| 492 | static inline bool __fscache_unuse_cookie(struct fscache_cookie *cookie)
|
| 493 | {
|
| 494 | return atomic_dec_and_test(&cookie->n_active);
|
| 495 | }
|
| 496 |
|
| 497 | static inline void __fscache_wake_unused_cookie(struct fscache_cookie *cookie)
|
| 498 | {
|
| 499 | wake_up_atomic_t(&cookie->n_active);
|
| 500 | }
|
| 501 |
|
| 502 | |
| 503 | * fscache_unuse_cookie - Cease usage of cookie attached to an object
|
| 504 | * @object: Object description
|
| 505 | *
|
| 506 | * Cease usage of the cookie attached to an object. When the users count
|
| 507 | * reaches zero then the cookie relinquishment will be permitted to proceed.
|
| 508 |
|
| 509 | static inline void fscache_unuse_cookie(struct fscache_object *object)
|
| 510 | {
|
| 511 | struct fscache_cookie *cookie = object->cookie;
|
| 512 | if (__fscache_unuse_cookie(cookie))
|
| 513 | __fscache_wake_unused_cookie(cookie);
|
| 514 | }
|
| 515 |
|
| 516 | |
| 517 | * out-of-line cache backend functions
|
| 518 |
|
| 519 | extern __printf(3, 4)
|
| 520 | void fscache_init_cache(struct fscache_cache *cache,
|
| 521 | const struct fscache_cache_ops *ops,
|
| 522 | const char *idfmt, ...);
|
| 523 |
|
| 524 | extern int fscache_add_cache(struct fscache_cache *cache,
|
| 525 | struct fscache_object *fsdef,
|
| 526 | const char *tagname);
|
| 527 | extern void fscache_withdraw_cache(struct fscache_cache *cache);
|
| 528 |
|
| 529 | extern void fscache_io_error(struct fscache_cache *cache);
|
| 530 |
|
| 531 | extern void fscache_mark_page_cached(struct fscache_retrieval *op,
|
| 532 | struct page *page);
|
| 533 |
|
| 534 | extern void fscache_mark_pages_cached(struct fscache_retrieval *op,
|
| 535 | struct pagevec *pagevec);
|
| 536 |
|
| 537 | extern bool fscache_object_sleep_till_congested(signed long *timeoutp);
|
| 538 |
|
| 539 | extern enum fscache_checkaux fscache_check_aux(struct fscache_object *object,
|
| 540 | const void *data,
|
| 541 | uint16_t datalen);
|
| 542 |
|
| 543 | extern void fscache_object_retrying_stale(struct fscache_object *object);
|
| 544 |
|
| 545 | enum fscache_why_object_killed {
|
| 546 | FSCACHE_OBJECT_IS_STALE,
|
| 547 | FSCACHE_OBJECT_NO_SPACE,
|
| 548 | FSCACHE_OBJECT_WAS_RETIRED,
|
| 549 | FSCACHE_OBJECT_WAS_CULLED,
|
| 550 | };
|
| 551 | extern void fscache_object_mark_killed(struct fscache_object *object,
|
| 552 | enum fscache_why_object_killed why);
|
| 553 |
|
| 554 | #endif
|