aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/filesystems/caching/fscache.txt2
-rw-r--r--fs/fscache/internal.h5
-rw-r--r--fs/fscache/object.c1
-rw-r--r--fs/fscache/page.c112
-rw-r--r--fs/fscache/stats.c12
-rw-r--r--include/linux/fscache-cache.h4
6 files changed, 75 insertions, 61 deletions
diff --git a/Documentation/filesystems/caching/fscache.txt b/Documentation/filesystems/caching/fscache.txt
index 7097fd29fb3d..3c23411956bb 100644
--- a/Documentation/filesystems/caching/fscache.txt
+++ b/Documentation/filesystems/caching/fscache.txt
@@ -253,6 +253,7 @@ proc files.
253 int=N Number of alloc reqs aborted -ERESTARTSYS 253 int=N Number of alloc reqs aborted -ERESTARTSYS
254 ops=N Number of alloc reqs submitted 254 ops=N Number of alloc reqs submitted
255 owt=N Number of alloc reqs waited for CPU time 255 owt=N Number of alloc reqs waited for CPU time
256 abt=N Number of alloc reqs aborted due to object death
256 Retrvls n=N Number of retrieval (read) requests seen 257 Retrvls n=N Number of retrieval (read) requests seen
257 ok=N Number of successful retr reqs 258 ok=N Number of successful retr reqs
258 wt=N Number of retr reqs that waited on lookup completion 259 wt=N Number of retr reqs that waited on lookup completion
@@ -262,6 +263,7 @@ proc files.
262 oom=N Number of retr reqs failed -ENOMEM 263 oom=N Number of retr reqs failed -ENOMEM
263 ops=N Number of retr reqs submitted 264 ops=N Number of retr reqs submitted
264 owt=N Number of retr reqs waited for CPU time 265 owt=N Number of retr reqs waited for CPU time
266 abt=N Number of retr reqs aborted due to object death
265 Stores n=N Number of storage (write) requests seen 267 Stores n=N Number of storage (write) requests seen
266 ok=N Number of successful store reqs 268 ok=N Number of successful store reqs
267 agn=N Number of store reqs on a page already pending storage 269 agn=N Number of store reqs on a page already pending storage
diff --git a/fs/fscache/internal.h b/fs/fscache/internal.h
index 2bf463d26080..5b49a373689b 100644
--- a/fs/fscache/internal.h
+++ b/fs/fscache/internal.h
@@ -156,6 +156,7 @@ extern atomic_t fscache_n_allocs_ok;
156extern atomic_t fscache_n_allocs_wait; 156extern atomic_t fscache_n_allocs_wait;
157extern atomic_t fscache_n_allocs_nobufs; 157extern atomic_t fscache_n_allocs_nobufs;
158extern atomic_t fscache_n_allocs_intr; 158extern atomic_t fscache_n_allocs_intr;
159extern atomic_t fscache_n_allocs_object_dead;
159extern atomic_t fscache_n_alloc_ops; 160extern atomic_t fscache_n_alloc_ops;
160extern atomic_t fscache_n_alloc_op_waits; 161extern atomic_t fscache_n_alloc_op_waits;
161 162
@@ -166,6 +167,7 @@ extern atomic_t fscache_n_retrievals_nodata;
166extern atomic_t fscache_n_retrievals_nobufs; 167extern atomic_t fscache_n_retrievals_nobufs;
167extern atomic_t fscache_n_retrievals_intr; 168extern atomic_t fscache_n_retrievals_intr;
168extern atomic_t fscache_n_retrievals_nomem; 169extern atomic_t fscache_n_retrievals_nomem;
170extern atomic_t fscache_n_retrievals_object_dead;
169extern atomic_t fscache_n_retrieval_ops; 171extern atomic_t fscache_n_retrieval_ops;
170extern atomic_t fscache_n_retrieval_op_waits; 172extern atomic_t fscache_n_retrieval_op_waits;
171 173
@@ -249,9 +251,12 @@ static inline void fscache_stat_d(atomic_t *stat)
249 atomic_dec(stat); 251 atomic_dec(stat);
250} 252}
251 253
254#define __fscache_stat(stat) (stat)
255
252extern const struct file_operations fscache_stats_fops; 256extern const struct file_operations fscache_stats_fops;
253#else 257#else
254 258
259#define __fscache_stat(stat) (NULL)
255#define fscache_stat(stat) do {} while (0) 260#define fscache_stat(stat) do {} while (0)
256#endif 261#endif
257 262
diff --git a/fs/fscache/object.c b/fs/fscache/object.c
index 74bc562a2cbc..c85c9f582166 100644
--- a/fs/fscache/object.c
+++ b/fs/fscache/object.c
@@ -201,6 +201,7 @@ static void fscache_object_state_machine(struct fscache_object *object)
201 } 201 }
202 spin_unlock(&object->lock); 202 spin_unlock(&object->lock);
203 fscache_enqueue_dependents(object); 203 fscache_enqueue_dependents(object);
204 fscache_start_operations(object);
204 goto terminal_transit; 205 goto terminal_transit;
205 206
206 /* handle an abort during initialisation */ 207 /* handle an abort during initialisation */
diff --git a/fs/fscache/page.c b/fs/fscache/page.c
index fc76798bd968..c598ea4c4e7d 100644
--- a/fs/fscache/page.c
+++ b/fs/fscache/page.c
@@ -314,6 +314,43 @@ static int fscache_wait_for_deferred_lookup(struct fscache_cookie *cookie)
314} 314}
315 315
316/* 316/*
317 * wait for an object to become active (or dead)
318 */
319static int fscache_wait_for_retrieval_activation(struct fscache_object *object,
320 struct fscache_retrieval *op,
321 atomic_t *stat_op_waits,
322 atomic_t *stat_object_dead)
323{
324 int ret;
325
326 if (!test_bit(FSCACHE_OP_WAITING, &op->op.flags))
327 goto check_if_dead;
328
329 _debug(">>> WT");
330 fscache_stat(stat_op_waits);
331 if (wait_on_bit(&op->op.flags, FSCACHE_OP_WAITING,
332 fscache_wait_bit_interruptible,
333 TASK_INTERRUPTIBLE) < 0) {
334 ret = fscache_cancel_op(&op->op);
335 if (ret == 0)
336 return -ERESTARTSYS;
337
338 /* it's been removed from the pending queue by another party,
339 * so we should get to run shortly */
340 wait_on_bit(&op->op.flags, FSCACHE_OP_WAITING,
341 fscache_wait_bit, TASK_UNINTERRUPTIBLE);
342 }
343 _debug("<<< GO");
344
345check_if_dead:
346 if (unlikely(fscache_object_is_dead(object))) {
347 fscache_stat(stat_object_dead);
348 return -ENOBUFS;
349 }
350 return 0;
351}
352
353/*
317 * read a page from the cache or allocate a block in which to store it 354 * read a page from the cache or allocate a block in which to store it
318 * - we return: 355 * - we return:
319 * -ENOMEM - out of memory, nothing done 356 * -ENOMEM - out of memory, nothing done
@@ -376,25 +413,12 @@ int __fscache_read_or_alloc_page(struct fscache_cookie *cookie,
376 413
377 /* we wait for the operation to become active, and then process it 414 /* we wait for the operation to become active, and then process it
378 * *here*, in this thread, and not in the thread pool */ 415 * *here*, in this thread, and not in the thread pool */
379 if (test_bit(FSCACHE_OP_WAITING, &op->op.flags)) { 416 ret = fscache_wait_for_retrieval_activation(
380 _debug(">>> WT"); 417 object, op,
381 fscache_stat(&fscache_n_retrieval_op_waits); 418 __fscache_stat(&fscache_n_retrieval_op_waits),
382 if (wait_on_bit(&op->op.flags, FSCACHE_OP_WAITING, 419 __fscache_stat(&fscache_n_retrievals_object_dead));
383 fscache_wait_bit_interruptible, 420 if (ret < 0)
384 TASK_INTERRUPTIBLE) < 0) { 421 goto error;
385 ret = fscache_cancel_op(&op->op);
386 if (ret == 0) {
387 ret = -ERESTARTSYS;
388 goto error;
389 }
390
391 /* it's been removed from the pending queue by another
392 * party, so we should get to run shortly */
393 wait_on_bit(&op->op.flags, FSCACHE_OP_WAITING,
394 fscache_wait_bit, TASK_UNINTERRUPTIBLE);
395 }
396 _debug("<<< GO");
397 }
398 422
399 /* ask the cache to honour the operation */ 423 /* ask the cache to honour the operation */
400 if (test_bit(FSCACHE_COOKIE_NO_DATA_YET, &object->cookie->flags)) { 424 if (test_bit(FSCACHE_COOKIE_NO_DATA_YET, &object->cookie->flags)) {
@@ -506,25 +530,12 @@ int __fscache_read_or_alloc_pages(struct fscache_cookie *cookie,
506 530
507 /* we wait for the operation to become active, and then process it 531 /* we wait for the operation to become active, and then process it
508 * *here*, in this thread, and not in the thread pool */ 532 * *here*, in this thread, and not in the thread pool */
509 if (test_bit(FSCACHE_OP_WAITING, &op->op.flags)) { 533 ret = fscache_wait_for_retrieval_activation(
510 _debug(">>> WT"); 534 object, op,
511 fscache_stat(&fscache_n_retrieval_op_waits); 535 __fscache_stat(&fscache_n_retrieval_op_waits),
512 if (wait_on_bit(&op->op.flags, FSCACHE_OP_WAITING, 536 __fscache_stat(&fscache_n_retrievals_object_dead));
513 fscache_wait_bit_interruptible, 537 if (ret < 0)
514 TASK_INTERRUPTIBLE) < 0) { 538 goto error;
515 ret = fscache_cancel_op(&op->op);
516 if (ret == 0) {
517 ret = -ERESTARTSYS;
518 goto error;
519 }
520
521 /* it's been removed from the pending queue by another
522 * party, so we should get to run shortly */
523 wait_on_bit(&op->op.flags, FSCACHE_OP_WAITING,
524 fscache_wait_bit, TASK_UNINTERRUPTIBLE);
525 }
526 _debug("<<< GO");
527 }
528 539
529 /* ask the cache to honour the operation */ 540 /* ask the cache to honour the operation */
530 if (test_bit(FSCACHE_COOKIE_NO_DATA_YET, &object->cookie->flags)) { 541 if (test_bit(FSCACHE_COOKIE_NO_DATA_YET, &object->cookie->flags)) {
@@ -612,25 +623,12 @@ int __fscache_alloc_page(struct fscache_cookie *cookie,
612 623
613 fscache_stat(&fscache_n_alloc_ops); 624 fscache_stat(&fscache_n_alloc_ops);
614 625
615 if (test_bit(FSCACHE_OP_WAITING, &op->op.flags)) { 626 ret = fscache_wait_for_retrieval_activation(
616 _debug(">>> WT"); 627 object, op,
617 fscache_stat(&fscache_n_alloc_op_waits); 628 __fscache_stat(&fscache_n_alloc_op_waits),
618 if (wait_on_bit(&op->op.flags, FSCACHE_OP_WAITING, 629 __fscache_stat(&fscache_n_allocs_object_dead));
619 fscache_wait_bit_interruptible, 630 if (ret < 0)
620 TASK_INTERRUPTIBLE) < 0) { 631 goto error;
621 ret = fscache_cancel_op(&op->op);
622 if (ret == 0) {
623 ret = -ERESTARTSYS;
624 goto error;
625 }
626
627 /* it's been removed from the pending queue by another
628 * party, so we should get to run shortly */
629 wait_on_bit(&op->op.flags, FSCACHE_OP_WAITING,
630 fscache_wait_bit, TASK_UNINTERRUPTIBLE);
631 }
632 _debug("<<< GO");
633 }
634 632
635 /* ask the cache to honour the operation */ 633 /* ask the cache to honour the operation */
636 fscache_stat(&fscache_n_cop_allocate_page); 634 fscache_stat(&fscache_n_cop_allocate_page);
diff --git a/fs/fscache/stats.c b/fs/fscache/stats.c
index 9e15289eb5c1..05f77caf4a2d 100644
--- a/fs/fscache/stats.c
+++ b/fs/fscache/stats.c
@@ -39,6 +39,7 @@ atomic_t fscache_n_allocs_ok;
39atomic_t fscache_n_allocs_wait; 39atomic_t fscache_n_allocs_wait;
40atomic_t fscache_n_allocs_nobufs; 40atomic_t fscache_n_allocs_nobufs;
41atomic_t fscache_n_allocs_intr; 41atomic_t fscache_n_allocs_intr;
42atomic_t fscache_n_allocs_object_dead;
42atomic_t fscache_n_alloc_ops; 43atomic_t fscache_n_alloc_ops;
43atomic_t fscache_n_alloc_op_waits; 44atomic_t fscache_n_alloc_op_waits;
44 45
@@ -49,6 +50,7 @@ atomic_t fscache_n_retrievals_nodata;
49atomic_t fscache_n_retrievals_nobufs; 50atomic_t fscache_n_retrievals_nobufs;
50atomic_t fscache_n_retrievals_intr; 51atomic_t fscache_n_retrievals_intr;
51atomic_t fscache_n_retrievals_nomem; 52atomic_t fscache_n_retrievals_nomem;
53atomic_t fscache_n_retrievals_object_dead;
52atomic_t fscache_n_retrieval_ops; 54atomic_t fscache_n_retrieval_ops;
53atomic_t fscache_n_retrieval_op_waits; 55atomic_t fscache_n_retrieval_op_waits;
54 56
@@ -188,9 +190,10 @@ static int fscache_stats_show(struct seq_file *m, void *v)
188 atomic_read(&fscache_n_allocs_wait), 190 atomic_read(&fscache_n_allocs_wait),
189 atomic_read(&fscache_n_allocs_nobufs), 191 atomic_read(&fscache_n_allocs_nobufs),
190 atomic_read(&fscache_n_allocs_intr)); 192 atomic_read(&fscache_n_allocs_intr));
191 seq_printf(m, "Allocs : ops=%u owt=%u\n", 193 seq_printf(m, "Allocs : ops=%u owt=%u abt=%u\n",
192 atomic_read(&fscache_n_alloc_ops), 194 atomic_read(&fscache_n_alloc_ops),
193 atomic_read(&fscache_n_alloc_op_waits)); 195 atomic_read(&fscache_n_alloc_op_waits),
196 atomic_read(&fscache_n_allocs_object_dead));
194 197
195 seq_printf(m, "Retrvls: n=%u ok=%u wt=%u nod=%u nbf=%u" 198 seq_printf(m, "Retrvls: n=%u ok=%u wt=%u nod=%u nbf=%u"
196 " int=%u oom=%u\n", 199 " int=%u oom=%u\n",
@@ -201,9 +204,10 @@ static int fscache_stats_show(struct seq_file *m, void *v)
201 atomic_read(&fscache_n_retrievals_nobufs), 204 atomic_read(&fscache_n_retrievals_nobufs),
202 atomic_read(&fscache_n_retrievals_intr), 205 atomic_read(&fscache_n_retrievals_intr),
203 atomic_read(&fscache_n_retrievals_nomem)); 206 atomic_read(&fscache_n_retrievals_nomem));
204 seq_printf(m, "Retrvls: ops=%u owt=%u\n", 207 seq_printf(m, "Retrvls: ops=%u owt=%u abt=%u\n",
205 atomic_read(&fscache_n_retrieval_ops), 208 atomic_read(&fscache_n_retrieval_ops),
206 atomic_read(&fscache_n_retrieval_op_waits)); 209 atomic_read(&fscache_n_retrieval_op_waits),
210 atomic_read(&fscache_n_retrievals_object_dead));
207 211
208 seq_printf(m, "Stores : n=%u ok=%u agn=%u nbf=%u oom=%u\n", 212 seq_printf(m, "Stores : n=%u ok=%u agn=%u nbf=%u oom=%u\n",
209 atomic_read(&fscache_n_stores), 213 atomic_read(&fscache_n_stores),
diff --git a/include/linux/fscache-cache.h b/include/linux/fscache-cache.h
index 4750d5fb419f..907bb56c5888 100644
--- a/include/linux/fscache-cache.h
+++ b/include/linux/fscache-cache.h
@@ -404,6 +404,10 @@ extern const char *fscache_object_states[];
404 (obj)->state >= FSCACHE_OBJECT_AVAILABLE && \ 404 (obj)->state >= FSCACHE_OBJECT_AVAILABLE && \
405 (obj)->state < FSCACHE_OBJECT_DYING) 405 (obj)->state < FSCACHE_OBJECT_DYING)
406 406
407#define fscache_object_is_dead(obj) \
408 (test_bit(FSCACHE_IOERROR, &(obj)->cache->flags) && \
409 (obj)->state >= FSCACHE_OBJECT_DYING)
410
407extern const struct slow_work_ops fscache_object_slow_work_ops; 411extern const struct slow_work_ops fscache_object_slow_work_ops;
408 412
409/** 413/**