ocfs2: extend transaction for ocfs2_remove_rightmost_path and ocfs2_update_edge_lengths before to avoid inconsistency between inode and et
PATCH 1/3 ocfs2: extend transaction for ocfs2_remove_rightmost_path and ocfs2_update_edge_lengths before to avoid inconsistency between inode and et
The following functions will be called while truncating an extent:ocfs2_remove_btree_range
-> ocfs2_start_trans
-> ocfs2_remove_extent
-> ocfs2_truncate_rec
-> ocfs2_extend_rotate_transaction
-> jbd2_journal_restart if jbd2_journal_extend fail
-> ocfs2_rotate_tree_left
-> ocfs2_remove_rightmost_path
-> ocfs2_extend_rotate_transaction
-> ocfs2_unlink_subtree
-> ocfs2_update_edge_lengths
-> ocfs2_extend_trans
-> jbd2_journal_restart if jbd2_journal_extend fail -> ocfs2_et_update_clusters
-> ocfs2_commit_trans
Function jbd2_journal_restart() may be called and it may happened that the buffers dirtied in ocfs2_truncate_rec() are committed while buffers dirtied in ocfs2_et_update_clusters() are not, the total clusters on extent tree and i_clusters in ocfs2_dinode is inconsistency. So the clusters got from ocfs2_dinode is incorrect, and it also cause read-only problem when call ocfs2_commit_truncate() with the error message:
"Inode %llu has empty extent block at %llu".
We should extend enough credits for function ocfs2_remove_rightmost_path and ocfs2_update_edge_lengths to avoid this inconsistency.
--- fs/ocfs2/alloc.c | 82 +++++++++++++++++++++++++++++++++++++------------------- 1 file changed, 54 insertions(+), 28 deletions(-)
fs/ocfs2/alloc.c +54 -28
@@ -2526,21 +2526,6 @@ static int ocfs2_update_edge_lengths(handle_t *handle,struct ocfs2_extent_block *eb;u32 range; -/* -* In normal tree rotation process, we will never touch the -* tree branch above subtree_index and ocfs2_extend_rotate_transaction -* doesn't reserve the credits for them either. -* -* But we do have a special case here which will update the rightmost -* records for all the bh in the path. -* So we have to allocate extra credits and access them. -*/ - ret =ocfs2_extend_trans (handle, subtree_index); -if (ret) { -mlog_errno (ret); - goto out; - } - ret =ocfs2_journal_access_path (et->et_ci, handle, path);if (ret) {mlog_errno (ret);
@@ -2967,7 +2952,7 @@ static int __ocfs2_rotate_tree_left(handle_t *handle, right_path->p_node[subtree_root].bh->b_blocknr, right_path->p_tree_depth); - ret =ocfs2_extend_rotate_transaction (handle, subtree_root, + ret =ocfs2_extend_rotate_transaction (handle,0 , orig_credits, left_path);if (ret) {mlog_errno (ret);
@@ -3040,21 +3025,9 @@ static int ocfs2_remove_rightmost_path(handle_t *handle,struct ocfs2_extent_block *eb;struct ocfs2_extent_list *el; - ret =ocfs2_et_sanity_check (et);if (ret) goto out; -/* -* There's two ways we handle this depending on -* whether path is the only existing one. -*/ - ret =ocfs2_extend_rotate_transaction (handle,0 , - handle->h_buffer_credits, - path); -if (ret) { -mlog_errno (ret); - goto out; - } ret =ocfs2_journal_access_path (et->et_ci, handle, path);if (ret) {
@@ -3628,6 +3601,14 @@ static int ocfs2_merge_rec_left(struct ocfs2_path *right_path,*/ if (le16_to_cpu (right_rec->e_leaf_clusters) ==0 &&le16_to_cpu (el->l_next_free_rec) ==1 ) { +/* extend credit for ocfs2_remove_rightmost_path */ + ret =ocfs2_extend_rotate_transaction (handle,0 , + handle->h_buffer_credits, + right_path); +if (ret) { +mlog_errno (ret); + goto out; + } ret = ocfs2_remove_rightmost_path(handle, et, right_path,
@@ -3666,6 +3647,14 @@ static int ocfs2_try_to_merge_extent(handle_t *handle,BUG_ON (ctxt->c_contig_type ==CONTIG_NONE );if (ctxt->c_split_covers_rec && ctxt->c_has_empty_extent) { +/* extend credit for ocfs2_remove_rightmost_path */ + ret =ocfs2_extend_rotate_transaction (handle,0 , + handle->h_buffer_credits, + path); +if (ret) { +mlog_errno (ret); + goto out; + }/* * The merge code will need to create an empty * extent to take the place of the newly
@@ -3714,6 +3703,15 @@ static int ocfs2_try_to_merge_extent(handle_t *handle,*/ BUG_ON (!ocfs2_is_empty_extent (&el->l_recs[0 ])); +/* extend credit for ocfs2_remove_rightmost_path */ + ret =ocfs2_extend_rotate_transaction (handle,0 , + handle->h_buffer_credits, + path); +if (ret) { +mlog_errno (ret); + goto out; + } +/* The merge left us with an empty extent, remove it. */ ret =ocfs2_rotate_tree_left (handle, et, path, dealloc);if (ret) {
@@ -3735,6 +3733,15 @@ static int ocfs2_try_to_merge_extent(handle_t *handle, goto out; } +/* extend credit for ocfs2_remove_rightmost_path */ + ret =ocfs2_extend_rotate_transaction (handle,0 , + handle->h_buffer_credits, + path); +if (ret) { +mlog_errno (ret); + goto out; + } + ret =ocfs2_rotate_tree_left (handle, et, path, dealloc);/* * Error from this last rotate is not critical, so
@@ -3770,6 +3777,16 @@ static int ocfs2_try_to_merge_extent(handle_t *handle, }if (ctxt->c_split_covers_rec) { +/* extend credit for ocfs2_remove_rightmost_path */ + ret =ocfs2_extend_rotate_transaction (handle,0 , + handle->h_buffer_credits, + path); +if (ret) { +mlog_errno (ret); + ret =0 ; + goto out; + } +/* * The merge may have left an empty extent in * our leaf. Try to rotate it away.
@@ -5337,6 +5354,15 @@ static int ocfs2_truncate_rec(handle_t *handle,struct ocfs2_extent_block *eb;if (ocfs2_is_empty_extent (&el->l_recs[0 ]) && index >0 ) { +/* extend credit for ocfs2_remove_rightmost_path */ + ret =ocfs2_extend_rotate_transaction (handle,0 , + handle->h_buffer_credits, + path); +if (ret) { +mlog_errno (ret); + goto out; + } + ret =ocfs2_rotate_tree_left (handle, et, path, dealloc);if (ret) {mlog_errno (ret);
Signature · 1 line
1.8.4.3