Skip to content

Commit

Permalink
cachefiles: unmark inode in use in error path
Browse files Browse the repository at this point in the history
Unmark inode in use if error encountered. If the in-use flag leakage
occurs in cachefiles_open_file(), Cachefiles will complain "Inode
already in use" when later another cookie with the same index key is
looked up.

If the in-use flag leakage occurs in cachefiles_create_tmpfile(), though
the "Inode already in use" warning won't be triggered, fix the leakage
anyway.

Reported-by: Gao Xiang <hsiangkao@linux.alibaba.com>
Fixes: 1f08c92 ("cachefiles: Implement backing file wrangling")
Signed-off-by: Jeffle Xu <jefflexu@linux.alibaba.com>
  • Loading branch information
lostjeffle committed Mar 31, 2022
1 parent e8b767f commit 3c71705
Showing 1 changed file with 24 additions and 9 deletions.
33 changes: 24 additions & 9 deletions fs/cachefiles/namei.c
Expand Up @@ -57,6 +57,16 @@ static void __cachefiles_unmark_inode_in_use(struct cachefiles_object *object,
trace_cachefiles_mark_inactive(object, inode);
}

static void cachefiles_do_unmark_inode_in_use(struct cachefiles_object *object,
struct dentry *dentry)
{
struct inode *inode = d_backing_inode(dentry);

inode_lock(inode);
__cachefiles_unmark_inode_in_use(object, dentry);
inode_unlock(inode);
}

/*
* Unmark a backing inode and tell cachefilesd that there's something that can
* be culled.
Expand All @@ -68,9 +78,7 @@ void cachefiles_unmark_inode_in_use(struct cachefiles_object *object,
struct inode *inode = file_inode(file);

if (inode) {
inode_lock(inode);
__cachefiles_unmark_inode_in_use(object, file->f_path.dentry);
inode_unlock(inode);
cachefiles_do_unmark_inode_in_use(object, file->f_path.dentry);

if (!test_bit(CACHEFILES_OBJECT_USING_TMPFILE, &object->flags)) {
atomic_long_add(inode->i_blocks, &cache->b_released);
Expand Down Expand Up @@ -484,7 +492,7 @@ struct file *cachefiles_create_tmpfile(struct cachefiles_object *object)
object, d_backing_inode(path.dentry), ret,
cachefiles_trace_trunc_error);
file = ERR_PTR(ret);
goto out_dput;
goto out_unuse;
}
}

Expand All @@ -494,15 +502,20 @@ struct file *cachefiles_create_tmpfile(struct cachefiles_object *object)
trace_cachefiles_vfs_error(object, d_backing_inode(path.dentry),
PTR_ERR(file),
cachefiles_trace_open_error);
goto out_dput;
goto out_unuse;
}
if (unlikely(!file->f_op->read_iter) ||
unlikely(!file->f_op->write_iter)) {
fput(file);
pr_notice("Cache does not support read_iter and write_iter\n");
file = ERR_PTR(-EINVAL);
goto out_unuse;
}

goto out_dput;

out_unuse:
cachefiles_do_unmark_inode_in_use(object, path.dentry);
out_dput:
dput(path.dentry);
out:
Expand Down Expand Up @@ -590,14 +603,16 @@ static bool cachefiles_open_file(struct cachefiles_object *object,
check_failed:
fscache_cookie_lookup_negative(object->cookie);
cachefiles_unmark_inode_in_use(object, file);
if (ret == -ESTALE) {
fput(file);
dput(dentry);
fput(file);
dput(dentry);
if (ret == -ESTALE)
return cachefiles_create_file(object);
}
return false;

error_fput:
fput(file);
error:
cachefiles_do_unmark_inode_in_use(object, dentry);
dput(dentry);
return false;
}
Expand Down

0 comments on commit 3c71705

Please sign in to comment.