All of lore.kernel.org
 help / color / mirror / Atom feed
From: Miao Xie <miaox@cn.fujitsu.com>
To: <linux-btrfs@vger.kernel.org>
Subject: [PATCH 05/18] Btrfs: fix wrong device bytes_used in the super block
Date: Wed, 3 Sep 2014 21:35:34 +0800	[thread overview]
Message-ID: <1409751347-5296-5-git-send-email-miaox@cn.fujitsu.com> (raw)
In-Reply-To: <1409751347-5296-1-git-send-email-miaox@cn.fujitsu.com>

device->bytes_used will be changed when allocating a new chunk, and
disk_total_size will be changed if resizing is successful.
Meanwhile, the on-disk super blocks of the previous transaction
might not be updated. Considering the consistency of the metadata
in the previous transaction, We should use the size in the previous
transaction to check if the super block is beyond the boundary
of the device.

Though it is not big problem because we don't use it now, but anyway
it is better that we make it be consistent with the common metadata,
maybe we will use it in the future.

Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
---
 fs/btrfs/dev-replace.c |  3 +++
 fs/btrfs/disk-io.c     |  3 ++-
 fs/btrfs/transaction.c |  1 +
 fs/btrfs/volumes.c     | 27 +++++++++++++++++++++++++++
 fs/btrfs/volumes.h     |  4 ++++
 5 files changed, 37 insertions(+), 1 deletion(-)

diff --git a/fs/btrfs/dev-replace.c b/fs/btrfs/dev-replace.c
index 7877b0f..1be03d8 100644
--- a/fs/btrfs/dev-replace.c
+++ b/fs/btrfs/dev-replace.c
@@ -172,6 +172,8 @@ no_valid_dev_replace_entry_found:
 					dev_replace->srcdev->commit_total_bytes;
 				dev_replace->tgtdev->bytes_used =
 					dev_replace->srcdev->bytes_used;
