Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 783013c0 authored by Bob Peterson's avatar Bob Peterson
Browse files

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: default avatarBob Peterson <rpeterso@redhat.com>
parent ee530bea
Loading
Loading
Loading
Loading
+7 −9
Original line number Original line Diff line number Diff line
@@ -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_inode *dip = GFS2_I(dir), *ip;
	struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode);
	struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode);
	struct gfs2_glock *io_gl;
	struct gfs2_glock *io_gl;
	int error, free_vfs_inode = 0;
	int error, free_vfs_inode = 1;
	u32 aflags = 0;
	u32 aflags = 0;
	unsigned blocks = 1;
	unsigned blocks = 1;
	struct gfs2_diradd da = { .bh = NULL, .save_loc = 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);
	error = posix_acl_create(dir, &mode, &default_acl, &acl);
	if (error)
	if (error)
		goto fail_free_vfs_inode;
		goto fail_gunlock;


	ip = GFS2_I(inode);
	ip = GFS2_I(inode);
	error = gfs2_rsqa_alloc(ip);
	error = gfs2_rsqa_alloc(ip);
@@ -739,6 +739,9 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry,
	gfs2_set_iop(inode);
	gfs2_set_iop(inode);
	insert_inode_hash(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) {
	if (default_acl) {
		error = gfs2_set_acl(inode, default_acl, ACL_TYPE_DEFAULT);
		error = gfs2_set_acl(inode, default_acl, ACL_TYPE_DEFAULT);
		posix_acl_release(default_acl);
		posix_acl_release(default_acl);
@@ -772,11 +775,8 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry,
	return error;
	return error;


fail_gunlock3:
fail_gunlock3:
	gfs2_glock_dq_uninit(ghs + 1);
	gfs2_glock_dq_uninit(&ip->i_iopen_gh);
	if (ip->i_gl)
	gfs2_glock_put(io_gl);
		gfs2_glock_put(ip->i_gl);
	goto fail_gunlock;

fail_gunlock2:
fail_gunlock2:
	gfs2_glock_dq_uninit(ghs + 1);
	gfs2_glock_dq_uninit(ghs + 1);
fail_free_inode:
fail_free_inode:
@@ -788,8 +788,6 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry,
		posix_acl_release(default_acl);
		posix_acl_release(default_acl);
	if (acl)
	if (acl)
		posix_acl_release(acl);
		posix_acl_release(acl);
fail_free_vfs_inode:
	free_vfs_inode = 1;
fail_gunlock:
fail_gunlock:
	gfs2_dir_no_add(&da);
	gfs2_dir_no_add(&da);
	gfs2_glock_dq_uninit(ghs);
	gfs2_glock_dq_uninit(ghs);