diff options
| author | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-12-17 13:36:00 -0800 | 
|---|---|---|
| committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-12-17 13:36:00 -0800 | 
| commit | 23afc5c67588c92a062b4828a97b119755dffb51 (patch) | |
| tree | 637cdaf8e1a64075840026ee080ebb68cec5289e /fs | |
| parent | 13ef7b69b54aa8ae4ed264d0bf41339737f8543a (diff) | |
| parent | e8aed3450c0afd6fdb79ec233f806e3e69454dfe (diff) | |
Merge branch 'upstream-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mfasheh/ocfs2
* 'upstream-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mfasheh/ocfs2:
  ocfs2: Re-journal buffers after transaction extend
  ocfs2: Allow for debugging of transaction extends
  ocfs2: Don't panic when truncating an empty extent
  ocfs2: fix exit-while-locked bug in ocfs2_queue_orphans()
Diffstat (limited to 'fs')
| -rw-r--r-- | fs/ocfs2/alloc.c | 68 | ||||
| -rw-r--r-- | fs/ocfs2/journal.c | 13 | 
2 files changed, 57 insertions, 24 deletions
| diff --git a/fs/ocfs2/alloc.c b/fs/ocfs2/alloc.c index ce62c152823..23c8cda43f1 100644 --- a/fs/ocfs2/alloc.c +++ b/fs/ocfs2/alloc.c @@ -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 diff --git a/fs/ocfs2/journal.c b/fs/ocfs2/journal.c index f9d01e25298..8d81f6c1b87 100644 --- a/fs/ocfs2/journal.c +++ b/fs/ocfs2/journal.c @@ -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); | 
