Merge tag 'fscache-fixes-20141013' of git://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs
Pull fs-cache fixes from David Howells:
"Two fixes for bugs in CacheFiles and a cleanup in FS-Cache"
* tag 'fscache-fixes-20141013' of git://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs:
fs/fscache/object-list.c: use __seq_open_private()
CacheFiles: Fix incorrect test for in-memory object collision
CacheFiles: Handle object being killed before being set up
diff --git a/fs/cachefiles/interface.c b/fs/cachefiles/interface.c
index 584743d..1c7293c 100644
--- a/fs/cachefiles/interface.c
+++ b/fs/cachefiles/interface.c
@@ -268,20 +268,27 @@
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 or the object gets retired
+ * before we set it up.
+ */
+ 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)) {
diff --git a/fs/cachefiles/namei.c b/fs/cachefiles/namei.c
index dad7d95..e12f189 100644
--- a/fs/cachefiles/namei.c
+++ b/fs/cachefiles/namei.c
@@ -189,7 +189,7 @@
/* an old object from a previous incarnation is hogging the slot - we
* need to wait for it to be destroyed */
wait_for_old_object:
- if (fscache_object_is_live(&object->fscache)) {
+ if (fscache_object_is_live(&xobject->fscache)) {
pr_err("\n");
pr_err("Error: Unexpected object collision\n");
cachefiles_printk_object(object, xobject);
diff --git a/fs/fscache/object-list.c b/fs/fscache/object-list.c
index b8179ca..51dde81 100644
--- a/fs/fscache/object-list.c
+++ b/fs/fscache/object-list.c
@@ -380,26 +380,14 @@
static int fscache_objlist_open(struct inode *inode, struct file *file)
{
struct fscache_objlist_data *data;
- struct seq_file *m;
- int ret;
- ret = seq_open(file, &fscache_objlist_ops);
- if (ret < 0)
- return ret;
-
- m = file->private_data;
-
- /* buffer for key extraction */
- data = kmalloc(sizeof(struct fscache_objlist_data), GFP_KERNEL);
- if (!data) {
- seq_release(inode, file);
+ data = __seq_open_private(file, &fscache_objlist_ops, sizeof(*data));
+ if (!data)
return -ENOMEM;
- }
/* get the configuration key */
fscache_objlist_config(data);
- m->private = data;
return 0;
}