[prev in list] [next in list] [prev in thread] [next in thread] 

List:       git-commits-head
Subject:    Btrfs: preserve commit_root for async caching
From:       Linux Kernel Mailing List <linux-kernel () vger ! kernel ! org>
Date:       2009-07-30 23:59:58
Message-ID: 200907302359.n6UNxws3024639 () hera ! kernel ! org
[Download RAW message or body]

Gitweb:     http://git.kernel.org/linus/276e680d192a67d222fcea51af37b056feffb665
Commit:     276e680d192a67d222fcea51af37b056feffb665
Parent:     f25784b35f590c81d5fb8245a8cd45e1afb6f1b2
Author:     Yan Zheng <zheng.yan@oracle.com>
AuthorDate: Thu Jul 30 09:40:40 2009 -0400
Committer:  Chris Mason <chris.mason@oracle.com>
CommitDate: Thu Jul 30 09:40:40 2009 -0400

    Btrfs: preserve commit_root for async caching
    
    The async block group caching code uses the commit_root pointer
    to get a stable version of the extent allocation tree for scanning.
    This copy of the tree root isn't going to change and it significantly
    reduces the complexity of the scanning code.
    
    During a commit, we have a loop where we update the extent allocation
    tree root.  We need to loop because updating the root pointer in
    the tree of tree roots may allocate blocks which may change the
    extent allocation tree.
    
    Right now the commit_root pointer is changed inside this loop.  It
    is more correct to change the commit_root pointer only after all the
    looping is done.
    
    Signed-off-by: Yan Zheng <zheng.yan@oracle.com>
    Signed-off-by: Chris Mason <chris.mason@oracle.com>
---
 fs/btrfs/ctree.h       |    4 +---
 fs/btrfs/disk-io.c     |    2 +-
 fs/btrfs/extent-tree.c |    6 +++---
 fs/btrfs/transaction.c |   12 +++++++++---
 4 files changed, 14 insertions(+), 10 deletions(-)

diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
index 17ad92c..38eeb6c 100644
--- a/fs/btrfs/ctree.h
+++ b/fs/btrfs/ctree.h
@@ -827,6 +827,7 @@ struct btrfs_fs_info {
 	struct mutex drop_mutex;
 	struct mutex volume_mutex;
 	struct mutex tree_reloc_mutex;
+	struct rw_semaphore extent_commit_sem;
 
 	/*
 	 * this protects the ordered operations list only while we are
@@ -961,9 +962,6 @@ struct btrfs_root {
 	/* the node lock is held while changing the node pointer */
 	spinlock_t node_lock;
 
-	/* taken when updating the commit root */
-	struct rw_semaphore commit_root_sem;
-
 	struct extent_buffer *commit_root;
 	struct btrfs_root *log_root;
 	struct btrfs_root *reloc_root;
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index 3a9b887..3cf4cfa 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -907,7 +907,6 @@ static int __setup_root(u32 nodesize, u32 leafsize, u32 sectorsize,
 	spin_lock_init(&root->inode_lock);
 	mutex_init(&root->objectid_mutex);
 	mutex_init(&root->log_mutex);
-	init_rwsem(&root->commit_root_sem);
 	init_waitqueue_head(&root->log_writer_wait);
 	init_waitqueue_head(&root->log_commit_wait[0]);
 	init_waitqueue_head(&root->log_commit_wait[1]);
@@ -1624,6 +1623,7 @@ struct btrfs_root *open_ctree(struct super_block *sb,
 	mutex_init(&fs_info->cleaner_mutex);
 	mutex_init(&fs_info->volume_mutex);
 	mutex_init(&fs_info->tree_reloc_mutex);
+	init_rwsem(&fs_info->extent_commit_sem);
 
 	btrfs_init_free_cluster(&fs_info->meta_alloc_cluster);
 	btrfs_init_free_cluster(&fs_info->data_alloc_cluster);
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index fadf69a..2fe21fa 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -267,7 +267,7 @@ static int caching_kthread(void *data)
 	last = max_t(u64, block_group->key.objectid, BTRFS_SUPER_INFO_OFFSET);
 again:
 	/* need to make sure the commit_root doesn't disappear */
-	down_read(&fs_info->extent_root->commit_root_sem);
+	down_read(&fs_info->extent_commit_sem);
 
 	/*
 	 * We don't want to deadlock with somebody trying to allocate a new
@@ -304,7 +304,7 @@ again:
 
 			if (need_resched()) {
 				btrfs_release_path(fs_info->extent_root, path);
-				up_read(&fs_info->extent_root->commit_root_sem);
+				up_read(&fs_info->extent_commit_sem);
 				cond_resched();
 				goto again;
 			}
@@ -345,7 +345,7 @@ next:
 
 err:
 	btrfs_free_path(path);
-	up_read(&fs_info->extent_root->commit_root_sem);
+	up_read(&fs_info->extent_commit_sem);
 	atomic_dec(&block_group->space_info->caching_threads);
 	wake_up(&block_group->caching_q);
 
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c
index e51d2bc..de48e4e 100644
--- a/fs/btrfs/transaction.c
+++ b/fs/btrfs/transaction.c
@@ -42,10 +42,8 @@ static noinline void put_transaction(struct btrfs_transaction *transaction)
 
 static noinline void switch_commit_root(struct btrfs_root *root)
 {
-	down_write(&root->commit_root_sem);
 	free_extent_buffer(root->commit_root);
 	root->commit_root = btrfs_root_node(root);
-	up_write(&root->commit_root_sem);
 }
 
 /*
@@ -466,7 +464,10 @@ static int update_cowonly_root(struct btrfs_trans_handle *trans,
 		ret = btrfs_write_dirty_block_groups(trans, root);
 		BUG_ON(ret);
 	}
-	switch_commit_root(root);
+
+	if (root != root->fs_info->extent_root)
+		switch_commit_root(root);
+
 	return 0;
 }
 
@@ -499,6 +500,11 @@ static noinline int commit_cowonly_roots(struct btrfs_trans_handle *trans,
 
 		update_cowonly_root(trans, root);
 	}
+
+	down_write(&fs_info->extent_commit_sem);
+	switch_commit_root(fs_info->extent_root);
+	up_write(&fs_info->extent_commit_sem);
+
 	return 0;
 }
 
--
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic