File 0126-btrfs-progs-Use-oldest-super-for-btrfs-select-super..patch of Package btrfsprogs

From a780325614c0d89c9c0ea6779ada5af512b6e319 Mon Sep 17 00:00:00 2001
From: David Marcin <djmarcin@google.com>
Date: Tue, 22 Nov 2011 10:09:35 -0800
Subject: [PATCH 27/35] btrfs-progs: Use oldest super for btrfs-select-super. 
 Add required confirmation to btrfs-select-super.

Signed-off-by: David Marcin <djmarcin@google.com>
---
 btrfs-select-super.c |   38 ++++++++++++++++++++++++++++++--------
 disk-io.c            |    2 +-
 2 files changed, 31 insertions(+), 9 deletions(-)

diff --git a/btrfs-select-super.c b/btrfs-select-super.c
index 51eb9c9..4d27f1b 100644
--- a/btrfs-select-super.c
+++ b/btrfs-select-super.c
@@ -34,7 +34,9 @@
 
 static void print_usage(void)
 {
-	fprintf(stderr, "usage: btrfs-select-super -s number dev\n");
+	fprintf(stderr, "usage: btrfs-select-super [-c] [-e] -s number dev\n");
+	fprintf(stderr, "       -c Commit changes to disk [IRREVERSIBLE]\n");
+	fprintf(stderr, "       -e Use the earliest super found, may help recover transid verify problems\n");
 	fprintf(stderr, "%s\n", BTRFS_BUILD_VERSION);
 	exit(1);
 }
@@ -45,10 +47,13 @@ int main(int ac, char **av)
 	int ret;
 	int num;
 	u64 bytenr = 0;
+	int commit = 0;
+	int use_lowest_bdev = 0;
+	int fp;
 
 	while(1) {
 		int c;
-		c = getopt(ac, av, "s:");
+		c = getopt(ac, av, "s:ce");
 		if (c < 0)
 			break;
 		switch(c) {
@@ -58,6 +63,12 @@ int main(int ac, char **av)
 				printf("using SB copy %d, bytenr %llu\n", num,
 				       (unsigned long long)bytenr);
 				break;
+			case 'c':
+				commit = 1;
+				break;
+			case 'e':
+				use_earliest_bdev = 1;
+				break;
 			default:
 				print_usage();
 		}
@@ -74,22 +85,33 @@ int main(int ac, char **av)
 
 	radix_tree_init();
 
-	if((ret = check_mounted(av[optind])) < 0) {
+	if ((ret = check_mounted(av[optind])) < 0) {
 		fprintf(stderr, "Could not check mount status: %s\n", strerror(-ret));
 		return ret;
-	} else if(ret) {
+	} else if (ret) {
 		fprintf(stderr, "%s is currently mounted. Aborting.\n", av[optind]);
 		return -EBUSY;
 	}
 
-	root = open_ctree(av[optind], bytenr, 1);
+	fp = open(av[optind], O_CREAT|O_RDRW, 0600);
+	if (fp < 0) {
+		fprintf(stderr, "Could not open %s\n", av[optind]);
+		return 1;
+	}
+	root = open_ctree_fd(fp, av[optind], bytenr, 1, use_earliest_bdev);
 
 	if (root == NULL)
 		return 1;
 
-	/* make the super writing code think we've read the first super */
-	root->fs_info->super_bytenr = BTRFS_SUPER_INFO_OFFSET;
-	ret = write_all_supers(root);
+	fprintf(stderr, "Found superblock with generation %llu.\n", root->fs_info->super_copy.generation);
+
+	if (commit) {
+		fprintf(stderr, "Committing...\n");
+
+		/* make the super writing code think we've read the first super */
+		root->fs_info->super_bytenr = BTRFS_SUPER_INFO_OFFSET;
+		ret = write_all_supers(root);
+	}
 
 	/* we don't close the ctree or anything, because we don't want a real
 	 * transaction commit.  We just want the super copy we pulled off the
diff --git a/disk-io.c b/disk-io.c
index a161f15..9585057 100644
--- a/disk-io.c
+++ b/disk-io.c
@@ -871,7 +871,7 @@ struct btrfs_root *open_ctree_recovery(const char *filename, u64 sb_bytenr,
 		fprintf (stderr, "Could not open %s\n", filename);
 		return NULL;
 	}
-	root = __open_ctree_fd(fp, filename, sb_bytenr, root_tree_bytenr, 0);
+	root = __open_ctree_fd(fp, filename, sb_bytenr, root_tree_bytenr, 0, 0);
 	close(fp);
 
 	return root;
-- 
1.7.6.233.gd79bc

openSUSE Build Service is sponsored by