aboutsummaryrefslogtreecommitdiffstats
path: root/fs/fscache
diff options
context:
space:
mode:
authorDavid Howells <dhowells@redhat.com>2009-11-19 13:11:32 -0500
committerDavid Howells <dhowells@redhat.com>2009-11-19 13:11:32 -0500
commite3d4d28b1c8cc7c26536a50b43d86ccd39878550 (patch)
tree23f6dacd5ffdf6c6d01c411517855a41405381b9 /fs/fscache
parent285e728b0ac55b53a673114096168d6f74930167 (diff)
FS-Cache: Handle read request vs lookup, creation or other cache failure
FS-Cache doesn't correctly handle the netfs requesting a read from the cache on an object that failed or was withdrawn by the cache. A trace similar to the following might be seen: CacheFiles: Lookup failed error -105 [exe ] unexpected submission OP165afe [OBJ6cac OBJECT_LC_DYING] [exe ] objstate=OBJECT_LC_DYING [OBJECT_LC_DYING] [exe ] objflags=0 [exe ] objevent=9 [fffffffffffffffb] [exe ] ops=0 inp=0 exc=0 Pid: 6970, comm: exe Not tainted 2.6.32-rc6-cachefs #50 Call Trace: [<ffffffffa0076477>] fscache_submit_op+0x3ff/0x45a [fscache] [<ffffffffa0077997>] __fscache_read_or_alloc_pages+0x187/0x3c4 [fscache] [<ffffffffa00b6480>] ? nfs_readpage_from_fscache_complete+0x0/0x66 [nfs] [<ffffffffa00b6388>] __nfs_readpages_from_fscache+0x7e/0x176 [nfs] [<ffffffff8108e483>] ? __alloc_pages_nodemask+0x11c/0x5cf [<ffffffffa009d796>] nfs_readpages+0x114/0x1d7 [nfs] [<ffffffff81090314>] __do_page_cache_readahead+0x15f/0x1ec [<ffffffff81090228>] ? __do_page_cache_readahead+0x73/0x1ec [<ffffffff810903bd>] ra_submit+0x1c/0x20 [<ffffffff810906bb>] ondemand_readahead+0x227/0x23a [<ffffffff81090762>] page_cache_sync_readahead+0x17/0x19 [<ffffffff8108a99e>] generic_file_aio_read+0x236/0x5a0 [<ffffffffa00937bd>] nfs_file_read+0xe4/0xf3 [nfs] [<ffffffff810b2fa2>] do_sync_read+0xe3/0x120 [<ffffffff81354cc3>] ? _spin_unlock_irq+0x2b/0x31 [<ffffffff8104c0f1>] ? autoremove_wake_function+0x0/0x34 [<ffffffff811848e5>] ? selinux_file_permission+0x5d/0x10f [<ffffffff81352bdb>] ? thread_return+0x3e/0x101 [<ffffffff8117d7b0>] ? security_file_permission+0x11/0x13 [<ffffffff810b3b06>] vfs_read+0xaa/0x16f [<ffffffff81058df0>] ? trace_hardirqs_on_caller+0x10c/0x130 [<ffffffff810b3c84>] sys_read+0x45/0x6c [<ffffffff8100ae2b>] system_call_fastpath+0x16/0x1b The object state might also be OBJECT_DYING or OBJECT_WITHDRAWING. This should be handled by simply rejecting the new operation with ENOBUFS. There's no need to log an error for it. Events of this type now appear in the stats file under Ops:rej. Signed-off-by: David Howells <dhowells@redhat.com>
Diffstat (limited to 'fs/fscache')
-rw-r--r--fs/fscache/internal.h1
-rw-r--r--fs/fscache/operation.c5
-rw-r--r--fs/fscache/stats.c6
3 files changed, 10 insertions, 2 deletions
diff --git a/fs/fscache/internal.h b/fs/fscache/internal.h
index ba1853fa1ff9..a0769872b19c 100644
--- a/fs/fscache/internal.h
+++ b/fs/fscache/internal.h
@@ -143,6 +143,7 @@ extern atomic_t fscache_n_op_deferred_release;
143extern atomic_t fscache_n_op_release; 143extern atomic_t fscache_n_op_release;
144extern atomic_t fscache_n_op_gc; 144extern atomic_t fscache_n_op_gc;
145extern atomic_t fscache_n_op_cancelled; 145extern atomic_t fscache_n_op_cancelled;
146extern atomic_t fscache_n_op_rejected;
146 147
147extern atomic_t fscache_n_attr_changed; 148extern atomic_t fscache_n_attr_changed;
148extern atomic_t fscache_n_attr_changed_ok; 149extern atomic_t fscache_n_attr_changed_ok;
diff --git a/fs/fscache/operation.c b/fs/fscache/operation.c
index 296492efb81b..313e79a14266 100644
--- a/fs/fscache/operation.c
+++ b/fs/fscache/operation.c
@@ -232,6 +232,11 @@ int fscache_submit_op(struct fscache_object *object,
232 list_add_tail(&op->pend_link, &object->pending_ops); 232 list_add_tail(&op->pend_link, &object->pending_ops);
233 fscache_stat(&fscache_n_op_pend); 233 fscache_stat(&fscache_n_op_pend);
234 ret = 0; 234 ret = 0;
235 } else if (object->state == FSCACHE_OBJECT_DYING ||
236 object->state == FSCACHE_OBJECT_LC_DYING ||
237 object->state == FSCACHE_OBJECT_WITHDRAWING) {
238 fscache_stat(&fscache_n_op_rejected);
239 ret = -ENOBUFS;
235 } else if (!test_bit(FSCACHE_IOERROR, &object->cache->flags)) { 240 } else if (!test_bit(FSCACHE_IOERROR, &object->cache->flags)) {
236 fscache_report_unexpected_submission(object, op, ostate); 241 fscache_report_unexpected_submission(object, op, ostate);
237 ASSERT(!fscache_object_is_active(object)); 242 ASSERT(!fscache_object_is_active(object));
diff --git a/fs/fscache/stats.c b/fs/fscache/stats.c
index 1d53ea68409e..045ba396dbf2 100644
--- a/fs/fscache/stats.c
+++ b/fs/fscache/stats.c
@@ -26,6 +26,7 @@ atomic_t fscache_n_op_deferred_release;
26atomic_t fscache_n_op_release; 26atomic_t fscache_n_op_release;
27atomic_t fscache_n_op_gc; 27atomic_t fscache_n_op_gc;
28atomic_t fscache_n_op_cancelled; 28atomic_t fscache_n_op_cancelled;
29atomic_t fscache_n_op_rejected;
29 30
30atomic_t fscache_n_attr_changed; 31atomic_t fscache_n_attr_changed;
31atomic_t fscache_n_attr_changed_ok; 32atomic_t fscache_n_attr_changed_ok;
@@ -210,11 +211,12 @@ static int fscache_stats_show(struct seq_file *m, void *v)
210 atomic_read(&fscache_n_store_radix_deletes), 211 atomic_read(&fscache_n_store_radix_deletes),
211 atomic_read(&fscache_n_store_pages_over_limit)); 212 atomic_read(&fscache_n_store_pages_over_limit));
212 213
213 seq_printf(m, "Ops : pend=%u run=%u enq=%u can=%u\n", 214 seq_printf(m, "Ops : pend=%u run=%u enq=%u can=%u rej=%u\n",
214 atomic_read(&fscache_n_op_pend), 215 atomic_read(&fscache_n_op_pend),
215 atomic_read(&fscache_n_op_run), 216 atomic_read(&fscache_n_op_run),
216 atomic_read(&fscache_n_op_enqueue), 217 atomic_read(&fscache_n_op_enqueue),
217 atomic_read(&fscache_n_op_cancelled)); 218 atomic_read(&fscache_n_op_cancelled),
219 atomic_read(&fscache_n_op_rejected));
218 seq_printf(m, "Ops : dfr=%u rel=%u gc=%u\n", 220 seq_printf(m, "Ops : dfr=%u rel=%u gc=%u\n",
219 atomic_read(&fscache_n_op_deferred_release), 221 atomic_read(&fscache_n_op_deferred_release),
220 atomic_read(&fscache_n_op_release), 222 atomic_read(&fscache_n_op_release),