Skip to content

Commit

Permalink
gfs2: gfs2_inode_lookup rework
Browse files Browse the repository at this point in the history
Rework gfs2_inode_lookup() to only set up the new inode's glocks after
verifying that the new inode is valid.

There is no need for flushing the inode glock work queue anymore now,
so remove that as well.

While at it, get rid of the useless wrapper around iget5_locked() and
its unnecessary is_bad_inode() check.

Signed-off-by: Andreas Gruenbacher <[email protected]>
  • Loading branch information
Andreas Gruenbacher committed Dec 2, 2021
1 parent b8e12e3 commit 5f6e13b
Showing 1 changed file with 33 additions and 51 deletions.
84 changes: 33 additions & 51 deletions fs/gfs2/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,37 +40,6 @@ static const struct inode_operations gfs2_file_iops;
static const struct inode_operations gfs2_dir_iops;
static const struct inode_operations gfs2_symlink_iops;

static int iget_test(struct inode *inode, void *opaque)
{
u64 no_addr = *(u64 *)opaque;

return GFS2_I(inode)->i_no_addr == no_addr;
}

static int iget_set(struct inode *inode, void *opaque)
{
u64 no_addr = *(u64 *)opaque;

GFS2_I(inode)->i_no_addr = no_addr;
inode->i_ino = no_addr;
return 0;
}

static struct inode *gfs2_iget(struct super_block *sb, u64 no_addr)
{
struct inode *inode;

repeat:
inode = iget5_locked(sb, no_addr, iget_test, iget_set, &no_addr);
if (!inode)
return inode;
if (is_bad_inode(inode)) {
iput(inode);
goto repeat;
}
return inode;
}

/**
* gfs2_set_iop - Sets inode operations
* @inode: The inode with correct i_mode filled in
Expand Down Expand Up @@ -104,6 +73,22 @@ static void gfs2_set_iop(struct inode *inode)
}
}

static int iget_test(struct inode *inode, void *opaque)
{
u64 no_addr = *(u64 *)opaque;

return GFS2_I(inode)->i_no_addr == no_addr;
}

static int iget_set(struct inode *inode, void *opaque)
{
u64 no_addr = *(u64 *)opaque;

GFS2_I(inode)->i_no_addr = no_addr;
inode->i_ino = no_addr;
return 0;
}

/**
* gfs2_inode_lookup - Lookup an inode
* @sb: The super block
Expand Down Expand Up @@ -132,35 +117,28 @@ struct inode *gfs2_inode_lookup(struct super_block *sb, unsigned int type,
{
struct inode *inode;
struct gfs2_inode *ip;
struct gfs2_glock *io_gl = NULL;
struct gfs2_holder i_gh;
int error;

gfs2_holder_mark_uninitialized(&i_gh);
inode = gfs2_iget(sb, no_addr);
inode = iget5_locked(sb, no_addr, iget_test, iget_set, &no_addr);
if (!inode)
return ERR_PTR(-ENOMEM);

ip = GFS2_I(inode);

if (inode->i_state & I_NEW) {
struct gfs2_sbd *sdp = GFS2_SB(inode);
struct gfs2_glock *io_gl;

error = gfs2_glock_get(sdp, no_addr, &gfs2_inode_glops, CREATE, &ip->i_gl);
if (unlikely(error))
goto fail;
flush_delayed_work(&ip->i_gl->gl_work);

error = gfs2_glock_get(sdp, no_addr, &gfs2_iopen_glops, CREATE, &io_gl);
if (unlikely(error))
goto fail;
if (blktype != GFS2_BLKST_UNLINKED)
gfs2_cancel_delete_work(io_gl);

if (type == DT_UNKNOWN || blktype != GFS2_BLKST_FREE) {
/*
* The GL_SKIP flag indicates to skip reading the inode
* block. We read the inode with gfs2_inode_refresh
* block. We read the inode when instantiating it
* after possibly checking the block type.
*/
error = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE,
Expand All @@ -181,31 +159,39 @@ struct inode *gfs2_inode_lookup(struct super_block *sb, unsigned int type,
}
}

glock_set_object(ip->i_gl, ip);
set_bit(GLF_INSTANTIATE_NEEDED, &ip->i_gl->gl_flags);
error = gfs2_glock_nq_init(io_gl, LM_ST_SHARED, GL_EXACT, &ip->i_iopen_gh);

error = gfs2_glock_get(sdp, no_addr, &gfs2_iopen_glops, CREATE, &io_gl);
if (unlikely(error))
goto fail;
glock_set_object(ip->i_iopen_gh.gh_gl, ip);
if (blktype != GFS2_BLKST_UNLINKED)
gfs2_cancel_delete_work(io_gl);
error = gfs2_glock_nq_init(io_gl, LM_ST_SHARED, GL_EXACT, &ip->i_iopen_gh);
gfs2_glock_put(io_gl);
io_gl = NULL;
if (unlikely(error))
goto fail;

/* Lowest possible timestamp; will be overwritten in gfs2_dinode_in. */
inode->i_atime.tv_sec = 1LL << (8 * sizeof(inode->i_atime.tv_sec) - 1);
inode->i_atime.tv_nsec = 0;

glock_set_object(ip->i_gl, ip);

if (type == DT_UNKNOWN) {
/* Inode glock must be locked already */
error = gfs2_instantiate(&i_gh);
if (error)
if (error) {
glock_clear_object(ip->i_gl, ip);
goto fail;
}
} else {
ip->i_no_formal_ino = no_formal_ino;
inode->i_mode = DT2IF(type);
}

if (gfs2_holder_initialized(&i_gh))
gfs2_glock_dq_uninit(&i_gh);
glock_set_object(ip->i_iopen_gh.gh_gl, ip);

gfs2_set_iop(inode);
unlock_new_inode(inode);
Expand All @@ -220,12 +206,8 @@ struct inode *gfs2_inode_lookup(struct super_block *sb, unsigned int type,
return inode;

fail:
if (gfs2_holder_initialized(&ip->i_iopen_gh)) {
glock_clear_object(ip->i_iopen_gh.gh_gl, ip);
if (gfs2_holder_initialized(&ip->i_iopen_gh))
gfs2_glock_dq_uninit(&ip->i_iopen_gh);
}
if (io_gl)
gfs2_glock_put(io_gl);
if (gfs2_holder_initialized(&i_gh))
gfs2_glock_dq_uninit(&i_gh);
iget_failed(inode);
Expand Down

0 comments on commit 5f6e13b

Please sign in to comment.