All of lore.kernel.org
 help / color / mirror / Atom feed
From: Nikolay Borisov <nborisov@suse.com>
To: linux-btrfs@vger.kernel.org
Cc: Nikolay Borisov <nborisov@suse.com>
Subject: [PATCH v4 03/15] btrfs: Handle pending/pinned chunks before blockgroup relocation during device shrink
Date: Wed, 27 Mar 2019 14:24:06 +0200	[thread overview]
Message-ID: <20190327122418.24027-4-nborisov@suse.com> (raw)
In-Reply-To: <20190327122418.24027-1-nborisov@suse.com>

During device shrink pinned/pending chunks (i.e those which have been
deleted/created respectively, in the current transaction and haven't
touched disk) need to be accounted when doing device shrink. Presently
this happens after the main relocation loop in btrfs_shrink_device,
which could lead to making another go in the body of the function.

Since there is no hard requirement to perform pinned/pending chunks
handling after the relocation loop, move the code before it. This leads
to simplifying the code flow around - i.e no need to use 'goto again'.

Signed-off-by: Nikolay Borisov <nborisov@suse.com>
---
 fs/btrfs/volumes.c | 57 +++++++++++++++++++---------------------------
 1 file changed, 24 insertions(+), 33 deletions(-)

diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
index 66f4032dba13..256f7c5476bc 100644
--- a/fs/btrfs/volumes.c
+++ b/fs/btrfs/volumes.c
@@ -4722,15 +4722,16 @@ int btrfs_shrink_device(struct btrfs_device *device, u64 new_size)
 	int slot;
 	int failed = 0;
 	bool retried = false;
-	bool checked_pending_chunks = false;
 	struct extent_buffer *l;
 	struct btrfs_key key;
 	struct btrfs_super_block *super_copy = fs_info->super_copy;
 	u64 old_total = btrfs_super_total_bytes(super_copy);
 	u64 old_size = btrfs_device_get_total_bytes(device);
 	u64 diff;
+	u64 start;
 
-	new_size = round_down(new_size, fs_info->sectorsize);
+	start = round_down(new_size, fs_info->sectorsize);
+	new_size = start;
 	diff = round_down(old_size - new_size, fs_info->sectorsize);
 
 	if (test_bit(BTRFS_DEV_STATE_REPLACE_TGT, &device->dev_state))
@@ -4742,6 +4743,12 @@ int btrfs_shrink_device(struct btrfs_device *device, u64 new_size)
 
 	path->reada = READA_BACK;
 
+	trans = btrfs_start_transaction(root, 0);
+	if (IS_ERR(trans)) {
+		btrfs_free_path(path);
+		return PTR_ERR(trans);
+	}
+
 	mutex_lock(&fs_info->chunk_mutex);
 
 	btrfs_device_set_total_bytes(device, new_size);
@@ -4749,7 +4756,21 @@ int btrfs_shrink_device(struct btrfs_device *device, u64 new_size)
 		device->fs_devices->total_rw_bytes -= diff;
 		atomic64_sub(diff, &fs_info->free_chunk_space);
 	}
-	mutex_unlock(&fs_info->chunk_mutex);
+
+	/*
+	 * Once the device's size has been set to the new size, ensure all
+	 * in-memory chunks are synced to disk so that the loop below sees them
+	 * and relocates them accordingly.
+	 */
+	if (contains_pending_extent(trans->transaction, device, &start, diff)) {
+		mutex_unlock(&fs_info->chunk_mutex);
+		ret = btrfs_commit_transaction(trans);
+		if (ret)
+			goto done;
+	} else {
+		mutex_unlock(&fs_info->chunk_mutex);
+		btrfs_end_transaction(trans);
+	}
 
 again:
 	key.objectid = device->devid;
@@ -4840,36 +4861,6 @@ int btrfs_shrink_device(struct btrfs_device *device, u64 new_size)
 	}
 
 	mutex_lock(&fs_info->chunk_mutex);
