[Ocfs2-tools-devel] [PATCH] libocfs2: ocfs2_write_super() should update all superblocks

Joel Becker Joel.Becker at oracle.com
Wed Jul 9 00:44:49 PDT 2008


Normal operations should keep the backup superblocks up to date.  Thus,
ocfs2_write_super() is modified to refresh the backups.
ocfs2_write_primary_super() is introduced for operations that want to
leave the backups untouched.

The backup superblock APIs are slightly modified for clarity.  In
particular, ocfs2_refresh_backup_supers() is introduced to refresh all
backups.  It does nothing if backup superblocks are not enabled.  The
old API are kept but deprecated.

The rest of the tools now use the new APIs.  This includes using
ocfs2_write_primary_super() where necessary.

Signed-off-by: Joel Becker <joel.becker at oracle.com>
---
 debugfs.ocfs2/commands.c   |    4 +-
 fsck.ocfs2/fsck.c          |   38 ++---------------------------
 fsck.ocfs2/pass1.c         |    4 +-
 fsck.ocfs2/pass3.c         |    2 +-
 include/ocfs2/ocfs2.h      |   30 +++++++++++++++++-----
 libocfs2/backup_super.c    |   51 +++++++++++++++++++++++++++++++++------
 libocfs2/openfs.c          |   13 +++++++++-
 mkfs.ocfs2/mkfs.c          |    7 +++--
 o2image/o2image.c          |    9 ++++---
 tunefs.ocfs2/remove_slot.c |    2 +-
 tunefs.ocfs2/resize.c      |    2 +-
 tunefs.ocfs2/tunefs.c      |   57 +++++++------------------------------------
 12 files changed, 107 insertions(+), 112 deletions(-)

diff --git a/debugfs.ocfs2/commands.c b/debugfs.ocfs2/commands.c
index c8f4278..0fb89c4 100644
--- a/debugfs.ocfs2/commands.c
+++ b/debugfs.ocfs2/commands.c
@@ -390,8 +390,8 @@ static int process_open_args(char **args,
 	if (!s)
 		return 0;
 
-	num = ocfs2_get_backup_super_offset(NULL,
-					    byte_off, ARRAY_SIZE(byte_off));
+	num = ocfs2_get_backup_super_offsets(NULL, byte_off,
+					     ARRAY_SIZE(byte_off));
 	if (!num)
 		return -1;
 
diff --git a/fsck.ocfs2/fsck.c b/fsck.ocfs2/fsck.c
index a09530d..4d6070b 100644
--- a/fsck.ocfs2/fsck.c
+++ b/fsck.ocfs2/fsck.c
@@ -236,32 +236,6 @@ static errcode_t write_out_superblock(o2fsck_state *ost)
 	return ocfs2_write_super(ost->ost_fs);
 }
 
