All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 0/9] Superblock read and verify cleanups
@ 2018-03-27 23:39 Anand Jain
  2018-03-27 23:39 ` [PATCH 1/8] btrfs: cleanup btrfs_check_super_csum() for better code flow Anand Jain
                   ` (7 more replies)
  0 siblings, 8 replies; 14+ messages in thread
From: Anand Jain @ 2018-03-27 23:39 UTC (permalink / raw)
  To: linux-btrfs

v1->v2:
 Various changes suggested by Nicokay. Thanks. For specific changes
 pls ref to the patch.

Patch 1-4/8 are preparatory patches adds cleanups and nonstatic requisites.

Patch 5/8 makes sure that all copies of the superblock have the same fsid
when we scan the device.

Patch 6/8 verifies superblock csum when we read it in the scan context.

Patch 7/8 fixes a bug that we weren't verifying the superblock csum for
the non-latest_bdev.

And 8/8 patch drops the redundant invalidate_bdev() call during mount.

There is a btrfs-progs patch which is a kind of related, as its found that
we weren't wiping the non-overwritten superblock, so it could cause
confusion during the superblock recovery process. So the patch btrfs-progs
1/1 adds code to wipe superblock if we aren't overwriting it.

Now since kernel patch 5/8 checks if all the superblock copies are
pointing to the same fsid on the disk, so the scan will fail if without
the above 1/1 btrfs-progs, as in the example below [1]. However the simple
workaround is to wipe the superblock manually [2] or apply the btrfs-progs
patch below.

[1]
 mkfs.btrfs -qf /dev/sdb <-- 1T disk
 mkfs.btrfs -b 256M  /dev/sdb
 ERROR: device scan failed on /dev/sdb

[2]
 dd if=/dev/zero of=<dev> seek=274877906944 ibs=1 obs=1 count4K

Unfortunately, the error messages should have been failed to register
[3] device into the kernel to be more appropriate to the error.

[3]
        ret = ioctl(fd, BTRFS_IOC_SCAN_DEV, &args);
        if (ret < 0) {
                error("device scan failed on '%s': %m", fname);
                ret = -errno;
        }


Patches 1-7/8 were sent independently before. And  I found few more things
to fix alongs the line, and since they are related, so I am sending these
all together. Also, as there are minor changes, like in pr_err strings,
and splitting the unrelated changes into a separate patch, so though I am
thankful for the received reviewed-by, I couldn't include them here. Sorry.

Finally, here I am including the function relations [4] so that it will help
to review the code. And this flow is before these patches were applied.

[4]
In the long term, I suggest deprecating ioctl args which pass device path
(where possible), like in delete-device/replace. And
btrfs_read_dev_one_super() should replace btrfs_read_disk_super()

delete-device/replace:
btrfs_rm_device() || btrfs_dev_replace_by_ioctl()
|_btrfs_find_device_by_devspec()
  |_btrfs_find_device_missing_or_by_path()
    |_btrfs_find_device_by_path()
      |_btrfs_get_bdev_and_sb()
        |_btrfs_read_dev_super()
          |_btrfs_read_dev_one_super()
            |___bread()

btrfs_mount_root()
 |
 |_btrfs_parse_early_options (-o device only)
 | |_btrfs_scan_one_device
 |   |_btrfs_read_disk_super()
 |     |_read_cache_page_gfp()
 |
 |_btrfs_scan_one_device(mount-arg-dev only)
 | |_btrfs_read_disk_super()
 |   |_read_cache_page_gfp()
 |
 |
 |_btrfs_open_devices(fsid:all)
 |  |_btrfs_open_one_device()
 |    |_btrfs_get_bdev_and_sb()  <--- invalidate_bdev(fsid:all)
 |      |_btrfs_read_dev_super()
 |        |_btrfs_read_dev_one_super()
 |          |___bread()
 |
 |_btrfs_fill_super()
   |_btrfs_open_ctree()   <-- invalidate_bdev(latest_bdev) <-- redundant
     |_btrfs_read_dev_super(latest_bdev only)
     | |_btrfs_read_dev_one_super(latest_bdev only)
     |   |___bread(latest_bdev)
     |
     |_btrfs_check_super_csum(latest_bdev only) [*]
     |
     |_btrfs_read_chunk_tree
     | |_read_one_dev()
     |   |_open_seed_devices()
     |     |_btrfs_open_devices(fs_devices->seed only)

scan/ready
|
|_btrfs_scan_one_device(ioctl-arg-dev only)
   |_btrfs_read_disk_super()
     |_read_cache_page_gfp()


Anand Jain (8):
  btrfs: cleanup btrfs_check_super_csum() for better code flow
  btrfs: return required error from btrfs_check_super_csum
  btrfs: cleanup btrfs_read_disk_super() to return std error
  btrfs: make btrfs_check_super_csum() non static
  btrfs: check if the fsid in the primary sb and copy sb are same
  btrfs: verify checksum when superblock is read for scan
  btrfs: verify checksum for all devices in mount context
  btrfs: drop the redundant invalidate_bdev()

 fs/btrfs/disk-io.c | 72 +++++++++++++++++++++++-----------------------
 fs/btrfs/disk-io.h |  1 +
 fs/btrfs/volumes.c | 84 ++++++++++++++++++++++++++++++++++++++++++------------
 3 files changed, 102 insertions(+), 55 deletions(-)

Anand Jain (1):
  btrfs-progs: wipe copies of the stale superblock beyond -b size

 utils.c | 35 +++++++++++++++++++++++++++++++++++
 1 file changed, 35 insertions(+)

-- 
2.7.0


^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH 1/8] btrfs: cleanup btrfs_check_super_csum() for better code flow
  2018-03-27 23:39 [PATCH v2 0/9] Superblock read and verify cleanups Anand Jain
