Skip to content

Commit e3d4d28

Browse files
committed
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 torvalds#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>
1 parent 285e728 commit e3d4d28

File tree

4 files changed

+11
-2
lines changed

4 files changed

+11
-2
lines changed

Documentation/filesystems/caching/fscache.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -276,6 +276,7 @@ proc files.
276276
run=N Number of times async ops given CPU time
277277
enq=N Number of times async ops queued for processing
278278
can=N Number of async ops cancelled
279+
rej=N Number of async ops rejected due to object lookup/create failure
279280
dfr=N Number of async ops queued for deferred release
280281
rel=N Number of async ops released
281282
gc=N Number of deferred-release async ops garbage collected

fs/fscache/internal.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,7 @@ extern atomic_t fscache_n_op_deferred_release;
143143
extern atomic_t fscache_n_op_release;
144144
extern atomic_t fscache_n_op_gc;
145145
extern atomic_t fscache_n_op_cancelled;
146+
extern atomic_t fscache_n_op_rejected;
146147

147148
extern atomic_t fscache_n_attr_changed;
148149
extern atomic_t fscache_n_attr_changed_ok;

fs/fscache/operation.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,11 @@ int fscache_submit_op(struct fscache_object *object,
232232
list_add_tail(&op->pend_link, &object->pending_ops);
233233
fscache_stat(&fscache_n_op_pend);
234234
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;
235240
} else if (!test_bit(FSCACHE_IOERROR, &object->cache->flags)) {
236241
fscache_report_unexpected_submission(object, op, ostate);
237242
ASSERT(!fscache_object_is_active(object));

fs/fscache/stats.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ atomic_t fscache_n_op_deferred_release;
2626
atomic_t fscache_n_op_release;
2727
atomic_t fscache_n_op_gc;
2828
atomic_t fscache_n_op_cancelled;
29+
atomic_t fscache_n_op_rejected;
2930

3031
atomic_t fscache_n_attr_changed;
3132
atomic_t fscache_n_attr_changed_ok;
@@ -210,11 +211,12 @@ static int fscache_stats_show(struct seq_file *m, void *v)
210211
atomic_read(&fscache_n_store_radix_deletes),
211212
atomic_read(&fscache_n_store_pages_over_limit));
212213

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",
214215
atomic_read(&fscache_n_op_pend),
215216
atomic_read(&fscache_n_op_run),
216217
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));
218220
seq_printf(m, "Ops : dfr=%u rel=%u gc=%u\n",
219221
atomic_read(&fscache_n_op_deferred_release),
220222
atomic_read(&fscache_n_op_release),

0 commit comments

Comments
 (0)