aboutsummaryrefslogtreecommitdiffstats
path: root/meta/recipes-devtools/btrfs-tools/btrfs-tools/upstream-for-dragonn/0001-Fill-missing-devices-so-degraded-filesystems-can-be-.patch
blob: e4665335ee886614248c444e6101c1fa64c08e32 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
Upstream-Status: Inappropriate [Backport]
From a6c54702d8973aef081cff81ed8d90427bb21768 Mon Sep 17 00:00:00 2001
From: Chris Mason <chris.mason@oracle.com>
Date: Wed, 15 Dec 2010 16:00:23 -0500
Subject: [PATCH 1/5] Fill missing devices so degraded filesystems can be read

When a device is missing, the btrfs tools need to be able to read alternate
copies from the remaining devices.  This creates placeholder devices
that always return -EIO so the tools can limp along.

Signed-off-by: Chris Mason <chris.mason@oracle.com>
---
 disk-io.c |    1 +
 volumes.c |   15 +++++++++++++--
 2 files changed, 14 insertions(+), 2 deletions(-)

diff --git a/disk-io.c b/disk-io.c
index 5bd9cfc..f4368f3 100644
--- a/disk-io.c
+++ b/disk-io.c
@@ -204,6 +204,7 @@ struct extent_buffer *read_tree_block(struct btrfs_root *root, u64 bytenr,
 		eb->dev_bytenr = multi->stripes[0].physical;
 		kfree(multi);
 		ret = read_extent_from_disk(eb);
+
 		if (ret == 0 && check_tree_block(root, eb) == 0 &&
 		    csum_tree_block(root, eb, 1) == 0 &&
 		    verify_parent_transid(eb->tree, eb, parent_transid) == 0) {
diff --git a/volumes.c b/volumes.c
index 4bb77e2..5773467 100644
--- a/volumes.c
+++ b/volumes.c
@@ -1263,6 +1263,16 @@ int btrfs_chunk_readonly(struct btrfs_root *root, u64 chunk_offset)
 	return readonly;
 }
 
+static struct btrfs_device *fill_missing_device(u64 devid)
+{
+	struct btrfs_device *device;
+
+	device = kzalloc(sizeof(*device), GFP_NOFS);
+	device->devid = devid;
+	device->fd = -1;
+	return device;
+}
+
 static int read_one_chunk(struct btrfs_root *root, struct btrfs_key *key,
 			  struct extent_buffer *leaf,
 			  struct btrfs_chunk *chunk)
@@ -1313,8 +1323,9 @@ static int read_one_chunk(struct btrfs_root *root, struct btrfs_key *key,
 		map->stripes[i].dev = btrfs_find_device(root, devid, uuid,
 							NULL);
 		if (!map->stripes[i].dev) {
-			kfree(map);
-			return -EIO;
+			map->stripes[i].dev = fill_missing_device(devid);
+			printf("warning, device %llu is missing\n",
+			       (unsigned long long)devid);
 		}
 
 	}
-- 
1.7.2.3