Commit 2297ab61 authored by Bob Peterson's avatar Bob Peterson Committed by Andreas Gruenbacher

gfs2: Fix problems regarding gfs2_qa_get and _put

This patch fixes a couple of places in which gfs2_qa_get and gfs2_qa_put are
not balanced: we now keep references around whenever a file is open for writing
(see gfs2_open_common and gfs2_release), so we need to put all references we
grab in function gfs2_create_inode.  This was broken in the successful case and
on one error path.

This also means that we don't have a reference to put in gfs2_evict_inode.

In addition, gfs2_qa_put was called for the wrong inode in gfs2_link.
Signed-off-by: default avatarBob Peterson <rpeterso@redhat.com>
Signed-off-by: default avatarAndreas Gruenbacher <agruenba@redhat.com>
parent aa83da7f
...@@ -622,7 +622,7 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry, ...@@ -622,7 +622,7 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry,
error = finish_no_open(file, NULL); error = finish_no_open(file, NULL);
} }
gfs2_glock_dq_uninit(ghs); gfs2_glock_dq_uninit(ghs);
return error; goto fail;
} else if (error != -ENOENT) { } else if (error != -ENOENT) {
goto fail_gunlock; goto fail_gunlock;
} }
...@@ -764,9 +764,11 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry, ...@@ -764,9 +764,11 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry,
error = finish_open(file, dentry, gfs2_open_common); error = finish_open(file, dentry, gfs2_open_common);
} }
gfs2_glock_dq_uninit(ghs); gfs2_glock_dq_uninit(ghs);
gfs2_qa_put(ip);
gfs2_glock_dq_uninit(ghs + 1); gfs2_glock_dq_uninit(ghs + 1);
clear_bit(GLF_INODE_CREATING, &io_gl->gl_flags); clear_bit(GLF_INODE_CREATING, &io_gl->gl_flags);
gfs2_glock_put(io_gl); gfs2_glock_put(io_gl);
gfs2_qa_put(dip);
return error; return error;
fail_gunlock3: fail_gunlock3:
...@@ -776,7 +778,6 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry, ...@@ -776,7 +778,6 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry,
clear_bit(GLF_INODE_CREATING, &io_gl->gl_flags); clear_bit(GLF_INODE_CREATING, &io_gl->gl_flags);
gfs2_glock_put(io_gl); gfs2_glock_put(io_gl);
fail_free_inode: fail_free_inode:
gfs2_qa_put(ip);
if (ip->i_gl) { if (ip->i_gl) {
glock_clear_object(ip->i_gl, ip); glock_clear_object(ip->i_gl, ip);
gfs2_glock_put(ip->i_gl); gfs2_glock_put(ip->i_gl);
...@@ -1005,7 +1006,7 @@ static int gfs2_link(struct dentry *old_dentry, struct inode *dir, ...@@ -1005,7 +1006,7 @@ static int gfs2_link(struct dentry *old_dentry, struct inode *dir,
out_child: out_child:
gfs2_glock_dq(ghs); gfs2_glock_dq(ghs);
out_parent: out_parent:
gfs2_qa_put(ip); gfs2_qa_put(dip);
gfs2_holder_uninit(ghs); gfs2_holder_uninit(ghs);
gfs2_holder_uninit(ghs + 1); gfs2_holder_uninit(ghs + 1);
return error; return error;
......
...@@ -1404,7 +1404,6 @@ static void gfs2_evict_inode(struct inode *inode) ...@@ -1404,7 +1404,6 @@ static void gfs2_evict_inode(struct inode *inode)
if (ip->i_qadata) if (ip->i_qadata)
gfs2_assert_warn(sdp, ip->i_qadata->qa_ref == 0); gfs2_assert_warn(sdp, ip->i_qadata->qa_ref == 0);
gfs2_rs_delete(ip, NULL); gfs2_rs_delete(ip, NULL);
gfs2_qa_put(ip);
gfs2_ordered_del_inode(ip); gfs2_ordered_del_inode(ip);
clear_inode(inode); clear_inode(inode);
gfs2_dir_hash_inval(ip); gfs2_dir_hash_inval(ip);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment