[Ocfs2-tools-devel] [PATCH 1/2] mkfs.ocfs2: Use ocfs2_filesys efficiently

Joel Becker joel.becker at oracle.com
Fri Nov 14 15:49:33 PST 2008


mkfs.ocfs2 is really slow on large volumes, because it re-reads the
cluster bitmap four times.  Actually, eight.

Each function that uses libocfs2 (format_journals(), format_slotmap(),
etc) calls ocfs2_open(), does its work, and then calls ocfs2_close().
Thus, there is no caching of the cluster bitmap between these functions.
There are four of them, thus the four distinct reads of the cluster
bitmap.  We fix that by calling ocfs2_open() once, calling each of these
functions, and then calling ocfs2_close().

The next thing we do is use the io_cache.  This prevents us from some
double-reads of blocks inside the libocfs2 mechanics.

Signed-off-by: Joel Becker <joel.becker at oracle.com>
---
 mkfs.ocfs2/mkfs.c |  166 ++++++++++++++++++++++++----------------------------
 1 files changed, 77 insertions(+), 89 deletions(-)

diff --git a/mkfs.ocfs2/mkfs.c b/mkfs.ocfs2/mkfs.c
index aad166b..ae5eb67 100644
--- a/mkfs.ocfs2/mkfs.c
+++ b/mkfs.ocfs2/mkfs.c
@@ -82,10 +82,10 @@ static AllocGroup * initialize_alloc_group(State *s, const char *name,
 					   uint64_t blkno,
 					   uint16_t chain, uint16_t cpg,
 					   uint16_t bpc);
-static void create_lost_found_dir(State *s);
-static void format_journals(State *s);
-static void format_slotmap(State *s);
-static int format_backup_super(State *s);
+static void create_lost_found_dir(State *s, ocfs2_filesys *fs);
+static void format_journals(State *s, ocfs2_filesys *fs);
+static void format_slotmap(State *s, ocfs2_filesys *fs);
+static int format_backup_super(State *s, ocfs2_filesys *fs);
 
 extern char *optarg;
 extern int optind, opterr, optopt;
@@ -191,6 +191,70 @@ static inline uint32_t system_dir_bytes_needed(State *s)
 	return each * sys_blocks_needed(s->initial_slots);
 }
 
+static void finish_normal_format(State *s)
+{
+	errcode_t ret;
+	int num;
+	ocfs2_filesys *fs;
+
+	/* These routines use libocfs2 to do their work. We
+	 * don't share an ocfs2_filesys context between the
+	 * journal format and the lost+found create so that
+	 * the library can use the journal for the latter in
+	 * future revisions. */
+
+	ret = ocfs2_open(s->device_name, OCFS2_FLAG_RW, 0, 0, &fs);
+	if (ret) {
+		com_err(s->progname, ret,
+			"while opening file system for final "
+			"operations.");
+		clear_both_ends(s);
+		exit(1);
+	}
+
+	ret = io_init_cache(fs->fs_io,
+			    ocfs2_extent_recs_per_eb(fs->fs_blocksize));
+	if (ret)
+		com_err(s->progname, ret,
+			"while initializing the I/O cache.  Continuing "
+			"without a cache (safe, but slower)");
+
+	if (!s->no_backup_super) {
+		if (!s->quiet)
+			printf("Writing backup superblock: ");
+
+		num = format_backup_super(s, fs);
+		if (!s->quiet)
+			printf("%d block(s)\n", num);
+	}
+
+	if (!s->quiet)
+		printf("Formatting Journals: ");
+
+	format_journals(s, fs);
+
+	if (!s->quiet)
+		printf("done\n");
+
+	if (!s->quiet)
+		printf("Formatting slot map: ");
+
+	format_slotmap(s, fs);
+
+	if (!s->quiet)
+		printf("done\n");
+
+	if (!s->quiet)
+		printf("Writing lost+found: ");
+
+	create_lost_found_dir(s, fs);
+
+	if (!s->quiet)
+		printf("done\n");
+
+	ocfs2_close(fs);
+}
+
 int
 main(int argc, char **argv)
 {
@@ -457,46 +521,8 @@ main(int argc, char **argv)
 	if (!s->quiet)
 		printf("done\n");
 
-	if (!s->hb_dev) {
-		/* These routines use libocfs2 to do their work. We
-		 * don't share an ocfs2_filesys context between the
-		 * journal format and the lost+found create so that
-		 * the library can use the journal for the latter in
-		 * future revisions. */
-
-		if (!s->no_backup_super) {
-			if (!s->quiet)
-				printf("Writing backup superblock: ");
-
-			num = format_backup_super(s);
-			if (!s->quiet)
-				printf("%d block(s)\n", num);
-		}
-
-		if (!s->quiet)
-			printf("Formatting Journals: ");
-
-		format_journals(s);
-
-		if (!s->quiet)
-			printf("done\n");
-
-		if (!s->quiet)
-			printf("Formatting slot map: ");
-
-		format_slotmap(s);
-
-		if (!s->quiet)
-			printf("done\n");
-
-		if (!s->quiet)
-			printf("Writing lost+found: ");
-
-		create_lost_found_dir(s);
-
-		if (!s->quiet)
-			printf("done\n");
-	}
+	if (!s->hb_dev)
+		finish_normal_format(s);
 
 	close_device(s);
 
@@ -2363,18 +2389,11 @@ clear_both_ends(State *s)
 	return ;
 }
 
