linux-btrfs.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] btrfs-progs: rescue-zero-log: Modify super block directly
@ 2019-10-26 10:11 Qu Wenruo
  2019-11-01 10:52 ` David Sterba
  0 siblings, 1 reply; 4+ messages in thread
From: Qu Wenruo @ 2019-10-26 10:11 UTC (permalink / raw)
  To: linux-btrfs; +Cc: Christian Pernegger

For log zeroing, we only need to reset log_root and log_root_level to 0.

However current zero-log still goes full open_ctree() which can be
rejected easily by extent tree corruption.

So this patch will change the behavior to modifying super block
directly, avoid any possible rejection from open_ctree()

Reported-by: Christian Pernegger <pernegger@gmail.com>
Signed-off-by: Qu Wenruo <wqu@suse.com>
---
 cmds/rescue.c | 48 ++++++++++++++++++++++++++++++++++++------------
 1 file changed, 36 insertions(+), 12 deletions(-)

diff --git a/cmds/rescue.c b/cmds/rescue.c
index e8eab6808bc3..3e2dedf04fda 100644
--- a/cmds/rescue.c
+++ b/cmds/rescue.c
@@ -19,6 +19,9 @@
 #include "kerncompat.h"
 
 #include <getopt.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/stat.h>
 #include "ctree.h"
 #include "volumes.h"
 #include "transaction.h"
@@ -164,10 +167,11 @@ static const char * const cmd_rescue_zero_log_usage[] = {
 static int cmd_rescue_zero_log(const struct cmd_struct *cmd,
 			       int argc, char **argv)
 {
-	struct btrfs_root *root;
-	struct btrfs_trans_handle *trans;
-	struct btrfs_super_block *sb;
 	char *devname;
+	u8 buf[BTRFS_SUPER_INFO_SIZE];
+	u8 result[BTRFS_CSUM_SIZE];
+	struct btrfs_super_block *sb = (struct btrfs_super_block *)buf;
+	int fd;
 	int ret;
 
 	clean_args_no_options(cmd, argc, argv);
@@ -187,24 +191,44 @@ static int cmd_rescue_zero_log(const struct cmd_struct *cmd,
 		goto out;
 	}
 
-	root = open_ctree(devname, 0, OPEN_CTREE_WRITES | OPEN_CTREE_PARTIAL);
-	if (!root) {
-		error("could not open ctree");
-		return 1;
+	fd = open(devname, O_RDWR);
+	if (fd < 0) {
+		ret = -errno;
+		error("failed to open '%s': %m", devname);
+		goto out;
+	}
+	/*
+	 * Log tree only exists in the primary super block, so SBREAD_DEFAULT
+	 * is enough.
+	 */
+	ret = btrfs_read_dev_super(fd, sb, BTRFS_SUPER_INFO_OFFSET,
+				   SBREAD_DEFAULT);
+	if (ret < 0) {
+		errno = -ret;
+		error("failed to read super block on '%s': %m", devname);
+		goto close_fd;
 	}
 
-	sb = root->fs_info->super_copy;
 	printf("Clearing log on %s, previous log_root %llu, level %u\n",
 			devname,
 			(unsigned long long)btrfs_super_log_root(sb),
 			(unsigned)btrfs_super_log_root_level(sb));
-	trans = btrfs_start_transaction(root, 1);
-	BUG_ON(IS_ERR(trans));
 	btrfs_set_super_log_root(sb, 0);
 	btrfs_set_super_log_root_level(sb, 0);
-	btrfs_commit_transaction(trans, root);
-	close_ctree(root);
+	btrfs_csum_data(btrfs_super_csum_type(sb), (u8 *)sb + BTRFS_CSUM_SIZE,
+			result, BTRFS_SUPER_INFO_SIZE - BTRFS_CSUM_SIZE);
+	memcpy(&sb->csum[0], result, BTRFS_CSUM_SIZE);
+	ret = pwrite64(fd, sb, BTRFS_SUPER_INFO_SIZE, BTRFS_SUPER_INFO_OFFSET);
+	if (ret != BTRFS_SUPER_INFO_SIZE) {
+		ret = -EIO;
+		errno = -ret;
+		error("failed to write super block for '%s': %m", devname);
+	} else {
+		ret = 0;
+	}
 
+close_fd:
+	close(fd);
 out:
 	return !!ret;
 }
-- 
2.23.0


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

end of thread, other threads:[~2019-11-01 11:08 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-10-26 10:11 [PATCH] btrfs-progs: rescue-zero-log: Modify super block directly Qu Wenruo
2019-11-01 10:52 ` David Sterba
2019-11-01 10:56   ` Qu WenRuo
2019-11-01 11:08     ` David Sterba

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).