+				dev_replace->tgtdev->commit_bytes_used =
+					dev_replace->srcdev->commit_bytes_used;
 			}
 			dev_replace->tgtdev->is_tgtdev_for_dev_replace = 1;
 			btrfs_init_dev_replace_tgtdev_for_resume(fs_info,
@@ -558,6 +560,7 @@ static int btrfs_dev_replace_finishing(struct btrfs_fs_info *fs_info,
 	ASSERT(list_empty(&src_device->resized_list));
 	tgt_device->commit_total_bytes = src_device->commit_total_bytes;
 	tgt_device->bytes_used = src_device->bytes_used;
+	tgt_device->commit_bytes_used = src_device->bytes_used;
 	if (fs_info->sb->s_bdev == src_device->bdev)
 		fs_info->sb->s_bdev = tgt_device->bdev;
 	if (fs_info->fs_devices->latest_bdev == src_device->bdev)
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index 0c7ae0e..ff3ee22 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -3450,7 +3450,8 @@ static int write_all_supers(struct btrfs_root *root, int max_mirrors)
 		btrfs_set_stack_device_id(dev_item, dev->devid);
 		btrfs_set_stack_device_total_bytes(dev_item,
 						   dev->commit_total_bytes);
-		btrfs_set_stack_device_bytes_used(dev_item, dev->bytes_used);
+		btrfs_set_stack_device_bytes_used(dev_item,
+						  dev->commit_bytes_used);
 		btrfs_set_stack_device_io_align(dev_item, dev->io_align);
 		btrfs_set_stack_device_io_width(dev_item, dev->io_width);
 		btrfs_set_stack_device_sector_size(dev_item, dev->sector_size);
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c
index 2f7c0be..16d0c1b 100644
--- a/fs/btrfs/transaction.c
+++ b/fs/btrfs/transaction.c
@@ -1869,6 +1869,7 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans,
 	       sizeof(*root->fs_info->super_copy));
 
 	btrfs_update_commit_device_size(root->fs_info);
+	btrfs_update_commit_device_bytes_used(root, cur_trans);
 
 	spin_lock(&root->fs_info->trans_lock);
 	cur_trans->state = TRANS_STATE_UNBLOCKED;
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
index 7b5c042..f8273bb 100644
--- a/fs/btrfs/volumes.c
+++ b/fs/btrfs/volumes.c
@@ -2370,6 +2370,7 @@ int btrfs_init_dev_replace_tgtdev(struct btrfs_root *root, char *device_path,
 	ASSERT(list_empty(&srcdev->resized_list));
 	device->commit_total_bytes = srcdev->commit_total_bytes;
 	device->bytes_used = srcdev->bytes_used;
+	device->commit_bytes_used = device->bytes_used;
 	device->dev_root = fs_info->dev_root;
 	device->bdev = bdev;
 	device->in_fs_metadata = 1;
@@ -6009,6 +6010,7 @@ static void fill_device_from_item(struct extent_buffer *leaf,
 	device->total_bytes = device->disk_total_bytes;
 	device->commit_total_bytes = device->disk_total_bytes;
 	device->bytes_used = btrfs_device_bytes_used(leaf, dev_item);
+	device->commit_bytes_used = device->bytes_used;
 	device->type = btrfs_device_type(leaf, dev_item);
 	device->io_align = btrfs_device_io_align(leaf, dev_item);
 	device->io_width = btrfs_device_io_width(leaf, dev_item);
@@ -6558,3 +6560,28 @@ void btrfs_update_commit_device_size(struct btrfs_fs_info *fs_info)
 	unlock_chunks(fs_info->dev_root);
 	mutex_unlock(&fs_devices->device_list_mutex);
 }
+
+/* Must be invoked during the transaction commit */
+void btrfs_update_commit_device_bytes_used(struct btrfs_root *root,
+					struct btrfs_transaction *transaction)
+{
+	struct extent_map *em;
+	struct map_lookup *map;
+	struct btrfs_device *dev;
+	int i;
+
+	if (list_empty(&transaction->pending_chunks))
+		return;
+
+	/* In order to kick the device replace finish process */
+	lock_chunks(root);
+	list_for_each_entry(em, &transaction->pending_chunks, list) {
+		map = (struct map_lookup *)em->bdev;
+
+		for (i = 0; i < map->num_stripes; i++) {
+			dev = map->stripes[i].dev;
+			dev->commit_bytes_used = dev->bytes_used;
+		}
+	}
+	unlock_chunks(root);
+}
diff --git a/fs/btrfs/volumes.h b/fs/btrfs/volumes.h
index b30d018..f79d532 100644
--- a/fs/btrfs/volumes.h
+++ b/fs/btrfs/volumes.h
@@ -95,6 +95,8 @@ struct btrfs_device {
 	 */
 	u64 commit_total_bytes;
 
+	/* bytes used on the current transaction */
+	u64 commit_bytes_used;
 	/*
 	 * used to manage the device which is resized
 	 *
@@ -420,4 +422,6 @@ static inline void btrfs_dev_stat_reset(struct btrfs_device *dev,
 }
 
 void btrfs_update_commit_device_size(struct btrfs_fs_info *fs_info);
+void btrfs_update_commit_device_bytes_used(struct btrfs_root *root,
+					struct btrfs_transaction *transaction);
 #endif
-- 
1.9.3


  parent reply	other threads:[~2014-09-03 13:34 UTC|newest]

Thread overview: 19+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-09-03 13:35 [PATCH 01/18] Btrfs: cleanup unused num_can_discard in fs_devices Miao Xie
2014-09-03 13:35 ` [PATCH 02/18] Btrfs: cleanup double assignment of device->bytes_used when device replace finishes Miao Xie
2014-09-03 13:35 ` [PATCH 03/18] Btrfs: fix unprotected assignment of the target device Miao Xie
2014-09-03 13:35 ` [PATCH 04/18] Btrfs: fix wrong disk size when writing super blocks Miao Xie
2014-09-03 13:35 ` Miao Xie [this message]
2014-09-03 13:35 ` [PATCH 06/18] Btrfs: Fix wrong free_chunk_space assignment during removing a device Miao Xie
2014-09-03 13:35 ` [PATCH 07/18] Btrfs: fix unprotected device->bytes_used update Miao Xie
2014-09-03 13:35 ` [PATCH 08/18] Btrfs: update free_chunk_space during allocting a new chunk Miao Xie
2014-09-03 13:35 ` [PATCH 09/18] Btrfs: fix unprotected device's variants on 32bits machine Miao Xie
2014-09-03 13:35 ` [PATCH 10/18] Btrfs: fix unprotected system chunk array insertion Miao Xie
2014-09-03 13:35 ` [PATCH 11/18] Btrfs: fix unprotected device list access when getting the fs information Miao Xie
2014-09-03 13:35 ` [PATCH 12/18] Btrfs: Fix misuse of chunk mutex Miao Xie
2014-09-11 15:39   ` Chris Mason
2014-09-03 13:35 ` [PATCH 13/18] Btrfs: fix unprotected device list access when cloning fs devices Miao Xie
2014-09-03 13:35 ` [PATCH 14/18] Btrfs: fix use-after-free problem of the device during device replace Miao Xie
2014-09-03 13:35 ` [PATCH 15/18] Btrfs: make the logic of source device removing more clear Miao Xie
2014-09-03 13:35 ` [PATCH 16/18] Btrfs: stop mounting the fs if the non-ENOENT errors happen when opening seed fs Miao Xie
2014-09-03 13:35 ` [PATCH 17/18] Btrfs: move the missing device to its own fs device list Miao Xie
2014-09-03 13:35 ` [PATCH 18/18] Btrfs: modify rw_devices counter under chunk_mutex context Miao Xie

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1409751347-5296-5-git-send-email-miaox@cn.fujitsu.com \
    --to=miaox@cn.fujitsu.com \
    --cc=linux-btrfs@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.