diff mbox

[2/2] Btrfs-progs: mkfs: make sure we can deal with hard links with -r option

Message ID 1394533749-3138-2-git-send-email-wangsl.fnst@cn.fujitsu.com (mailing list archive)
State Accepted, archived
Headers show

Commit Message

Wang Shilong March 11, 2014, 10:29 a.m. UTC
Steps to reproduce:
 # mkdir -p /tmp/test
 # touch /tmp/test/file
 # ln /tmp/test/file /tmp/test/hardlinks
 # mkfs.btrfs -f /dev/sda13 -r /tmp/test
 # btrfs check /dev/sda13

To deal with hard link, we must deal with inode with same inode id rather
than increase inode id by ourselves.

Signed-off-by: Wang Shilong <wangsl.fnst@cn.fujitsu.com>
---
 mkfs.c | 21 +++++++++------------
 1 file changed, 9 insertions(+), 12 deletions(-)

Comments

David Sterba March 12, 2014, 4:21 p.m. UTC | #1
On Tue, Mar 11, 2014 at 06:29:09PM +0800, Wang Shilong wrote:
> @@ -840,6 +833,10 @@ static int traverse_directory(struct btrfs_trans_handle *trans,
>  					      cur_file->d_name, cur_inum,
>  					      parent_inum, dir_index_cnt,
>  					      &cur_inode);
> +			if (ret == -EEXIST) {
> +				BUG_ON(st.st_nlink <= 1);

As the mkfs operation is restartable, can we handle the error?

Otherwise, good fix, thanks.

> +				continue;
> +			}
>  			if (ret) {
>  				fprintf(stderr, "add_inode_items failed\n");
>  				goto fail;
--
To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Wang Shilong March 13, 2014, 11:24 a.m. UTC | #2
Hi Dave,

On 03/13/2014 12:21 AM, David Sterba wrote:
> On Tue, Mar 11, 2014 at 06:29:09PM +0800, Wang Shilong wrote:
>> @@ -840,6 +833,10 @@ static int traverse_directory(struct btrfs_trans_handle *trans,
>>   					      cur_file->d_name, cur_inum,
>>   					      parent_inum, dir_index_cnt,
>>   					      &cur_inode);
>> +			if (ret == -EEXIST) {
>> +				BUG_ON(st.st_nlink <= 1);
> As the mkfs operation is restartable, can we handle the error?
This should be a logic error which means a inode has hard links(but 
links <= 1). :-)

Add error handling may be better,  i will update it.

Thanks,
Wang
>
> Otherwise, good fix, thanks.
>
>> +				continue;
>> +			}
>>   			if (ret) {
>>   				fprintf(stderr, "add_inode_items failed\n");
>>   				goto fail;
> --
> To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>

--
To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/mkfs.c b/mkfs.c
index 2f7dfef..b9385bc 100644
--- a/mkfs.c
+++ b/mkfs.c
@@ -380,7 +380,10 @@  static int add_directory_items(struct btrfs_trans_handle *trans,
 	ret = btrfs_insert_dir_item(trans, root, name, name_len,
 				    parent_inum, &location,
 				    filetype, index_cnt);
-
+	if (ret)
+		return ret;
+	ret = btrfs_insert_inode_ref(trans, root, name, name_len,
+				     objectid, parent_inum, index_cnt);
 	*dir_index_cnt = index_cnt;
 	index_cnt++;
 
@@ -493,9 +496,7 @@  static int add_inode_items(struct btrfs_trans_handle *trans,
 	struct btrfs_inode_item btrfs_inode;
 	u64 objectid;
 	u64 inode_size = 0;
-	int name_len;
 
-	name_len = strlen(name);
 	fill_inode_item(trans, root, &btrfs_inode, st);
 	objectid = self_objectid;
 
@@ -509,16 +510,8 @@  static int add_inode_items(struct btrfs_trans_handle *trans,
 	btrfs_set_key_type(&inode_key, BTRFS_INODE_ITEM_KEY);
 
 	ret = btrfs_insert_inode(trans, root, objectid, &btrfs_inode);
-	if (ret)
-		goto fail;
-
-	ret = btrfs_insert_inode_ref(trans, root, name, name_len,
-				     objectid, parent_inum, dir_index_cnt);
-	if (ret)
-		goto fail;
 
 	*inode_ret = btrfs_inode;
-fail:
 	return ret;
 }
 
@@ -826,7 +819,7 @@  static int traverse_directory(struct btrfs_trans_handle *trans,
 				goto fail;
 			}
 
-			cur_inum = ++highest_inum + BTRFS_FIRST_FREE_OBJECTID;
+			cur_inum = st.st_ino;
 			ret = add_directory_items(trans, root,
 						  cur_inum, parent_inum,
 						  cur_file->d_name,
@@ -840,6 +833,10 @@  static int traverse_directory(struct btrfs_trans_handle *trans,
 					      cur_file->d_name, cur_inum,
 					      parent_inum, dir_index_cnt,
 					      &cur_inode);
+			if (ret == -EEXIST) {
+				BUG_ON(st.st_nlink <= 1);
+				continue;
+			}
 			if (ret) {
 				fprintf(stderr, "add_inode_items failed\n");
 				goto fail;