aboutsummaryrefslogtreecommitdiffstats
path: root/fs/f2fs/acl.c
diff options
context:
space:
mode:
authorChao Yu <chao2.yu@samsung.com>2015-04-18 06:03:58 -0400
committerJaegeuk Kim <jaegeuk@kernel.org>2015-05-07 14:38:31 -0400
commit272e083f7a968bc81dd01e4f16860a1e9617d454 (patch)
tree64cff853b2789f18fed41884641d0c0770ac1978 /fs/f2fs/acl.c
parent5d799881391277e52787df06bafe865e91ae8296 (diff)
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,
334 struct page *dpage) 334 struct page *dpage)
335{ 335{
336 struct posix_acl *p; 336 struct posix_acl *p;
337 struct posix_acl *clone;
337 int ret; 338 int ret;
338 339
340 *acl = NULL;
341 *default_acl = NULL;
342
339 if (S_ISLNK(*mode) || !IS_POSIXACL(dir)) 343 if (S_ISLNK(*mode) || !IS_POSIXACL(dir))
340 goto no_acl; 344 return 0;
341 345
342 p = __f2fs_get_acl(dir, ACL_TYPE_DEFAULT, dpage); 346 p = __f2fs_get_acl(dir, ACL_TYPE_DEFAULT, dpage);
343 if (IS_ERR(p)) { 347 if (!p || p == ERR_PTR(-EOPNOTSUPP)) {
344 if (p == ERR_PTR(-EOPNOTSUPP)) 348 *mode &= ~current_umask();
345 goto apply_umask; 349 return 0;
346 return PTR_ERR(p);
347 } 350 }
351 if (IS_ERR(p))
352 return PTR_ERR(p);
348 353
349 if (!p) 354 clone = f2fs_acl_clone(p, GFP_NOFS);
350 goto apply_umask; 355 if (!clone)
351
352 *acl = f2fs_acl_clone(p, GFP_NOFS);
353 if (!*acl)
354 goto no_mem; 356 goto no_mem;
355 357
356 ret = f2fs_acl_create_masq(*acl, mode); 358 ret = f2fs_acl_create_masq(clone, mode);
357 if (ret < 0) 359 if (ret < 0)
358 goto no_mem_clone; 360 goto no_mem_clone;
359 361
360 if (ret == 0) { 362 if (ret == 0)
361 posix_acl_release(*acl); 363 posix_acl_release(clone);
362 *acl = NULL; 364 else
363 } 365 *acl = clone;
364 366
365 if (!S_ISDIR(*mode)) { 367 if (!S_ISDIR(*mode))
366 posix_acl_release(p); 368 posix_acl_release(p);
367 *default_acl = NULL; 369 else
368 } else {
369 *default_acl = p; 370 *default_acl = p;
370 }
371 return 0;
372 371
373apply_umask:
374 *mode &= ~current_umask();
375no_acl:
376 *default_acl = NULL;
377 *acl = NULL;
378 return 0; 372 return 0;
379 373
380no_mem_clone: 374no_mem_clone:
381 posix_acl_release(*acl); 375 posix_acl_release(clone);
382no_mem: 376no_mem:
383 posix_acl_release(p); 377 posix_acl_release(p);
384 return -ENOMEM; 378 return -ENOMEM;