[Btrfs-devel][PATCH]Update btrfs-progs to handle backrefs

Yan Zheng yanzheng at 21cn.com
Wed Dec 19 04:37:32 PST 2007


Hello,

This patch updates btrfs-progs according to kernel module's code. It
updates btrfs-progs to properly handle back reference and exports some
functions in extent-tree.c

Regards
YZ
----
diff -r a1a37f51dcb2 ctree.c
--- a/ctree.c	Fri Dec 14 11:00:30 2007 -0500
+++ b/ctree.c	Wed Dec 19 19:52:02 2007 +0800
@@ -53,10 +53,10 @@ void btrfs_release_path(struct btrfs_roo
 	}
 	memset(p, 0, sizeof(*p));
 }
+
 int btrfs_cow_block(struct btrfs_trans_handle *trans, struct btrfs_root
-			   *root, struct btrfs_buffer *buf, struct btrfs_buffer
-			   *parent, int parent_slot, struct btrfs_buffer
-			   **cow_ret)
+		    *root, struct btrfs_buffer *buf, struct btrfs_buffer
+		    *parent, int parent_slot, struct btrfs_buffer **cow_ret)
 {
 	struct btrfs_buffer *cow;
 	u64 root_gen;
diff -r a1a37f51dcb2 ctree.h
--- a/ctree.h	Fri Dec 14 11:00:30 2007 -0500
+++ b/ctree.h	Wed Dec 19 19:52:02 2007 +0800
@@ -432,8 +432,8 @@ BTRFS_SETGET_STACK_FUNCS(inode_compat_fl
 BTRFS_SETGET_STACK_FUNCS(inode_compat_flags, struct btrfs_inode_item,
 			 compat_flags, 16);

-BTRFS_SETGET_STACK_FUNCS(timpsec_sec, struct btrfs_inode_timespec, sec, 64);
-BTRFS_SETGET_STACK_FUNCS(timpsec_nsec, struct btrfs_inode_timespec, nsec, 32);
+BTRFS_SETGET_STACK_FUNCS(timespec_sec, struct btrfs_inode_timespec, sec, 64);
+BTRFS_SETGET_STACK_FUNCS(timespec_nsec, struct btrfs_inode_timespec, nsec, 32);
 BTRFS_SETGET_STACK_FUNCS(extent_refs, struct btrfs_extent_item, refs, 32);

 BTRFS_SETGET_STACK_FUNCS(inode_ref_name_len, struct btrfs_inode_ref,
@@ -607,7 +607,7 @@ BTRFS_SETGET_STACK_FUNCS(file_extent_num
 	btrfs_item_offset((leaf)->items + (slot))))
 #define btrfs_item_ptr_offset(leaf, slot) \
 	((unsigned long)(btrfs_leaf_data(leaf) + \
-	btrfs_item_offset_nr(leaf, slot)))
+	btrfs_item_offset((leaf)->items + (slot))))

 static inline u32 btrfs_level_size(struct btrfs_root *root, int level)
 {
@@ -616,9 +616,28 @@ static inline u32 btrfs_level_size(struc
 	return root->nodesize;
 }
 int btrfs_comp_keys(struct btrfs_disk_key *disk, struct btrfs_key *k2);
+int update_block_group(struct btrfs_trans_handle *trans, struct btrfs_root
+		       *root, u64 bytenr, u64 num, int alloc);
+int btrfs_extent_post_op(struct btrfs_trans_handle *trans,
+			 struct btrfs_root *root);
 struct btrfs_buffer *btrfs_alloc_free_block(struct btrfs_trans_handle *trans,
 					    struct btrfs_root *root,
 					    u32 blocksize);
+u64 hash_extent_ref(u64 root_objectid, u64 ref_generation, u64 owner,
+		    u64 owner_offset);
+int lookup_extent_backref(struct btrfs_trans_handle *trans,
+			  struct btrfs_root *root, struct btrfs_path *path,
+			  u64 bytenr, u64 root_objectid, u64 ref_generation,	
+			  u64 owner, u64 owner_offset, int del);
+int insert_extent_backref(struct btrfs_trans_handle *trans,
+			  struct btrfs_root *root, struct btrfs_path *path,
+			  u64 bytenr,	 u64 root_objectid, u64 ref_generation,
+			  u64 owner, u64 owner_offset);
+int lookup_block_ref(struct btrfs_trans_handle *trans, struct btrfs_root
+		     *root, u64 bytenr, u32 blocksize, u32 *refs);
+int inc_block_ref(struct btrfs_trans_handle *trans, struct btrfs_root
+		  *root, u64 bytenr, u32 blocksize, u64 root_objectid,
+		  u64 ref_generation, u64 owner, u64 owner_offset);
 int btrfs_inc_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root,
 		  struct btrfs_buffer *buf);
 int btrfs_inc_root_ref(struct btrfs_trans_handle *trans,
diff -r a1a37f51dcb2 disk-io.c
--- a/disk-io.c	Fri Dec 14 11:00:30 2007 -0500
+++ b/disk-io.c	Wed Dec 19 19:52:02 2007 +0800
@@ -298,12 +298,13 @@ int btrfs_commit_transaction(struct btrf
 	btrfs_finish_extent_commit(trans, root->fs_info->extent_root);
 	btrfs_finish_extent_commit(trans, root->fs_info->tree_root);

+	ret = btrfs_drop_snapshot(trans, root, snap);
+	BUG_ON(ret);
+	ret = btrfs_del_root(trans, root->fs_info->tree_root, &snap_key);
+	BUG_ON(ret);
+	
 	root->commit_root = root->node;
 	root->node->count++;
-	ret = btrfs_drop_snapshot(trans, root, snap);
-	BUG_ON(ret);
-	ret = btrfs_del_root(trans, root->fs_info->tree_root, &snap_key);
-	BUG_ON(ret);
 	btrfs_free_transaction(root, trans);
 	return ret;
 }
diff -r a1a37f51dcb2 extent-tree.c
--- a/extent-tree.c	Fri Dec 14 11:00:30 2007 -0500
+++ b/extent-tree.c	Wed Dec 19 19:52:02 2007 +0800
@@ -31,8 +31,8 @@ static int run_pending(struct btrfs_tran
 static int run_pending(struct btrfs_trans_handle *trans, struct btrfs_root
 		       *extent_root);

-static u64 hash_extent_ref(u64 root_objectid, u64 ref_generation,
-			   u64 owner, u64 owner_offset)
+u64 hash_extent_ref(u64 root_objectid, u64 ref_generation,
+		    u64 owner, u64 owner_offset)
 {
 	u32 high_crc = ~(u32)0;
 	u32 low_crc = ~(u32)0;
@@ -55,15 +55,22 @@ static int match_extent_ref(struct btrfs
 static int match_extent_ref(struct btrfs_extent_ref *disk_ref,
 			    struct btrfs_extent_ref *cpu_ref)
 {
-	int ret = memcmp(cpu_ref, disk_ref, sizeof(*cpu_ref));
+	int ret;
+	int len;
+
+	if (cpu_ref->objectid)
+		len = sizeof(*cpu_ref);
+	else
+		len = 2 * sizeof(u64);
+	ret = memcmp(cpu_ref, disk_ref, len);
 	return ret == 0;
 }

-static int lookup_extent_backref(struct btrfs_trans_handle *trans,
-				 struct btrfs_root *root,
-				 struct btrfs_path *path, u64 bytenr,
-				 u64 root_objectid, u64 ref_generation,
-				 u64 owner, u64 owner_offset, int del)
+int lookup_extent_backref(struct btrfs_trans_handle *trans,
+			  struct btrfs_root *root,
+			  struct btrfs_path *path, u64 bytenr,
+			  u64 root_objectid, u64 ref_generation,	
+			  u64 owner, u64 owner_offset, int del)
 {
 	u64 hash;
 	struct btrfs_key key;
@@ -126,11 +133,11 @@ out:
 	return ret;
 }

-static int insert_extent_backref(struct btrfs_trans_handle *trans,
-				 struct btrfs_root *root,
-				 struct btrfs_path *path, u64 bytenr,
-				 u64 root_objectid, u64 ref_generation,
-				 u64 owner, u64 owner_offset)
+int insert_extent_backref(struct btrfs_trans_handle *trans,
+			  struct btrfs_root *root,
+			  struct btrfs_path *path, u64 bytenr,	
+			  u64 root_objectid, u64 ref_generation,
+			  u64 owner, u64 owner_offset)
 {
 	u64 hash;
 	struct btrfs_key key;
@@ -156,6 +163,7 @@ static int insert_extent_backref(struct
 		if (match_extent_ref(disk_ref, &ref))
 			goto out;
 		key.offset++;
+		btrfs_release_path(root, path);
 		ret = btrfs_insert_empty_item(trans, root, path, &key,
 					      sizeof(ref));
 	}
@@ -164,16 +172,16 @@ static int insert_extent_backref(struct
 	disk_ref = btrfs_item_ptr(&path->nodes[0]->leaf, path->slots[0],
 				  struct btrfs_extent_ref);
 	memcpy(disk_ref, &ref, sizeof(ref));
-	dirty_tree_block(trans, root, path->nodes[0]);
+	BUG_ON(list_empty(&path->nodes[0]->dirty));
 out:
 	btrfs_release_path(root, path);
 	return ret;
 }

-static int inc_block_ref(struct btrfs_trans_handle *trans, struct btrfs_root
-			 *root, u64 bytenr, u32 blocksize,
-			 u64 root_objectid, u64 ref_generation,
-			 u64 owner, u64 owner_offset)
+int inc_block_ref(struct btrfs_trans_handle *trans, struct btrfs_root
+		  *root, u64 bytenr, u32 blocksize,
+		  u64 root_objectid, u64 ref_generation,
+		  u64 owner, u64 owner_offset)
 {
 	struct btrfs_path path;
 	int ret;
@@ -209,8 +217,8 @@ static int inc_block_ref(struct btrfs_tr
 	return 0;
 }

-static int lookup_block_ref(struct btrfs_trans_handle *trans, struct btrfs_root
-			    *root, u64 bytenr, u32 blocksize, u32 *refs)
+int lookup_block_ref(struct btrfs_trans_handle *trans, struct btrfs_root
+		     *root, u64 bytenr, u32 blocksize, u32 *refs)
 {
 	struct btrfs_path path;
 	int ret;
@@ -226,38 +234,66 @@ static int lookup_block_ref(struct btrfs
 	ret = btrfs_search_slot(trans, root->fs_info->extent_root, &key, &path,
 				0, 0);
 	if (ret != 0)
-		BUG();
+		goto out;
 	l = &path.nodes[0]->leaf;
 	item = btrfs_item_ptr(l, path.slots[0], struct btrfs_extent_item);
 	*refs = btrfs_extent_refs(item);
+out:
 	btrfs_release_path(root->fs_info->extent_root, &path);
-	return 0;
+	return ret;
 }

 int btrfs_inc_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root,
 		  struct btrfs_buffer *buf)
 {
 	u64 bytenr;
-	u32 blocksize;
+	u32 nritems;
+	struct btrfs_key key;
+	struct btrfs_file_extent_item *fi;
 	int i;
 	int level;
+	int ret;

 	if (!root->ref_cows)
 		return 0;

-	level = btrfs_header_level(&buf->node.header) - 1;
-	blocksize = btrfs_level_size(root, level);
-
-	if (btrfs_is_leaf(&buf->node))
-		return 0;
-
-	for (i = 0; i < btrfs_header_nritems(&buf->node.header); i++) {
-		bytenr = btrfs_node_blockptr(&buf->node, i);
-		inc_block_ref(trans, root, bytenr, blocksize,
-			      root->root_key.objectid, trans->transid, 0, 0);
-	}
-
-	return 0;
+	level = btrfs_header_level(&buf->node.header);
+	nritems = btrfs_header_nritems(&buf->node.header);
+	for (i = 0; i < nritems; i++) {
+		if (level == 0) {
+			u64 disk_bytenr;
+			btrfs_disk_key_to_cpu(&key, &buf->leaf.items[i].key);
+			if (btrfs_key_type(&key) != BTRFS_EXTENT_DATA_KEY)
+				continue;
+			fi = btrfs_item_ptr(&buf->leaf, i,
+					    struct btrfs_file_extent_item);
+			if (btrfs_file_extent_type(fi) ==
+			    BTRFS_FILE_EXTENT_INLINE)
+				continue;
+			disk_bytenr = btrfs_file_extent_disk_bytenr(fi);
+			if (disk_bytenr == 0)
+				continue;
+			ret = inc_block_ref(trans, root, disk_bytenr,
+				    btrfs_file_extent_disk_num_bytes(fi),
+				    root->root_key.objectid, trans->transid,
+				    key.objectid, key.offset);
+			if (ret)
+				goto fail;
+		} else {
+			btrfs_disk_key_to_cpu(&key, &buf->node.ptrs[i].key);
+			bytenr = btrfs_node_blockptr(&buf->node, i);
+			ret = inc_block_ref(trans, root, bytenr,
+				    btrfs_level_size(root, level - 1),
+				    root->root_key.objectid, trans->transid, 	
+				    level - 1, key.objectid);
+			if (ret)
+				goto fail;
+		}
+	}
+	return 0;
+fail:
+	BUG();
+	return ret;
 }

 int btrfs_inc_root_ref(struct btrfs_trans_handle *trans,
@@ -326,9 +362,9 @@ int btrfs_write_dirty_block_groups(struc
 	return werr;
 }

-static int update_block_group(struct btrfs_trans_handle *trans,
-			      struct btrfs_root *root,
-			      u64 bytenr, u64 num, int alloc)
+int update_block_group(struct btrfs_trans_handle *trans,
+		       struct btrfs_root *root,
+		       u64 bytenr, u64 num, int alloc)
 {
 	struct btrfs_block_group_cache *bg;
 	struct cache_extent *cache;
@@ -388,12 +424,15 @@ static int finish_current_insert(struct
 {
 	struct btrfs_key ins;
 	struct btrfs_extent_item extent_item;
-	int ret;
 	struct btrfs_fs_info *info = extent_root->fs_info;
+	struct btrfs_buffer *buf;
 	struct cache_extent *pe;
 	struct cache_extent *next;
 	struct cache_tree *pending_tree = &info->pending_tree;
+	struct btrfs_disk_key *first_key;
 	struct btrfs_path path;
+	int ret;
+	int level;

 	btrfs_init_path(&path);
 	btrfs_set_extent_refs(&extent_item, 1);
@@ -419,10 +458,18 @@ static int finish_current_insert(struct
 		}
 		BUG_ON(ret);

-		ret = insert_extent_backref(trans, extent_root, &path,
-					    ins.objectid,
-					    extent_root->root_key.objectid,
-					    0, 0, 0);
+		buf = read_tree_block(extent_root, ins.objectid, ins.offset);
+		level = btrfs_header_level(&buf->node.header);
+		if (level == 0) {
+			first_key = &buf->leaf.items[0].key;
+		} else {
+			first_key = &buf->node.ptrs[0].key;
+		}
+
+		ret = insert_extent_backref(trans, extent_root, &path,
+				ins.objectid, extent_root->root_key.objectid,
+				0, level, btrfs_disk_key_objectid(first_key));
+		btrfs_block_release(extent_root, buf);
 		BUG_ON(ret);
 	}
 	return 0;
@@ -490,11 +537,10 @@ static int __free_extent(struct btrfs_tr
 					  root_bytes_used - num_bytes);

 		ret = btrfs_del_item(trans, extent_root, &path);
+		BUG_ON(ret);
 		if (!pin && extent_root->fs_info->last_insert.objectid >
 		    bytenr)
 			extent_root->fs_info->last_insert.objectid = bytenr;
-		if (ret)
-			BUG();
 		ret = update_block_group(trans, root, bytenr, num_bytes, 0);
 		BUG_ON(ret);
 	}
@@ -539,6 +585,13 @@ static int run_pending(struct btrfs_tran
 	return 0;
 }

+int btrfs_extent_post_op(struct btrfs_trans_handle *trans,
+			 struct btrfs_root *root)
+{
+	finish_current_insert(trans, root->fs_info->extent_root);
+	del_pending_extents(trans, root->fs_info->extent_root);
+	return 0;
+}

 /*
  * remove an extent from the root, returns 0 on success
@@ -711,6 +764,7 @@ static int alloc_extent(struct btrfs_tra

 	ret = find_free_extent(trans, root, num_bytes, search_start,
 			       search_end, ins);
+	BUG_ON(ret);
 	if (ret)
 		return ret;

@@ -777,8 +831,45 @@ struct btrfs_buffer *btrfs_alloc_free_bl
 	memcpy(buf->node.header.fsid, root->fs_info->disk_super->fsid,
 	       sizeof(buf->node.header.fsid));
 	dirty_tree_block(trans, root, buf);
+	trans->blocks_used++;
 	return buf;
-
+}
+
+static int drop_leaf_ref(struct btrfs_trans_handle *trans,
+			 struct btrfs_root *root, struct btrfs_buffer *buf)
+{
+	u64 leaf_owner;
+	u64 leaf_generation;
+	struct btrfs_key key;
+	struct btrfs_leaf *leaf = &buf->leaf;
+	struct btrfs_file_extent_item *fi;
+	int i;
+	int nritems;
+	int ret;
+
+	nritems = btrfs_header_nritems(&leaf->header);
+	leaf_owner = btrfs_header_owner(&leaf->header);
+	leaf_generation = btrfs_header_generation(&leaf->header);
+
+	for (i = 0; i < nritems; i++) {
+		u64 disk_bytenr;
+
+		btrfs_disk_key_to_cpu(&key, &leaf->items[i].key);
+		if (btrfs_key_type(&key) != BTRFS_EXTENT_DATA_KEY)
+			continue;
+		fi = btrfs_item_ptr(leaf, i, struct btrfs_file_extent_item);
+		if (btrfs_file_extent_type(fi) == BTRFS_FILE_EXTENT_INLINE)
+			continue;
+		disk_bytenr = btrfs_file_extent_disk_bytenr(fi);
+		if (disk_bytenr == 0)
+			continue;
+		ret = btrfs_free_extent(trans, root, disk_bytenr,
+				btrfs_file_extent_disk_num_bytes(fi),
+				leaf_owner, leaf_generation,
+				key.objectid, key.offset, 0);
+		BUG_ON(ret);
+	}
+	return 0;
 }

 /*
@@ -805,16 +896,22 @@ static int walk_down_tree(struct btrfs_t
 	/*
 	 * walk down to the last node level and free all the leaves
 	 */
-	while(*level > 0) {
+	while(*level >= 0) {
 		u32 size = btrfs_level_size(root, *level - 1);

 		cur = path->nodes[*level];
 		if (path->slots[*level] >=
 		    btrfs_header_nritems(&cur->node.header))
 			break;
+		if (*level == 0) {
+			ret = drop_leaf_ref(trans, root, cur);
+			BUG_ON(ret);
+			break;
+		}
 		bytenr = btrfs_node_blockptr(&cur->node, path->slots[*level]);
 		ret = lookup_block_ref(trans, root, bytenr, size, &refs);
-		if (refs != 1 || *level == 1) {
+		BUG_ON(ret);
+		if (refs != 1) {
 			parent = path->nodes[*level];
 			root_owner = btrfs_header_owner(&parent->node.header);
 			root_gen =
@@ -834,12 +931,14 @@ static int walk_down_tree(struct btrfs_t
 		path->slots[*level] = 0;
 	}
 out:
-	if (*level == BTRFS_MAX_LEVEL - 1 || !path->nodes[*level + 1])
+	if (path->nodes[*level] == root->commit_root) {
+		root_owner = root->root_key.objectid;
 		parent = path->nodes[*level];
-	else
+	} else {
 		parent = path->nodes[*level + 1];
-
-	root_owner = btrfs_header_owner(&parent->node.header);
+		root_owner = btrfs_header_owner(&parent->node.header);
+	}
+
 	root_gen = btrfs_header_generation(&parent->node.header);
 	ret = btrfs_free_extent(trans, root, path->nodes[*level]->bytenr,
 				btrfs_level_size(root, *level),
@@ -864,7 +963,7 @@ static int walk_up_tree(struct btrfs_tra
 	int ret;
 	u64 root_owner;
 	u64 root_gen;
-	struct btrfs_buffer *parent;
+	struct btrfs_node *node;
 	for(i = *level; i < BTRFS_MAX_LEVEL - 1 && path->nodes[i]; i++) {
 		slot = path->slots[i];
 		if (slot <
@@ -873,14 +972,14 @@ static int walk_up_tree(struct btrfs_tra
 			*level = i;
 			return 0;
 		} else {
-			if (path->nodes[*level] == root->node)
-				parent = path->nodes[*level];
-			else
-				parent = path->nodes[*level + 1];
-
-			root_owner = btrfs_header_owner(&parent->node.header);
-			root_gen =
-				btrfs_header_generation(&parent->node.header);
+			if (path->nodes[*level] == root->commit_root) {
+				node = &path->nodes[*level]->node;
+				root_owner = root->root_key.objectid;
+			} else {
+				node = &path->nodes[*level + 1]->node;
+				root_owner = btrfs_header_owner(&node->header);
+			}
+			root_gen = btrfs_header_generation(&node->header);
 			ret = btrfs_free_extent(trans, root,
 					path->nodes[*level]->bytenr,
 					btrfs_level_size(root, *level),
diff -r a1a37f51dcb2 inode-item.c
--- a/inode-item.c	Fri Dec 14 11:00:30 2007 -0500
+++ b/inode-item.c	Wed Dec 19 19:52:02 2007 +0800
@@ -24,6 +24,35 @@
 #include "disk-io.h"
 #include "transaction.h"

+int find_name_in_backref(struct btrfs_path *path, const char * name,
+			 int name_len, struct btrfs_inode_ref **ref_ret)
+{
+	struct btrfs_leaf *leaf;
+	struct btrfs_inode_ref *ref;
+	char *ptr;
+	char *name_ptr;
+	u32 item_size;
+	u32 cur_offset = 0;
+	int len;
+
+	leaf = &path->nodes[0]->leaf;
+	item_size = btrfs_item_size(leaf->items + path->slots[0]);
+	ptr = btrfs_item_ptr(leaf, path->slots[0], char);
+	while (cur_offset < item_size) {
+		ref = (struct btrfs_inode_ref *)(ptr + cur_offset);
+		len = btrfs_inode_ref_name_len(ref);
+		name_ptr = (char *)(ref + 1);
+		cur_offset += len + sizeof(*ref);
+		if (len != name_len)
+			continue;
+		if (memcmp(name, name_ptr, name_len) == 0) {
+			*ref_ret = ref;
+			return 1;
+		}
+	}
+	return 0;
+}
+
 int btrfs_insert_inode_ref(struct btrfs_trans_handle *trans,
 			   struct btrfs_root *root,
 			   const char *name, int name_len,
@@ -31,6 +60,7 @@ int btrfs_insert_inode_ref(struct btrfs_
 {
 	struct btrfs_path path;
 	struct btrfs_key key;
+	struct btrfs_leaf *leaf;
 	struct btrfs_inode_ref *ref;
 	char *ptr;
 	int ret;
@@ -44,23 +74,21 @@ int btrfs_insert_inode_ref(struct btrfs_
 	ret = btrfs_insert_empty_item(trans, root, &path, &key,
 				      ins_len);
 	if (ret == -EEXIST) {
-#if 0
 		u32 old_size;

-		if (find_name_in_backref(path, name, name_len, &ref))
+		if (find_name_in_backref(&path, name, name_len, &ref))
 			goto out;

-		old_size = btrfs_item_size_nr(path->nodes[0], path->slots[0]);
-		ret = btrfs_extend_item(trans, root, path, ins_len);
+		leaf = &path.nodes[0]->leaf;
+		old_size = btrfs_item_size(leaf->items + path.slots[0]);
+		ret = btrfs_extend_item(trans, root, &path, ins_len);
 		BUG_ON(ret);
-		ref = btrfs_item_ptr(path->nodes[0], path->slots[0],
+		ref = btrfs_item_ptr(leaf, path.slots[0],
 				     struct btrfs_inode_ref);
 		ref = (struct btrfs_inode_ref *)((unsigned long)ref + old_size);
-		btrfs_set_inode_ref_name_len(path->nodes[0], ref, name_len);
-		ptr = (unsigned long)(ref + 1);
+		btrfs_set_inode_ref_name_len(ref, name_len);
+		ptr = (char *)(ref + 1);
 		ret = 0;
-#endif
-		goto out;
 	} else if (ret < 0) {
 		goto out;
 	} else {
@@ -70,8 +98,7 @@ int btrfs_insert_inode_ref(struct btrfs_
 		ptr = (char *)(ref + 1);
 	}
 	memcpy(ptr, name, name_len);
-	dirty_tree_block(trans, root, path.nodes[0]);
-
+	BUG_ON(list_empty(&path.nodes[0]->dirty));
 out:
 	btrfs_release_path(root, &path);
 	return ret;



More information about the Btrfs-devel mailing list