From 986cdb862e4aafc92a1537e04388898fc42b8bc0 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 18 Sep 2014 17:38:59 -0400 Subject: [PATCH 1/3] gfs2: bugger off early if O_CREAT open finds a directory Signed-off-by: Al Viro --- fs/gfs2/inode.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c index c4ed823d150e..310e2487239d 100644 --- a/fs/gfs2/inode.c +++ b/fs/gfs2/inode.c @@ -624,6 +624,11 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry, inode = gfs2_dir_search(dir, &dentry->d_name, !S_ISREG(mode) || excl); error = PTR_ERR(inode); if (!IS_ERR(inode)) { + if (S_ISDIR(inode->i_mode)) { + iput(inode); + inode = ERR_PTR(-EISDIR); + goto fail_gunlock; + } d = d_splice_alias(inode, dentry); error = PTR_ERR(d); if (IS_ERR(d)) { From 81295ce635a83f052497656348e9edc794b4cae6 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 18 Sep 2014 17:42:35 -0400 Subject: [PATCH 2/3] gfs2_create_inode(): don't bother with d_splice_alias() dentry is always hashed and negative, inode - non-error, non-NULL and non-directory. In such conditions d_splice_alias() is equivalent to "d_instantiate(dentry, inode) and return NULL", which simplifies the downstream code and is consistent with the "have to create a new object" case. Signed-off-by: Al Viro --- fs/gfs2/inode.c | 18 ++++-------------- 1 file changed, 4 insertions(+), 14 deletions(-) diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c index 310e2487239d..ce0cf9ad5f97 100644 --- a/fs/gfs2/inode.c +++ b/fs/gfs2/inode.c @@ -596,7 +596,6 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry, struct gfs2_inode *dip = GFS2_I(dir), *ip; struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode); struct gfs2_glock *io_gl; - struct dentry *d; int error, free_vfs_inode = 0; u32 aflags = 0; unsigned blocks = 1; @@ -629,22 +628,13 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry, inode = ERR_PTR(-EISDIR); goto fail_gunlock; } - d = d_splice_alias(inode, dentry); - error = PTR_ERR(d); - if (IS_ERR(d)) { - inode = ERR_CAST(d); - goto fail_gunlock; - } + d_instantiate(dentry, inode); error = 0; if (file) { - if (S_ISREG(inode->i_mode)) { - WARN_ON(d != NULL); + if (S_ISREG(inode->i_mode)) error = finish_open(file, dentry, gfs2_open_common, opened); - } else { - error = finish_no_open(file, d); - } - } else { - dput(d); + else + error = finish_no_open(file, NULL); } gfs2_glock_dq_uninit(ghs); return error; From 845409b49bcc8fe2ad9f1a948cc4f54c301b742d Mon Sep 17 00:00:00 2001 From: Al Viro Date: Tue, 18 Nov 2014 21:10:23 -0500 Subject: [PATCH 3/3] gfs2_atomic_open(): simplify the use of finish_no_open() In ->atomic_open(inode, dentry, file, opened) calling finish_no_open(file, NULL) is equivalent to dget(dentry); return finish_no_open(file, dentry); No need to open-code that... Signed-off-by: Al Viro --- fs/gfs2/inode.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c index ce0cf9ad5f97..6e2917433170 100644 --- a/fs/gfs2/inode.c +++ b/fs/gfs2/inode.c @@ -1249,11 +1249,8 @@ static int gfs2_atomic_open(struct inode *dir, struct dentry *dentry, if (d != NULL) dentry = d; if (dentry->d_inode) { - if (!(*opened & FILE_OPENED)) { - if (d == NULL) - dget(dentry); - return finish_no_open(file, dentry); - } + if (!(*opened & FILE_OPENED)) + return finish_no_open(file, d); dput(d); return 0; }