]> www.infradead.org Git - users/jedix/linux-maple.git/commit
ocfs2: Take inode cluster lock before moving reflinked inode from orphan dir
authorAshish Samant <ashish.samant@oracle.com>
Fri, 2 Mar 2018 23:04:28 +0000 (15:04 -0800)
committerBrian Maly <brian.maly@oracle.com>
Mon, 23 Apr 2018 21:02:28 +0000 (17:02 -0400)
commitbf44c656535bdce468d6ca9005f10c854cba104d
tree7dc9cd020684da75fcdcf844c7081d2522e56f06
parent19ac87afee84c597b11c3158bd6a6ebbbeff817f
ocfs2: Take inode cluster lock before moving reflinked inode from orphan dir

Orabug: 27869411

While reflinking an inode, we create a new inode in orphan directory, then
take EX lock on it, reflink the original inode to orphan inode and release
EX lock. Once the lock is released another node might request it in PR mode
which causes downconvert of the lock to PR mode.

Later we attempt to initialize security acl for the orphan inode and move
it to the reflink destination. However, while doing this we dont take EX
lock on the inode. So effectively, we are doing this and accessing the
journal for this inode while holding PR lock. While accessing the journal,
we make

ci->ci_last_trans = journal->j_trans_id

At this point, if there is another downconvert request on this inode from
another node (PR->NL), we will trip on the following condition in
ocfs2_ci_checkpointed()

BUG_ON(lockres->l_level != DLM_LOCK_EX && !checkpointed);

because we hold the lock in PR mode and journal->j_trans_id is not greater
than ci_last_trans for the inode.

Fix this by taking orphan inode cluster lock in EX mode before
initializing security and moving orphan inode to reflink destination.
Use the __tracker variant while taking inode lock to avoid recursive
locking in the ocfs2_init_security_and_acl() call chain.

Signed-off-by: Ashish Samant <ashish.samant@oracle.com>
Reviewed-by: Junxiao Bi <junxiao.bi@oracle.com>
Acked-by: Jun Piao <piaojun@huawei.com>
Reviewed-by: Joseph Qi <jiangqi903@gmail.com>
Signed-off-by: Brian Maly <brian.maly@oracle.com>
fs/ocfs2/refcounttree.c