Commit b66648ad authored by Andreas Gruenbacher's avatar Andreas Gruenbacher

gfs2: Move inode generation number check into gfs2_inode_lookup

Move the inode generation number check from gfs2_lookup_by_inum into
gfs2_inode_lookup: gfs2_inode_lookup may be able to decide that an inode with
the given inode generation number cannot exist without having to verify the
block type or reading the inode from disk.
Signed-off-by: default avatarAndreas Gruenbacher <agruenba@redhat.com>
parent 6bdcadea
...@@ -114,6 +114,10 @@ static void gfs2_set_iop(struct inode *inode) ...@@ -114,6 +114,10 @@ static void gfs2_set_iop(struct inode *inode)
* placeholder because it doesn't otherwise make sense), the on-disk block type * placeholder because it doesn't otherwise make sense), the on-disk block type
* is verified to be @blktype. * is verified to be @blktype.
* *
* When @no_formal_ino is non-zero, this function will return ERR_PTR(-ESTALE)
* if it detects that @no_formal_ino doesn't match the actual inode generation
* number. However, it doesn't always know unless @type is DT_UNKNOWN.
*
* Returns: A VFS inode, or an error * Returns: A VFS inode, or an error
*/ */
...@@ -157,6 +161,11 @@ struct inode *gfs2_inode_lookup(struct super_block *sb, unsigned int type, ...@@ -157,6 +161,11 @@ struct inode *gfs2_inode_lookup(struct super_block *sb, unsigned int type,
if (error) if (error)
goto fail; goto fail;
error = -ESTALE;
if (no_formal_ino &&
gfs2_inode_already_deleted(ip->i_gl, no_formal_ino))
goto fail;
if (blktype != GFS2_BLKST_FREE) { if (blktype != GFS2_BLKST_FREE) {
error = gfs2_check_blk_type(sdp, no_addr, error = gfs2_check_blk_type(sdp, no_addr,
blktype); blktype);
...@@ -189,13 +198,23 @@ struct inode *gfs2_inode_lookup(struct super_block *sb, unsigned int type, ...@@ -189,13 +198,23 @@ struct inode *gfs2_inode_lookup(struct super_block *sb, unsigned int type,
inode->i_mode = DT2IF(type); inode->i_mode = DT2IF(type);
} }
if (gfs2_holder_initialized(&i_gh))
gfs2_glock_dq_uninit(&i_gh);
gfs2_set_iop(inode); gfs2_set_iop(inode);
}
unlock_new_inode(inode); if (no_formal_ino && ip->i_no_formal_ino &&
no_formal_ino != ip->i_no_formal_ino) {
if (inode->i_state & I_NEW)
goto fail;
iput(inode);
return ERR_PTR(-ESTALE);
} }
if (gfs2_holder_initialized(&i_gh)) if (inode->i_state & I_NEW)
gfs2_glock_dq_uninit(&i_gh); unlock_new_inode(inode);
return inode; return inode;
fail: fail:
...@@ -221,16 +240,12 @@ struct inode *gfs2_lookup_by_inum(struct gfs2_sbd *sdp, u64 no_addr, ...@@ -221,16 +240,12 @@ struct inode *gfs2_lookup_by_inum(struct gfs2_sbd *sdp, u64 no_addr,
struct inode *inode; struct inode *inode;
int error; int error;
inode = gfs2_inode_lookup(sb, DT_UNKNOWN, no_addr, 0, blktype); inode = gfs2_inode_lookup(sb, DT_UNKNOWN, no_addr, no_formal_ino,
blktype);
if (IS_ERR(inode)) if (IS_ERR(inode))
return inode; return inode;
/* Two extra checks for NFS only */
if (no_formal_ino) { if (no_formal_ino) {
error = -ESTALE;
if (GFS2_I(inode)->i_no_formal_ino != no_formal_ino)
goto fail_iput;
error = -EIO; error = -EIO;
if (GFS2_I(inode)->i_diskflags & GFS2_DIF_SYSTEM) if (GFS2_I(inode)->i_diskflags & GFS2_DIF_SYSTEM)
goto fail_iput; goto fail_iput;
......
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