aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2013-07-02 12:52:47 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2013-07-02 12:52:47 -0400
commitbcd7351e83728859833e3c5b8aae9a2816914e4b (patch)
tree940487a8b04f6ec79212836954d9c1389a9d80ed /include/linux
parent6072a93b98e660211c4b46a8381833425bdcf7b7 (diff)
parentdcfae32f892f03dee9896b19d1960c1ecd3f0583 (diff)
Merge tag 'fscache-20130702' of git://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs
Pull FS-Cache updates from David Howells: "This contains a number of fixes for various FS-Cache issues plus some cleanups. The commits are, in order: 1) Provide a system wait_on_atomic_t() and wake_up_atomic_t() sharing the bit-wait table (enhancement for #8). 2) Don't put spin_lock() in a while-condition as spin_lock() may have a do {} while(0) wrapper (cleanup). 3) Symbolically name i_mutex lock classes rather than using numbers in CacheFiles (cleanup). 4) Don't sleep in page release if __GFP_FS is not set (deadlock vs ext4). 5) Uninline fscache_object_init() (cleanup for #7). 6) Wrap checks on object state (cleanup for #7). 7) Simplify the object state machine by separating work states from wait states. 8) Simplify cookie retention by objects (NULL pointer deref fix). 9) Remove unused list_to_page() macro (cleanup). 10) Make the remaining-pages counter in the retrieval op atomic (assertion failure fix). 11) Don't use spin_is_locked() in assertions (assertion failure fix)" * tag 'fscache-20130702' of git://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs: FS-Cache: Don't use spin_is_locked() in assertions FS-Cache: The retrieval remaining-pages counter needs to be atomic_t cachefiles: remove unused macro list_to_page() FS-Cache: Simplify cookie retention for fscache_objects, fixing oops FS-Cache: Fix object state machine to have separate work and wait states FS-Cache: Wrap checks on object state FS-Cache: Uninline fscache_object_init() FS-Cache: Don't sleep in page release if __GFP_FS is not set CacheFiles: name i_mutex lock class explicitly fs/fscache: remove spin_lock() from the condition in while() Add wait_on_atomic_t() and wake_up_atomic_t()
Diffstat (limited to 'include/linux')
-rw-r--r--include/linux/fscache-cache.h175
-rw-r--r--include/linux/wait.h24
2 files changed, 113 insertions, 86 deletions
diff --git a/include/linux/fscache-cache.h b/include/linux/fscache-cache.h
index 5dfa0aa216b6..a9ff9a36b86d 100644
--- a/include/linux/fscache-cache.h
+++ b/include/linux/fscache-cache.h
@@ -97,7 +97,8 @@ struct fscache_operation {
97#define FSCACHE_OP_WAITING 4 /* cleared when op is woken */ 97#define FSCACHE_OP_WAITING 4 /* cleared when op is woken */
98#define FSCACHE_OP_EXCLUSIVE 5 /* exclusive op, other ops must wait */ 98#define FSCACHE_OP_EXCLUSIVE 5 /* exclusive op, other ops must wait */
99#define FSCACHE_OP_DEC_READ_CNT 6 /* decrement object->n_reads on destruction */ 99#define FSCACHE_OP_DEC_READ_CNT 6 /* decrement object->n_reads on destruction */
100#define FSCACHE_OP_KEEP_FLAGS 0x0070 /* flags to keep when repurposing an op */ 100#define FSCACHE_OP_UNUSE_COOKIE 7 /* call fscache_unuse_cookie() on completion */
101#define FSCACHE_OP_KEEP_FLAGS 0x00f0 /* flags to keep when repurposing an op */
101 102
102 enum fscache_operation_state state; 103 enum fscache_operation_state state;
103 atomic_t usage; 104 atomic_t usage;
@@ -150,7 +151,7 @@ struct fscache_retrieval {
150 void *context; /* netfs read context (pinned) */ 151 void *context; /* netfs read context (pinned) */
151 struct list_head to_do; /* list of things to be done by the backend */ 152 struct list_head to_do; /* list of things to be done by the backend */
152 unsigned long start_time; /* time at which retrieval started */ 153 unsigned long start_time; /* time at which retrieval started */
153 unsigned n_pages; /* number of pages to be retrieved */ 154 atomic_t n_pages; /* number of pages to be retrieved */
154}; 155};
155 156
156typedef int (*fscache_page_retrieval_func_t)(struct fscache_retrieval *op, 157typedef int (*fscache_page_retrieval_func_t)(struct fscache_retrieval *op,
@@ -194,15 +195,14 @@ static inline void fscache_enqueue_retrieval(struct fscache_retrieval *op)
194static inline void fscache_retrieval_complete(struct fscache_retrieval *op, 195static inline void fscache_retrieval_complete(struct fscache_retrieval *op,
195 int n_pages) 196 int n_pages)
196{ 197{
197 op->n_pages -= n_pages; 198 atomic_sub(n_pages, &op->n_pages);
198 if (op->n_pages <= 0) 199 if (atomic_read(&op->n_pages) <= 0)
199 fscache_op_complete(&op->op, true); 200 fscache_op_complete(&op->op, true);
200} 201}
201 202
202/** 203/**
203 * fscache_put_retrieval - Drop a reference to a retrieval operation 204 * fscache_put_retrieval - Drop a reference to a retrieval operation
204 * @op: The retrieval operation affected 205 * @op: The retrieval operation affected
205 * @n_pages: The number of pages to account for
206 * 206 *
207 * Drop a reference to a retrieval operation. 207 * Drop a reference to a retrieval operation.
208 */ 208 */
@@ -314,6 +314,7 @@ struct fscache_cache_ops {
314struct fscache_cookie { 314struct fscache_cookie {
315 atomic_t usage; /* number of users of this cookie */ 315 atomic_t usage; /* number of users of this cookie */
316 atomic_t n_children; /* number of children of this cookie */ 316 atomic_t n_children; /* number of children of this cookie */
317 atomic_t n_active; /* number of active users of netfs ptrs */
317 spinlock_t lock; 318 spinlock_t lock;
318 spinlock_t stores_lock; /* lock on page store tree */ 319 spinlock_t stores_lock; /* lock on page store tree */
319 struct hlist_head backing_objects; /* object(s) backing this file/index */ 320 struct hlist_head backing_objects; /* object(s) backing this file/index */
@@ -326,13 +327,11 @@ struct fscache_cookie {
326 327
327 unsigned long flags; 328 unsigned long flags;
328#define FSCACHE_COOKIE_LOOKING_UP 0 /* T if non-index cookie being looked up still */ 329#define FSCACHE_COOKIE_LOOKING_UP 0 /* T if non-index cookie being looked up still */
329#define FSCACHE_COOKIE_CREATING 1 /* T if non-index object being created still */ 330#define FSCACHE_COOKIE_NO_DATA_YET 1 /* T if new object with no cached data yet */
330#define FSCACHE_COOKIE_NO_DATA_YET 2 /* T if new object with no cached data yet */ 331#define FSCACHE_COOKIE_UNAVAILABLE 2 /* T if cookie is unavailable (error, etc) */
331#define FSCACHE_COOKIE_PENDING_FILL 3 /* T if pending initial fill on object */ 332#define FSCACHE_COOKIE_INVALIDATING 3 /* T if cookie is being invalidated */
332#define FSCACHE_COOKIE_FILLING 4 /* T if filling object incrementally */ 333#define FSCACHE_COOKIE_RELINQUISHED 4 /* T if cookie has been relinquished */
333#define FSCACHE_COOKIE_UNAVAILABLE 5 /* T if cookie is unavailable (error, etc) */ 334#define FSCACHE_COOKIE_RETIRED 5 /* T if cookie was retired */
334#define FSCACHE_COOKIE_WAITING_ON_READS 6 /* T if cookie is waiting on reads */
335#define FSCACHE_COOKIE_INVALIDATING 7 /* T if cookie is being invalidated */
336}; 335};
337 336
338extern struct fscache_cookie fscache_fsdef_index; 337extern struct fscache_cookie fscache_fsdef_index;
@@ -341,45 +340,40 @@ extern struct fscache_cookie fscache_fsdef_index;
341 * Event list for fscache_object::{event_mask,events} 340 * Event list for fscache_object::{event_mask,events}
342 */ 341 */
343enum { 342enum {
344 FSCACHE_OBJECT_EV_REQUEUE, /* T if object should be requeued */ 343 FSCACHE_OBJECT_EV_NEW_CHILD, /* T if object has a new child */
344 FSCACHE_OBJECT_EV_PARENT_READY, /* T if object's parent is ready */
345 FSCACHE_OBJECT_EV_UPDATE, /* T if object should be updated */ 345 FSCACHE_OBJECT_EV_UPDATE, /* T if object should be updated */
346 FSCACHE_OBJECT_EV_INVALIDATE, /* T if cache requested object invalidation */ 346 FSCACHE_OBJECT_EV_INVALIDATE, /* T if cache requested object invalidation */
347 FSCACHE_OBJECT_EV_CLEARED, /* T if accessors all gone */ 347 FSCACHE_OBJECT_EV_CLEARED, /* T if accessors all gone */
348 FSCACHE_OBJECT_EV_ERROR, /* T if fatal error occurred during processing */ 348 FSCACHE_OBJECT_EV_ERROR, /* T if fatal error occurred during processing */
349 FSCACHE_OBJECT_EV_RELEASE, /* T if netfs requested object release */ 349 FSCACHE_OBJECT_EV_KILL, /* T if netfs relinquished or cache withdrew object */
350 FSCACHE_OBJECT_EV_RETIRE, /* T if netfs requested object retirement */
351 FSCACHE_OBJECT_EV_WITHDRAW, /* T if cache requested object withdrawal */
352 NR_FSCACHE_OBJECT_EVENTS 350 NR_FSCACHE_OBJECT_EVENTS
353}; 351};
354 352
355#define FSCACHE_OBJECT_EVENTS_MASK ((1UL << NR_FSCACHE_OBJECT_EVENTS) - 1) 353#define FSCACHE_OBJECT_EVENTS_MASK ((1UL << NR_FSCACHE_OBJECT_EVENTS) - 1)
356 354
357/* 355/*
356 * States for object state machine.
357 */
358struct fscache_transition {
359 unsigned long events;
360 const struct fscache_state *transit_to;
361};
362
363struct fscache_state {
364 char name[24];
365 char short_name[8];
366 const struct fscache_state *(*work)(struct fscache_object *object,
367 int event);
368 const struct fscache_transition transitions[];
369};
370
371/*
358 * on-disk cache file or index handle 372 * on-disk cache file or index handle
359 */ 373 */
360struct fscache_object { 374struct fscache_object {
361 enum fscache_object_state { 375 const struct fscache_state *state; /* Object state machine state */
362 FSCACHE_OBJECT_INIT, /* object in initial unbound state */ 376 const struct fscache_transition *oob_table; /* OOB state transition table */
363 FSCACHE_OBJECT_LOOKING_UP, /* looking up object */
364 FSCACHE_OBJECT_CREATING, /* creating object */
365
366 /* active states */
367 FSCACHE_OBJECT_AVAILABLE, /* cleaning up object after creation */
368 FSCACHE_OBJECT_ACTIVE, /* object is usable */
369 FSCACHE_OBJECT_INVALIDATING, /* object is invalidating */
370 FSCACHE_OBJECT_UPDATING, /* object is updating */
371
372 /* terminal states */
373 FSCACHE_OBJECT_DYING, /* object waiting for accessors to finish */
374 FSCACHE_OBJECT_LC_DYING, /* object cleaning up after lookup/create */
375 FSCACHE_OBJECT_ABORT_INIT, /* abort the init state */
376 FSCACHE_OBJECT_RELEASING, /* releasing object */
377 FSCACHE_OBJECT_RECYCLING, /* retiring object */
378 FSCACHE_OBJECT_WITHDRAWING, /* withdrawing object */
379 FSCACHE_OBJECT_DEAD, /* object is now dead */
380 FSCACHE_OBJECT__NSTATES
381 } state;
382
383 int debug_id; /* debugging ID */ 377 int debug_id; /* debugging ID */
384 int n_children; /* number of child objects */ 378 int n_children; /* number of child objects */
385 int n_ops; /* number of extant ops on object */ 379 int n_ops; /* number of extant ops on object */
@@ -390,6 +384,7 @@ struct fscache_object {
390 spinlock_t lock; /* state and operations lock */ 384 spinlock_t lock; /* state and operations lock */
391 385
392 unsigned long lookup_jif; /* time at which lookup started */ 386 unsigned long lookup_jif; /* time at which lookup started */
387 unsigned long oob_event_mask; /* OOB events this object is interested in */
393 unsigned long event_mask; /* events this object is interested in */ 388 unsigned long event_mask; /* events this object is interested in */
394 unsigned long events; /* events to be processed by this object 389 unsigned long events; /* events to be processed by this object
395 * (order is important - using fls) */ 390 * (order is important - using fls) */
@@ -398,6 +393,9 @@ struct fscache_object {
398#define FSCACHE_OBJECT_LOCK 0 /* T if object is busy being processed */ 393#define FSCACHE_OBJECT_LOCK 0 /* T if object is busy being processed */
399#define FSCACHE_OBJECT_PENDING_WRITE 1 /* T if object has pending write */ 394#define FSCACHE_OBJECT_PENDING_WRITE 1 /* T if object has pending write */
400#define FSCACHE_OBJECT_WAITING 2 /* T if object is waiting on its parent */ 395#define FSCACHE_OBJECT_WAITING 2 /* T if object is waiting on its parent */
396#define FSCACHE_OBJECT_IS_LIVE 3 /* T if object is not withdrawn or relinquished */
397#define FSCACHE_OBJECT_IS_LOOKED_UP 4 /* T if object has been looked up */
398#define FSCACHE_OBJECT_IS_AVAILABLE 5 /* T if object has become active */
401 399
402 struct list_head cache_link; /* link in cache->object_list */ 400 struct list_head cache_link; /* link in cache->object_list */
403 struct hlist_node cookie_link; /* link in cookie->backing_objects */ 401 struct hlist_node cookie_link; /* link in cookie->backing_objects */
@@ -415,62 +413,40 @@ struct fscache_object {
415 loff_t store_limit_l; /* current storage limit */ 413 loff_t store_limit_l; /* current storage limit */
416}; 414};
417 415
418extern const char *fscache_object_states[]; 416extern void fscache_object_init(struct fscache_object *, struct fscache_cookie *,
417 struct fscache_cache *);
418extern void fscache_object_destroy(struct fscache_object *);
419 419
420#define fscache_object_is_active(obj) \ 420extern void fscache_object_lookup_negative(struct fscache_object *object);
421 (!test_bit(FSCACHE_IOERROR, &(obj)->cache->flags) && \ 421extern void fscache_obtained_object(struct fscache_object *object);
422 (obj)->state >= FSCACHE_OBJECT_AVAILABLE && \
423 (obj)->state < FSCACHE_OBJECT_DYING)
424 422
425#define fscache_object_is_dead(obj) \ 423static inline bool fscache_object_is_live(struct fscache_object *object)
426 (test_bit(FSCACHE_IOERROR, &(obj)->cache->flags) && \ 424{
427 (obj)->state >= FSCACHE_OBJECT_DYING) 425 return test_bit(FSCACHE_OBJECT_IS_LIVE, &object->flags);
426}
428 427
429extern void fscache_object_work_func(struct work_struct *work); 428static inline bool fscache_object_is_dying(struct fscache_object *object)
429{
430 return !fscache_object_is_live(object);
431}
430 432
431/** 433static inline bool fscache_object_is_available(struct fscache_object *object)
432 * fscache_object_init - Initialise a cache object description
433 * @object: Object description
434 *
435 * Initialise a cache object description to its basic values.
436 *
437 * See Documentation/filesystems/caching/backend-api.txt for a complete
438 * description.
439 */
440static inline
441void fscache_object_init(struct fscache_object *object,
442 struct fscache_cookie *cookie,
443 struct fscache_cache *cache)
444{ 434{
445 atomic_inc(&cache->object_count); 435 return test_bit(FSCACHE_OBJECT_IS_AVAILABLE, &object->flags);
446
447 object->state = FSCACHE_OBJECT_INIT;
448 spin_lock_init(&object->lock);
449 INIT_LIST_HEAD(&object->cache_link);
450 INIT_HLIST_NODE(&object->cookie_link);
451 INIT_WORK(&object->work, fscache_object_work_func);
452 INIT_LIST_HEAD(&object->dependents);
453 INIT_LIST_HEAD(&object->dep_link);
454 INIT_LIST_HEAD(&object->pending_ops);
455 object->n_children = 0;
456 object->n_ops = object->n_in_progress = object->n_exclusive = 0;
457 object->events = object->event_mask = 0;
458 object->flags = 0;
459 object->store_limit = 0;
460 object->store_limit_l = 0;
461 object->cache = cache;
462 object->cookie = cookie;
463 object->parent = NULL;
464} 436}
465 437
466extern void fscache_object_lookup_negative(struct fscache_object *object); 438static inline bool fscache_object_is_active(struct fscache_object *object)
467extern void fscache_obtained_object(struct fscache_object *object); 439{
440 return fscache_object_is_available(object) &&
441 fscache_object_is_live(object) &&
442 !test_bit(FSCACHE_IOERROR, &object->cache->flags);
443}
468 444
469#ifdef CONFIG_FSCACHE_OBJECT_LIST 445static inline bool fscache_object_is_dead(struct fscache_object *object)
470extern void fscache_object_destroy(struct fscache_object *object); 446{
471#else 447 return fscache_object_is_dying(object) &&
472#define fscache_object_destroy(object) do {} while(0) 448 test_bit(FSCACHE_IOERROR, &object->cache->flags);
473#endif 449}
474 450
475/** 451/**
476 * fscache_object_destroyed - Note destruction of an object in a cache 452 * fscache_object_destroyed - Note destruction of an object in a cache
@@ -531,6 +507,33 @@ static inline void fscache_end_io(struct fscache_retrieval *op,
531 op->end_io_func(page, op->context, error); 507 op->end_io_func(page, op->context, error);
532} 508}
533 509
510/**
511 * fscache_use_cookie - Request usage of cookie attached to an object
512 * @object: Object description
513 *
514 * Request usage of the cookie attached to an object. NULL is returned if the
515 * relinquishment had reduced the cookie usage count to 0.
516 */
517static inline bool fscache_use_cookie(struct fscache_object *object)
518{
519 struct fscache_cookie *cookie = object->cookie;
520 return atomic_inc_not_zero(&cookie->n_active) != 0;
521}
522
523/**
524 * fscache_unuse_cookie - Cease usage of cookie attached to an object
525 * @object: Object description
526 *
527 * Cease usage of the cookie attached to an object. When the users count
528 * reaches zero then the cookie relinquishment will be permitted to proceed.
529 */
530static inline void fscache_unuse_cookie(struct fscache_object *object)
531{
532 struct fscache_cookie *cookie = object->cookie;
533 if (atomic_dec_and_test(&cookie->n_active))
534 wake_up_atomic_t(&cookie->n_active);
535}
536
534/* 537/*
535 * out-of-line cache backend functions 538 * out-of-line cache backend functions
536 */ 539 */
diff --git a/include/linux/wait.h b/include/linux/wait.h
index 1133695eb067..f487a4750b7f 100644
--- a/include/linux/wait.h
+++ b/include/linux/wait.h
@@ -23,6 +23,7 @@ struct __wait_queue {
23struct wait_bit_key { 23struct wait_bit_key {
24 void *flags; 24 void *flags;
25 int bit_nr; 25 int bit_nr;
26#define WAIT_ATOMIC_T_BIT_NR -1
26}; 27};
27 28
28struct wait_bit_queue { 29struct wait_bit_queue {
@@ -60,6 +61,9 @@ struct task_struct;
60#define __WAIT_BIT_KEY_INITIALIZER(word, bit) \ 61#define __WAIT_BIT_KEY_INITIALIZER(word, bit) \
61 { .flags = word, .bit_nr = bit, } 62 { .flags = word, .bit_nr = bit, }
62 63
64#define __WAIT_ATOMIC_T_KEY_INITIALIZER(p) \
65 { .flags = p, .bit_nr = WAIT_ATOMIC_T_BIT_NR, }
66
63extern void __init_waitqueue_head(wait_queue_head_t *q, const char *name, struct lock_class_key *); 67extern void __init_waitqueue_head(wait_queue_head_t *q, const char *name, struct lock_class_key *);
64 68
65#define init_waitqueue_head(q) \ 69#define init_waitqueue_head(q) \
@@ -146,8 +150,10 @@ void __wake_up_bit(wait_queue_head_t *, void *, int);
146int __wait_on_bit(wait_queue_head_t *, struct wait_bit_queue *, int (*)(void *), unsigned); 150int __wait_on_bit(wait_queue_head_t *, struct wait_bit_queue *, int (*)(void *), unsigned);
147int __wait_on_bit_lock(wait_queue_head_t *, struct wait_bit_queue *, int (*)(void *), unsigned); 151int __wait_on_bit_lock(wait_queue_head_t *, struct wait_bit_queue *, int (*)(void *), unsigned);
148void wake_up_bit(void *, int); 152void wake_up_bit(void *, int);
153void wake_up_atomic_t(atomic_t *);
149int out_of_line_wait_on_bit(void *, int, int (*)(void *), unsigned); 154int out_of_line_wait_on_bit(void *, int, int (*)(void *), unsigned);
150int out_of_line_wait_on_bit_lock(void *, int, int (*)(void *), unsigned); 155int out_of_line_wait_on_bit_lock(void *, int, int (*)(void *), unsigned);
156int out_of_line_wait_on_atomic_t(atomic_t *, int (*)(atomic_t *), unsigned);
151wait_queue_head_t *bit_waitqueue(void *, int); 157wait_queue_head_t *bit_waitqueue(void *, int);
152 158
153#define wake_up(x) __wake_up(x, TASK_NORMAL, 1, NULL) 159#define wake_up(x) __wake_up(x, TASK_NORMAL, 1, NULL)
@@ -902,5 +908,23 @@ static inline int wait_on_bit_lock(void *word, int bit,
902 return 0; 908 return 0;
903 return out_of_line_wait_on_bit_lock(word, bit, action, mode); 909 return out_of_line_wait_on_bit_lock(word, bit, action, mode);
904} 910}
911
912/**
913 * wait_on_atomic_t - Wait for an atomic_t to become 0
914 * @val: The atomic value being waited on, a kernel virtual address
915 * @action: the function used to sleep, which may take special actions
916 * @mode: the task state to sleep in
917 *
918 * Wait for an atomic_t to become 0. We abuse the bit-wait waitqueue table for
919 * the purpose of getting a waitqueue, but we set the key to a bit number
920 * outside of the target 'word'.
921 */
922static inline
923int wait_on_atomic_t(atomic_t *val, int (*action)(atomic_t *), unsigned mode)
924{
925 if (atomic_read(val) == 0)
926 return 0;
927 return out_of_line_wait_on_atomic_t(val, action, mode);
928}
905 929
906#endif 930#endif