diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2013-09-16 19:22:33 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2013-09-17 17:08:50 -0400 |
commit | 03da633aa7b08bdc4d86e9c2780bb89277b65cd6 (patch) | |
tree | f663ce0d2f49867c6b4f9b0631976a9e7ea9556a /fs/namei.c | |
parent | 116cc0225381415b96551f725455d067f63a76a0 (diff) |
atomic_open: take care of EEXIST in no-open case with O_CREAT|O_EXCL in fs/namei.c
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/namei.c')
-rw-r--r-- | fs/namei.c | 33 |
1 files changed, 19 insertions, 14 deletions
diff --git a/fs/namei.c b/fs/namei.c index 22eb5484774c..645268f23eb6 100644 --- a/fs/namei.c +++ b/fs/namei.c | |||
@@ -2725,16 +2725,6 @@ static int atomic_open(struct nameidata *nd, struct dentry *dentry, | |||
2725 | goto out; | 2725 | goto out; |
2726 | } | 2726 | } |
2727 | 2727 | ||
2728 | acc_mode = op->acc_mode; | ||
2729 | if (WARN_ON(excl && !(*opened & FILE_CREATED))) | ||
2730 | *opened |= FILE_CREATED; | ||
2731 | |||
2732 | if (*opened & FILE_CREATED) { | ||
2733 | WARN_ON(!(open_flag & O_CREAT)); | ||
2734 | fsnotify_create(dir, dentry); | ||
2735 | acc_mode = MAY_OPEN; | ||
2736 | } | ||
2737 | |||
2738 | if (error) { /* returned 1, that is */ | 2728 | if (error) { /* returned 1, that is */ |
2739 | if (WARN_ON(file->f_path.dentry == DENTRY_NOT_SET)) { | 2729 | if (WARN_ON(file->f_path.dentry == DENTRY_NOT_SET)) { |
2740 | error = -EIO; | 2730 | error = -EIO; |
@@ -2744,10 +2734,19 @@ static int atomic_open(struct nameidata *nd, struct dentry *dentry, | |||
2744 | dput(dentry); | 2734 | dput(dentry); |
2745 | dentry = file->f_path.dentry; | 2735 | dentry = file->f_path.dentry; |
2746 | } | 2736 | } |
2747 | WARN_ON(!dentry->d_inode && (*opened & FILE_CREATED)); | 2737 | if (*opened & FILE_CREATED) |
2748 | if (create_error && dentry->d_inode == NULL) { | 2738 | fsnotify_create(dir, dentry); |
2749 | error = create_error; | 2739 | if (!dentry->d_inode) { |
2750 | goto out; | 2740 | WARN_ON(*opened & FILE_CREATED); |
2741 | if (create_error) { | ||
2742 | error = create_error; | ||
2743 | goto out; | ||
2744 | } | ||
2745 | } else { | ||
2746 | if (excl && !(*opened & FILE_CREATED)) { | ||
2747 | error = -EEXIST; | ||
2748 | goto out; | ||
2749 | } | ||
2751 | } | 2750 | } |
2752 | goto looked_up; | 2751 | goto looked_up; |
2753 | } | 2752 | } |
@@ -2756,6 +2755,12 @@ static int atomic_open(struct nameidata *nd, struct dentry *dentry, | |||
2756 | * We didn't have the inode before the open, so check open permission | 2755 | * We didn't have the inode before the open, so check open permission |
2757 | * here. | 2756 | * here. |
2758 | */ | 2757 | */ |
2758 | acc_mode = op->acc_mode; | ||
2759 | if (*opened & FILE_CREATED) { | ||
2760 | WARN_ON(!(open_flag & O_CREAT)); | ||
2761 | fsnotify_create(dir, dentry); | ||
2762 | acc_mode = MAY_OPEN; | ||
2763 | } | ||
2759 | error = may_open(&file->f_path, acc_mode, open_flag); | 2764 | error = may_open(&file->f_path, acc_mode, open_flag); |
2760 | if (error) | 2765 | if (error) |
2761 | fput(file); | 2766 | fput(file); |