@ 2018-03-27 23:39 ` Anand Jain
  2018-03-27 23:39 ` [PATCH v2 2/8] btrfs: return required error from btrfs_check_super_csum Anand Jain
                   ` (6 subsequent siblings)
  7 siblings, 0 replies; 14+ messages in thread
From: Anand Jain @ 2018-03-27 23:39 UTC (permalink / raw)
  To: linux-btrfs

We check the %csum_type twice. Drop one. Check for the csum_type and
then for the csum. Which also matches with the progs which have better
logic. This is preparatory patch to get proper error code from
btrfs_check_super_csum().

Signed-off-by: Anand Jain <anand.jain@oracle.com>
Reviewed-by: Nikolay Borisov <nborisov@suse.com>
---
 fs/btrfs/disk-io.c | 38 +++++++++++++++++---------------------
 1 file changed, 17 insertions(+), 21 deletions(-)

diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index 1657d6aa4fa6..b9b435579527 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -399,32 +399,28 @@ static int btrfs_check_super_csum(struct btrfs_fs_info *fs_info,
 	struct btrfs_super_block *disk_sb =
 		(struct btrfs_super_block *)raw_disk_sb;
 	u16 csum_type = btrfs_super_csum_type(disk_sb);
-	int ret = 0;
-
-	if (csum_type == BTRFS_CSUM_TYPE_CRC32) {
-		u32 crc = ~(u32)0;
-		char result[sizeof(crc)];
-
-		/*
-		 * The super_block structure does not span the whole
-		 * BTRFS_SUPER_INFO_SIZE range, we expect that the unused space
-		 * is filled with zeros and is included in the checksum.
-		 */
-		crc = btrfs_csum_data(raw_disk_sb + BTRFS_CSUM_SIZE,
-				crc, BTRFS_SUPER_INFO_SIZE - BTRFS_CSUM_SIZE);
-		btrfs_csum_final(crc, result);
-
-		if (memcmp(raw_disk_sb, result, sizeof(result)))
-			ret = 1;
-	}
+	u32 crc = ~(u32)0;
+	char result[sizeof(crc)];
 
 	if (csum_type >= ARRAY_SIZE(btrfs_csum_sizes)) {
 		btrfs_err(fs_info, "unsupported checksum algorithm %u",
-				csum_type);
-		ret = 1;
+			  csum_type);
+		return 1;
 	}
 
-	return ret;
+	/*
+	 * The super_block structure does not span the whole
+	 * BTRFS_SUPER_INFO_SIZE range, we expect that the unused space
+	 * is filled with zeros and is included in the checksum.
+	 */
+	crc = btrfs_csum_data(raw_disk_sb + BTRFS_CSUM_SIZE,
+			      crc, BTRFS_SUPER_INFO_SIZE - BTRFS_CSUM_SIZE);
+	btrfs_csum_final(crc, result);
+
+	if (memcmp(raw_disk_sb, result, sizeof(result)))
+		return 1;
+
+	return 0;
 }
 
 /*
-- 
2.7.0


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH v2 2/8] btrfs: return required error from btrfs_check_super_csum
  2018-03-27 23:39 [PATCH v2 0/9] Superblock read and verify cleanups Anand Jain
  2018-03-27 23:39 ` [PATCH 1/8] btrfs: cleanup btrfs_check_super_csum() for better code flow Anand Jain