-static errcode_t update_backup_super(o2fsck_state *ost)
-{
-	errcode_t ret;
-	int num;
-	struct ocfs2_dinode *di = ost->ost_fs->fs_super;
-	struct ocfs2_super_block *sb = OCFS2_RAW_SB(di);
-	uint64_t blocks[OCFS2_MAX_BACKUP_SUPERBLOCKS];
-
-	if (!OCFS2_HAS_COMPAT_FEATURE(sb, OCFS2_FEATURE_COMPAT_BACKUP_SB))
-		return 0;
-
-	num = ocfs2_get_backup_super_offset(ost->ost_fs,
-					    blocks, ARRAY_SIZE(blocks));
-	if (!num)
-		return 0;
-
-	ret = ocfs2_refresh_backup_super(ost->ost_fs, blocks, num);
-	if (ret) {
-		com_err(whoami, ret, "while refreshing backup superblocks.");
-		goto bail;
-	}
-
-bail:
-	return ret;
-}
-
 static void scale_time(time_t secs, unsigned *scaled, char **units)
 {
 	if (secs < 60) {
@@ -494,7 +468,7 @@ static errcode_t recover_backup_super(o2fsck_state *ost,
 	if (sb_num < 1 || sb_num > OCFS2_MAX_BACKUP_SUPERBLOCKS)
 		return -1;
 
-	ocfs2_get_backup_super_offset(NULL, offsets, ARRAY_SIZE(offsets));
+	ocfs2_get_backup_super_offsets(NULL, offsets, ARRAY_SIZE(offsets));
 
 	/* iterate all the blocksize to get the right one. */
 	for (blksize = OCFS2_MIN_BLOCKSIZE;
@@ -517,7 +491,7 @@ static errcode_t recover_backup_super(o2fsck_state *ost,
 	    	   "Recover superblock information from backup block"
 		   "#%"PRIu64"?", sb)) {
 		fs->fs_super->i_blkno = OCFS2_SUPER_BLOCK_BLKNO;
-		ret = ocfs2_write_super(fs);
+		ret = ocfs2_write_primary_super(fs);
 		if (ret)
 			goto bail;
 	}
@@ -871,13 +845,7 @@ done:
 		ret = write_out_superblock(ost);
 		if (ret)
 			com_err(whoami, ret, "while writing back the "
-				"superblock");
-		else {
-			ret = update_backup_super(ost);
-			if (ret)
-				com_err(whoami, ret,
-					"while updating backup superblock.");
-		}
+				"superblock(s)");
 	}
 
 unlock:
diff --git a/fsck.ocfs2/pass1.c b/fsck.ocfs2/pass1.c
index bef2863..70611b4 100644
--- a/fsck.ocfs2/pass1.c
+++ b/fsck.ocfs2/pass1.c
@@ -1147,8 +1147,8 @@ static void write_cluster_alloc(o2fsck_state *ost)
 	memset(&clusters, 0, sizeof(clusters));
 	if (OCFS2_HAS_COMPAT_FEATURE(OCFS2_RAW_SB(ost->ost_fs->fs_super),
 				     OCFS2_FEATURE_COMPAT_BACKUP_SB)) {
-		num = ocfs2_get_backup_super_offset(ost->ost_fs, blocks,
-					   ARRAY_SIZE(blocks));
+		num = ocfs2_get_backup_super_offsets(ost->ost_fs, blocks,
+						     ARRAY_SIZE(blocks));
 		if (num) {
 			backup_super = 1;
 			for (i = 0; i < num; i++)
diff --git a/fsck.ocfs2/pass3.c b/fsck.ocfs2/pass3.c
index f546a72..a77424d 100644
--- a/fsck.ocfs2/pass3.c
+++ b/fsck.ocfs2/pass3.c
@@ -95,7 +95,7 @@ static void check_root(o2fsck_state *ost)
 	ost->ost_fs->fs_root_blkno = blkno;
 	sb->s_root_blkno = blkno;
 
-	ret = ocfs2_write_super(ost->ost_fs);
+	ret = ocfs2_write_primary_super(ost->ost_fs);
 	if (ret) {
 		com_err(whoami, ret, "while writing the super block with a "
 			"new root directory inode");
diff --git a/include/ocfs2/ocfs2.h b/include/ocfs2/ocfs2.h
index cd14153..ad6bd79 100644
--- a/include/ocfs2/ocfs2.h
+++ b/include/ocfs2/ocfs2.h
@@ -244,6 +244,9 @@ errcode_t io_init_cache_size(io_channel *channel, size_t bytes);
 void io_destroy_cache(io_channel *channel);
 
 errcode_t ocfs2_read_super(ocfs2_filesys *fs, uint64_t superblock, char *sb);
+/* Writes the main superblock at OCFS2_SUPER_BLOCK_BLKNO */
+errcode_t ocfs2_write_primary_super(ocfs2_filesys *fs);
+/* Writes the primary and backups if enabled */
 errcode_t ocfs2_write_super(ocfs2_filesys *fs);
 
 /*
@@ -592,8 +595,8 @@ errcode_t ocfs2_write_backup_super(ocfs2_filesys *fs, uint64_t blkno);
  * The unused ones, depending on the volume size, are zeroed.
  * Return the length of the block array.
  */
-int ocfs2_get_backup_super_offset(ocfs2_filesys *fs,
-				  uint64_t *blocks, size_t len);
+int ocfs2_get_backup_super_offsets(ocfs2_filesys *fs,
+				   uint64_t *blocks, size_t len);
 
 /* This function will get the superblock pointed to by fs and copy it to
  * the blocks. But first it will ensure all the appropriate clusters are free.
@@ -602,12 +605,14 @@ int ocfs2_get_backup_super_offset(ocfs2_filesys *fs,
  * In case of updating, it will override the backup blocks with the newest
  * superblock information.
  */
-errcode_t ocfs2_set_backup_super(ocfs2_filesys *fs,
-				 uint64_t *blocks, size_t len);
+errcode_t ocfs2_set_backup_super_list(ocfs2_filesys *fs,
+				      uint64_t *blocks, size_t len);
 
-/* Refresh the backup superblock inoformation. */
-errcode_t ocfs2_refresh_backup_super(ocfs2_filesys *fs,
-				     uint64_t *blocks, size_t len);
+/* Refresh the backup superblock information */
+errcode_t ocfs2_refresh_backup_supers(ocfs2_filesys *fs);
+/* Refresh a specific list of backup superblocks */
+errcode_t ocfs2_refresh_backup_super_list(ocfs2_filesys *fs,
+					  uint64_t *blocks, size_t len);
 
 errcode_t ocfs2_read_backup_super(ocfs2_filesys *fs, int backup, char *sbbuf);
 
@@ -615,6 +620,17 @@ errcode_t ocfs2_read_backup_super(ocfs2_filesys *fs, int backup, char *sbbuf);
 errcode_t ocfs2_get_last_cluster_offset(ocfs2_filesys *fs,
 					struct ocfs2_dinode *di,
 					uint32_t *v_cluster);
+
+/* These are deprecated names - don't use them */
+int ocfs2_get_backup_super_offset(ocfs2_filesys *fs,
+				  uint64_t *blocks, size_t len);
+errcode_t ocfs2_set_backup_super(ocfs2_filesys *fs,
+				 uint64_t *blocks, size_t len);
+errcode_t ocfs2_set_backup_super(ocfs2_filesys *fs,
+				 uint64_t *blocks, size_t len);
+
+
+
 /* 
  * ${foo}_to_${bar} is a floor function.  blocks_to_clusters will
  * returns the cluster that contains a block, not the number of clusters
diff --git a/libocfs2/backup_super.c b/libocfs2/backup_super.c
index c5bbdb2..54a1743 100644
--- a/libocfs2/backup_super.c
+++ b/libocfs2/backup_super.c
@@ -29,8 +29,8 @@
 /* In case we don't have fs_blocksize, we will return
  * byte offsets and let the caller calculate them by itself.
  */
-int ocfs2_get_backup_super_offset(ocfs2_filesys *fs,
-				  uint64_t *offsets, size_t len)
+int ocfs2_get_backup_super_offsets(ocfs2_filesys *fs,
+				   uint64_t *offsets, size_t len)
 {
 	size_t i;
 	uint64_t blkno;
@@ -73,8 +73,8 @@ bail:
 	return ret;
 }
 
-errcode_t ocfs2_set_backup_super(ocfs2_filesys *fs,
-				 uint64_t *blocks, size_t len)
+errcode_t ocfs2_set_backup_super_list(ocfs2_filesys *fs,
+				      uint64_t *blocks, size_t len)
 {
 	size_t i;
 	errcode_t ret = 0;
@@ -127,7 +127,7 @@ errcode_t ocfs2_set_backup_super(ocfs2_filesys *fs,
 			goto bail;
 	}
 
-	ret = ocfs2_refresh_backup_super(fs, blocks, len);
+	ret = ocfs2_refresh_backup_super_list(fs, blocks, len);
 	if (ret)
 		goto bail;
 
@@ -148,8 +148,8 @@ bail:
 	return ret;
 }
 
-errcode_t ocfs2_refresh_backup_super(ocfs2_filesys *fs,
-				     uint64_t *blocks, size_t len)
+errcode_t ocfs2_refresh_backup_super_list(ocfs2_filesys *fs,
+					  uint64_t *blocks, size_t len)
 {
 	errcode_t ret = 0;
 	size_t i;
@@ -164,6 +164,20 @@ bail:
 	return ret;
 }
 
+errcode_t ocfs2_refresh_backup_supers(ocfs2_filesys *fs)
+{
+	int num;
+	uint64_t blocks[OCFS2_MAX_BACKUP_SUPERBLOCKS];
+
+	if (!OCFS2_HAS_COMPAT_FEATURE(OCFS2_RAW_SB(fs->fs_super),
+				      OCFS2_FEATURE_COMPAT_BACKUP_SB))
+		return 0;  /* Do nothing */
+
+	num = ocfs2_get_backup_super_offsets(fs, blocks,
+					     ARRAY_SIZE(blocks));
+	return num ? ocfs2_refresh_backup_super_list(fs, blocks, num) : 0;
+}
+
 errcode_t ocfs2_read_backup_super(ocfs2_filesys *fs, int backup, char *sbbuf)
 {
 	int numsb;
@@ -173,9 +187,30 @@ errcode_t ocfs2_read_backup_super(ocfs2_filesys *fs, int backup, char *sbbuf)
 				      OCFS2_FEATURE_COMPAT_BACKUP_SB))
 		return OCFS2_ET_NO_BACKUP_SUPER;
 
-	numsb = ocfs2_get_backup_super_offset(fs, blocks, ARRAY_SIZE(blocks));
+	numsb = ocfs2_get_backup_super_offsets(fs, blocks,
+					       ARRAY_SIZE(blocks));
 	if (backup < 1 || backup > numsb)
 		return OCFS2_ET_NO_BACKUP_SUPER;
 
 	return ocfs2_read_super(fs, blocks[backup], sbbuf);
 }
+
+
+/* These were terrible names, don't use them */
+int ocfs2_get_backup_super_offset(ocfs2_filesys *fs,
+				  uint64_t *offsets, size_t len)
+{
+	return ocfs2_get_backup_super_offsets(fs, offsets, len);
+}
+errcode_t ocfs2_refresh_backup_super(ocfs2_filesys *fs,
+				     uint64_t *blocks, size_t len)
+{
+	return ocfs2_refresh_backup_super_list(fs, blocks, len);
+}
+errcode_t ocfs2_set_backup_super(ocfs2_filesys *fs,
+				 uint64_t *blocks, size_t len)
+{
+	return ocfs2_set_backup_super_list(fs, blocks, len);
+}
+
+
diff --git a/libocfs2/openfs.c b/libocfs2/openfs.c
index db5921a..4044757 100644
--- a/libocfs2/openfs.c
+++ b/libocfs2/openfs.c
@@ -136,7 +136,7 @@ out_blk:
 	return ret;
 }
 
-errcode_t ocfs2_write_super(ocfs2_filesys *fs)
+errcode_t ocfs2_write_primary_super(ocfs2_filesys *fs)
 {
 	errcode_t ret;
 	char *blk;
@@ -163,6 +163,17 @@ out_blk:
 	return ret;
 }
 
+errcode_t ocfs2_write_super(ocfs2_filesys *fs)
+{
+	errcode_t ret;
+
+	ret = ocfs2_write_primary_super(fs);
+	if (!ret)
+		ret = ocfs2_refresh_backup_supers(fs);
+
+	return ret;
+}
+
 errcode_t ocfs2_write_backup_super(ocfs2_filesys *fs, uint64_t blkno)
 {
 	errcode_t ret;
diff --git a/mkfs.ocfs2/mkfs.c b/mkfs.ocfs2/mkfs.c
index 77018af..8a1074d 100644
--- a/mkfs.ocfs2/mkfs.c
+++ b/mkfs.ocfs2/mkfs.c
@@ -2404,9 +2404,9 @@ static int format_backup_super(State *s)
 		goto error;
 	}
 
-	len = ocfs2_get_backup_super_offset(fs, blocks, ARRAY_SIZE(blocks));
+	len = ocfs2_get_backup_super_offsets(fs, blocks, ARRAY_SIZE(blocks));
 
-	ret = ocfs2_set_backup_super(fs, blocks, len);
+	ret = ocfs2_set_backup_super_list(fs, blocks, len);
 	if (ret) {
 		com_err(s->progname, ret, "while backing up superblock.");
 		goto error;
@@ -2415,7 +2415,8 @@ static int format_backup_super(State *s)
 	OCFS2_SET_COMPAT_FEATURE(OCFS2_RAW_SB(fs->fs_super),
 				 OCFS2_FEATURE_COMPAT_BACKUP_SB);
 
-	ret = ocfs2_write_super(fs);
+	/* ocfs2_set_backup_super_list() wrote the backups */
+	ret = ocfs2_write_primary_super(fs);
 	if (ret) {
 		com_err(s->progname, ret, "while updating superblock.");
 		goto error;
diff --git a/o2image/o2image.c b/o2image/o2image.c
index c12d305..99cbf7c 100644
--- a/o2image/o2image.c
+++ b/o2image/o2image.c
@@ -271,8 +271,8 @@ static errcode_t o2image_initialize(ocfs2_filesys *ofs, int raw_flag,
 
 	/* traverse and mark super blocks for backup */
 	if (super->s_feature_compat & OCFS2_FEATURE_COMPAT_BACKUP_SB) {
-		len = ocfs2_get_backup_super_offset(ofs, blocks,
-						    ARRAY_SIZE(blocks));
+		len = ocfs2_get_backup_super_offsets(ofs, blocks,
+						     ARRAY_SIZE(blocks));
 		for (i = 0; i < len; i++)
 			ocfs2_image_mark_bitmap(ofs, blocks[i]);
 	}
@@ -412,8 +412,9 @@ static errcode_t write_image_file(ocfs2_filesys *ofs, int fd)
 	hdr->hdr_fsblksz 	= ofs->fs_blocksize;
 	hdr->hdr_imgblkcnt	= blk;
 	hdr->hdr_bmpblksz	= ost->ost_bmpblksz;
-	hdr->hdr_superblkcnt 	= ocfs2_get_backup_super_offset(ofs, supers,
-							ARRAY_SIZE(supers));
+	hdr->hdr_superblkcnt 	=
+		ocfs2_get_backup_super_offsets(ofs, supers,
+					       ARRAY_SIZE(supers));
 	for (i = 0; i < hdr->hdr_superblkcnt; i++)
 		hdr->hdr_superblocks[i] = ocfs2_image_get_blockno(ofs,
 								  supers[i]);
diff --git a/tunefs.ocfs2/remove_slot.c b/tunefs.ocfs2/remove_slot.c
index ed4d460..a83f5a8 100644
--- a/tunefs.ocfs2/remove_slot.c
+++ b/tunefs.ocfs2/remove_slot.c
@@ -571,7 +571,7 @@ errcode_t remove_slots(ocfs2_filesys *fs)
 
 		/* The slot number is updated in the super block.*/
 		OCFS2_RAW_SB(fs->fs_super)->s_max_slots--;
-		ret = ocfs2_write_super(fs);
+		ret = ocfs2_write_primary_super(fs);
 		if (ret)
 			goto bail;
 
diff --git a/tunefs.ocfs2/resize.c b/tunefs.ocfs2/resize.c
index 6dc6851..911731a 100644
--- a/tunefs.ocfs2/resize.c
+++ b/tunefs.ocfs2/resize.c
@@ -199,7 +199,7 @@ static errcode_t reserve_backup_in_group(ocfs2_filesys *fs,
 				      OCFS2_FEATURE_COMPAT_BACKUP_SB))
 		goto out;
 
-	numsb = ocfs2_get_backup_super_offset(fs, blocks, ARRAY_SIZE(blocks));
+	numsb = ocfs2_get_backup_super_offsets(fs, blocks, ARRAY_SIZE(blocks));
 	if (numsb <= 0)
 		goto out;
 
diff --git a/tunefs.ocfs2/tunefs.c b/tunefs.ocfs2/tunefs.c
index be10eb2..ab47555 100644
--- a/tunefs.ocfs2/tunefs.c
+++ b/tunefs.ocfs2/tunefs.c
@@ -797,7 +797,8 @@ static errcode_t backup_super_check(ocfs2_filesys *fs)
 		return -1;
 	}
 
-	num = ocfs2_get_backup_super_offset(fs, blocks, ARRAY_SIZE(blocks));
+	num = ocfs2_get_backup_super_offsets(fs, blocks,
+					     ARRAY_SIZE(blocks));
 	if (!num) {
 		com_err(opts.progname, 0,
 			"Volume is too small to hold backup superblocks");
@@ -1001,21 +1002,6 @@ bail:
 	return ret;
 }
 
-static errcode_t refresh_backup_super(ocfs2_filesys *fs)
-{
-	errcode_t ret;
-	int num;
-	uint64_t blocks[OCFS2_MAX_BACKUP_SUPERBLOCKS];
-
-	num = ocfs2_get_backup_super_offset(fs, blocks, ARRAY_SIZE(blocks));
-	if (!num)
-		return 0;
-
-	ret = ocfs2_refresh_backup_super(fs, blocks, num);
-
-	return ret;
-}
-
 static errcode_t update_backup_super(ocfs2_filesys *fs, uint64_t startblk,
 				     uint64_t newblocks)
 {
@@ -1023,7 +1009,8 @@ static errcode_t update_backup_super(ocfs2_filesys *fs, uint64_t startblk,
 	int num, i;
 	uint64_t *new_backup_super, blocks[OCFS2_MAX_BACKUP_SUPERBLOCKS];
 
-	num = ocfs2_get_backup_super_offset(fs, blocks, ARRAY_SIZE(blocks));
+	num = ocfs2_get_backup_super_offsets(fs, blocks,
+					     ARRAY_SIZE(blocks));
 	if (!num)
 		return 0;
 
@@ -1041,7 +1028,7 @@ static errcode_t update_backup_super(ocfs2_filesys *fs, uint64_t startblk,
 	} else
 		new_backup_super = blocks;
 
-	ret = ocfs2_set_backup_super(fs, new_backup_super, num);
+	ret = ocfs2_set_backup_super_list(fs, new_backup_super, num);
 	if (ret) {
 		com_err(opts.progname, ret, "while backing up superblock.");
 		goto bail;
@@ -1407,7 +1394,7 @@ skip_cluster_start:
 				OCFS2_TUNEFS_INPROG_REMOVE_SLOT;
 		}
 
-		ret = ocfs2_write_super(fs);
+		ret = ocfs2_write_primary_super(fs);
 		if (ret) {
 			com_err(opts.progname, ret,
 				"while writing resize incompat flag");
@@ -1552,38 +1539,14 @@ skip_cluster_start:
 		block_signals(SIG_BLOCK);
 		ret = ocfs2_write_super(fs);
 		if (ret) {
-			com_err(opts.progname, ret, "while writing superblock");
+			com_err(opts.progname, ret,
+				"while writing superblock(s)");
 			goto unlock;
 		}
 		block_signals(SIG_UNBLOCK);
-		printf("Wrote Superblock\n");
-
-		/* superblock's information has changed.
-		 * We need to synchronize the backup blocks if needed.
-		 * We also have to admit that if upd_backup_super is set,
-		 * there is no need to refresh the backups since they are
-		 * written above by update_backup_super.
-		 */
-		if (!upd_backup_super &&
-		    OCFS2_HAS_COMPAT_FEATURE(OCFS2_RAW_SB(fs->fs_super),
-					     OCFS2_FEATURE_COMPAT_BACKUP_SB)) {
-			block_signals(SIG_BLOCK);
-			ret = refresh_backup_super(fs);
-			block_signals(SIG_UNBLOCK);
-			if (ret) {
-				printf("Unable to refresh backup superblocks. "
-					"Please run fsck.ocfs2 before running "
-					"tunefs.ocfs2 to re-enable "
-					"backup superblocks.");
-				OCFS2_CLEAR_COMPAT_FEATURE(
-					OCFS2_RAW_SB(fs->fs_super),
-					OCFS2_FEATURE_COMPAT_BACKUP_SB);
-				block_signals(SIG_BLOCK);
-				ocfs2_write_super(fs);
-				block_signals(SIG_UNBLOCK);
-			}
-		}
+		printf("Wrote Superblock(s)\n");
 	}
+
 online_resize_unlock:
 	if (online_resize)
 		online_resize_unlock(fs);
-- 
1.5.6


-- 

Life's Little Instruction Book #252

	"Take good care of those you love."

Joel Becker
Principal Software Developer
Oracle
E-mail: joel.becker at oracle.com
Phone: (650) 506-8127



More information about the Ocfs2-tools-devel mailing list