diff options
-rw-r--r-- | fs/fscache/object.c | 41 | ||||
-rw-r--r-- | fs/fscache/operation.c | 29 | ||||
-rw-r--r-- | fs/fscache/page.c | 27 | ||||
-rw-r--r-- | include/linux/fscache-cache.h | 12 |
4 files changed, 103 insertions, 6 deletions
diff --git a/fs/fscache/object.c b/fs/fscache/object.c index d236eb1d6f37..615b63dd9ecc 100644 --- a/fs/fscache/object.c +++ b/fs/fscache/object.c | |||
@@ -14,9 +14,10 @@ | |||
14 | 14 | ||
15 | #define FSCACHE_DEBUG_LEVEL COOKIE | 15 | #define FSCACHE_DEBUG_LEVEL COOKIE |
16 | #include <linux/module.h> | 16 | #include <linux/module.h> |
17 | #include <linux/seq_file.h> | ||
17 | #include "internal.h" | 18 | #include "internal.h" |
18 | 19 | ||
19 | const char *fscache_object_states[] = { | 20 | const char *fscache_object_states[FSCACHE_OBJECT__NSTATES] = { |
20 | [FSCACHE_OBJECT_INIT] = "OBJECT_INIT", | 21 | [FSCACHE_OBJECT_INIT] = "OBJECT_INIT", |
21 | [FSCACHE_OBJECT_LOOKING_UP] = "OBJECT_LOOKING_UP", | 22 | [FSCACHE_OBJECT_LOOKING_UP] = "OBJECT_LOOKING_UP", |
22 | [FSCACHE_OBJECT_CREATING] = "OBJECT_CREATING", | 23 | [FSCACHE_OBJECT_CREATING] = "OBJECT_CREATING", |
@@ -33,9 +34,28 @@ const char *fscache_object_states[] = { | |||
33 | }; | 34 | }; |
34 | EXPORT_SYMBOL(fscache_object_states); | 35 | EXPORT_SYMBOL(fscache_object_states); |
35 | 36 | ||
37 | static const char fscache_object_states_short[FSCACHE_OBJECT__NSTATES][5] = { | ||
38 | [FSCACHE_OBJECT_INIT] = "INIT", | ||
39 | [FSCACHE_OBJECT_LOOKING_UP] = "LOOK", | ||
40 | [FSCACHE_OBJECT_CREATING] = "CRTN", | ||
41 | [FSCACHE_OBJECT_AVAILABLE] = "AVBL", | ||
42 | [FSCACHE_OBJECT_ACTIVE] = "ACTV", | ||
43 | [FSCACHE_OBJECT_UPDATING] = "UPDT", | ||
44 | [FSCACHE_OBJECT_DYING] = "DYNG", | ||
45 | [FSCACHE_OBJECT_LC_DYING] = "LCDY", | ||
46 | [FSCACHE_OBJECT_ABORT_INIT] = "ABTI", | ||
47 | [FSCACHE_OBJECT_RELEASING] = "RELS", | ||
48 | [FSCACHE_OBJECT_RECYCLING] = "RCYC", | ||
49 | [FSCACHE_OBJECT_WITHDRAWING] = "WTHD", | ||
50 | [FSCACHE_OBJECT_DEAD] = "DEAD", | ||
51 | }; | ||
52 | |||
36 | static void fscache_object_slow_work_put_ref(struct slow_work *); | 53 | static void fscache_object_slow_work_put_ref(struct slow_work *); |
37 | static int fscache_object_slow_work_get_ref(struct slow_work *); | 54 | static int fscache_object_slow_work_get_ref(struct slow_work *); |
38 | static void fscache_object_slow_work_execute(struct slow_work *); | 55 | static void fscache_object_slow_work_execute(struct slow_work *); |
56 | #ifdef CONFIG_SLOW_WORK_PROC | ||
57 | static void fscache_object_slow_work_desc(struct slow_work *, struct seq_file *); | ||
58 | #endif | ||
39 | static void fscache_initialise_object(struct fscache_object *); | 59 | static void fscache_initialise_object(struct fscache_object *); |
40 | static void fscache_lookup_object(struct fscache_object *); | 60 | static void fscache_lookup_object(struct fscache_object *); |
41 | static void fscache_object_available(struct fscache_object *); | 61 | static void fscache_object_available(struct fscache_object *); |
@@ -49,6 +69,9 @@ const struct slow_work_ops fscache_object_slow_work_ops = { | |||
49 | .get_ref = fscache_object_slow_work_get_ref, | 69 | .get_ref = fscache_object_slow_work_get_ref, |
50 | .put_ref = fscache_object_slow_work_put_ref, | 70 | .put_ref = fscache_object_slow_work_put_ref, |
51 | .execute = fscache_object_slow_work_execute, | 71 | .execute = fscache_object_slow_work_execute, |
72 | #ifdef CONFIG_SLOW_WORK_PROC | ||
73 | .desc = fscache_object_slow_work_desc, | ||
74 | #endif | ||
52 | }; | 75 | }; |
53 | EXPORT_SYMBOL(fscache_object_slow_work_ops); | 76 | EXPORT_SYMBOL(fscache_object_slow_work_ops); |
54 | 77 | ||
@@ -327,6 +350,22 @@ static void fscache_object_slow_work_execute(struct slow_work *work) | |||
327 | } | 350 | } |
328 | 351 | ||
329 | /* | 352 | /* |
353 | * describe an object for slow-work debugging | ||
354 | */ | ||
355 | #ifdef CONFIG_SLOW_WORK_PROC | ||
356 | static void fscache_object_slow_work_desc(struct slow_work *work, | ||
357 | struct seq_file *m) | ||
358 | { | ||
359 | struct fscache_object *object = | ||
360 | container_of(work, struct fscache_object, work); | ||
361 | |||
362 | seq_printf(m, "FSC: OBJ%x: %s", | ||
363 | object->debug_id, | ||
364 | fscache_object_states_short[object->state]); | ||
365 | } | ||
366 | #endif | ||
367 | |||
368 | /* | ||
330 | * initialise an object | 369 | * initialise an object |
331 | * - check the specified object's parent to see if we can make use of it | 370 | * - check the specified object's parent to see if we can make use of it |
332 | * immediately to do a creation | 371 | * immediately to do a creation |
diff --git a/fs/fscache/operation.c b/fs/fscache/operation.c index f1a2857b2ff5..91bbe6f0377c 100644 --- a/fs/fscache/operation.c +++ b/fs/fscache/operation.c | |||
@@ -13,6 +13,7 @@ | |||
13 | 13 | ||
14 | #define FSCACHE_DEBUG_LEVEL OPERATION | 14 | #define FSCACHE_DEBUG_LEVEL OPERATION |
15 | #include <linux/module.h> | 15 | #include <linux/module.h> |
16 | #include <linux/seq_file.h> | ||
16 | #include "internal.h" | 17 | #include "internal.h" |
17 | 18 | ||
18 | atomic_t fscache_op_debug_id; | 19 | atomic_t fscache_op_debug_id; |
@@ -31,6 +32,8 @@ void fscache_enqueue_operation(struct fscache_operation *op) | |||
31 | _enter("{OBJ%x OP%x,%u}", | 32 | _enter("{OBJ%x OP%x,%u}", |
32 | op->object->debug_id, op->debug_id, atomic_read(&op->usage)); | 33 | op->object->debug_id, op->debug_id, atomic_read(&op->usage)); |
33 | 34 | ||
35 | fscache_set_op_state(op, "EnQ"); | ||
36 | |||
34 | ASSERT(op->processor != NULL); | 37 | ASSERT(op->processor != NULL); |
35 | ASSERTCMP(op->object->state, >=, FSCACHE_OBJECT_AVAILABLE); | 38 | ASSERTCMP(op->object->state, >=, FSCACHE_OBJECT_AVAILABLE); |
36 | ASSERTCMP(atomic_read(&op->usage), >, 0); | 39 | ASSERTCMP(atomic_read(&op->usage), >, 0); |
@@ -67,6 +70,8 @@ EXPORT_SYMBOL(fscache_enqueue_operation); | |||
67 | static void fscache_run_op(struct fscache_object *object, | 70 | static void fscache_run_op(struct fscache_object *object, |
68 | struct fscache_operation *op) | 71 | struct fscache_operation *op) |
69 | { | 72 | { |
73 | fscache_set_op_state(op, "Run"); | ||
74 | |||
70 | object->n_in_progress++; | 75 | object->n_in_progress++; |
71 | if (test_and_clear_bit(FSCACHE_OP_WAITING, &op->flags)) | 76 | if (test_and_clear_bit(FSCACHE_OP_WAITING, &op->flags)) |
72 | wake_up_bit(&op->flags, FSCACHE_OP_WAITING); | 77 | wake_up_bit(&op->flags, FSCACHE_OP_WAITING); |
@@ -87,6 +92,8 @@ int fscache_submit_exclusive_op(struct fscache_object *object, | |||
87 | 92 | ||
88 | _enter("{OBJ%x OP%x},", object->debug_id, op->debug_id); | 93 | _enter("{OBJ%x OP%x},", object->debug_id, op->debug_id); |
89 | 94 | ||
95 | fscache_set_op_state(op, "SubmitX"); | ||
96 | |||
90 | spin_lock(&object->lock); | 97 | spin_lock(&object->lock); |
91 | ASSERTCMP(object->n_ops, >=, object->n_in_progress); | 98 | ASSERTCMP(object->n_ops, >=, object->n_in_progress); |
92 | ASSERTCMP(object->n_ops, >=, object->n_exclusive); | 99 | ASSERTCMP(object->n_ops, >=, object->n_exclusive); |
@@ -190,6 +197,8 @@ int fscache_submit_op(struct fscache_object *object, | |||
190 | 197 | ||
191 | ASSERTCMP(atomic_read(&op->usage), >, 0); | 198 | ASSERTCMP(atomic_read(&op->usage), >, 0); |
192 | 199 | ||
200 | fscache_set_op_state(op, "Submit"); | ||
201 | |||
193 | spin_lock(&object->lock); | 202 | spin_lock(&object->lock); |
194 | ASSERTCMP(object->n_ops, >=, object->n_in_progress); | 203 | ASSERTCMP(object->n_ops, >=, object->n_in_progress); |
195 | ASSERTCMP(object->n_ops, >=, object->n_exclusive); | 204 | ASSERTCMP(object->n_ops, >=, object->n_exclusive); |
@@ -298,6 +307,8 @@ void fscache_put_operation(struct fscache_operation *op) | |||
298 | if (!atomic_dec_and_test(&op->usage)) | 307 | if (!atomic_dec_and_test(&op->usage)) |
299 | return; | 308 | return; |
300 | 309 | ||
310 | fscache_set_op_state(op, "Put"); | ||
311 | |||
301 | _debug("PUT OP"); | 312 | _debug("PUT OP"); |
302 | if (test_and_set_bit(FSCACHE_OP_DEAD, &op->flags)) | 313 | if (test_and_set_bit(FSCACHE_OP_DEAD, &op->flags)) |
303 | BUG(); | 314 | BUG(); |
@@ -452,9 +463,27 @@ static void fscache_op_execute(struct slow_work *work) | |||
452 | _leave(""); | 463 | _leave(""); |
453 | } | 464 | } |
454 | 465 | ||
466 | /* | ||
467 | * describe an operation for slow-work debugging | ||
468 | */ | ||
469 | #ifdef CONFIG_SLOW_WORK_PROC | ||
470 | static void fscache_op_desc(struct slow_work *work, struct seq_file *m) | ||
471 | { | ||
472 | struct fscache_operation *op = | ||
473 | container_of(work, struct fscache_operation, slow_work); | ||
474 | |||
475 | seq_printf(m, "FSC: OBJ%x OP%x: %s/%s fl=%lx", | ||
476 | op->object->debug_id, op->debug_id, | ||
477 | op->name, op->state, op->flags); | ||
478 | } | ||
479 | #endif | ||
480 | |||
455 | const struct slow_work_ops fscache_op_slow_work_ops = { | 481 | const struct slow_work_ops fscache_op_slow_work_ops = { |
456 | .owner = THIS_MODULE, | 482 | .owner = THIS_MODULE, |
457 | .get_ref = fscache_op_get_ref, | 483 | .get_ref = fscache_op_get_ref, |
458 | .put_ref = fscache_op_put_ref, | 484 | .put_ref = fscache_op_put_ref, |
459 | .execute = fscache_op_execute, | 485 | .execute = fscache_op_execute, |
486 | #ifdef CONFIG_SLOW_WORK_PROC | ||
487 | .desc = fscache_op_desc, | ||
488 | #endif | ||
460 | }; | 489 | }; |
diff --git a/fs/fscache/page.c b/fs/fscache/page.c index 2568e0eb644f..e8bbc395cef6 100644 --- a/fs/fscache/page.c +++ b/fs/fscache/page.c | |||
@@ -63,14 +63,19 @@ static void fscache_end_page_write(struct fscache_cookie *cookie, struct page *p | |||
63 | static void fscache_attr_changed_op(struct fscache_operation *op) | 63 | static void fscache_attr_changed_op(struct fscache_operation *op) |
64 | { | 64 | { |
65 | struct fscache_object *object = op->object; | 65 | struct fscache_object *object = op->object; |
66 | int ret; | ||
66 | 67 | ||
67 | _enter("{OBJ%x OP%x}", object->debug_id, op->debug_id); | 68 | _enter("{OBJ%x OP%x}", object->debug_id, op->debug_id); |
68 | 69 | ||
69 | fscache_stat(&fscache_n_attr_changed_calls); | 70 | fscache_stat(&fscache_n_attr_changed_calls); |
70 | 71 | ||
71 | if (fscache_object_is_active(object) && | 72 | if (fscache_object_is_active(object)) { |
72 | object->cache->ops->attr_changed(object) < 0) | 73 | fscache_set_op_state(op, "CallFS"); |
73 | fscache_abort_object(object); | 74 | ret = object->cache->ops->attr_changed(object); |
75 | fscache_set_op_state(op, "Done"); | ||
76 | if (ret < 0) | ||
77 | fscache_abort_object(object); | ||
78 | } | ||
74 | 79 | ||
75 | _leave(""); | 80 | _leave(""); |
76 | } | 81 | } |
@@ -99,6 +104,7 @@ int __fscache_attr_changed(struct fscache_cookie *cookie) | |||
99 | fscache_operation_init(op, NULL); | 104 | fscache_operation_init(op, NULL); |
100 | fscache_operation_init_slow(op, fscache_attr_changed_op); | 105 | fscache_operation_init_slow(op, fscache_attr_changed_op); |
101 | op->flags = FSCACHE_OP_SLOW | (1 << FSCACHE_OP_EXCLUSIVE); | 106 | op->flags = FSCACHE_OP_SLOW | (1 << FSCACHE_OP_EXCLUSIVE); |
107 | fscache_set_op_name(op, "Attr"); | ||
102 | 108 | ||
103 | spin_lock(&cookie->lock); | 109 | spin_lock(&cookie->lock); |
104 | 110 | ||
@@ -184,6 +190,7 @@ static struct fscache_retrieval *fscache_alloc_retrieval( | |||
184 | op->start_time = jiffies; | 190 | op->start_time = jiffies; |
185 | INIT_WORK(&op->op.fast_work, fscache_retrieval_work); | 191 | INIT_WORK(&op->op.fast_work, fscache_retrieval_work); |
186 | INIT_LIST_HEAD(&op->to_do); | 192 | INIT_LIST_HEAD(&op->to_do); |
193 | fscache_set_op_name(&op->op, "Retr"); | ||
187 | return op; | 194 | return op; |
188 | } | 195 | } |
189 | 196 | ||
@@ -257,6 +264,7 @@ int __fscache_read_or_alloc_page(struct fscache_cookie *cookie, | |||
257 | _leave(" = -ENOMEM"); | 264 | _leave(" = -ENOMEM"); |
258 | return -ENOMEM; | 265 | return -ENOMEM; |
259 | } | 266 | } |
267 | fscache_set_op_name(&op->op, "RetrRA1"); | ||
260 | 268 | ||
261 | spin_lock(&cookie->lock); | 269 | spin_lock(&cookie->lock); |
262 | 270 | ||
@@ -369,6 +377,7 @@ int __fscache_read_or_alloc_pages(struct fscache_cookie *cookie, | |||
369 | op = fscache_alloc_retrieval(mapping, end_io_func, context); | 377 | op = fscache_alloc_retrieval(mapping, end_io_func, context); |
370 | if (!op) | 378 | if (!op) |
371 | return -ENOMEM; | 379 | return -ENOMEM; |
380 | fscache_set_op_name(&op->op, "RetrRAN"); | ||
372 | 381 | ||
373 | spin_lock(&cookie->lock); | 382 | spin_lock(&cookie->lock); |
374 | 383 | ||
@@ -461,6 +470,7 @@ int __fscache_alloc_page(struct fscache_cookie *cookie, | |||
461 | op = fscache_alloc_retrieval(page->mapping, NULL, NULL); | 470 | op = fscache_alloc_retrieval(page->mapping, NULL, NULL); |
462 | if (!op) | 471 | if (!op) |
463 | return -ENOMEM; | 472 | return -ENOMEM; |
473 | fscache_set_op_name(&op->op, "RetrAL1"); | ||
464 | 474 | ||
465 | spin_lock(&cookie->lock); | 475 | spin_lock(&cookie->lock); |
466 | 476 | ||
@@ -529,6 +539,8 @@ static void fscache_write_op(struct fscache_operation *_op) | |||
529 | 539 | ||
530 | _enter("{OP%x,%d}", op->op.debug_id, atomic_read(&op->op.usage)); | 540 | _enter("{OP%x,%d}", op->op.debug_id, atomic_read(&op->op.usage)); |
531 | 541 | ||
542 | fscache_set_op_state(&op->op, "GetPage"); | ||
543 | |||
532 | spin_lock(&cookie->lock); | 544 | spin_lock(&cookie->lock); |
533 | spin_lock(&object->lock); | 545 | spin_lock(&object->lock); |
534 | 546 | ||
@@ -559,13 +571,17 @@ static void fscache_write_op(struct fscache_operation *_op) | |||
559 | spin_unlock(&cookie->lock); | 571 | spin_unlock(&cookie->lock); |
560 | 572 | ||
561 | if (page) { | 573 | if (page) { |
574 | fscache_set_op_state(&op->op, "Store"); | ||
562 | ret = object->cache->ops->write_page(op, page); | 575 | ret = object->cache->ops->write_page(op, page); |
576 | fscache_set_op_state(&op->op, "EndWrite"); | ||
563 | fscache_end_page_write(cookie, page); | 577 | fscache_end_page_write(cookie, page); |
564 | page_cache_release(page); | 578 | page_cache_release(page); |
565 | if (ret < 0) | 579 | if (ret < 0) { |
580 | fscache_set_op_state(&op->op, "Abort"); | ||
566 | fscache_abort_object(object); | 581 | fscache_abort_object(object); |
567 | else | 582 | } else { |
568 | fscache_enqueue_operation(&op->op); | 583 | fscache_enqueue_operation(&op->op); |
584 | } | ||
569 | } | 585 | } |
570 | 586 | ||
571 | _leave(""); | 587 | _leave(""); |
@@ -634,6 +650,7 @@ int __fscache_write_page(struct fscache_cookie *cookie, | |||
634 | fscache_operation_init(&op->op, fscache_release_write_op); | 650 | fscache_operation_init(&op->op, fscache_release_write_op); |
635 | fscache_operation_init_slow(&op->op, fscache_write_op); | 651 | fscache_operation_init_slow(&op->op, fscache_write_op); |
636 | op->op.flags = FSCACHE_OP_SLOW | (1 << FSCACHE_OP_WAITING); | 652 | op->op.flags = FSCACHE_OP_SLOW | (1 << FSCACHE_OP_WAITING); |
653 | fscache_set_op_name(&op->op, "Write1"); | ||
637 | 654 | ||
638 | ret = radix_tree_preload(gfp & ~__GFP_HIGHMEM); | 655 | ret = radix_tree_preload(gfp & ~__GFP_HIGHMEM); |
639 | if (ret < 0) | 656 | if (ret < 0) |
diff --git a/include/linux/fscache-cache.h b/include/linux/fscache-cache.h index 84d3532dd3ea..7a9847ccd192 100644 --- a/include/linux/fscache-cache.h +++ b/include/linux/fscache-cache.h | |||
@@ -102,6 +102,16 @@ struct fscache_operation { | |||
102 | 102 | ||
103 | /* operation releaser */ | 103 | /* operation releaser */ |
104 | fscache_operation_release_t release; | 104 | fscache_operation_release_t release; |
105 | |||
106 | #ifdef CONFIG_SLOW_WORK_PROC | ||
107 | const char *name; /* operation name */ | ||
108 | const char *state; /* operation state */ | ||
109 | #define fscache_set_op_name(OP, N) do { (OP)->name = (N); } while(0) | ||
110 | #define fscache_set_op_state(OP, S) do { (OP)->state = (S); } while(0) | ||
111 | #else | ||
112 | #define fscache_set_op_name(OP, N) do { } while(0) | ||
113 | #define fscache_set_op_state(OP, S) do { } while(0) | ||
114 | #endif | ||
105 | }; | 115 | }; |
106 | 116 | ||
107 | extern atomic_t fscache_op_debug_id; | 117 | extern atomic_t fscache_op_debug_id; |
@@ -125,6 +135,7 @@ static inline void fscache_operation_init(struct fscache_operation *op, | |||
125 | op->debug_id = atomic_inc_return(&fscache_op_debug_id); | 135 | op->debug_id = atomic_inc_return(&fscache_op_debug_id); |
126 | op->release = release; | 136 | op->release = release; |
127 | INIT_LIST_HEAD(&op->pend_link); | 137 | INIT_LIST_HEAD(&op->pend_link); |
138 | fscache_set_op_state(op, "Init"); | ||
128 | } | 139 | } |
129 | 140 | ||
130 | /** | 141 | /** |
@@ -337,6 +348,7 @@ struct fscache_object { | |||
337 | FSCACHE_OBJECT_RECYCLING, /* retiring object */ | 348 | FSCACHE_OBJECT_RECYCLING, /* retiring object */ |
338 | FSCACHE_OBJECT_WITHDRAWING, /* withdrawing object */ | 349 | FSCACHE_OBJECT_WITHDRAWING, /* withdrawing object */ |
339 | FSCACHE_OBJECT_DEAD, /* object is now dead */ | 350 | FSCACHE_OBJECT_DEAD, /* object is now dead */ |
351 | FSCACHE_OBJECT__NSTATES | ||
340 | } state; | 352 | } state; |
341 | 353 | ||
342 | int debug_id; /* debugging ID */ | 354 | int debug_id; /* debugging ID */ |