ocfs2 fixes
PATCH 1/1 ocfs2 fixes
Please pull from 'upstream-linus' branch ofgit://git.kernel.org/pub/scm/linux/kernel/git/mfasheh/ocfs2.git upstream-linus
to receive the following updates:
fs/ocfs2/alloc.c | 68 ++++++++++++++++++++++++++++++++++----------------- fs/ocfs2/journal.c | 13 +++++++++- 2 files changed, 57 insertions(+), 24 deletions(-)
Mark Fasheh (4):
ocfs2: fix exit-while-locked bug in ocfs2_queue_orphans()
ocfs2: Don't panic when truncating an empty extent
ocfs2: Allow for debugging of transaction extends
ocfs2: Re-journal buffers after transaction extend
fs/ocfs2/alloc.c +45 -23
@@ -2389,6 +2389,18 @@ static int __ocfs2_rotate_tree_left(struct inode *inode, goto out; } +/* +* Caller might still want to make changes to the +* tree root, so re-add it to the journal here. +*/ + ret =ocfs2_journal_access (handle, inode, +path_root_bh (left_path), +OCFS2_JOURNAL_ACCESS_WRITE ); +if (ret) { +mlog_errno (ret); + goto out; + } + ret =ocfs2_rotate_subtree_left (inode, handle, left_path, right_path, subtree_root, dealloc, &deleted);
@@ -3289,16 +3301,6 @@ static int ocfs2_insert_path(struct inode *inode,int ret, subtree_index;struct buffer_head *leaf_bh =path_leaf_bh (right_path); -/* -* Pass both paths to the journal. The majority of inserts -* will be touching all components anyway. -*/ - ret =ocfs2_journal_access_path (inode, handle, right_path); -if (ret <0 ) { -mlog_errno (ret); - goto out; - } -if (left_path) {int credits = handle->h_buffer_credits;
@@ -3323,6 +3325,16 @@ static int ocfs2_insert_path(struct inode *inode, } } +/* +* Pass both paths to the journal. The majority of inserts +* will be touching all components anyway. +*/ + ret =ocfs2_journal_access_path (inode, handle, right_path); +if (ret <0 ) { +mlog_errno (ret); + goto out; + } +if (insert->ins_split !=SPLIT_NONE ) {/* * We could call ocfs2_insert_at_leaf() for some types
@@ -3331,6 +3343,17 @@ static int ocfs2_insert_path(struct inode *inode,*/ ocfs2_split_record (inode, left_path, right_path, insert_rec, insert->ins_split); + +/* +* Split might have modified either leaf and we don't +* have a guarantee that the later edge insert will +* dirty this for us. +*/ +if (left_path) + ret =ocfs2_journal_dirty (handle, +path_leaf_bh (left_path)); +if (ret) +mlog_errno (ret); }else ocfs2_insert_at_leaf (insert_rec,path_leaf_el (right_path), insert, inode);
@@ -3430,6 +3453,17 @@ static int ocfs2_do_insert_extent(struct inode *inode,mlog_errno (ret); goto out; } + +/* +* ocfs2_rotate_tree_right() might have extended the +* transaction without re-journaling our tree root. +*/ + ret =ocfs2_journal_access (handle, inode, di_bh, +OCFS2_JOURNAL_ACCESS_WRITE ); +if (ret) { +mlog_errno (ret); + goto out; + } }else if (type->ins_appending ==APPEND_TAIL && type->ins_contig !=CONTIG_LEFT ) { ret = ocfs2_append_rec_to_path(inode, handle, insert_rec,
@@ -3941,7 +3975,7 @@ static int __ocfs2_mark_extent_written(struct inode *inode, {int ret =0 ;struct ocfs2_extent_list *el =path_leaf_el (path); -struct buffer_head *eb_bh, *last_eb_bh =NULL ; +struct buffer_head *last_eb_bh =NULL ;struct ocfs2_extent_rec *rec = &el->l_recs[split_index];struct ocfs2_merge_ctxt ctxt;struct ocfs2_extent_list *rightmost_el;
@@ -3960,14 +3994,6 @@ static int __ocfs2_mark_extent_written(struct inode *inode, goto out; } - eb_bh =path_leaf_bh (path); - ret =ocfs2_journal_access (handle, inode, eb_bh, -OCFS2_JOURNAL_ACCESS_WRITE ); -if (ret) { -mlog_errno (ret); - goto out; - } - ctxt.c_contig_type =ocfs2_figure_merge_contig_type (inode, el, split_index, split_rec);
@@ -4029,8 +4055,6 @@ static int __ocfs2_mark_extent_written(struct inode *inode,mlog_errno (ret); } -ocfs2_journal_dirty (handle, eb_bh); - out:brelse (last_eb_bh);return ret;
@@ -6093,8 +6117,6 @@ start:mlog (0 ,"clusters_to_del = %u in this pass, tail blk=%llu\n" , clusters_to_del, (unsigned long long )path_leaf_bh (path)->b_blocknr); -BUG_ON (clusters_to_del ==0 ); -mutex_lock (&tl_inode->i_mutex); tl_sem =1 ;/* ocfs2_truncate_log_needs_flush guarantees us at least one
fs/ocfs2/journal.c +12 -1
@@ -174,6 +174,12 @@ int ocfs2_commit_trans(struct ocfs2_super *osb,* transaction. extend_trans will either extend the current handle by * nblocks, or commit it and start a new one with nblocks credits. * +* This might call journal_restart() which will commit dirty buffers +* and then restart the transaction. Before calling +* ocfs2_extend_trans(), any changed blocks should have been +* dirtied. After calling it, all blocks which need to be changed must +* go through another set of journal_access/journal_dirty calls. +* * WARNING: This will not release any semaphores or disk locks taken * during the transaction, so make sure they were taken *before* * start_trans or we'll have ordering deadlocks.
@@ -193,11 +199,15 @@ int ocfs2_extend_trans(handle_t *handle, int nblocks)mlog (0 ,"Trying to extend transaction by %d blocks\n" , nblocks); +#ifdef OCFS2_DEBUG_FS + status =1 ; +#else status =journal_extend (handle, nblocks);if (status <0 ) {mlog_errno (status); goto bail; } +#endif if (status >0 ) {mlog (0 ,"journal_extend failed, trying journal_restart\n" );
@@ -1277,11 +1287,12 @@ static int ocfs2_queue_orphans(struct ocfs2_super *osb, ocfs2_orphan_filldir);if (status) {mlog_errno (status); - goto out; + goto out_cluster; } *head = priv.head; +out_cluster:ocfs2_meta_unlock (orphan_dir_inode,0 ); out:mutex_unlock (&orphan_dir_inode->i_mutex);