linux-btrfs.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Anand Jain <anand.jain@oracle.com>
To: linux-btrfs@vger.kernel.org
Subject: [PATCH v2 4/7] btrfs: check if the fsid in the primary sb and copy sb are same
Date: Fri, 30 Mar 2018 08:09:20 +0800	[thread overview]
Message-ID: <20180330000924.11148-5-anand.jain@oracle.com> (raw)
In-Reply-To: <20180330000924.11148-1-anand.jain@oracle.com>

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>
Reviewed-by: Nikolay Borisov <nborisov@suse.com>
---
v1->v2:
  Do an explicit read for primary superblock. Drop kzalloc().
  Fix split pr_err().

 fs/btrfs/volumes.c | 48 ++++++++++++++++++++++++++++++++++++++----------
 1 file changed, 38 insertions(+), 10 deletions(-)

diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
index e63723f23227..035affa447fa 100644
--- a/fs/btrfs/volumes.c
+++ b/fs/btrfs/volumes.c
@@ -1198,39 +1198,67 @@ 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_rel_primary;
+		}
+		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_rel_primary:
+	btrfs_release_disk_super(page_primary);
 
 error_bdev_put:
 	blkdev_put(bdev, flags);
-- 
2.7.0


  parent reply	other threads:[~2018-03-30  0:16 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-03-30  0:09 [PATCH v4 0/7] Superblock read and verify cleanups Anand Jain
2018-03-30  0:09 ` [PATCH 1/7] btrfs: cleanup btrfs_check_super_csum() for better code flow Anand Jain
2018-03-30  0:09 ` [PATCH v4 2/7] btrfs: return required error from btrfs_check_super_csum Anand Jain
2018-03-30  0:09 ` [PATCH v2 3/7] btrfs: cleanup btrfs_read_disk_super() to return std error Anand Jain
2018-03-30  0:09 ` Anand Jain [this message]
2018-03-30  0:09 ` [PATCH v4 5/7] btrfs: verify superblock checksum during scan Anand Jain
2018-03-30  0:09 ` [PATCH v2 6/7] btrfs: verify checksum for all devices in mount context Anand Jain
2018-03-30  0:09 ` [PATCH 7/7] btrfs: drop the redundant invalidate_bdev() Anand Jain
2018-04-10 14:48 ` [PATCH v4 0/7] Superblock read and verify cleanups David Sterba
2018-04-12  6:43   ` Anand Jain
  -- strict thread matches above, loose matches on Subject: below --
2018-03-29 10:36 [PATCH v3 0/9] " Anand Jain
2018-03-29 10:37 ` [PATCH v2 4/7] btrfs: check if the fsid in the primary sb and copy sb are same Anand Jain
2018-03-29 12:56   ` Nikolay Borisov

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20180330000924.11148-5-anand.jain@oracle.com \
    --to=anand.jain@oracle.com \
    --cc=linux-btrfs@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).