-static void create_lost_found_dir(State *s)
+static void create_lost_found_dir(State *s, ocfs2_filesys *fs)
 {
 	errcode_t ret;
-	ocfs2_filesys *fs = NULL;
 	uint64_t lost_found_blkno;
 
-	ret = ocfs2_open(s->device_name, OCFS2_FLAG_RW, 0, 0, &fs);
-	if (ret) {
-		com_err(s->progname, ret, "while opening new file system");
-		goto bail;
-	}
-
 	ret = ocfs2_new_inode(fs, &lost_found_blkno, S_IFDIR | 0755);
 	if (ret) {
 		com_err(s->progname, ret, "while creating lost+found");
@@ -2395,7 +2414,6 @@ static void create_lost_found_dir(State *s)
 		goto bail;
 	}
 
-	ocfs2_close(fs);
 	return ;
 
 bail:
@@ -2403,25 +2421,18 @@ bail:
 	exit(1);
 }
 
-static void format_journals(State *s)
+static void format_journals(State *s, ocfs2_filesys *fs)
 {
 	errcode_t ret;
 	int i;
 	uint32_t journal_size_in_clusters;
 	uint64_t blkno;
-	ocfs2_filesys *fs = NULL;
 	char jrnl_file[40];
 	ocfs2_fs_options features = {
 		.opt_incompat =
 			s->journal64 ? JBD2_FEATURE_INCOMPAT_64BIT : 0,
 	};
 
-	ret = ocfs2_open(s->device_name, OCFS2_FLAG_RW, 0, 0, &fs);
-	if (ret) {
-		com_err(s->progname, ret, "while opening new file system");
-		goto error;
-	}
-
 	journal_size_in_clusters = s->journal_size_in_bytes >>
 		OCFS2_RAW_SB(fs->fs_super)->s_clustersize_bits;
 
@@ -2447,7 +2458,6 @@ static void format_journals(State *s)
 		}
 	}
 
-	ocfs2_close(fs);
 	return;
 
 error:
@@ -2455,45 +2465,24 @@ error:
 	exit(1);
 }
 
-static void format_slotmap(State *s)
+static void format_slotmap(State *s, ocfs2_filesys *fs)
 {
 	errcode_t ret;
-	ocfs2_filesys *fs;
-
-	ret = ocfs2_open(s->device_name, OCFS2_FLAG_RW, 0, 0, &fs);
-	if (ret) {
-		com_err(s->progname, ret, "while opening new file system");
-		goto error;
-	}
 
 	ret = ocfs2_format_slot_map(fs);
 	if (ret) {
-	    com_err(s->progname, ret, "while formatting the slot map");
-	    goto error;
+		com_err(s->progname, ret, "while formatting the slot map");
+		clear_both_ends(s);
+		exit(1);
 	}
-
-	ocfs2_close(fs);
-	return;
-
-error:
-	clear_both_ends(s);
-	exit(1);
 }
 
-static int format_backup_super(State *s)
+static int format_backup_super(State *s, ocfs2_filesys *fs)
 {
 	errcode_t ret;
-	ocfs2_filesys *fs = NULL;
 	size_t len;
 	uint64_t blocks[OCFS2_MAX_BACKUP_SUPERBLOCKS];
 
-	ret = ocfs2_open(s->device_name, OCFS2_FLAG_RW, 0, 0, &fs);
-	if (ret) {
-		com_err(s->progname, ret,
-			"while opening file system for backup superblock.");
-		goto error;
-	}
-
 	len = ocfs2_get_backup_super_offsets(fs, blocks, ARRAY_SIZE(blocks));
 
 	ret = ocfs2_set_backup_super_list(fs, blocks, len);
@@ -2512,7 +2501,6 @@ static int format_backup_super(State *s)
 		goto error;
 	}
 
-	ocfs2_close(fs);
 	return len;
 
 error:
-- 
1.5.6.5




More information about the Ocfs2-tools-devel mailing list