diff options
author | Chao Yu <chao2.yu@samsung.com> | 2015-04-18 13:03:58 +0300 |
---|---|---|
committer | Jaegeuk Kim <jaegeuk@kernel.org> | 2015-05-07 21:38:31 +0300 |
commit | 272e083f7a968bc81dd01e4f16860a1e9617d454 (patch) | |
tree | 64cff853b2789f18fed41884641d0c0770ac1978 /fs/f2fs/acl.c | |
parent | 5d799881391277e52787df06bafe865e91ae8296 (diff) | |
download | linux-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.c | 46 |
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; |