[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <153080828373.5496.13488467818713940417.stgit@warthog.procyon.org.uk>
Date: Thu, 05 Jul 2018 17:31:23 +0100
From: David Howells <dhowells@...hat.com>
To: linux-cachefs@...hat.com
Cc: kiran.modukuri@...il.com, carmark.dlut@...il.com,
vegard.nossum@...il.com, linux-kernel@...r.kernel.org,
neilb@...e.com, aderobertis@...rics.net, dhowells@...hat.com,
dja@...ens.net
Subject: [PATCH 3/4] cachefiles: Fix missing clear of the
CACHEFILES_OBJECT_ACTIVE flag
From: KiranKumar Modukuri <kiran.modukuri@...il.com>
In cachefiles_mark_object_active(), the new object is marked active and
then we try to add it to the active object tree. If a conflicting object
is already present, we want to wait for that to go away. After the wait,
we go round again and try to re-mark the object as being active - but it's
already marked active from the first time we went through and a BUG is
issued.
Fix this by clearing the CACHEFILES_OBJECT_ACTIVE flag before we try again.
Analysis from Kiran Kumar Modukuri:
[Impact]
Oops during heavy NFS + FSCache + Cachefiles
CacheFiles: Error: Overlong wait for old active object to go away.
BUG: unable to handle kernel NULL pointer dereference at 0000000000000002
CacheFiles: Error: Object already active kernel BUG at
fs/cachefiles/namei.c:163!
[Cause]
In a heavily loaded system with big files being read and truncated, an
fscache object for a cookie is being dropped and a new object being
looked. The new object being looked for has to wait for the old object
to go away before the new object is moved to active state.
[Fix]
Clear the flag 'CACHEFILES_OBJECT_ACTIVE' for the new object when
retrying the object lookup.
[Testcase]
Have run ~100 hours of NFS stress tests and have not seen this bug recur.
[Regression Potential]
- Limited to fscache/cachefiles.
Signed-off-by: Kiran Kumar Modukuri <kiran.modukuri@...il.com>
Signed-off-by: David Howells <dhowells@...hat.com>
---
fs/cachefiles/namei.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/fs/cachefiles/namei.c b/fs/cachefiles/namei.c
index ab0bbe93b398..b5d6dd72dfa0 100644
--- a/fs/cachefiles/namei.c
+++ b/fs/cachefiles/namei.c
@@ -186,6 +186,7 @@ static int cachefiles_mark_object_active(struct cachefiles_cache *cache,
* need to wait for it to be destroyed */
wait_for_old_object:
trace_cachefiles_wait_active(object, dentry, xobject);
+ clear_bit(CACHEFILES_OBJECT_ACTIVE, &object->flags);
if (fscache_object_is_live(&xobject->fscache)) {
pr_err("\n");
@@ -248,7 +249,6 @@ static int cachefiles_mark_object_active(struct cachefiles_cache *cache,
goto try_again;
requeue:
- clear_bit(CACHEFILES_OBJECT_ACTIVE, &object->flags);
cache->cache.ops->put_object(&xobject->fscache, cachefiles_obj_put_wait_timeo);
_leave(" = -ETIMEDOUT");
return -ETIMEDOUT;
Powered by blists - more mailing lists