ocfs2: fix race between dio and recover orphan
PATCH v2 1/2 ocfs2: fix race between dio and recover orphan
During direct io the inode will be added to orphan first and then deleted from orphan. There is a race window that the orphan entry will be deleted twice and thus trigger the BUG when validating OCFS2_DIO_ORPHANED_FL in ocfs2_del_inode_from_orphan.
ocfs2_direct_IO_write
...
ocfs2_add_inode_to_orphan
>>>>>>>> race window.
1) another node may rm the file and then down, this node take care of orphan recovery and clear flag OCFS2_DIO_ORPHANED_FL.
2) since rw lock is unlocked, it may race with another orphan recovery and append dio.
ocfs2_del_inode_from_orphan
So take Take inode mutex lock when recover orphans and make rw unlock at the end of aio write in case of append dio.
--- fs/ocfs2/aops.c | 9 ++++++--- fs/ocfs2/file.c | 2 +- fs/ocfs2/inode.h | 2 -- fs/ocfs2/journal.c | 8 ++++---- fs/ocfs2/namei.c | 42 +++++++++++++----------------------------- fs/ocfs2/super.c | 2 -- 6 files changed, 24 insertions(+), 41 deletions(-)
fs/ocfs2/aops.c +6 -3
@@ -627,10 +627,13 @@ static void ocfs2_dio_end_io(struct kiocb *iocb,mutex_unlock (&OCFS2_I (inode)->ip_unaligned_aio); } -ocfs2_iocb_clear_rw_locked (iocb); +/* Let rw unlock to be done later to protect append direct io write */ +if (offset + bytes <=i_size_read (inode)) { +ocfs2_iocb_clear_rw_locked (iocb); - level =ocfs2_iocb_rw_locked_level (iocb); -ocfs2_rw_unlock (inode, level); + level =ocfs2_iocb_rw_locked_level (iocb); +ocfs2_rw_unlock (inode, level); + } }static int ocfs2_releasepage (struct page *page,gfp_t wait)
fs/ocfs2/file.c +1 -1
@@ -2410,7 +2410,7 @@ no_sync: unaligned_dio =0 ; } -if (unaligned_dio) { +if (unaligned_dio &&ocfs2_iocb_is_unaligned_aio (iocb)) {ocfs2_iocb_clear_unaligned_aio (iocb);mutex_unlock (&OCFS2_I (inode)->ip_unaligned_aio); }
fs/ocfs2/inode.h +0 -2
@@ -81,8 +81,6 @@ struct ocfs2_inode_infotid_t i_sync_tid;tid_t i_datasync_tid; -wait_queue_head_t append_dio_wq; -struct dquot *i_dquot[MAXQUOTAS ]; };
fs/ocfs2/journal.c +4 -4
@@ -2170,6 +2170,7 @@ static int ocfs2_recover_orphans(struct ocfs2_super *osb, iter = oi->ip_next_orphan; oi->ip_next_orphan =NULL ; +mutex_lock (&inode->i_mutex); ret =ocfs2_rw_lock (inode,1 );if (ret <0 ) {mlog_errno (ret);
@@ -2206,17 +2207,16 @@ static int ocfs2_recover_orphans(struct ocfs2_super *osb, ret =ocfs2_del_inode_from_orphan (osb, inode, di_bh,0 ,0 );if (ret)mlog_errno (ret); - -wake_up (&OCFS2_I (inode)->append_dio_wq); }/* else if ORPHAN_NO_NEED_TRUNCATE, do nothing */ unlock_inode:ocfs2_inode_unlock (inode,1 ); +brelse (di_bh); + di_bh =NULL ; unlock_rw:ocfs2_rw_unlock (inode,1 ); next: +mutex_unlock (&inode->i_mutex);iput (inode); -brelse (di_bh); - di_bh =NULL ; inode = iter; }
fs/ocfs2/namei.c +13 -29
62 lines not on this page · raw message
fs/ocfs2/super.c +0 -2
@@ -1746,8 +1746,6 @@ static void ocfs2_inode_init_once(void *data)ocfs2_lock_res_init_once (&oi->ip_inode_lockres);ocfs2_lock_res_init_once (&oi->ip_open_lockres); -init_waitqueue_head (&oi->append_dio_wq); -ocfs2_metadata_cache_init (INODE_CACHE (&oi->vfs_inode), &ocfs2_inode_caching_ops);
Signature · 1 line
1.8.4.3
PATCH v2 1/2 ocfs2: fix race between dio and recover orphan
Hi Joseph,
The following added lines are same as the deleted. Is it because the unnecessary trailing whitespaces?
- level = ocfs2_iocb_rw_locked_level(iocb);
- ocfs2_rw_unlock(inode, level);
+ level = ocfs2_iocb_rw_locked_level(iocb);
+ ocfs2_rw_unlock(inode, level);
--
Eric
_______________________________________________
Ocfs2-devel mailing list
Ocfs2-devel at oss.oracle.com
https://oss.oracle.com/mailman/listinfo/ocfs2-devel
PATCH v2 1/2 ocfs2: fix race between dio and recover orphan
fs/ocfs2/aops.c static void ocfs2_dio_end_io(struct kiocb *iocb, · line 635
Quoted 9 lines · Zhen Ren
Hi Joseph,
The following added lines are same as the deleted. Is it because the unnecessary trailing whitespaces?
fs/ocfs2/aops.c +2
-2- level =ocfs2_iocb_rw_locked_level (iocb); -ocfs2_rw_unlock (inode, level); + level =ocfs2_iocb_rw_locked_level (iocb); +ocfs2_rw_unlock (inode, level);
No, I want rw unlock to be done later in case of append direct io. This is for preventing the described race case.
Quoted 10 lines
--
Eric
_______________________________________________
Ocfs2-devel mailing list
Ocfs2-devel at oss.oracle.com
https://oss.oracle.com/mailman/listinfo/ocfs2-devel