[7/9] Btrfs: stop joining the log transaction if sync log fails
diff mbox

Message ID 1392890939-19044-7-git-send-email-miaox@cn.fujitsu.com
State Accepted, archived
Headers show

Commit Message

Miao Xie Feb. 20, 2014, 10:08 a.m. UTC
If the log sync fails, there is something wrong in the log tree, we
should not continue to join the log transaction and log the metadata.
What we should do is to do a full commit.

This patch fixes this problem by setting ->last_trans_log_full_commit
to the current transaction id, it will tell the tasks not to join
the log transaction, and do a full commit.

Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
---
 fs/btrfs/tree-log.c | 16 ++++++++++++++--
 1 file changed, 14 insertions(+), 2 deletions(-)

Comments

David Sterba Feb. 22, 2014, 12:27 a.m. UTC | #1
On Thu, Feb 20, 2014 at 06:08:57PM +0800, Miao Xie wrote:
> --- a/fs/btrfs/tree-log.c
> +++ b/fs/btrfs/tree-log.c
> @@ -142,6 +142,12 @@ static int start_log_trans(struct btrfs_trans_handle *trans,
>  
>  	mutex_lock(&root->log_mutex);
>  	if (root->log_root) {
> +		if (ACCESS_ONCE(root->fs_info->last_trans_log_full_commit) ==
> +		    trans->transid) {
> +			ret = -EAGAIN;
> +			goto out;
> +		}

So last_trans_log_full_commit needs special handling, but opencoding it
everywhere is no very clean. Documented set/get helpers would be much
better.
--
To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Miao Xie Feb. 26, 2014, 8:51 a.m. UTC | #2
On Sat, 22 Feb 2014 01:27:51 +0100, David Sterba wrote:
> On Thu, Feb 20, 2014 at 06:08:57PM +0800, Miao Xie wrote:
>> --- a/fs/btrfs/tree-log.c
>> +++ b/fs/btrfs/tree-log.c
>> @@ -142,6 +142,12 @@ static int start_log_trans(struct btrfs_trans_handle *trans,
>>  
>>  	mutex_lock(&root->log_mutex);
>>  	if (root->log_root) {
>> +		if (ACCESS_ONCE(root->fs_info->last_trans_log_full_commit) ==
>> +		    trans->transid) {
>> +			ret = -EAGAIN;
>> +			goto out;
>> +		}
> 
> So last_trans_log_full_commit needs special handling, but opencoding it
> everywhere is no very clean. Documented set/get helpers would be much
> better.
> 

Right, I'll update it in the next version.

Thanks for your review.
Miao
--
To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Patch
diff mbox

diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c
index c27e2c9..4326da9 100644
--- a/fs/btrfs/tree-log.c
+++ b/fs/btrfs/tree-log.c
@@ -142,6 +142,12 @@  static int start_log_trans(struct btrfs_trans_handle *trans,
 
 	mutex_lock(&root->log_mutex);
 	if (root->log_root) {
+		if (ACCESS_ONCE(root->fs_info->last_trans_log_full_commit) ==
+		    trans->transid) {
+			ret = -EAGAIN;
+			goto out;
+		}
+
 		if (!root->log_start_pid) {
 			root->log_start_pid = current->pid;
 			clear_bit(BTRFS_ROOT_MULTI_LOG_TASKS, &root->state);
@@ -2488,6 +2494,8 @@  int btrfs_sync_log(struct btrfs_trans_handle *trans,
 		blk_finish_plug(&plug);
 		btrfs_abort_transaction(trans, root, ret);
 		btrfs_free_logged_extents(log, log_transid);
+		ACCESS_ONCE(root->fs_info->last_trans_log_full_commit) =
+								trans->transid;
 		mutex_unlock(&root->log_mutex);
 		goto out;
 	}
@@ -2520,13 +2528,13 @@  int btrfs_sync_log(struct btrfs_trans_handle *trans,
 
 	if (ret) {
 		blk_finish_plug(&plug);
+		ACCESS_ONCE(root->fs_info->last_trans_log_full_commit) =
+								trans->transid;
 		if (ret != -ENOSPC) {
 			btrfs_abort_transaction(trans, root, ret);
 			mutex_unlock(&log_root_tree->log_mutex);
 			goto out;
 		}
-		ACCESS_ONCE(root->fs_info->last_trans_log_full_commit) =
-								trans->transid;
 		btrfs_wait_marked_extents(log, &log->dirty_log_pages, mark);
 		btrfs_free_logged_extents(log, log_transid);
 		mutex_unlock(&log_root_tree->log_mutex);
@@ -2572,6 +2580,8 @@  int btrfs_sync_log(struct btrfs_trans_handle *trans,
 					 EXTENT_DIRTY | EXTENT_NEW);
 	blk_finish_plug(&plug);
 	if (ret) {
+		ACCESS_ONCE(root->fs_info->last_trans_log_full_commit) =
+								trans->transid;
 		btrfs_abort_transaction(trans, root, ret);
 		btrfs_free_logged_extents(log, log_transid);
 		mutex_unlock(&log_root_tree->log_mutex);
@@ -2600,6 +2610,8 @@  int btrfs_sync_log(struct btrfs_trans_handle *trans,
 	 */
 	ret = write_ctree_super(trans, root->fs_info->tree_root, 1);
 	if (ret) {
+		ACCESS_ONCE(root->fs_info->last_trans_log_full_commit) =
+								trans->transid;
 		btrfs_abort_transaction(trans, root, ret);
 		goto out_wake_log_root;
 	}