gfs2: Clean up inode initialization and teardown
authorAndreas Gruenbacher <agruenba@redhat.com>
Fri, 24 Jan 2020 13:14:46 +0000 (14:14 +0100)
committerBob Peterson <rpeterso@redhat.com>
Fri, 27 Mar 2020 19:08:04 +0000 (14:08 -0500)
When allocating a new inode, mark the iopen glock holder as uninitialized to
make sure gfs2_evict_inode won't fail after an incomplete create or lookup.  In
gfs2_evict_inode, allow the inode glock to be NULL and remove the duplicate
iopen glock teardown code.  In gfs2_inode_lookup, don't tear down things that
gfs2_evict_inode will already tear down.

Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
Signed-off-by: Bob Peterson <rpeterso@redhat.com>
fs/gfs2/inode.c
fs/gfs2/super.c

index 2716d56ed0a07e537935c371e19c21c8f986670a..b5d04f3a247e0c656bc9d676e595a1d508d22174 100644 (file)
@@ -144,7 +144,7 @@ struct inode *gfs2_inode_lookup(struct super_block *sb, unsigned int type,
 
                error = gfs2_glock_get(sdp, no_addr, &gfs2_iopen_glops, CREATE, &io_gl);
                if (unlikely(error))
-                       goto fail_put;
+                       goto fail;
 
                if (type == DT_UNKNOWN || blktype != GFS2_BLKST_FREE) {
                        /*
@@ -155,13 +155,13 @@ struct inode *gfs2_inode_lookup(struct super_block *sb, unsigned int type,
                        error = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE,
                                                   GL_SKIP, &i_gh);
                        if (error)
-                               goto fail_put;
+                               goto fail;
 
                        if (blktype != GFS2_BLKST_FREE) {
                                error = gfs2_check_blk_type(sdp, no_addr,
                                                            blktype);
                                if (error)
-                                       goto fail_put;
+                                       goto fail;
                        }
                }
 
@@ -169,7 +169,7 @@ struct inode *gfs2_inode_lookup(struct super_block *sb, unsigned int type,
                set_bit(GIF_INVALID, &ip->i_flags);
                error = gfs2_glock_nq_init(io_gl, LM_ST_SHARED, GL_EXACT, &ip->i_iopen_gh);
                if (unlikely(error))
-                       goto fail_put;
+                       goto fail;
                glock_set_object(ip->i_iopen_gh.gh_gl, ip);
                gfs2_glock_put(io_gl);
                io_gl = NULL;
@@ -182,7 +182,7 @@ struct inode *gfs2_inode_lookup(struct super_block *sb, unsigned int type,
                        /* Inode glock must be locked already */
                        error = gfs2_inode_refresh(GFS2_I(inode));
                        if (error)
-                               goto fail_refresh;
+                               goto fail;
                } else {
                        ip->i_no_formal_ino = no_formal_ino;
                        inode->i_mode = DT2IF(type);
@@ -197,17 +197,11 @@ struct inode *gfs2_inode_lookup(struct super_block *sb, unsigned int type,
                gfs2_glock_dq_uninit(&i_gh);
        return inode;
 
-fail_refresh:
-       ip->i_iopen_gh.gh_flags |= GL_NOCACHE;
-       glock_clear_object(ip->i_iopen_gh.gh_gl, ip);
-       gfs2_glock_dq_uninit(&ip->i_iopen_gh);
-fail_put:
+fail:
        if (io_gl)
                gfs2_glock_put(io_gl);
-       glock_clear_object(ip->i_gl, ip);
        if (gfs2_holder_initialized(&i_gh))
                gfs2_glock_dq_uninit(&i_gh);
-fail:
        iget_failed(inode);
        return ERR_PTR(error);
 }
index 693c6d13473c5e65b1b33c02cb81982554d2d0ef..d664b01759468546f2d84264e7d36890564d6545 100644 (file)
@@ -1393,14 +1393,6 @@ out_unlock:
        if (gfs2_rs_active(&ip->i_res))
                gfs2_rs_deltree(&ip->i_res);
 
-       if (gfs2_holder_initialized(&ip->i_iopen_gh)) {
-               glock_clear_object(ip->i_iopen_gh.gh_gl, ip);
-               if (test_bit(HIF_HOLDER, &ip->i_iopen_gh.gh_iflags)) {
-                       ip->i_iopen_gh.gh_flags |= GL_NOCACHE;
-                       gfs2_glock_dq(&ip->i_iopen_gh);
-               }
-               gfs2_holder_uninit(&ip->i_iopen_gh);
-       }
        if (gfs2_holder_initialized(&gh)) {
                glock_clear_object(ip->i_gl, ip);
                gfs2_glock_dq_uninit(&gh);
@@ -1413,18 +1405,23 @@ out:
        gfs2_ordered_del_inode(ip);
        clear_inode(inode);
        gfs2_dir_hash_inval(ip);
-       glock_clear_object(ip->i_gl, ip);
-       wait_on_bit_io(&ip->i_flags, GIF_GLOP_PENDING, TASK_UNINTERRUPTIBLE);
-       gfs2_glock_add_to_lru(ip->i_gl);
-       gfs2_glock_put_eventually(ip->i_gl);
-       ip->i_gl = NULL;
+       if (ip->i_gl) {
+               glock_clear_object(ip->i_gl, ip);
+               wait_on_bit_io(&ip->i_flags, GIF_GLOP_PENDING, TASK_UNINTERRUPTIBLE);
+               gfs2_glock_add_to_lru(ip->i_gl);
+               gfs2_glock_put_eventually(ip->i_gl);
+               ip->i_gl = NULL;
+       }
        if (gfs2_holder_initialized(&ip->i_iopen_gh)) {
                struct gfs2_glock *gl = ip->i_iopen_gh.gh_gl;
 
                glock_clear_object(gl, ip);
-               ip->i_iopen_gh.gh_flags |= GL_NOCACHE;
+               if (test_bit(HIF_HOLDER, &ip->i_iopen_gh.gh_iflags)) {
+                       ip->i_iopen_gh.gh_flags |= GL_NOCACHE;
+                       gfs2_glock_dq(&ip->i_iopen_gh);
+               }
                gfs2_glock_hold(gl);
-               gfs2_glock_dq_uninit(&ip->i_iopen_gh);
+               gfs2_holder_uninit(&ip->i_iopen_gh);
                gfs2_glock_put_eventually(gl);
        }
 }
@@ -1438,6 +1435,7 @@ static struct inode *gfs2_alloc_inode(struct super_block *sb)
                return NULL;
        ip->i_flags = 0;
        ip->i_gl = NULL;
+       gfs2_holder_mark_uninitialized(&ip->i_iopen_gh);
        memset(&ip->i_res, 0, sizeof(ip->i_res));
        RB_CLEAR_NODE(&ip->i_res.rs_node);
        ip->i_rahead = 0;