All of lore.kernel.org
 help / color / mirror / Atom feed
From: Anand Jain <anand.jain@oracle.com>
To: linux-btrfs@vger.kernel.org
Subject: [PATCH 5/8] btrfs: check if the fsid in the primary sb and copy sb are same
Date: Mon, 26 Mar 2018 16:27:38 +0800	[thread overview]
Message-ID: <20180326082742.9235-6-anand.jain@oracle.com> (raw)
In-Reply-To: <20180326082742.9235-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.
So 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 btrfs-progs patch
  btrfs-progs: wipe copies of the stale superblock beyond -b size
which shall find and wipe the non overwriting superblock.

Signed-off-by: Anand Jain <anand.jain@oracle.com>
---
 fs/btrfs/volumes.c | 60 ++++++++++++++++++++++++++++++++++++++++++------------
 1 file changed, 47 insertions(+), 13 deletions(-)

diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
index ed22f0a3d239..45dd0674571b 100644
--- a/fs/btrfs/volumes.c
+++ b/fs/btrfs/volumes.c
@@ -1198,40 +1198,74 @@ 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;
 	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);
-	if (ret)
+	disk_super_primary = kzalloc(sizeof(*disk_super_primary), GFP_KERNEL);
+	if (!disk_super_primary) {
+		ret = -ENOMEM;
 		goto error_bdev_put;
+	}
+
+	/*
+	 * 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.
+	 */
+	for (i = 0; i < BTRFS_SUPER_MIRROR_MAX; i++) {
+		u64 bytenr = btrfs_sb_offset(i);
+
+		ret = btrfs_read_disk_super(bdev, bytenr, &page, &disk_super);
+		if (ret) {
+			if (i == 0)
+				goto error_kfree;
+			/* copy2 is optional */
+			ret = 0;
+			continue;
+		}
+
+		if (i == 0) {
+			memcpy(disk_super_primary, disk_super,
+			       sizeof(*disk_super_primary));
+			btrfs_release_disk_super(page);
+			continue;
+		} else if (memcmp(disk_super_primary->fsid, disk_super->fsid,
+			   BTRFS_FSID_SIZE)) {
+			pr_err("BTRFS (device %pg): superblock fsid missmatch "\
+				"primary %pU copy%d %pU", bdev,
+				disk_super_primary->fsid, i, disk_super->fsid);
+			ret = -EINVAL;
+			btrfs_release_disk_super(page);
+			goto error_kfree;
+		}
+		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_kfree:
+	kfree(disk_super_primary);
 error_bdev_put:
 	blkdev_put(bdev, flags);
 
-- 
2.7.0


  parent reply	other threads:[~2018-03-26  8:25 UTC|newest]

Thread overview: 26+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-03-26  8:27 [PATCH 0/8] Superblock read and verify cleanups Anand Jain
2018-03-26  8:27 ` [PATCH 1/8] btrfs: cleanup btrfs_check_super_csum() for better code flow Anand Jain
2018-03-27 12:10   ` Nikolay Borisov
2018-03-26  8:27 ` [PATCH 2/8] btrfs: return required error from btrfs_check_super_csum Anand Jain
2018-03-27  8:05   ` Nikolay Borisov
2018-03-27 19:16     ` David Sterba
2018-03-27 20:43       ` Anand Jain
2018-04-05 14:48         ` David Sterba
2018-03-26  8:27 ` [PATCH 3/8] btrfs: cleanup btrfs_read_disk_super() to return std error Anand Jain
2018-03-27  8:07   ` Nikolay Borisov
2018-03-26  8:27 ` [PATCH 4/8] btrfs: make btrfs_check_super_csum() non-static Anand Jain
2018-03-27 12:10   ` Nikolay Borisov
2018-03-26  8:27 ` Anand Jain [this message]
2018-03-27  8:49   ` [PATCH 5/8] btrfs: check if the fsid in the primary sb and copy sb are same Nikolay Borisov
2018-03-27 22:06     ` Anand Jain
2018-03-28  6:08       ` Nikolay Borisov
2018-03-28  7:05         ` Anand Jain
2018-03-26  8:27 ` [PATCH 6/8] btrfs: verify checksum when superblock is read for scan Anand Jain
2018-03-27 11:30   ` Nikolay Borisov
2018-03-27 12:09     ` Nikolay Borisov
2018-03-27 23:01       ` Anand Jain
2018-03-28  6:12         ` Nikolay Borisov
2018-03-26  8:27 ` [PATCH 7/8] btrfs: verify checksum for all devices in mount context Anand Jain
2018-03-27 12:21   ` Nikolay Borisov
2018-03-27 22:48     ` Anand Jain
2018-03-26  8:27 ` [PATCH 8/8] btrfs: drop the redundant invalidate_bdev() Anand Jain

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=20180326082742.9235-6-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 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.