@ 2018-03-27 23:39 ` Anand Jain
  2018-03-27 23:39 ` [PATCH v2 3/8] btrfs: cleanup btrfs_read_disk_super() to return std error Anand Jain
                   ` (5 subsequent siblings)
  7 siblings, 0 replies; 14+ messages in thread
From: Anand Jain @ 2018-03-27 23:39 UTC (permalink / raw)
  To: linux-btrfs

Return the required -EINVAL and -EUCLEAN from the function
btrfs_check_super_csum(). And more the error log into the
parent function.

Signed-off-by: Anand Jain <anand.jain@oracle.com>
---
v1->v2:
 Fix commit indent reported by checkpatch.pl
 Fix pr_err split string

 fs/btrfs/disk-io.c | 25 ++++++++++++++-----------
 1 file changed, 14 insertions(+), 11 deletions(-)

diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index b9b435579527..4c573602480c 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -392,9 +392,10 @@ static int verify_parent_transid(struct extent_io_tree *io_tree,
 /*
  * Return 0 if the superblock checksum type matches the checksum value of that
  * algorithm. Pass the raw disk superblock data.
+ * Otherwise:	-EINVAL  if csum type is not found
+ *		-EUCLEAN if csum does not match
  */
-static int btrfs_check_super_csum(struct btrfs_fs_info *fs_info,
-				  char *raw_disk_sb)
+static int btrfs_check_super_csum(char *raw_disk_sb)
 {
 	struct btrfs_super_block *disk_sb =
 		(struct btrfs_super_block *)raw_disk_sb;
@@ -402,11 +403,8 @@ static int btrfs_check_super_csum(struct btrfs_fs_info *fs_info,
 	u32 crc = ~(u32)0;
 	char result[sizeof(crc)];
 
-	if (csum_type >= ARRAY_SIZE(btrfs_csum_sizes)) {
-		btrfs_err(fs_info, "unsupported checksum algorithm %u",
-			  csum_type);
-		return 1;
-	}
+	if (csum_type >= ARRAY_SIZE(btrfs_csum_sizes))
+		return -EINVAL;
 
 	/*
 	 * The super_block structure does not span the whole
@@ -418,7 +416,7 @@ static int btrfs_check_super_csum(struct btrfs_fs_info *fs_info,
 	btrfs_csum_final(crc, result);
 
 	if (memcmp(raw_disk_sb, result, sizeof(result)))
-		return 1;
+		return -EUCLEAN;
 
 	return 0;
 }
@@ -2570,9 +2568,14 @@ int open_ctree(struct super_block *sb,
 	 * We want to check superblock checksum, the type is stored inside.
 	 * Pass the whole disk block of size BTRFS_SUPER_INFO_SIZE (4k).
 	 */
-	if (btrfs_check_super_csum(fs_info, bh->b_data)) {
-		btrfs_err(fs_info, "superblock checksum mismatch");
-		err = -EINVAL;
+	err = btrfs_check_super_csum(bh->b_data);
+	if (err) {
+		if (err == -EINVAL)
+			pr_err("BTRFS error (device %pg): unsupported checksum algorithm",
+				fs_devices->latest_bdev);
+		else
+			pr_err("BTRFS error (device %pg): superblock checksum mismatch",
+				fs_devices->latest_bdev);
 		brelse(bh);
 		goto fail_alloc;
 	}
-- 
2.7.0


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH v2 3/8] btrfs: cleanup btrfs_read_disk_super() to return std error
  2018-03-27 23:39 [PATCH v2 0/9] Superblock read and verify cleanups Anand Jain
  2018-03-27 23:39 ` [PATCH 1/8] btrfs: cleanup btrfs_check_super_csum() for better code flow Anand Jain
  2018-03-27 23:39 ` [PATCH v2 2/8] btrfs: return required error from btrfs_check_super_csum Anand Jain
@ 2018-03-27 23:39 ` Anand Jain
  2018-03-28  7:05   ` Nikolay Borisov
  2018-03-27 23:39 ` [PATCH 4/8] btrfs: make btrfs_check_super_csum() non-static Anand Jain
                   ` (4 subsequent siblings)
  7 siblings, 1 reply; 14+ messages in thread
From: Anand Jain @ 2018-03-27 23:39 UTC (permalink / raw)
  To: linux-btrfs

The only caller btrfs_scan_one_device() sets -EINVAL for error from
btrfs_read_disk_super(), so this patch returns -EINVAL from the latter
function.

A preparatory patch to add csum check in btrfs_read_disk_super().

Signed-off-by: Anand Jain <anand.jain@oracle.com>
---
v1->v2:
 Check btrfs_read_disk_super() to be more explicit ret < 0

 fs/btrfs/volumes.c | 15 +++++++--------
 1 file changed, 7 insertions(+), 8 deletions(-)

diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
index 87d183accdb2..e63723f23227 100644
--- a/fs/btrfs/volumes.c
+++ b/fs/btrfs/volumes.c
@@ -1154,23 +1154,23 @@ static int btrfs_read_disk_super(struct block_device *bdev, u64 bytenr,
 
 	/* make sure our super fits in the device */
 	if (bytenr + PAGE_SIZE >= i_size_read(bdev->bd_inode))
-		return 1;
+		return -EINVAL;
 
 	/* make sure our super fits in the page */
 	if (sizeof(**disk_super) > PAGE_SIZE)
-		return 1;
+		return -EINVAL;
 
 	/* make sure our super doesn't straddle pages on disk */
 	index = bytenr >> PAGE_SHIFT;
 	if ((bytenr + sizeof(**disk_super) - 1) >> PAGE_SHIFT != index)
-		return 1;
+		return -EINVAL;
 
 	/* pull in the page with our super */
 	*page = read_cache_page_gfp(bdev->bd_inode->i_mapping,
 				   index, GFP_KERNEL);
 
 	if (IS_ERR_OR_NULL(*page))
-		return 1;
+		return -EINVAL;
 
 	p = kmap(*page);
 
@@ -1180,7 +1180,7 @@ static int btrfs_read_disk_super(struct block_device *bdev, u64 bytenr,
 	if (btrfs_super_bytenr(*disk_super) != bytenr ||
 	    btrfs_super_magic(*disk_super) != BTRFS_MAGIC) {
 		btrfs_release_disk_super(*page);
-		return 1;
+		return -EINVAL;
 	}
 
 	if ((*disk_super)->label[0] &&
@@ -1218,10 +1218,9 @@ int btrfs_scan_one_device(const char *path, fmode_t flags, void *holder,
 	if (IS_ERR(bdev))
 		return PTR_ERR(bdev);
 
-	if (btrfs_read_disk_super(bdev, bytenr, &page, &disk_super)) {
-		ret = -EINVAL;
+	ret = btrfs_read_disk_super(bdev, bytenr, &page, &disk_super);
+	if (ret < 0)
 		goto error_bdev_put;
-	}
 
 	mutex_lock(&uuid_mutex);
 	device = device_list_add(path, disk_super);
-- 
2.7.0


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 4/8] btrfs: make btrfs_check_super_csum() non-static
  2018-03-27 23:39 [PATCH v2 0/9] Superblock read and verify cleanups Anand Jain
                   ` (2 preceding siblings ...)
  2018-03-27 23:39 ` [PATCH v2 3/8] btrfs: cleanup btrfs_read_disk_super() to return std error Anand Jain
@ 2018-03-27 23:39 ` Anand Jain
  2018-03-27 23:39 ` [PATCH v2 5/8] btrfs: check if the fsid in the primary sb and copy sb are same Anand Jain
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 14+ messages in thread
From: Anand Jain @ 2018-03-27 23:39 UTC (permalink / raw)
  To: linux-btrfs

In preparation to add the superblock csum verification for the
scan context, make btrfs_check_super_csum() non-static.

Signed-off-by: Anand Jain <anand.jain@oracle.com>
Reviewed-by: Nikolay Borisov <nborisov@suse.com>
---
 fs/btrfs/disk-io.c | 2 +-
 fs/btrfs/disk-io.h | 1 +
 2 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index 4c573602480c..35dbbdc613cd 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -395,7 +395,7 @@ static int verify_parent_transid(struct extent_io_tree *io_tree,
  * Otherwise:	-EINVAL  if csum type is not found
  *		-EUCLEAN if csum does not match
  */
-static int btrfs_check_super_csum(char *raw_disk_sb)
+int btrfs_check_super_csum(char *raw_disk_sb)
 {
 	struct btrfs_super_block *disk_sb =
 		(struct btrfs_super_block *)raw_disk_sb;
diff --git a/fs/btrfs/disk-io.h b/fs/btrfs/disk-io.h
index 70a88d61b547..c400cc68f913 100644
--- a/fs/btrfs/disk-io.h
+++ b/fs/btrfs/disk-io.h
@@ -69,6 +69,7 @@ int write_all_supers(struct btrfs_fs_info *fs_info, int max_mirrors);
 struct buffer_head *btrfs_read_dev_super(struct block_device *bdev);
 int btrfs_read_dev_one_super(struct block_device *bdev, int copy_num,
 			struct buffer_head **bh_ret);
+int btrfs_check_super_csum(char *raw_disk_sb);
 int btrfs_commit_super(struct btrfs_fs_info *fs_info);
 struct btrfs_root *btrfs_read_fs_root(struct btrfs_root *tree_root,
 				      struct btrfs_key *location);
-- 
2.7.0


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH v2 5/8] btrfs: check if the fsid in the primary sb and copy sb are same
  2018-03-27 23:39 [PATCH v2 0/9] Superblock read and verify cleanups Anand Jain
                   ` (3 preceding siblings ...)
  2018-03-27 23:39 ` [PATCH 4/8] btrfs: make btrfs_check_super_csum() non-static Anand Jain
@ 2018-03-27 23:39 ` Anand Jain
  2018-03-28  7:10   ` Nikolay Borisov
  2018-03-27 23:39 ` [PATCH v2 6/8] btrfs: verify superblock checksum during scan Anand Jain
                   ` (2 subsequent siblings)
  7 siblings, 1 reply; 14+ messages in thread
From: Anand Jain @ 2018-03-27 23:39 UTC (permalink / raw)
  To: linux-btrfs

During the btrfs dev scan make sure that other copies of superblock
contain the same fsid as the primary SB. So that we bring to the
user notice if the superblock has been overwritten.

 mkfs.btrfs -fq /dev/sdc
 mkfs.btrfs -fq /dev/sdb
 dd if=/dev/sdb of=/dev/sdc count=4K skip=64K seek=64K obs=1 ibs=1
 mount /dev/sdc /btrfs

Caveat: Pls note that older btrfs-progs do not wipe the non-overwriting
stale superblock like copy2 if a smaller mkfs.btrfs -b  <size> is created.
Thus this patch in the kernel will report error. The workaround is to wipe
the superblock manually, like
  dd if=/dev/zero of=<dev> seek=274877906944 ibs=1 obs=1 count4K
OR apply the btrfs-progs patch
  btrfs-progs: wipe copies of the stale superblock beyond -b size
which shall find and wipe the non overwriting superblock during mkfs.

Signed-off-by: Anand Jain <anand.jain@oracle.com>
---
v1->v2:
  Do an explicit read for primary superblock. Drop kzalloc().
  Fix split pr_err().

 fs/btrfs/volumes.c | 47 ++++++++++++++++++++++++++++++++++++-----------
 1 file changed, 36 insertions(+), 11 deletions(-)

diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
index e63723f23227..b099823f60d1 100644
--- a/fs/btrfs/volumes.c
+++ b/fs/btrfs/volumes.c
@@ -1198,40 +1198,65 @@ static int btrfs_read_disk_super(struct block_device *bdev, u64 bytenr,
 int btrfs_scan_one_device(const char *path, fmode_t flags, void *holder,
 			  struct btrfs_fs_devices **fs_devices_ret)
 {
+	struct btrfs_super_block *disk_super_primary;
 	struct btrfs_super_block *disk_super;
 	struct btrfs_device *device;
 	struct block_device *bdev;
+	struct page *page_primary;
 	struct page *page;
 	int ret = 0;
 	u64 bytenr;
+	int i;
 
-	/*
-	 * we would like to check all the supers, but that would make
-	 * a btrfs mount succeed after a mkfs from a different FS.
-	 * So, we need to add a special mount option to scan for
-	 * later supers, using BTRFS_SUPER_MIRROR_MAX instead
-	 */
-	bytenr = btrfs_sb_offset(0);
 	flags |= FMODE_EXCL;
 
 	bdev = blkdev_get_by_path(path, flags, holder);
 	if (IS_ERR(bdev))
 		return PTR_ERR(bdev);
 
-	ret = btrfs_read_disk_super(bdev, bytenr, &page, &disk_super);
+	/*
+	 * We would like to check all the supers and use one good copy,
+	 * but that would make a btrfs mount succeed after a mkfs from
+	 * a different FS.
+	 * So, we need to add a special mount option to scan for
+	 * later supers, using BTRFS_SUPER_MIRROR_MAX instead.
+	 * So, just validate if all copies of the superblocks are ok
+	 * and have the same fsid.
+	 */
+	bytenr = btrfs_sb_offset(0);
+	ret = btrfs_read_disk_super(bdev, bytenr, &page_primary,
+				    &disk_super_primary);
 	if (ret < 0)
 		goto error_bdev_put;
 
+	for (i = 1; i < BTRFS_SUPER_MIRROR_MAX; i++) {
+		bytenr = btrfs_sb_offset(i);
+		ret = btrfs_read_disk_super(bdev, bytenr, &page, &disk_super);
+		if (ret < 0) {
+			ret = 0;
+			continue;
+		}
+
+		if (memcmp(disk_super_primary->fsid, disk_super->fsid,
+			   BTRFS_FSID_SIZE)) {
+			pr_err("BTRFS (device %pg): superblock fsid mismatch, primary %pU copy%d %pU",
+				bdev, disk_super_primary->fsid, i,
+				disk_super->fsid);
+			ret = -EINVAL;
+			btrfs_release_disk_super(page);
+			goto error_bdev_put;
+		}
+		btrfs_release_disk_super(page);
+	}
+
 	mutex_lock(&uuid_mutex);
-	device = device_list_add(path, disk_super);
+	device = device_list_add(path, disk_super_primary);
 	if (IS_ERR(device))
 		ret = PTR_ERR(device);
 	else
 		*fs_devices_ret = device->fs_devices;
 	mutex_unlock(&uuid_mutex);
 
-	btrfs_release_disk_super(page);
-
 error_bdev_put:
 	blkdev_put(bdev, flags);
 
-- 
2.7.0


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH v2 6/8] btrfs: verify superblock checksum during scan
  2018-03-27 23:39 [PATCH v2 0/9] Superblock read and verify cleanups Anand Jain
                   ` (4 preceding siblings ...)
  2018-03-27 23:39 ` [PATCH v2 5/8] btrfs: check if the fsid in the primary sb and copy sb are same Anand Jain
@ 2018-03-27 23:39 ` Anand Jain
  2018-03-28  7:21   ` Nikolay Borisov
  2018-03-27 23:39 ` [PATCH v2 7/8] btrfs: verify checksum for all devices in mount context Anand Jain
  2018-03-27 23:39 ` [PATCH 8/8] btrfs: drop the redundant invalidate_bdev() Anand Jain
  7 siblings, 1 reply; 14+ messages in thread
From: Anand Jain @ 2018-03-27 23:39 UTC (permalink / raw)
  To: linux-btrfs

During the scan context, we aren't verifying the superblock-
checksum when read.
This patch fixes it by adding the checksum verification function
btrfs_check_super_csum() in the function btrfs_read_disk_super().
And makes device scan to error fail if the primary superblock csum
is wrong, whereas if the copy-superblock csum is wrong it will just
just report mismatch and continue mount/scan as usual. When the
mount is successful We anyway overwrite all superblocks upon unmount.

The context in which this will be called is - device scan, device ready,
and mount -o device option.

Test script:

 Corrupt primary superblock and check if device scan and mount
 fails:
  mkfs.btrfs -fq /dev/sdc
  dd if=/dev/urandom of=/dev/sdc ibs=1 obs=1 count=1 seek=64K
  btrfs dev scan /dev/sdc
  mount /dev/sdc /btrfs

 Corrupt secondary superblock and check if device scan and mount
 is succcessful, check for the dmesg for errors.
  mkfs.btrfs -fq /dev/sdc
  dd if=/dev/urandom of=/dev/sdc ibs=1 obs=1 count=1 seek=67108864
  btrfs dev scan /dev/sdc
  mount /dev/sdc /btrfs

Signed-off-by: Anand Jain <anand.jain@oracle.com>
---
v1->v2:
 changed title.
 use explicit (< 0) check for %errr.
 Un-split pr_err() string.
 Fix typo in the git commit log.
 Move the csum check after bytenr and btrfs magic verified.

 fs/btrfs/volumes.c | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
index b099823f60d1..eda86ba258fc 100644
--- a/fs/btrfs/volumes.c
+++ b/fs/btrfs/volumes.c
@@ -1149,6 +1149,7 @@ static int btrfs_read_disk_super(struct block_device *bdev, u64 bytenr,
 				 struct page **page,
 				 struct btrfs_super_block **disk_super)
 {
+	int err;
 	void *p;
 	pgoff_t index;
 
@@ -1183,6 +1184,18 @@ static int btrfs_read_disk_super(struct block_device *bdev, u64 bytenr,
 		return -EINVAL;
 	}
 
+	err = btrfs_check_super_csum((char *) *disk_super);
+	if (err < 0) {
+		if (err == -EINVAL)
+			pr_err("BTRFS error (device %pg): unsupported checksum type, bytenr=%llu",
+				bdev, bytenr);
+		else
+			pr_err("BTRFS error (device %pg): superblock checksum failed, bytenr=%llu",
+				bdev, bytenr);
+		btrfs_release_disk_super(*page);
+		return err;
+	}
+
 	if ((*disk_super)->label[0] &&
 		(*disk_super)->label[BTRFS_LABEL_SIZE - 1])
 		(*disk_super)->label[BTRFS_LABEL_SIZE - 1] = '\0';
-- 
2.7.0


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH v2 7/8] btrfs: verify checksum for all devices in mount context
  2018-03-27 23:39 [PATCH v2 0/9] Superblock read and verify cleanups Anand Jain
                   ` (5 preceding siblings ...)
  2018-03-27 23:39 ` [PATCH v2 6/8] btrfs: verify superblock checksum during scan Anand Jain
@ 2018-03-27 23:39 ` Anand Jain
  2018-03-27 23:39 ` [PATCH 8/8] btrfs: drop the redundant invalidate_bdev() Anand Jain
  7 siblings, 0 replies; 14+ messages in thread
From: Anand Jain @ 2018-03-27 23:39 UTC (permalink / raw)
  To: linux-btrfs

During mount context, we aren't verifying the superblock checksum
for all the devices, instead, we verify it only for the
struct btrfs_fs_device::latest_bdev. This patch fixes it by moving
the checksum verification code from the function open_ctree() into
the function btrfs_read_dev_one_super().

By doing this now we are verifying the superblock checksum in the
mount-context, device-replace and, device-delete context. The
device-replace and device-delete call-chain is as show below after
this patch.

delete-device/replace:
btrfs_rm_device() || btrfs_dev_replace_by_ioctl()
|_btrfs_find_device_by_devspec()
  |_btrfs_find_device_missing_or_by_path()
    |_btrfs_find_device_by_path()
      |_btrfs_get_bdev_and_sb()
        |_btrfs_read_dev_super()
          |_btrfs_read_dev_one_super()
	    |_btrfs_check_super_csum()

Test case:
 Before:
   mkfs.btrfs -fq -draid1 -mraid1 /dev/sdb /dev/sdc
   dd if=/dev/urandom of=/dev/sdc ibs=1 obs=1 count=1 seek=64K
   mount /dev/sdb /btrfs <-- success as kernel does not check csum
			     for non-btrfs_fs_devices::latest_bdev.
 After:
   mkfs.btrfs -fq -draid1 -mraid1 /dev/sdb /dev/sdc
   dd if=/dev/urandom of=/dev/sdc ibs=1 obs=1 count=1 seek=64K
   mount /dev/sdb /btrfs
     mount: mount /dev/sdc on /btrfs failed: Structure needs cleaning
   mount -o degraded /dev/sdc /btrfs
     mount: mount /dev/sdc on /btrfs failed: Structure needs cleaning

 So the current recovery step is to fix the primary superblock, by
 using the btrfs-progs cli.

Signed-off-by: Anand Jain <anand.jain@oracle.com>
Reviewed-by: Nikolay Borisov <nborisov@suse.com>
---
v1->v2:
 git commit log update. With the call-chain (which I believe will
  go away in the long term, we need the uuid from the userland not
  the disk-path). And add test case.
 Check err < 0 explicitly and drop check for "else if (err == -EUCLEAN)"
  v1:
	err = btrfs_check_super_csum(bh->b_data);
	if (err) {
		if (err == -EINVAL)
			pr_err("BTRFS error (device %pg): unsupported checksum algorithm",
				bdev);
		else if (err == -EUCLEAN)
			pr_err("BTRFS error (device %pg): superblock checksum mismatch",
				bdev);
		brelse(bh);
		return err;
	}

 fs/btrfs/disk-io.c | 33 +++++++++++++++++----------------
 1 file changed, 17 insertions(+), 16 deletions(-)

diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index 35dbbdc613cd..110465bec775 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -2565,22 +2565,6 @@ int open_ctree(struct super_block *sb,
 	}
 
 	/*
-	 * We want to check superblock checksum, the type is stored inside.
-	 * Pass the whole disk block of size BTRFS_SUPER_INFO_SIZE (4k).
-	 */
-	err = btrfs_check_super_csum(bh->b_data);
-	if (err) {
-		if (err == -EINVAL)
-			pr_err("BTRFS error (device %pg): unsupported checksum algorithm",
-				fs_devices->latest_bdev);
-		else
-			pr_err("BTRFS error (device %pg): superblock checksum mismatch",
-				fs_devices->latest_bdev);
-		brelse(bh);
-		goto fail_alloc;
-	}
-
-	/*
 	 * super_copy is zeroed at allocation time and we never touch the
 	 * following bytes up to INFO_SIZE, the checksum is calculated from
 	 * the whole block of INFO_SIZE
@@ -3126,6 +3110,7 @@ int btrfs_read_dev_one_super(struct block_device *bdev, int copy_num,
 	struct buffer_head *bh;
 	struct btrfs_super_block *super;
 	u64 bytenr;
+	int err;
 
 	bytenr = btrfs_sb_offset(copy_num);
 	if (bytenr + BTRFS_SUPER_INFO_SIZE >= i_size_read(bdev->bd_inode))
@@ -3146,6 +3131,22 @@ int btrfs_read_dev_one_super(struct block_device *bdev, int copy_num,
 		return -EINVAL;
 	}
 
+	/*
+	 * Check the superblock checksum, the type is stored inside.
+	 * Pass the whole disk block of size BTRFS_SUPER_INFO_SIZE (4k).
+	 */
+	err = btrfs_check_super_csum(bh->b_data);
+	if (err < 0) {
+		if (err == -EINVAL)
+			pr_err("BTRFS error (device %pg): unsupported checksum algorithm",
+				bdev);
+		else
+			pr_err("BTRFS error (device %pg): superblock checksum mismatch",
+				bdev);
+		brelse(bh);
+		return err;
+	}
+
 	*bh_ret = bh;
 	return 0;
 }
-- 
2.7.0


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 8/8] btrfs: drop the redundant invalidate_bdev()
  2018-03-27 23:39 [PATCH v2 0/9] Superblock read and verify cleanups Anand Jain
                   ` (6 preceding siblings ...)
  2018-03-27 23:39 ` [PATCH v2 7/8] btrfs: verify checksum for all devices in mount context Anand Jain
@ 2018-03-27 23:39 ` Anand Jain
  7 siblings, 0 replies; 14+ messages in thread
