Skip to content

Commit 7f27ec9

Browse files
yangwenfangtorvalds
authored andcommitted
ocfs2: call ocfs2_journal_access_di() before ocfs2_journal_dirty() in ocfs2_write_end_nolock()
1: After we call ocfs2_journal_access_di() in ocfs2_write_begin(), jbd2_journal_restart() may also be called, in this function transaction A's t_updates-- and obtains a new transaction B. If jbd2_journal_commit_transaction() is happened to commit transaction A, when t_updates==0, it will continue to complete commit and unfile buffer. So when jbd2_journal_dirty_metadata(), the handle is pointed a new transaction B, and the buffer head's journal head is already freed, jh->b_transaction == NULL, jh->b_next_transaction == NULL, it returns EINVAL, So it triggers the BUG_ON(status). thread 1 jbd2 ocfs2_write_begin jbd2_journal_commit_transaction ocfs2_write_begin_nolock ocfs2_start_trans jbd2__journal_start(t_updates+1, transaction A) ocfs2_journal_access_di ocfs2_write_cluster_by_desc ocfs2_mark_extent_written ocfs2_change_extent_flag ocfs2_split_extent ocfs2_extend_rotate_transaction jbd2_journal_restart (t_updates-1,transaction B) t_updates==0 __jbd2_journal_refile_buffer (jh->b_transaction = NULL) ocfs2_write_end ocfs2_write_end_nolock ocfs2_journal_dirty jbd2_journal_dirty_metadata(bug) ocfs2_commit_trans 2. In ext4, I found that: jbd2_journal_get_write_access() called by ext4_write_end. ext4_write_begin ext4_journal_start __ext4_journal_start_sb ext4_journal_check_start jbd2__journal_start ext4_write_end ext4_mark_inode_dirty ext4_reserve_inode_write ext4_journal_get_write_access jbd2_journal_get_write_access ext4_mark_iloc_dirty ext4_do_update_inode ext4_handle_dirty_metadata jbd2_journal_dirty_metadata 3. So I think we should put ocfs2_journal_access_di before ocfs2_journal_dirty in the ocfs2_write_end. and it works well after my modification. Signed-off-by: vicky <[email protected]> Reviewed-by: Mark Fasheh <[email protected]> Cc: Joel Becker <[email protected]> Cc: Zhangguanghui <[email protected]> Signed-off-by: Andrew Morton <[email protected]> Signed-off-by: Linus Torvalds <[email protected]>
1 parent 40476b8 commit 7f27ec9

File tree

1 file changed

+11
-5
lines changed

1 file changed

+11
-5
lines changed

fs/ocfs2/aops.c

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2207,10 +2207,7 @@ int ocfs2_write_begin_nolock(struct file *filp,
22072207
if (ret)
22082208
goto out_commit;
22092209
}
2210-
/*
2211-
* We don't want this to fail in ocfs2_write_end(), so do it
2212-
* here.
2213-
*/
2210+
22142211
ret = ocfs2_journal_access_di(handle, INODE_CACHE(inode), wc->w_di_bh,
22152212
OCFS2_JOURNAL_ACCESS_WRITE);
22162213
if (ret) {
@@ -2367,7 +2364,7 @@ int ocfs2_write_end_nolock(struct address_space *mapping,
23672364
loff_t pos, unsigned len, unsigned copied,
23682365
struct page *page, void *fsdata)
23692366
{
2370-
int i;
2367+
int i, ret;
23712368
unsigned from, to, start = pos & (PAGE_CACHE_SIZE - 1);
23722369
struct inode *inode = mapping->host;
23732370
struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
@@ -2376,6 +2373,14 @@ int ocfs2_write_end_nolock(struct address_space *mapping,
23762373
handle_t *handle = wc->w_handle;
23772374
struct page *tmppage;
23782375

2376+
ret = ocfs2_journal_access_di(handle, INODE_CACHE(inode), wc->w_di_bh,
2377+
OCFS2_JOURNAL_ACCESS_WRITE);
2378+
if (ret) {
2379+
copied = ret;
2380+
mlog_errno(ret);
2381+
goto out;
2382+
}
2383+
23792384
if (OCFS2_I(inode)->ip_dyn_features & OCFS2_INLINE_DATA_FL) {
23802385
ocfs2_write_end_inline(inode, pos, len, &copied, di, wc);
23812386
goto out_write_size;
@@ -2431,6 +2436,7 @@ int ocfs2_write_end_nolock(struct address_space *mapping,
24312436
ocfs2_update_inode_fsync_trans(handle, inode, 1);
24322437
ocfs2_journal_dirty(handle, wc->w_di_bh);
24332438

2439+
out:
24342440
/* unlock pages before dealloc since it needs acquiring j_trans_barrier
24352441
* lock, or it will cause a deadlock since journal commit threads holds
24362442
* this lock and will ask for the page lock when flushing the data.

0 commit comments

Comments
 (0)