diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-10-14 08:40:15 +0200 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-10-14 08:40:15 +0200 |
commit | 1b5a5f59e3435337bede67b9255bbb1d39fc4827 (patch) | |
tree | c604f571dcc7bb26dfe5498eb920873248639c62 | |
parent | b11445f830df0ec9271f39bff19ecc6f8db58eb8 (diff) | |
parent | d5d962265d99088ce96480db3e61358d7170e24c (diff) |
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
-rw-r--r-- | fs/cachefiles/interface.c | 33 | ||||
-rw-r--r-- | fs/cachefiles/namei.c | 2 | ||||
-rw-r--r-- | fs/fscache/object-list.c | 16 |
3 files changed, 23 insertions, 28 deletions
diff --git a/fs/cachefiles/interface.c b/fs/cachefiles/interface.c index 584743d456c..1c7293c3a93 100644 --- a/fs/cachefiles/interface.c +++ b/fs/cachefiles/interface.c @@ -268,20 +268,27 @@ 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 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 dad7d9542a2..e12f189d539 100644 --- a/fs/cachefiles/namei.c +++ b/fs/cachefiles/namei.c @@ -189,7 +189,7 @@ try_again: /* 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 b8179ca6bf9..51dde817e1f 100644 --- a/fs/fscache/object-list.c +++ b/fs/fscache/object-list.c @@ -380,26 +380,14 @@ no_config: 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; } |