From: Anand Jain @ 2018-03-27 23:39 UTC (permalink / raw)
  To: linux-btrfs

During the mount context btrfs_open_devices() calls invalidate_bdev()
for all the devices. So drop the invalidate_bdev() in open_ctree()
which is only for the btrfs_fs_devices::latest_bdev.

The call trace is as shown below.

btrfs_mount_root()
 |
 |_btrfs_parse_early_options (-o device only)
 | |_btrfs_scan_one_device
 |   |_btrfs_read_disk_super()
 |     |_read_cache_page_gfp()
 |
 |_btrfs_scan_one_device(mount-arg-dev only)
 | |_btrfs_read_disk_super()
 |   |_read_cache_page_gfp()
 |
 |
 |_btrfs_open_devices(fsid:all)
 |  |_btrfs_open_one_device()
 |    |_btrfs_get_bdev_and_sb()  <--- invalidate_bdev(fsid:all)
 |      |_btrfs_read_dev_super()
 |        |_btrfs_read_dev_one_super()
 |          |___bread()
 |
 |_btrfs_fill_super()
   |_btrfs_open_ctree()   <-- invalidate_bdev(latest_bdev) <-- redundant
     |_btrfs_read_dev_super(latest_bdev only)
       |_btrfs_read_dev_one_super(latest_bdev only)
         |___bread(latest_bdev)

