[Linux-cachefs] PROBLEM: ASSERT(object->dentry) fails in cachefiles_delete_object()
David Howells
dhowells at redhat.com
Wed Sep 17 21:34:43 UTC 2014
Manuel Schölling <manuel.schoelling at gmx.de> wrote:
> #5 [ffff880575a03d80] cachefiles_delete_object at ffffffffa0433d4d
> [cachefiles]
> #6 [ffff880575a03da0] cachefiles_drop_object at ffffffffa043280f
> [cachefiles]
> #7 [ffff880575a03dc0] fscache_drop_object at ffffffffa02ac511 [fscache]
> #8 [ffff880575a03df0] fscache_object_work_func at ffffffffa02ac697
> [fscache]
Okay, we're in the DROP_OBJECT state. This cleans the object memory record up
before we free it and saves any data and metadata to the backing device or
deletes the object if retired.
> dentry = 0x0,
> backer = 0x0,
To get here with object->dentry set to NULL, I think we must've got to the
DROP_OBJECT state from one of the following states:
STATE TRANSITION PATH
============= ===========================
WAIT_FOR_INIT oob via ABORT_INIT
INIT_OBJECT directly
WAIT_FOR_PARENT oob via ABORT_INIT
PARENT_READY oob via ABORT_INIT
LOOKUP_OBJECT directly via LOOKUP_FAILURE
CREATE_OBJECT directly via LOOKUP_FAILURE
The object->dentry pointer is:
(1) set in cachefiles_walk_to_object(), which is called from
cachefiles_lookup_object();
(2) cleared in cachefiles_walk_to_object() upon failure; and
(3) cleared in cachefiles_drop_object() after the call to
cachefiles_delete_object() - in which the crash happened.
object->dentry is NULL, which suggests that we either haven't started the
on-disk object lookup/creation process yet or we did start it and we failed at
it. Either way, we go via DROP_OBJECT to clean up with a NULL dentry pointer.
> flags = 64,
FSCACHE_OBJECT_RETIRED is set in cachefiles->fscache.flags which suggest that
the file may have been obsoleted before we finished setting it up - maybe we
were still waiting for the parent object to be created on disk.
So, what I think is probably happening is that the object is being obsoleted
by the netfs before we manage to finish setting it up.
Does the attached patch help?
David
---
commit eac30680e912d223841dfc220824b53446bdf235
Author: David Howells <dhowells at redhat.com>
Date: Wed Sep 17 22:24:18 2014 +0100
CacheFiles: Handle object being killed before being set up
diff --git a/fs/cachefiles/interface.c b/fs/cachefiles/interface.c
index 584743d456c3..94fe77b5dd99 100644
--- a/fs/cachefiles/interface.c
+++ b/fs/cachefiles/interface.c
@@ -268,20 +268,26 @@ static void cachefiles_drop_object(struct fscache_object *_object)
ASSERT((atomic_read(&object->usage) & 0xffff0000) != 0x6b6b0000);
#endif
- /* delete retired objects */
- if (test_bit(FSCACHE_OBJECT_RETIRED, &object->fscache.flags) &&
- _object != cache->cache.fsdef
- ) {
- _debug("- retire object OBJ%x", object->fscache.debug_id);
- cachefiles_begin_secure(cache, &saved_cred);
- cachefiles_delete_object(cache, object);
- cachefiles_end_secure(cache, saved_cred);
- }
+ /* We need to tidy the object up if we did in fact manage to open it.
+ * It's possible for us to get here before the object is fully
+ * initialised if the parent goes away.
+ */
+ if (object->dentry) {
+ /* delete retired objects */
+ if (test_bit(FSCACHE_OBJECT_RETIRED, &object->fscache.flags) &&
+ _object != cache->cache.fsdef
+ ) {
+ _debug("- retire object OBJ%x", object->fscache.debug_id);
+ cachefiles_begin_secure(cache, &saved_cred);
+ cachefiles_delete_object(cache, object);
+ cachefiles_end_secure(cache, saved_cred);
+ }
- /* close the filesystem stuff attached to the object */
- if (object->backer != object->dentry)
- dput(object->backer);
- object->backer = NULL;
+ /* close the filesystem stuff attached to the object */
+ if (object->backer != object->dentry)
+ dput(object->backer);
+ object->backer = NULL;
+ }
/* note that the object is now inactive */
if (test_bit(CACHEFILES_OBJECT_ACTIVE, &object->flags)) {
More information about the Linux-cachefs
mailing list