Merge tag 'gfs2-for-5.8' of git://git.kernel.org/pub/scm/linux/kernel/git/gfs2/linux-gfs2
Pull gfs2 updates from Andreas Gruenbacher: - An iopen glock locking scheme rework that speeds up deletes of inodes accessed from multiple nodes - Various bug fixes and debugging improvements - Convert gfs2-glocks.txt to ReST * tag 'gfs2-for-5.8' of git://git.kernel.org/pub/scm/linux/kernel/git/gfs2/linux-gfs2: gfs2: fix use-after-free on transaction ail lists gfs2: new slab for transactions gfs2: initialize transaction tr_ailX_lists earlier gfs2: Smarter iopen glock waiting gfs2: Wake up when setting GLF_DEMOTE gfs2: Check inode generation number in delete_work_func gfs2: Move inode generation number check into gfs2_inode_lookup gfs2: Minor gfs2_lookup_by_inum cleanup gfs2: Try harder to delete inodes locally gfs2: Give up the iopen glock on contention gfs2: Turn gl_delete into a delayed work gfs2: Keep track of deleted inode generations in LVBs gfs2: Allow ASPACE glocks to also have an lvb gfs2: instrumentation wrt log_flush stuck gfs2: introduce new gfs2_glock_assert_withdraw gfs2: print mapping->nrpages in glock dump for address space glocks gfs2: Only do glock put in gfs2_create_inode for free inodes gfs2: Allow lock_nolock mount to specify jid=X gfs2: Don't ignore inode write errors during inode_go_sync docs: filesystems: convert gfs2-glocks.txt to ReST
This commit is contained in:
@@ -115,6 +115,10 @@ static void gfs2_set_iop(struct inode *inode)
|
||||
* placeholder because it doesn't otherwise make sense), the on-disk block type
|
||||
* 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
|
||||
*/
|
||||
|
||||
@@ -158,6 +162,11 @@ struct inode *gfs2_inode_lookup(struct super_block *sb, unsigned int type,
|
||||
if (error)
|
||||
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) {
|
||||
error = gfs2_check_blk_type(sdp, no_addr,
|
||||
blktype);
|
||||
@@ -171,6 +180,7 @@ struct inode *gfs2_inode_lookup(struct super_block *sb, unsigned int type,
|
||||
error = gfs2_glock_nq_init(io_gl, LM_ST_SHARED, GL_EXACT, &ip->i_iopen_gh);
|
||||
if (unlikely(error))
|
||||
goto fail;
|
||||
gfs2_cancel_delete_work(ip->i_iopen_gh.gh_gl);
|
||||
glock_set_object(ip->i_iopen_gh.gh_gl, ip);
|
||||
gfs2_glock_put(io_gl);
|
||||
io_gl = NULL;
|
||||
@@ -189,13 +199,23 @@ struct inode *gfs2_inode_lookup(struct super_block *sb, unsigned int type,
|
||||
inode->i_mode = DT2IF(type);
|
||||
}
|
||||
|
||||
gfs2_set_iop(inode);
|
||||
if (gfs2_holder_initialized(&i_gh))
|
||||
gfs2_glock_dq_uninit(&i_gh);
|
||||
|
||||
unlock_new_inode(inode);
|
||||
gfs2_set_iop(inode);
|
||||
}
|
||||
|
||||
if (gfs2_holder_initialized(&i_gh))
|
||||
gfs2_glock_dq_uninit(&i_gh);
|
||||
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 (inode->i_state & I_NEW)
|
||||
unlock_new_inode(inode);
|
||||
|
||||
return inode;
|
||||
|
||||
fail:
|
||||
@@ -207,23 +227,26 @@ fail:
|
||||
return ERR_PTR(error);
|
||||
}
|
||||
|
||||
/**
|
||||
* gfs2_lookup_by_inum - look up an inode by inode number
|
||||
* @sdp: The super block
|
||||
* @no_addr: The inode number
|
||||
* @no_formal_ino: The inode generation number (0 for any)
|
||||
* @blktype: Requested block type (see gfs2_inode_lookup)
|
||||
*/
|
||||
struct inode *gfs2_lookup_by_inum(struct gfs2_sbd *sdp, u64 no_addr,
|
||||
u64 *no_formal_ino, unsigned int blktype)
|
||||
u64 no_formal_ino, unsigned int blktype)
|
||||
{
|
||||
struct super_block *sb = sdp->sd_vfs;
|
||||
struct inode *inode;
|
||||
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))
|
||||
return inode;
|
||||
|
||||
/* Two extra checks for NFS only */
|
||||
if (no_formal_ino) {
|
||||
error = -ESTALE;
|
||||
if (GFS2_I(inode)->i_no_formal_ino != *no_formal_ino)
|
||||
goto fail_iput;
|
||||
|
||||
error = -EIO;
|
||||
if (GFS2_I(inode)->i_diskflags & GFS2_DIF_SYSTEM)
|
||||
goto fail_iput;
|
||||
@@ -725,6 +748,7 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry,
|
||||
if (error)
|
||||
goto fail_gunlock2;
|
||||
|
||||
gfs2_cancel_delete_work(ip->i_iopen_gh.gh_gl);
|
||||
glock_set_object(ip->i_iopen_gh.gh_gl, ip);
|
||||
gfs2_set_iop(inode);
|
||||
insert_inode_hash(inode);
|
||||
@@ -781,7 +805,8 @@ fail_gunlock2:
|
||||
fail_free_inode:
|
||||
if (ip->i_gl) {
|
||||
glock_clear_object(ip->i_gl, ip);
|
||||
gfs2_glock_put(ip->i_gl);
|
||||
if (free_vfs_inode) /* else evict will do the put for us */
|
||||
gfs2_glock_put(ip->i_gl);
|
||||
}
|
||||
gfs2_rs_delete(ip, NULL);
|
||||
gfs2_qa_put(ip);
|
||||
|
Reference in New Issue
Block a user