[PATCH 2/6] btrfs: relocation: Commit transaction before dropping btrfs_root::reloc_root

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Currently only relocation code cares about btrfs_root::reloc_root, and
they have the method to sync btrfs_root::reloc_root without screwing
things up.

However qgroup code doesn't really have the ability to keep
btrfs_root::reloc_root reliable.

Currently if someone outside of relocation code want to access
btrfs_root::reloc_root, it's highly possible some race could make
@reloc_root unreliable.

Thankfully, we only need to make qgroup code access
btrfs_root::reloc_root, and due to the nature of qgroup, it only needs
it before committing a transaction.

So alter the timming of transaction commit for merge_reloc_root(). For
every successful root merge, commit transaction before dropping
btrfs_root::reloc_root, making qgroup code happy with it.

Signed-off-by: Qu Wenruo <wqu@xxxxxxxx>
---
 fs/btrfs/relocation.c | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c
index 44efde9886fc..a8b62323f60b 100644
--- a/fs/btrfs/relocation.c
+++ b/fs/btrfs/relocation.c
@@ -2251,6 +2251,17 @@ static noinline_for_stack int merge_reloc_root(struct reloc_control *rc,
 	btrfs_free_path(path);
 
 	if (err == 0) {
+		/*
+		 * Commit current trans before we reset root->reloc_root
+		 * pointer, since qgroup code still needs root->reloc_root
+		 * to trace post-swap CoWs until we commit transaction.
+		 */
+		err = btrfs_commit_transaction(trans);
+		if (err < 0)
+			return err;
+		trans = btrfs_start_transaction(root, 0);
+		if (IS_ERR(trans))
+			return PTR_ERR(trans);
 		memset(&root_item->drop_progress, 0,
 		       sizeof(root_item->drop_progress));
 		root_item->drop_level = 0;
-- 
2.19.1




[Index of Archives]     [Linux Filesystem Development]     [Linux NFS]     [Linux NILFS]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux