summaryrefslogtreecommitdiff
path: root/fs/f2fs/acl.c
diff options
context:
space:
mode:
authorChao Yu <chao2.yu@samsung.com>2015-04-18 13:03:58 +0300
committerJaegeuk Kim <jaegeuk@kernel.org>2015-05-07 21:38:31 +0300
commit272e083f7a968bc81dd01e4f16860a1e9617d454 (patch)
tree64cff853b2789f18fed41884641d0c0770ac1978 /fs/f2fs/acl.c
parent5d799881391277e52787df06bafe865e91ae8296 (diff)
downloadlinux-272e083f7a968bc81dd01e4f16860a1e9617d454.tar.xz
f2fs: make posix_acl_create() safer and cleaner
Our f2fs_acl_create is copied from posix_acl_create in ./fs/posix_acl.c and modified to avoid deadlock bug when inline_dentry feature is enabled. Dan Carpenter rewrites posix_acl_create in commit 2799563b281f ("fs/posix_acl.c: make posix_acl_create() safer and cleaner") to make this function more safer, so that we can avoid potential bug in its caller, especially for ocfs2. Let's back port the patch to f2fs. Signed-off-by: Chao Yu <chao2.yu@samsung.com> Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
Diffstat (limited to 'fs/f2fs/acl.c')
-rw-r--r--fs/f2fs/acl.c46
1 files changed, 20 insertions, 26 deletions
diff --git a/fs/f2fs/acl.c b/fs/f2fs/acl.c
index 4320ffab3495..c8f25f7241f0 100644
--- a/fs/f2fs/acl.c
+++ b/fs/f2fs/acl.c
@@ -334,51 +334,45 @@ static int f2fs_acl_create(struct inode *dir, umode_t *mode,
struct page *dpage)
{
struct posix_acl *p;
+ struct posix_acl *clone;
int ret;
+ *acl = NULL;
+ *default_acl = NULL;
+
if (S_ISLNK(*mode) || !IS_POSIXACL(dir))
- goto no_acl;
+ return 0;
p = __f2fs_get_acl(dir, ACL_TYPE_DEFAULT, dpage);
- if (IS_ERR(p)) {
- if (p == ERR_PTR(-EOPNOTSUPP))
- goto apply_umask;
- return PTR_ERR(p);
+ if (!p || p == ERR_PTR(-EOPNOTSUPP)) {
+ *mode &= ~current_umask();
+ return 0;
}
+ if (IS_ERR(p))
+ return PTR_ERR(p);
- if (!p)
- goto apply_umask;
-
- *acl = f2fs_acl_clone(p, GFP_NOFS);
- if (!*acl)
+ clone = f2fs_acl_clone(p, GFP_NOFS);
+ if (!clone)
goto no_mem;
- ret = f2fs_acl_create_masq(*acl, mode);
+ ret = f2fs_acl_create_masq(clone, mode);
if (ret < 0)
goto no_mem_clone;
- if (ret == 0) {
- posix_acl_release(*acl);
- *acl = NULL;
- }
+ if (ret == 0)
+ posix_acl_release(clone);
+ else
+ *acl = clone;
- if (!S_ISDIR(*mode)) {
+ if (!S_ISDIR(*mode))
posix_acl_release(p);
- *default_acl = NULL;
- } else {
+ else
*default_acl = p;
- }
- return 0;
-apply_umask:
- *mode &= ~current_umask();
-no_acl:
- *default_acl = NULL;
- *acl = NULL;
return 0;
no_mem_clone:
- posix_acl_release(*acl);
+ posix_acl_release(clone);
no_mem:
posix_acl_release(p);
return -ENOMEM;