ocfs2: fix a tiny race when truncate dio orohaned entry
PATCH 1/1 ocfs2: fix a tiny race when truncate dio orohaned entry
Once dio crashed it will leave an entry in orphan dir. And orphan scan will take care of the clean up.
There is a tiny race case that the same entry will be truncated twice and then trigger the BUG in ocfs2_del_inode_from_orphan.
Signed-off-by Joseph Qi <[email protected]>
--- fs/ocfs2/aops.c | 12 +++++++++++- fs/ocfs2/journal.c | 47 +++++++++++++++++++++-------------------------- fs/ocfs2/namei.c | 22 +++++----------------- fs/ocfs2/namei.h | 4 ++-- 4 files changed, 39 insertions(+), 46 deletions(-)
fs/ocfs2/aops.c +11 -1
@@ -925,13 +925,23 @@ clean_orphan:int update_isize = written >0 ?1 :0 ;loff_t end = update_isize ? offset + written :0 ; - tmp_ret =ocfs2_del_inode_from_orphan (osb, inode, + tmp_ret =ocfs2_inode_lock (inode, &di_bh,1 ); +if (tmp_ret <0 ) { + ret = tmp_ret; +mlog_errno (ret); + goto out; + } + + tmp_ret =ocfs2_del_inode_from_orphan (osb, inode, di_bh, update_isize, end);if (tmp_ret <0 ) { ret = tmp_ret; +mlog_errno (ret); goto out; } +ocfs2_inode_unlock (inode,1 ); + tmp_ret =jbd2_journal_force_commit (journal);if (tmp_ret <0 ) { ret = tmp_ret;
fs/ocfs2/journal.c +21 -26
86 lines not on this page · raw message
fs/ocfs2/namei.c +5 -17
@@ -2670,30 +2670,22 @@ bail: }int ocfs2_del_inode_from_orphan (struct ocfs2_super *osb, -struct inode *inode,int update_isize, -loff_t end) +struct inode *inode,struct buffer_head *di_bh, +int update_isize,loff_t end) {struct inode *orphan_dir_inode =NULL ;struct buffer_head *orphan_dir_bh =NULL ; -struct buffer_head *di_bh =NULL ; -struct ocfs2_dinode *di =NULL ; +struct ocfs2_dinode *di = (struct ocfs2_dinode *)di_bh->b_data;handle_t *handle =NULL ;int status =0 ; - status =ocfs2_inode_lock (inode, &di_bh,1 ); -if (status <0 ) { -mlog_errno (status); - goto bail; - } - di = (struct ocfs2_dinode *) di_bh->b_data; - orphan_dir_inode =ocfs2_get_system_file_inode (osb,ORPHAN_DIR_SYSTEM_INODE ,le16_to_cpu (di->i_dio_orphaned_slot));if (!orphan_dir_inode) { status = -ENOENT ;mlog_errno (status); - goto bail_unlock_inode; + goto bail; }mutex_lock (&orphan_dir_inode->i_mutex);
@@ -2702,7 +2694,7 @@ int ocfs2_del_inode_from_orphan(struct ocfs2_super *osb,mutex_unlock (&orphan_dir_inode->i_mutex);iput (orphan_dir_inode);mlog_errno (status); - goto bail_unlock_inode; + goto bail; } handle = ocfs2_start_trans(osb,
@@ -2749,10 +2741,6 @@ bail_unlock_orphan:brelse (orphan_dir_bh);iput (orphan_dir_inode); -bail_unlock_inode: -ocfs2_inode_unlock (inode,1 ); -brelse (di_bh); - bail:return status; }
fs/ocfs2/namei.h +2 -2
@@ -42,8 +42,8 @@ int ocfs2_create_inode_in_orphan(struct inode *dir,int ocfs2_add_inode_to_orphan (struct ocfs2_super *osb,struct inode *inode);int ocfs2_del_inode_from_orphan (struct ocfs2_super *osb, -struct inode *inode,int update_isize, -loff_t end); +struct inode *inode,struct buffer_head *di_bh, +int update_isize,loff_t end);int ocfs2_mv_orphaned_inode_to_new (struct inode *dir,struct inode *new_inode,struct dentry *new_dentry);
Signature · 1 line
1.8.4.3