diff options
author | Bob Peterson <rpeterso@redhat.com> | 2015-12-04 17:19:14 +0100 |
---|---|---|
committer | Bob Peterson <rpeterso@redhat.com> | 2015-12-18 17:57:21 +0100 |
commit | 783013c0f5c7263a31703b15aeebbac279b4d4fe (patch) | |
tree | f30364b378ba779561cd3e74e2f6d7f912498c35 /fs/gfs2 | |
parent | GFS2: Truncate address space mapping when deleting an inode (diff) | |
download | linux-783013c0f5c7263a31703b15aeebbac279b4d4fe.tar.xz linux-783013c0f5c7263a31703b15aeebbac279b4d4fe.zip |
GFS2: Release iopen glock in gfs2_create_inode error cases
Some error cases in gfs2_create_inode were not unlocking the iopen
glock, getting the reference count off. This adds the proper unlock.
The error logic in function gfs2_create_inode was also convoluted,
so this patch simplifies it. It also takes care of a bug in
which gfs2_qa_delete() was not called in an error case.
Signed-off-by: Bob Peterson <rpeterso@redhat.com>
Diffstat (limited to 'fs/gfs2')
-rw-r--r-- | fs/gfs2/inode.c | 16 |
1 files changed, 7 insertions, 9 deletions
diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c index bf2af049359b..87fa5992e12a 100644 --- a/fs/gfs2/inode.c +++ b/fs/gfs2/inode.c @@ -594,7 +594,7 @@ 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; - int error, free_vfs_inode = 0; + int error, free_vfs_inode = 1; u32 aflags = 0; unsigned blocks = 1; struct gfs2_diradd da = { .bh = NULL, .save_loc = 1, }; @@ -651,7 +651,7 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry, error = posix_acl_create(dir, &mode, &default_acl, &acl); if (error) - goto fail_free_vfs_inode; + goto fail_gunlock; ip = GFS2_I(inode); error = gfs2_rsqa_alloc(ip); @@ -739,6 +739,9 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry, gfs2_set_iop(inode); insert_inode_hash(inode); + free_vfs_inode = 0; /* After this point, the inode is no longer + considered free. Any failures need to undo + the gfs2 structures. */ if (default_acl) { error = gfs2_set_acl(inode, default_acl, ACL_TYPE_DEFAULT); posix_acl_release(default_acl); @@ -772,11 +775,8 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry, return error; fail_gunlock3: - gfs2_glock_dq_uninit(ghs + 1); - if (ip->i_gl) - gfs2_glock_put(ip->i_gl); - goto fail_gunlock; - + gfs2_glock_dq_uninit(&ip->i_iopen_gh); + gfs2_glock_put(io_gl); fail_gunlock2: gfs2_glock_dq_uninit(ghs + 1); fail_free_inode: @@ -788,8 +788,6 @@ fail_free_acls: posix_acl_release(default_acl); if (acl) posix_acl_release(acl); -fail_free_vfs_inode: - free_vfs_inode = 1; fail_gunlock: gfs2_dir_no_add(&da); gfs2_glock_dq_uninit(ghs); |