diff options
author | Milosz Tanski <milosz@adfin.com> | 2014-08-13 12:58:26 -0400 |
---|---|---|
committer | David Howells <dhowells@redhat.com> | 2014-09-17 17:41:40 -0400 |
commit | 3e1199dcad004a40b55297a4736ccd1b9b81a952 (patch) | |
tree | 89789228bb9fae2ebfcc0c7c1ff593c8718f9ec9 /fs | |
parent | 920bce20d74817bdd8bfcbc28ecb1179c9e01081 (diff) |
FS-Cache: refcount becomes corrupt under vma pressure.
In rare cases under heavy VMA pressure the ref count for a fscache cookie
becomes corrupt. In this case we decrement ref count even if we fail before
incrementing the refcount.
FS-Cache: Assertion failed bnode-eca5f9c6/syslog
0 > 0 is false
------------[ cut here ]------------
kernel BUG at fs/fscache/cookie.c:519!
invalid opcode: 0000 [#1] SMP
Call Trace:
[<ffffffffa01ba060>] __fscache_relinquish_cookie+0x50/0x220 [fscache]
[<ffffffffa02d64ce>] ceph_fscache_unregister_inode_cookie+0x3e/0x50 [ceph]
[<ffffffffa02ae1d3>] ceph_destroy_inode+0x33/0x200 [ceph]
[<ffffffff811cf67e>] ? __fsnotify_inode_delete+0xe/0x10
[<ffffffff811a9e0c>] destroy_inode+0x3c/0x70
[<ffffffff811a9f51>] evict+0x111/0x180
[<ffffffff811aa763>] iput+0x103/0x190
[<ffffffff811a5de8>] __dentry_kill+0x1c8/0x220
[<ffffffff811a5f31>] shrink_dentry_list+0xf1/0x250
[<ffffffff811a762c>] prune_dcache_sb+0x4c/0x60
[<ffffffff811930af>] super_cache_scan+0xff/0x170
[<ffffffff8113d7a0>] shrink_slab_node+0x140/0x2c0
[<ffffffff8113f2da>] shrink_slab+0x8a/0x130
[<ffffffff81142572>] balance_pgdat+0x3e2/0x5d0
[<ffffffff811428ca>] kswapd+0x16a/0x4a0
[<ffffffff810a43f0>] ? __wake_up_sync+0x20/0x20
[<ffffffff81142760>] ? balance_pgdat+0x5d0/0x5d0
[<ffffffff81083e09>] kthread+0xc9/0xe0
[<ffffffff81010000>] ? ftrace_raw_event_xen_mmu_release_ptpage+0x70/0x90
[<ffffffff81083d40>] ? flush_kthread_worker+0xb0/0xb0
[<ffffffff8159f63c>] ret_from_fork+0x7c/0xb0
[<ffffffff81083d40>] ? flush_kthread_worker+0xb0/0xb0
RIP [<ffffffffa01b984b>] __fscache_disable_cookie+0x1db/0x210 [fscache]
RSP <ffff8803bc85f9b8>
---[ end trace 254d0d7c74a01f25 ]---
Signed-off-by: Milosz Tanski <milosz@adfin.com>
Signed-off-by: David Howells <dhowells@redhat.com>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/fscache/page.c | 7 |
1 files changed, 4 insertions, 3 deletions
diff --git a/fs/fscache/page.c b/fs/fscache/page.c index 781ac7b0b53e..de33b3fccca6 100644 --- a/fs/fscache/page.c +++ b/fs/fscache/page.c | |||
@@ -198,7 +198,7 @@ int __fscache_attr_changed(struct fscache_cookie *cookie) | |||
198 | { | 198 | { |
199 | struct fscache_operation *op; | 199 | struct fscache_operation *op; |
200 | struct fscache_object *object; | 200 | struct fscache_object *object; |
201 | bool wake_cookie; | 201 | bool wake_cookie = false; |
202 | 202 | ||
203 | _enter("%p", cookie); | 203 | _enter("%p", cookie); |
204 | 204 | ||
@@ -228,15 +228,16 @@ int __fscache_attr_changed(struct fscache_cookie *cookie) | |||
228 | 228 | ||
229 | __fscache_use_cookie(cookie); | 229 | __fscache_use_cookie(cookie); |
230 | if (fscache_submit_exclusive_op(object, op) < 0) | 230 | if (fscache_submit_exclusive_op(object, op) < 0) |
231 | goto nobufs; | 231 | goto nobufs_dec; |
232 | spin_unlock(&cookie->lock); | 232 | spin_unlock(&cookie->lock); |
233 | fscache_stat(&fscache_n_attr_changed_ok); | 233 | fscache_stat(&fscache_n_attr_changed_ok); |
234 | fscache_put_operation(op); | 234 | fscache_put_operation(op); |
235 | _leave(" = 0"); | 235 | _leave(" = 0"); |
236 | return 0; | 236 | return 0; |
237 | 237 | ||
238 | nobufs: | 238 | nobufs_dec: |
239 | wake_cookie = __fscache_unuse_cookie(cookie); | 239 | wake_cookie = __fscache_unuse_cookie(cookie); |
240 | nobufs: | ||
240 | spin_unlock(&cookie->lock); | 241 | spin_unlock(&cookie->lock); |
241 | kfree(op); | 242 | kfree(op); |
242 | if (wake_cookie) | 243 | if (wake_cookie) |