Signed-off-by: Anand Jain <anand.jain@oracle.com>
---
 fs/btrfs/disk-io.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index 110465bec775..628c2b1d1349 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -2553,8 +2553,6 @@ int open_ctree(struct super_block *sb,
 
 	__setup_root(tree_root, fs_info, BTRFS_ROOT_TREE_OBJECTID);
 
-	invalidate_bdev(fs_devices->latest_bdev);
-
 	/*
 	 * Read super block and check the signature bytes only
 	 */
-- 
2.7.0


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* Re: [PATCH v2 3/8] btrfs: cleanup btrfs_read_disk_super() to return std error
  2018-03-27 23:39 ` [PATCH v2 3/8] btrfs: cleanup btrfs_read_disk_super() to return std error Anand Jain
@ 2018-03-28  7:05   ` Nikolay Borisov
  0 siblings, 0 replies; 14+ messages in thread
From: Nikolay Borisov @ 2018-03-28  7:05 UTC (permalink / raw)
  To: Anand Jain, linux-btrfs



On 28.03.2018 02:39, Anand Jain wrote:
> The only caller btrfs_scan_one_device() sets -EINVAL for error from
> btrfs_read_disk_super(), so this patch returns -EINVAL from the latter
> function.
> 
> A preparatory patch to add csum check in btrfs_read_disk_super().
> 
> Signed-off-by: Anand Jain <anand.jain@oracle.com>

Reviewed-by: Nikolay Borisov <nborisov@suse.com>

> ---
> v1->v2:
>  Check btrfs_read_disk_super() to be more explicit ret < 0
> 
>  fs/btrfs/volumes.c | 15 +++++++--------
>  1 file changed, 7 insertions(+), 8 deletions(-)
> 
> diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
> index 87d183accdb2..e63723f23227 100644
> --- a/fs/btrfs/volumes.c
> +++ b/fs/btrfs/volumes.c
> @@ -1154,23 +1154,23 @@ static int btrfs_read_disk_super(struct block_device *bdev, u64 bytenr,
>  
>  	/* make sure our super fits in the device */
>  	if (bytenr + PAGE_SIZE >= i_size_read(bdev->bd_inode))
> -		return 1;
> +		return -EINVAL;
>  
>  	/* make sure our super fits in the page */
>  	if (sizeof(**disk_super) > PAGE_SIZE)
> -		return 1;
> +		return -EINVAL;
>  
>  	/* make sure our super doesn't straddle pages on disk */
>  	index = bytenr >> PAGE_SHIFT;
>  	if ((bytenr + sizeof(**disk_super) - 1) >> PAGE_SHIFT != index)
> -		return 1;
> +		return -EINVAL;
>  
>  	/* pull in the page with our super */
>  	*page = read_cache_page_gfp(bdev->bd_inode->i_mapping,
>  				   index, GFP_KERNEL);
>  
>  	if (IS_ERR_OR_NULL(*page))
> -		return 1;
> +		return -EINVAL;
>  
>  	p = kmap(*page);
>  
> @@ -1180,7 +1180,7 @@ static int btrfs_read_disk_super(struct block_device *bdev, u64 bytenr,
>  	if (btrfs_super_bytenr(*disk_super) != bytenr ||
>  	    btrfs_super_magic(*disk_super) != BTRFS_MAGIC) {
>  		btrfs_release_disk_super(*page);
> -		return 1;
> +		return -EINVAL;
>  	}
>  
>  	if ((*disk_super)->label[0] &&
> @@ -1218,10 +1218,9 @@ int btrfs_scan_one_device(const char *path, fmode_t flags, void *holder,
>  	if (IS_ERR(bdev))
>  		return PTR_ERR(bdev);
>  
> -	if (btrfs_read_disk_super(bdev, bytenr, &page, &disk_super)) {
> -		ret = -EINVAL;
> +	ret = btrfs_read_disk_super(bdev, bytenr, &page, &disk_super);
> +	if (ret < 0)
>  		goto error_bdev_put;
> -	}
>  
>  	mutex_lock(&uuid_mutex);
>  	device = device_list_add(path, disk_super);
> 

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v2 5/8] btrfs: check if the fsid in the primary sb and copy sb are same
  2018-03-27 23:39 ` [PATCH v2 5/8] btrfs: check if the fsid in the primary sb and copy sb are same Anand Jain
@ 2018-03-28  7:10   ` Nikolay Borisov
  2018-03-29 10:18     ` Anand Jain
  0 siblings, 1 reply; 14+ messages in thread
From: Nikolay Borisov @ 2018-03-28  7:10 UTC (permalink / raw)
  To: Anand Jain, linux-btrfs



On 28.03.2018 02:39, Anand Jain wrote:
> During the btrfs dev scan make sure that other copies of superblock
> contain the same fsid as the primary SB. So that we bring to the
> user notice if the superblock has been overwritten.
> 
>  mkfs.btrfs -fq /dev/sdc
>  mkfs.btrfs -fq /dev/sdb
>  dd if=/dev/sdb of=/dev/sdc count=4K skip=64K seek=64K obs=1 ibs=1
>  mount /dev/sdc /btrfs
> 
> Caveat: Pls note that older btrfs-progs do not wipe the non-overwriting
> stale superblock like copy2 if a smaller mkfs.btrfs -b  <size> is created.
> Thus this patch in the kernel will report error. The workaround is to wipe
> the superblock manually, like
>   dd if=/dev/zero of=<dev> seek=274877906944 ibs=1 obs=1 count4K
> OR apply the btrfs-progs patch
>   btrfs-progs: wipe copies of the stale superblock beyond -b size
> which shall find and wipe the non overwriting superblock during mkfs.
> 
> Signed-off-by: Anand Jain <anand.jain@oracle.com>
> ---
> v1->v2:
>   Do an explicit read for primary superblock. Drop kzalloc().
>   Fix split pr_err().
> 
>  fs/btrfs/volumes.c | 47 ++++++++++++++++++++++++++++++++++++-----------
>  1 file changed, 36 insertions(+), 11 deletions(-)
> 
> diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
> index e63723f23227..b099823f60d1 100644
> --- a/fs/btrfs/volumes.c
> +++ b/fs/btrfs/volumes.c
> @@ -1198,40 +1198,65 @@ static int btrfs_read_disk_super(struct block_device *bdev, u64 bytenr,
>  int btrfs_scan_one_device(const char *path, fmode_t flags, void *holder,
>  			  struct btrfs_fs_devices **fs_devices_ret)
>  {
> +	struct btrfs_super_block *disk_super_primary;
>  	struct btrfs_super_block *disk_super;
>  	struct btrfs_device *device;
>  	struct block_device *bdev;
> +	struct page *page_primary;
>  	struct page *page;
>  	int ret = 0;
>  	u64 bytenr;
> +	int i;
>  
> -	/*
> -	 * we would like to check all the supers, but that would make
> -	 * a btrfs mount succeed after a mkfs from a different FS.
> -	 * So, we need to add a special mount option to scan for
> -	 * later supers, using BTRFS_SUPER_MIRROR_MAX instead
> -	 */
> -	bytenr = btrfs_sb_offset(0);
>  	flags |= FMODE_EXCL;
>  
>  	bdev = blkdev_get_by_path(path, flags, holder);
>  	if (IS_ERR(bdev))
>  		return PTR_ERR(bdev);
>  
> -	ret = btrfs_read_disk_super(bdev, bytenr, &page, &disk_super);
> +	/*
> +	 * We would like to check all the supers and use one good copy,
> +	 * but that would make a btrfs mount succeed after a mkfs from
> +	 * a different FS.
> +	 * So, we need to add a special mount option to scan for
> +	 * later supers, using BTRFS_SUPER_MIRROR_MAX instead.
> +	 * So, just validate if all copies of the superblocks are ok
> +	 * and have the same fsid.
> +	 */
> +	bytenr = btrfs_sb_offset(0);
> +	ret = btrfs_read_disk_super(bdev, bytenr, &page_primary,
> +				    &disk_super_primary);
>  	if (ret < 0)
>  		goto error_bdev_put;
>  
> +	for (i = 1; i < BTRFS_SUPER_MIRROR_MAX; i++) {
> +		bytenr = btrfs_sb_offset(i);
> +		ret = btrfs_read_disk_super(bdev, bytenr, &page, &disk_super);
> +		if (ret < 0) {
> +			ret = 0;
> +			continue;
> +		}
> +
> +		if (memcmp(disk_super_primary->fsid, disk_super->fsid,
> +			   BTRFS_FSID_SIZE)) {
> +			pr_err("BTRFS (device %pg): superblock fsid mismatch, primary %pU copy%d %pU",
> +				bdev, disk_super_primary->fsid, i,
> +				disk_super->fsid);
> +			ret = -EINVAL;
> +			btrfs_release_disk_super(page);
> +			goto error_bdev_put;
> +		}
> +		btrfs_release_disk_super(page);
> +	}
> +
>  	mutex_lock(&uuid_mutex);
> -	device = device_list_add(path, disk_super);
> +	device = device_list_add(path, disk_super_primary);
>  	if (IS_ERR(device))
>  		ret = PTR_ERR(device);
>  	else
>  		*fs_devices_ret = device->fs_devices;
>  	mutex_unlock(&uuid_mutex);
>  
> -	btrfs_release_disk_super(page);
> ->  error_bdev_put:

You need a check whether page_primary is set here and release it,
otherwise you are leaking it. This needs to handle both the primary sb
read failure (where page_primary might not be set) as well as any FSID
mismatch from loop. (where it will be set)

>  	blkdev_put(bdev, flags);
>  
> 

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v2 6/8] btrfs: verify superblock checksum during scan
  2018-03-27 23:39 ` [PATCH v2 6/8] btrfs: verify superblock checksum during scan Anand Jain
@ 2018-03-28  7:21   ` Nikolay Borisov
  2018-03-29 10:17     ` Anand Jain
  0 siblings, 1 reply; 14+ messages in thread
From: Nikolay Borisov @ 2018-03-28  7:21 UTC (permalink / raw)
  To: Anand Jain, linux-btrfs



On 28.03.2018 02:39, Anand Jain wrote:
> During the scan context, we aren't verifying the superblock-
> checksum when read.
> This patch fixes it by adding the checksum verification function
> btrfs_check_super_csum() in the function btrfs_read_disk_super().
> And makes device scan to error fail if the primary superblock csum
> is wrong, whereas if the copy-superblock csum is wrong it will just
> just report mismatch and continue mount/scan as usual. When the

Where in this patch do you deal with the secondary sb.
btrfs_read_disk_super verifies only the primary sb which corresponds to
the first part of the sentence. But I'm confused about the second?

I also think that 4/8 should be merged into this one.

> mount is successful We anyway overwrite all superblocks upon unmount.
> 
> The context in which this will be called is - device scan, device ready,
> and mount -o device option.
> 
> Test script:
> 
>  Corrupt primary superblock and check if device scan and mount
>  fails:
>   mkfs.btrfs -fq /dev/sdc
>   dd if=/dev/urandom of=/dev/sdc ibs=1 obs=1 count=1 seek=64K
>   btrfs dev scan /dev/sdc
>   mount /dev/sdc /btrfs
> 
>  Corrupt secondary superblock and check if device scan and mount
>  is succcessful, check for the dmesg for errors.
>   mkfs.btrfs -fq /dev/sdc
>   dd if=/dev/urandom of=/dev/sdc ibs=1 obs=1 count=1 seek=67108864
>   btrfs dev scan /dev/sdc
>   mount /dev/sdc /btrfs
> 
> Signed-off-by: Anand Jain <anand.jain@oracle.com>
> ---
> v1->v2:
>  changed title.
>  use explicit (< 0) check for %errr.
>  Un-split pr_err() string.
>  Fix typo in the git commit log.
>  Move the csum check after bytenr and btrfs magic verified.
> 
>  fs/btrfs/volumes.c | 13 +++++++++++++
>  1 file changed, 13 insertions(+)
> 
> diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
> index b099823f60d1..eda86ba258fc 100644
> --- a/fs/btrfs/volumes.c
> +++ b/fs/btrfs/volumes.c
> @@ -1149,6 +1149,7 @@ static int btrfs_read_disk_super(struct block_device *bdev, u64 bytenr,
>  				 struct page **page,
>  				 struct btrfs_super_block **disk_super)
>  {
> +	int err;
>  	void *p;
>  	pgoff_t index;
>  
> @@ -1183,6 +1184,18 @@ static int btrfs_read_disk_super(struct block_device *bdev, u64 bytenr,
>  		return -EINVAL;
>  	}
>  
> +	err = btrfs_check_super_csum((char *) *disk_super);
> +	if (err < 0) {
> +		if (err == -EINVAL)
> +			pr_err("BTRFS error (device %pg): unsupported checksum type, bytenr=%llu",
> +				bdev, bytenr);
> +		else
> +			pr_err("BTRFS error (device %pg): superblock checksum failed, bytenr=%llu",
> +				bdev, bytenr);
> +		btrfs_release_disk_super(*page);
> +		return err;
> +	}
> +
>  	if ((*disk_super)->label[0] &&
>  		(*disk_super)->label[BTRFS_LABEL_SIZE - 1])
>  		(*disk_super)->label[BTRFS_LABEL_SIZE - 1] = '\0';
> 

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v2 6/8] btrfs: verify superblock checksum during scan
  2018-03-28  7:21   ` Nikolay Borisov
@ 2018-03-29 10:17     ` Anand Jain
  0 siblings, 0 replies; 14+ messages in thread
From: Anand Jain @ 2018-03-29 10:17 UTC (permalink / raw)
  To: Nikolay Borisov, linux-btrfs



On 03/28/2018 03:21 PM, Nikolay Borisov wrote:
> 
> 
> On 28.03.2018 02:39, Anand Jain wrote:
>> During the scan context, we aren't verifying the superblock-
>> checksum when read.
>> This patch fixes it by adding the checksum verification function
>> btrfs_check_super_csum() in the function btrfs_read_disk_super().
>> And makes device scan to error fail if the primary superblock csum
>> is wrong, whereas if the copy-superblock csum is wrong it will just
>> just report mismatch and continue mount/scan as usual. When the
> 
> Where in this patch do you deal with the secondary sb.


> btrfs_read_disk_super verifies only the primary sb which corresponds to
> the first part of the sentence. But I'm confused about the second?

  btrfs_read_disk_super() actaully reads and csum verifies the copy_num 
as provided.

         bytenr = btrfs_sb_offset(copy_num);

> I also think that 4/8 should be merged into this one.

  Right. I can do that.

Thanks, Anand

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v2 5/8] btrfs: check if the fsid in the primary sb and copy sb are same
  2018-03-28  7:10   ` Nikolay Borisov
@ 2018-03-29 10:18     ` Anand Jain
  0 siblings, 0 replies; 14+ messages in thread
From: Anand Jain @ 2018-03-29 10:18 UTC (permalink / raw)
  To: Nikolay Borisov, linux-btrfs





>> -	btrfs_release_disk_super(page);
>> ->  error_bdev_put:
> 
> You need a check whether page_primary is set here and release it,
> otherwise you are leaking it. This needs to handle both the primary sb
> read failure (where page_primary might not be set) as well as any FSID
> mismatch from loop. (where it will be set)> 

  Right. I should. Will do.

Thanks. Anand

>>   	blkdev_put(bdev, flags);
>>   
>>
> --
> 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
> 

^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2018-03-29 10:18 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-03-27 23:39 [PATCH v2 0/9] Superblock read and verify cleanups Anand Jain
2018-03-27 23:39 ` [PATCH 1/8] btrfs: cleanup btrfs_check_super_csum() for better code flow Anand Jain
2018-03-27 23:39 ` [PATCH v2 2/8] btrfs: return required error from btrfs_check_super_csum Anand Jain
2018-03-27 23:39 ` [PATCH v2 3/8] btrfs: cleanup btrfs_read_disk_super() to return std error Anand Jain
2018-03-28  7:05   ` Nikolay Borisov
2018-03-27 23:39 ` [PATCH 4/8] btrfs: make btrfs_check_super_csum() non-static Anand Jain
2018-03-27 23:39 ` [PATCH v2 5/8] btrfs: check if the fsid in the primary sb and copy sb are same Anand Jain
2018-03-28  7:10   ` Nikolay Borisov
2018-03-29 10:18     ` Anand Jain
2018-03-27 23:39 ` [PATCH v2 6/8] btrfs: verify superblock checksum during scan Anand Jain
2018-03-28  7:21   ` Nikolay Borisov
2018-03-29 10:17     ` Anand Jain
2018-03-27 23:39 ` [PATCH v2 7/8] btrfs: verify checksum for all devices in mount context Anand Jain
2018-03-27 23:39 ` [PATCH 8/8] btrfs: drop the redundant invalidate_bdev() Anand Jain

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.