diff options
| author | Jens Axboe <jaxboe@fusionio.com> | 2010-11-16 10:09:42 +0100 | 
|---|---|---|
| committer | Jens Axboe <jaxboe@fusionio.com> | 2010-11-16 10:09:42 +0100 | 
| commit | a02056349cdea2252cd2b21643ebf025e83a29f2 (patch) | |
| tree | b7c889d6cbe8e7188d07d99a5c9da858c53a5b6c /fs/jbd2/commit.c | |
| parent | 34db1d595ef6f183fbc1e42cda45a3dfa0035258 (diff) | |
| parent | e53beacd23d9cb47590da6a7a7f6d417b941a994 (diff) | |
| download | talos-op-linux-a02056349cdea2252cd2b21643ebf025e83a29f2.tar.gz talos-op-linux-a02056349cdea2252cd2b21643ebf025e83a29f2.zip  | |
Merge branch 'v2.6.37-rc2' into for-2.6.38/core
Diffstat (limited to 'fs/jbd2/commit.c')
| -rw-r--r-- | fs/jbd2/commit.c | 88 | 
1 files changed, 29 insertions, 59 deletions
diff --git a/fs/jbd2/commit.c b/fs/jbd2/commit.c index 7c068c189d80..f3ad1598b201 100644 --- a/fs/jbd2/commit.c +++ b/fs/jbd2/commit.c @@ -26,7 +26,9 @@  #include <linux/backing-dev.h>  #include <linux/bio.h>  #include <linux/blkdev.h> +#include <linux/bitops.h>  #include <trace/events/jbd2.h> +#include <asm/system.h>  /*   * Default IO end handler for temporary BJ_IO buffer_heads. @@ -134,25 +136,11 @@ static int journal_submit_commit_record(journal_t *journal,  	if (journal->j_flags & JBD2_BARRIER &&  	    !JBD2_HAS_INCOMPAT_FEATURE(journal, -				       JBD2_FEATURE_INCOMPAT_ASYNC_COMMIT)) { -		ret = submit_bh(WRITE_SYNC_PLUG | WRITE_BARRIER, bh); -		if (ret == -EOPNOTSUPP) { -			printk(KERN_WARNING -			       "JBD2: Disabling barriers on %s, " -			       "not supported by device\n", journal->j_devname); -			write_lock(&journal->j_state_lock); -			journal->j_flags &= ~JBD2_BARRIER; -			write_unlock(&journal->j_state_lock); - -			/* And try again, without the barrier */ -			lock_buffer(bh); -			set_buffer_uptodate(bh); -			clear_buffer_dirty(bh); -			ret = submit_bh(WRITE_SYNC_PLUG, bh); -		} -	} else { +				       JBD2_FEATURE_INCOMPAT_ASYNC_COMMIT)) +		ret = submit_bh(WRITE_SYNC_PLUG | WRITE_FLUSH_FUA, bh); +	else  		ret = submit_bh(WRITE_SYNC_PLUG, bh); -	} +  	*cbh = bh;  	return ret;  } @@ -166,29 +154,8 @@ static int journal_wait_on_commit_record(journal_t *journal,  {  	int ret = 0; -retry:  	clear_buffer_dirty(bh);  	wait_on_buffer(bh); -	if (buffer_eopnotsupp(bh) && (journal->j_flags & JBD2_BARRIER)) { -		printk(KERN_WARNING -		       "JBD2: %s: disabling barries on %s - not supported " -		       "by device\n", __func__, journal->j_devname); -		write_lock(&journal->j_state_lock); -		journal->j_flags &= ~JBD2_BARRIER; -		write_unlock(&journal->j_state_lock); - -		lock_buffer(bh); -		clear_buffer_dirty(bh); -		set_buffer_uptodate(bh); -		bh->b_end_io = journal_end_buffer_io_sync; - -		ret = submit_bh(WRITE_SYNC_PLUG, bh); -		if (ret) { -			unlock_buffer(bh); -			return ret; -		} -		goto retry; -	}  	if (unlikely(!buffer_uptodate(bh)))  		ret = -EIO; @@ -236,7 +203,7 @@ static int journal_submit_data_buffers(journal_t *journal,  	spin_lock(&journal->j_list_lock);  	list_for_each_entry(jinode, &commit_transaction->t_inode_list, i_list) {  		mapping = jinode->i_vfs_inode->i_mapping; -		jinode->i_flags |= JI_COMMIT_RUNNING; +		set_bit(__JI_COMMIT_RUNNING, &jinode->i_flags);  		spin_unlock(&journal->j_list_lock);  		/*  		 * submit the inode data buffers. We use writepage @@ -251,7 +218,8 @@ static int journal_submit_data_buffers(journal_t *journal,  		spin_lock(&journal->j_list_lock);  		J_ASSERT(jinode->i_transaction == commit_transaction);  		commit_transaction->t_flushed_data_blocks = 1; -		jinode->i_flags &= ~JI_COMMIT_RUNNING; +		clear_bit(__JI_COMMIT_RUNNING, &jinode->i_flags); +		smp_mb__after_clear_bit();  		wake_up_bit(&jinode->i_flags, __JI_COMMIT_RUNNING);  	}  	spin_unlock(&journal->j_list_lock); @@ -272,7 +240,7 @@ static int journal_finish_inode_data_buffers(journal_t *journal,  	/* For locking, see the comment in journal_submit_data_buffers() */  	spin_lock(&journal->j_list_lock);  	list_for_each_entry(jinode, &commit_transaction->t_inode_list, i_list) { -		jinode->i_flags |= JI_COMMIT_RUNNING; +		set_bit(__JI_COMMIT_RUNNING, &jinode->i_flags);  		spin_unlock(&journal->j_list_lock);  		err = filemap_fdatawait(jinode->i_vfs_inode->i_mapping);  		if (err) { @@ -288,7 +256,8 @@ static int journal_finish_inode_data_buffers(journal_t *journal,  				ret = err;  		}  		spin_lock(&journal->j_list_lock); -		jinode->i_flags &= ~JI_COMMIT_RUNNING; +		clear_bit(__JI_COMMIT_RUNNING, &jinode->i_flags); +		smp_mb__after_clear_bit();  		wake_up_bit(&jinode->i_flags, __JI_COMMIT_RUNNING);  	} @@ -360,7 +329,7 @@ void jbd2_journal_commit_transaction(journal_t *journal)  	int tag_bytes = journal_tag_bytes(journal);  	struct buffer_head *cbh = NULL; /* For transactional checksums */  	__u32 crc32_sum = ~0; -	int write_op = WRITE; +	int write_op = WRITE_SYNC;  	/*  	 * First job: lock down the current transaction and wait for @@ -701,6 +670,16 @@ start_journal_io:  		}  	} +	err = journal_finish_inode_data_buffers(journal, commit_transaction); +	if (err) { +		printk(KERN_WARNING +			"JBD2: Detected IO errors while flushing file data " +		       "on %s\n", journal->j_devname); +		if (journal->j_flags & JBD2_ABORT_ON_SYNCDATA_ERR) +			jbd2_journal_abort(journal, err); +		err = 0; +	} +  	/*   	 * If the journal is not located on the file system device,  	 * then we must flush the file system device before we issue @@ -709,8 +688,7 @@ start_journal_io:  	if (commit_transaction->t_flushed_data_blocks &&  	    (journal->j_fs_dev != journal->j_dev) &&  	    (journal->j_flags & JBD2_BARRIER)) -		blkdev_issue_flush(journal->j_fs_dev, GFP_KERNEL, NULL, -			BLKDEV_IFL_WAIT); +		blkdev_issue_flush(journal->j_fs_dev, GFP_KERNEL, NULL);  	/* Done it all: now write the commit record asynchronously. */  	if (JBD2_HAS_INCOMPAT_FEATURE(journal, @@ -719,19 +697,6 @@ start_journal_io:  						 &cbh, crc32_sum);  		if (err)  			__jbd2_journal_abort_hard(journal); -		if (journal->j_flags & JBD2_BARRIER) -			blkdev_issue_flush(journal->j_dev, GFP_KERNEL, NULL, -				BLKDEV_IFL_WAIT); -	} - -	err = journal_finish_inode_data_buffers(journal, commit_transaction); -	if (err) { -		printk(KERN_WARNING -			"JBD2: Detected IO errors while flushing file data " -		       "on %s\n", journal->j_devname); -		if (journal->j_flags & JBD2_ABORT_ON_SYNCDATA_ERR) -			jbd2_journal_abort(journal, err); -		err = 0;  	}  	/* Lo and behold: we have just managed to send a transaction to @@ -845,6 +810,11 @@ wait_for_iobuf:  	}  	if (!err && !is_journal_aborted(journal))  		err = journal_wait_on_commit_record(journal, cbh); +	if (JBD2_HAS_INCOMPAT_FEATURE(journal, +				      JBD2_FEATURE_INCOMPAT_ASYNC_COMMIT) && +	    journal->j_flags & JBD2_BARRIER) { +		blkdev_issue_flush(journal->j_dev, GFP_KERNEL, NULL); +	}  	if (err)  		jbd2_journal_abort(journal, err);  | 

