ocfs2: fix race between crashed dio and rm
PATCH 1/1 ocfs2: fix race between crashed dio and rm
There is a race case between crashed dio and rm, which will lead to OCFS2_VALID_FL not set read-only.
N1 N2
------------------------------------------------------------------------
dd with direct flag
rm file
crashed with an dio entry left
in orphan dir
clear OCFS2_VALID_FL in ocfs2_remove_inode
recover N1 and read the corrupted inode, and set filesystem read-only
So we skip the inode deletion this time and wait for dio entry recovered first.
Signed-off-by Joseph Qi <[email protected]>
--- fs/ocfs2/inode.c | 9 +++++++++ fs/ocfs2/journal.c | 4 +++- 2 files changed, 12 insertions(+), 1 deletion(-)
fs/ocfs2/inode.c +9 -0
@@ -971,6 +971,7 @@ static void ocfs2_delete_inode(struct inode *inode)int wipe, status;sigset_t oldset;struct buffer_head *di_bh =NULL ; +struct ocfs2_dinode *di =NULL ; trace_ocfs2_delete_inode(inode->i_ino, (unsigned long long)OCFS2_I(inode)->ip_blkno,
@@ -1025,6 +1026,14 @@ static void ocfs2_delete_inode(struct inode *inode) goto bail_unlock_nfs_sync; } + di = (struct ocfs2_dinode *)di_bh->b_data; +/* Skip inode deletion and wait for dio orphan entry recovered +* first */ +if (unlikely (di->i_flags &cpu_to_le32 (OCFS2_DIO_ORPHANED_FL ))) { +ocfs2_cleanup_delete_inode (inode,0 ); + goto bail_unlock_inode; + } +/* Query the cluster. This will be the final decision made * before we go ahead and wipe the inode. */ status =ocfs2_query_inode_wipe (inode, di_bh, &wipe);
fs/ocfs2/journal.c +3 -1
@@ -2195,7 +2195,9 @@ static int ocfs2_recover_orphans(struct ocfs2_super *osb,* ocfs2_delete_inode. */ oi->ip_flags |=OCFS2_INODE_MAYBE_ORPHANED ;spin_unlock (&oi->ip_lock); - }else if ((orphan_reco_type ==ORPHAN_NEED_TRUNCATE ) && + } + +if ((orphan_reco_type ==ORPHAN_NEED_TRUNCATE ) && (di->i_flags &cpu_to_le32 (OCFS2_DIO_ORPHANED_FL ))) { ret =ocfs2_truncate_file (inode, di_bh,i_size_read (inode));
Signature · 1 line
1.8.4.3