-
-	/*
-	 * We checked in the above loop all device extents that were already in
-	 * the device tree. However before we have updated the device's
-	 * total_bytes to the new size, we might have had chunk allocations that
-	 * have not complete yet (new block groups attached to transaction
-	 * handles), and therefore their device extents were not yet in the
-	 * device tree and we missed them in the loop above. So if we have any
-	 * pending chunk using a device extent that overlaps the device range
-	 * that we can not use anymore, commit the current transaction and
-	 * repeat the search on the device tree - this way we guarantee we will
-	 * not have chunks using device extents that end beyond 'new_size'.
-	 */
-	if (!checked_pending_chunks) {
-		u64 start = new_size;
-		u64 len = old_size - new_size;
-
-		if (contains_pending_extent(trans->transaction, device,
-					    &start, len)) {
-			mutex_unlock(&fs_info->chunk_mutex);
-			checked_pending_chunks = true;
-			failed = 0;
-			retried = false;
-			ret = btrfs_commit_transaction(trans);
-			if (ret)
-				goto done;
-			goto again;
-		}
-	}
-
 	btrfs_device_set_disk_total_bytes(device, new_size);
 	if (list_empty(&device->post_commit_list))
 		list_add_tail(&device->post_commit_list,
-- 
2.17.1


  parent reply	other threads:[~2019-03-27 12:24 UTC|newest]

Thread overview: 33+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-03-27 12:24 [PATCH v4 00/15] FITRIM improvement Nikolay Borisov
2019-03-27 12:24 ` [PATCH v4 01/15] btrfs: Honour FITRIM range constraints during free space trim Nikolay Borisov
2019-05-25  2:30   ` Qu Wenruo
2019-03-27 12:24 ` [PATCH v4 02/15] btrfs: combine device update operations during transaction commit Nikolay Borisov
2019-05-03 10:23   ` David Sterba
2019-03-27 12:24 ` Nikolay Borisov [this message]
2019-04-01 18:26   ` [PATCH v4 03/15] btrfs: Handle pending/pinned chunks before blockgroup relocation during device shrink David Sterba
2019-04-02  5:55     ` Nikolay Borisov
2019-04-02 15:52       ` David Sterba
2019-03-27 12:24 ` [PATCH v4 04/15] btrfs: Rename and export clear_btree_io_tree Nikolay Borisov
2019-03-27 12:24 ` [PATCH v4 05/15] btrfs: Populate ->orig_block_len during read_one_chunk Nikolay Borisov
2019-03-27 12:24 ` [PATCH v4 06/15] btrfs: Introduce new bits for device allocation tree Nikolay Borisov
2019-03-27 12:24 ` [PATCH v4 07/15] btrfs: Implement set_extent_bits_nowait Nikolay Borisov
2019-03-27 12:24 ` [PATCH v4 08/15] btrfs: Stop using call_rcu for device freeing Nikolay Borisov
2019-04-01 17:07   ` David Sterba
2019-04-01 17:20     ` Nikolay Borisov
2019-04-02 16:12       ` David Sterba
2019-03-27 12:24 ` [PATCH v4 09/15] btrfs: replace pending/pinned chunks lists with io tree Nikolay Borisov
2024-02-29 10:00   ` Alex Lyakas
2024-02-29 10:54     ` Filipe Manana
2024-02-29 11:07       ` Alex Lyakas
2019-03-27 12:24 ` [PATCH v4 10/15] btrfs: Transpose btrfs_close_devices/btrfs_mapping_tree_free in close_ctree Nikolay Borisov
2019-03-27 12:24 ` [PATCH v4 11/15] btrfs: Remove 'trans' argument from find_free_dev_extent(_start) Nikolay Borisov
2019-03-27 12:24 ` [PATCH v4 12/15] btrfs: Factor out in_range macro Nikolay Borisov
2019-03-27 12:24 ` [PATCH v4 13/15] btrfs: Optimize unallocated chunks discard Nikolay Borisov
2019-04-01 18:44   ` David Sterba
2019-04-02  8:01     ` Nikolay Borisov
2019-03-27 12:24 ` [PATCH v4 14/15] btrfs: Implement find_first_clear_extent_bit Nikolay Borisov
2019-03-27 12:24 ` [PATCH v4 15/15] btrfs: Switch btrfs_trim_free_extents to find_first_clear_extent_bit Nikolay Borisov
2019-03-28 23:18 ` [PATCH v4 00/15] FITRIM improvement David Sterba
2019-03-29  6:20   ` Nikolay Borisov
2019-03-29  6:55     ` Qu Wenruo
2019-04-03 13:46 ` David Sterba

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=20190327122418.24027-4-nborisov@suse.com \
    --to=nborisov@suse.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.