Commit 272e083f authored by Chao Yu's avatar Chao Yu Committed by Jaegeuk Kim

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: default avatarChao Yu <chao2.yu@samsung.com>
Signed-off-by: default avatarJaegeuk Kim <jaegeuk@kernel.org>
parent 5d799881
...@@ -334,51 +334,45 @@ static int f2fs_acl_create(struct inode *dir, umode_t *mode, ...@@ -334,51 +334,45 @@ static int f2fs_acl_create(struct inode *dir, umode_t *mode,
struct page *dpage) struct page *dpage)
{ {
struct posix_acl *p; struct posix_acl *p;
struct posix_acl *clone;
int ret; int ret;
*acl = NULL;
*default_acl = NULL;
if (S_ISLNK(*mode) || !IS_POSIXACL(dir)) if (S_ISLNK(*mode) || !IS_POSIXACL(dir))
goto no_acl; return 0;
p = __f2fs_get_acl(dir, ACL_TYPE_DEFAULT, dpage); p = __f2fs_get_acl(dir, ACL_TYPE_DEFAULT, dpage);
if (IS_ERR(p)) { if (!p || p == ERR_PTR(-EOPNOTSUPP)) {
if (p == ERR_PTR(-EOPNOTSUPP)) *mode &= ~current_umask();
goto apply_umask; return 0;
return PTR_ERR(p);
} }
if (IS_ERR(p))
return PTR_ERR(p);
if (!p) clone = f2fs_acl_clone(p, GFP_NOFS);
goto apply_umask; if (!clone)
*acl = f2fs_acl_clone(p, GFP_NOFS);
if (!*acl)
goto no_mem; goto no_mem;
ret = f2fs_acl_create_masq(*acl, mode); ret = f2fs_acl_create_masq(clone, mode);
if (ret < 0) if (ret < 0)
goto no_mem_clone; goto no_mem_clone;
if (ret == 0) { if (ret == 0)
posix_acl_release(*acl); posix_acl_release(clone);
*acl = NULL; else
} *acl = clone;
if (!S_ISDIR(*mode)) { if (!S_ISDIR(*mode))
posix_acl_release(p); posix_acl_release(p);
*default_acl = NULL; else
} else {
*default_acl = p; *default_acl = p;
}
return 0;
apply_umask:
*mode &= ~current_umask();
no_acl:
*default_acl = NULL;
*acl = NULL;
return 0; return 0;
no_mem_clone: no_mem_clone:
posix_acl_release(*acl); posix_acl_release(clone);
no_mem: no_mem:
posix_acl_release(p); posix_acl_release(p);
return -ENOMEM; return -ENOMEM;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment