All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH RFC v1 0/4] e2fsprogs: reserve more special inodes
@ 2015-03-12 16:20 Konstantin Khlebnikov
  2015-03-12 16:20 ` [PATCH RFC v1 1/4] resize2fs: allocate ext2_resize_t outside of resize_fs Konstantin Khlebnikov
                   ` (3 more replies)
  0 siblings, 4 replies; 9+ messages in thread
From: Konstantin Khlebnikov @ 2015-03-12 16:20 UTC (permalink / raw)
  To: Andreas Dilger, linux-ext4, Theodore Ts'o, Darrick J. Wong; +Cc: Li Xi

All reserved special inodes are used for various features (some of them
never been implemented in mainline). This patchset add option for reserving
more special inodes at mkfs time and option to reseze2fs for relocating
first inodes in existing filesystem and reserving them for special usage.

No changes in layout are required because index of first normal inode already
stored in superblock.

[ this is preparation for adding project quota feature ]

---

Konstantin Khlebnikov (4):
      resize2fs: allocate ext2_resize_t outside of resize_fs
      resize2fs: add option -I for reserving more special inodes
      mke2fs: add options extended option for changing first inode
      e2fsprogs: add test for mke2fs -E first_inode and resize2fs -I


 misc/mke2fs.8.in              |    8 +
 misc/mke2fs.c                 |   18 +++
 resize/main.c                 |   60 +++++++-
 resize/resize2fs.8.in         |    8 +
 resize/resize2fs.c            |   94 +++++++++----
 resize/resize2fs.h            |   10 +
 tests/r_resize_special/expect |  292 +++++++++++++++++++++++++++++++++++++++++
 tests/r_resize_special/name   |    1 
 tests/r_resize_special/script |   47 +++++++
 9 files changed, 497 insertions(+), 41 deletions(-)
 create mode 100644 tests/r_resize_special/expect
 create mode 100644 tests/r_resize_special/name
 create mode 100644 tests/r_resize_special/script

--
Signature

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

* [PATCH RFC v1 1/4] resize2fs: allocate ext2_resize_t outside of resize_fs
  2015-03-12 16:20 [PATCH RFC v1 0/4] e2fsprogs: reserve more special inodes Konstantin Khlebnikov
@ 2015-03-12 16:20 ` Konstantin Khlebnikov
  2015-03-12 16:20 ` [PATCH RFC v1 2/4] resize2fs: add option -I for reserving more special inodes Konstantin Khlebnikov
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 9+ messages in thread
From: Konstantin Khlebnikov @ 2015-03-12 16:20 UTC (permalink / raw)
  To: Andreas Dilger, linux-ext4, Theodore Ts'o, Darrick J. Wong; +Cc: Li Xi

This structure will be used for passing more parameters into resize_fs().

Signed-off-by: Konstantin Khlebnikov <khlebnikov@yandex-team.ru>
---
 resize/main.c      |   22 +++++++++++++++++++---
 resize/resize2fs.c |   42 ++++++++++++++----------------------------
 resize/resize2fs.h |    7 +++----
 3 files changed, 36 insertions(+), 35 deletions(-)

diff --git a/resize/main.c b/resize/main.c
index c25de61947f3..16f48d438cb0 100644
--- a/resize/main.c
+++ b/resize/main.c
@@ -187,6 +187,7 @@ int main (int argc, char ** argv)
 	long		sysval;
 	int		len, mount_flags;
 	char		*mtpt;
+	ext2_resize_t	rfs;
 
 #ifdef ENABLE_NLS
 	setlocale(LC_MESSAGES, "");
@@ -203,6 +204,15 @@ int main (int argc, char ** argv)
 	if (argc && *argv)
 		program_name = *argv;
 
+	/*
+	 * Create the data structure
+	 */
+	retval = ext2fs_get_memzero(sizeof(struct ext2_resize_struct), &rfs);
+	if (retval) {
+		com_err("resize2fs", retval, "can't allocate data structure\n");
+		exit(1);
+	}
+
 	while ((c = getopt(argc, argv, "d:fFhMPpS:bs")) != EOF) {
 		switch (c) {
 		case 'h':
@@ -526,9 +536,14 @@ int main (int argc, char ** argv)
 			printf(_("Resizing the filesystem on "
 				 "%s to %llu (%dk) blocks.\n"),
 			       device_name, new_size, blocksize / 1024);
-		retval = resize_fs(fs, &new_size, flags,
-				   ((flags & RESIZE_PERCENT_COMPLETE) ?
-				    resize_progress_func : 0));
+
+		rfs->flags = flags;
+		rfs->new_size = new_size;
+		if (flags & RESIZE_PERCENT_COMPLETE)
+			rfs->progress = resize_progress_func;
+
+		retval = resize_fs(fs, rfs);
+		new_size = rfs->new_size;
 	}
 	free(mtpt);
 	if (retval) {
@@ -562,5 +577,6 @@ int main (int argc, char ** argv)
 	if (fd > 0)
 		close(fd);
 	remove_error_table(&et_ext2_error_table);
+	ext2fs_free_mem(&rfs);
 	return (0);
 }
diff --git a/resize/resize2fs.c b/resize/resize2fs.c
index 041ff75029b2..dead364bf4bf 100644
--- a/resize/resize2fs.c
+++ b/resize/resize2fs.c
@@ -42,7 +42,7 @@
 #endif
 
 static void fix_uninit_block_bitmaps(ext2_filsys fs);
-static errcode_t adjust_superblock(ext2_resize_t rfs, blk64_t new_size);
+static errcode_t adjust_superblock(ext2_resize_t rfs);
 static errcode_t blocks_to_move(ext2_resize_t rfs);
 static errcode_t block_mover(ext2_resize_t rfs);
 static errcode_t inode_scan_and_fix(ext2_resize_t rfs);
@@ -56,7 +56,7 @@ static errcode_t mark_table_blocks(ext2_filsys fs,
 static errcode_t clear_sparse_super2_last_group(ext2_resize_t rfs);
 static errcode_t reserve_sparse_super2_last_group(ext2_resize_t rfs,
 						 ext2fs_block_bitmap meta_bmap);
-static errcode_t resize_group_descriptors(ext2_resize_t rfs, blk64_t new_size);
+static errcode_t resize_group_descriptors(ext2_resize_t rfs);
 static errcode_t move_bg_metadata(ext2_resize_t rfs);
 static errcode_t zero_high_bits_in_inodes(ext2_resize_t rfs);
 
@@ -84,28 +84,15 @@ static int lazy_itable_init;
 /*
  * This is the top-level routine which does the dirty deed....
  */
-errcode_t resize_fs(ext2_filsys fs, blk64_t *new_size, int flags,
-	    errcode_t (*progress)(ext2_resize_t rfs, int pass,
-					  unsigned long cur,
-					  unsigned long max_val))
+errcode_t resize_fs(ext2_filsys fs, ext2_resize_t rfs)
 {
-	ext2_resize_t	rfs;
 	errcode_t	retval;
 	struct resource_track	rtrack, overall_track;
+	int flags = rfs->flags;
 
-	/*
-	 * Create the data structure
-	 */
-	retval = ext2fs_get_mem(sizeof(struct ext2_resize_struct), &rfs);
-	if (retval)
-		return retval;
-
-	memset(rfs, 0, sizeof(struct ext2_resize_struct));
-	fs->priv_data = rfs;
 	rfs->old_fs = fs;
-	rfs->flags = flags;
-	rfs->itable_buf	 = 0;
-	rfs->progress = progress;
+	fs->priv_data = rfs;
+	rfs->itable_buf = 0;
 
 	init_resource_track(&overall_track, "overall resize2fs", fs->io);
 	init_resource_track(&rtrack, "read_bitmaps", fs->io);
@@ -126,7 +113,7 @@ errcode_t resize_fs(ext2_filsys fs, blk64_t *new_size, int flags,
 		goto errout;
 
 	init_resource_track(&rtrack, "resize_group_descriptors", fs->io);
-	retval = resize_group_descriptors(rfs, *new_size);
+	retval = resize_group_descriptors(rfs);
 	if (retval)
 		goto errout;
 	print_resource_track(rfs, &rtrack, fs->io);
@@ -144,7 +131,7 @@ errcode_t resize_fs(ext2_filsys fs, blk64_t *new_size, int flags,
 	print_resource_track(rfs, &rtrack, fs->io);
 
 	init_resource_track(&rtrack, "adjust_superblock", fs->io);
-	retval = adjust_superblock(rfs, *new_size);
+	retval = adjust_superblock(rfs);
 	if (retval)
 		goto errout;
 	print_resource_track(rfs, &rtrack, fs->io);
@@ -156,7 +143,7 @@ errcode_t resize_fs(ext2_filsys fs, blk64_t *new_size, int flags,
 	ext2fs_bg_flags_clear(rfs->new_fs, rfs->new_fs->group_desc_count - 1,
 			     EXT2_BG_BLOCK_UNINIT);
 
-	*new_size = ext2fs_blocks_count(rfs->new_fs->super);
+	rfs->new_size = ext2fs_blocks_count(rfs->new_fs->super);
 
 	init_resource_track(&rtrack, "blocks_to_move", fs->io);
 	retval = blocks_to_move(rfs);
@@ -240,7 +227,6 @@ errcode_t resize_fs(ext2_filsys fs, blk64_t *new_size, int flags,
 		ext2fs_free_block_bitmap(rfs->reserve_blocks);
 	if (rfs->move_blocks)
 		ext2fs_free_block_bitmap(rfs->move_blocks);
-	ext2fs_free_mem(&rfs);
 
 	return 0;
 
@@ -251,7 +237,6 @@ errout:
 	}
 	if (rfs->itable_buf)
 		ext2fs_free_mem(&rfs->itable_buf);
-	ext2fs_free_mem(&rfs);
 	return retval;
 }
 
@@ -274,7 +259,7 @@ static void adjust_reserved_gdt_blocks(ext2_filsys old_fs, ext2_filsys fs)
 }
 
 /* Toggle 64bit mode */
-static errcode_t resize_group_descriptors(ext2_resize_t rfs, blk64_t new_size)
+static errcode_t resize_group_descriptors(ext2_resize_t rfs)
 {
 	void *o, *n, *new_group_desc;
 	dgrp_t i;
@@ -284,7 +269,7 @@ static errcode_t resize_group_descriptors(ext2_resize_t rfs, blk64_t new_size)
 	if (!(rfs->flags & (RESIZE_DISABLE_64BIT | RESIZE_ENABLE_64BIT)))
 		return 0;
 
-	if (new_size != ext2fs_blocks_count(rfs->new_fs->super) ||
+	if (rfs->new_size != ext2fs_blocks_count(rfs->new_fs->super) ||
 	    ext2fs_blocks_count(rfs->new_fs->super) >= (1ULL << 32) ||
 	    (rfs->flags & RESIZE_DISABLE_64BIT &&
 	     rfs->flags & RESIZE_ENABLE_64BIT))
@@ -1006,7 +991,7 @@ errout:
  * This routine adjusts the superblock and other data structures, both
  * in disk as well as in memory...
  */
-static errcode_t adjust_superblock(ext2_resize_t rfs, blk64_t new_size)
+static errcode_t adjust_superblock(ext2_resize_t rfs)
 {
 	ext2_filsys	fs = rfs->new_fs;
 	int		adj = 0;
@@ -1024,7 +1009,8 @@ static errcode_t adjust_superblock(ext2_resize_t rfs, blk64_t new_size)
 	if (retval)
 		return retval;
 
-	retval = adjust_fs_info(fs, rfs->old_fs, rfs->reserve_blocks, new_size);
+	retval = adjust_fs_info(fs, rfs->old_fs,
+				rfs->reserve_blocks, rfs->new_size);
 	if (retval)
 		goto errout;
 
diff --git a/resize/resize2fs.h b/resize/resize2fs.h
index 829fcd8ea8e1..c5377e2b06c3 100644
--- a/resize/resize2fs.h
+++ b/resize/resize2fs.h
@@ -128,6 +128,8 @@ struct ext2_resize_struct {
 				    unsigned long cur,
 				    unsigned long max);
 	void		*prog_data;
+
+	blk64_t		new_size;
 };
 
 /*
@@ -141,10 +143,7 @@ struct ext2_resize_struct {
 
 
 /* prototypes */
-extern errcode_t resize_fs(ext2_filsys fs, blk64_t *new_size, int flags,
-			   errcode_t	(*progress)(ext2_resize_t rfs,
-					    int pass, unsigned long cur,
-					    unsigned long max));
+extern errcode_t resize_fs(ext2_filsys fs, ext2_resize_t rfs);
 
 extern errcode_t adjust_fs_info(ext2_filsys fs, ext2_filsys old_fs,
 				ext2fs_block_bitmap reserve_blocks,


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

* [PATCH RFC v1 2/4] resize2fs: add option -I for reserving more special inodes
  2015-03-12 16:20 [PATCH RFC v1 0/4] e2fsprogs: reserve more special inodes Konstantin Khlebnikov
  2015-03-12 16:20 ` [PATCH RFC v1 1/4] resize2fs: allocate ext2_resize_t outside of resize_fs Konstantin Khlebnikov
@ 2015-03-12 16:20 ` Konstantin Khlebnikov
  2015-03-12 19:26   ` Darrick J. Wong
  2015-03-12 16:20 ` [PATCH RFC v1 3/4] mke2fs: add options extended option for changing first inode Konstantin Khlebnikov
  2015-03-12 16:20 ` [PATCH RFC v1 4/4] e2fsprogs: add test for mke2fs -E first_inode and resize2fs -I Konstantin Khlebnikov
  3 siblings, 1 reply; 9+ messages in thread
From: Konstantin Khlebnikov @ 2015-03-12 16:20 UTC (permalink / raw)
  To: Andreas Dilger, linux-ext4, Theodore Ts'o, Darrick J. Wong; +Cc: Li Xi

Resize2fs relocates last inodes when it shinks filesystem.
This patch reuses this code for relocating first inodes,
it adds option '-I' for changing first normal inode.

Signed-off-by: Konstantin Khlebnikov <khlebnikov@yandex-team.ru>
---
 resize/main.c         |   38 ++++++++++++++++++++++++++++++++----
 resize/resize2fs.8.in |    8 ++++++++
 resize/resize2fs.c    |   52 +++++++++++++++++++++++++++++++++++++++++++++++--
 resize/resize2fs.h    |    3 +++
 4 files changed, 95 insertions(+), 6 deletions(-)

diff --git a/resize/main.c b/resize/main.c
index 16f48d438cb0..eae7146f41ab 100644
--- a/resize/main.c
+++ b/resize/main.c
@@ -41,8 +41,9 @@ static char *device_name, *io_options;
 
 static void usage (char *prog)
 {
-	fprintf (stderr, _("Usage: %s [-d debug_flags] [-f] [-F] [-M] [-P] "
-			   "[-p] device [-b|-s|new_size]\n\n"), prog);
+	fprintf (stderr, _("Usage: %s [-d debug_flags] [-f] [-F] [-M] [-P]"
+			   "[-p] [-I first_inode] device [-b|-s|new_size]\n\n"),
+			prog);
 
 	exit (1);
 }
@@ -213,7 +214,7 @@ int main (int argc, char ** argv)
 		exit(1);
 	}
 
-	while ((c = getopt(argc, argv, "d:fFhMPpS:bs")) != EOF) {
+	while ((c = getopt(argc, argv, "d:fFhMPpS:bsI:")) != EOF) {
 		switch (c) {
 		case 'h':
 			usage(program_name);
@@ -245,6 +246,10 @@ int main (int argc, char ** argv)
 		case 's':
 			flags |= RESIZE_DISABLE_64BIT;
 			break;
+		case 'I':
+			flags |= RESIZE_SPECIAL_INODES;
+			rfs->first_ino = atoi(optarg);
+			break;
 		default:
 			usage(program_name);
 		}
@@ -430,7 +435,8 @@ int main (int argc, char ** argv)
 			new_size &= ~((sys_page_size / blocksize)-1);
 	}
 	/* If changing 64bit, don't change the filesystem size. */
-	if (flags & (RESIZE_DISABLE_64BIT | RESIZE_ENABLE_64BIT)) {
+	if (flags & (RESIZE_DISABLE_64BIT | RESIZE_ENABLE_64BIT |
+		     RESIZE_SPECIAL_INODES)) {
 		new_size = ext2fs_blocks_count(fs->super);
 	}
 	if (!EXT2_HAS_INCOMPAT_FEATURE(fs->super,
@@ -507,6 +513,28 @@ int main (int argc, char ** argv)
 				"feature.\n"));
 			exit(1);
 		}
+	} else if (flags & RESIZE_SPECIAL_INODES) {
+		if (rfs->first_ino > fs->super->s_inodes_count) {
+			fprintf(stderr, _("First inode too big\n"));
+			exit(1);
+		}
+		if (rfs->first_ino < EXT2_FIRST_INO(fs->super)) {
+			fprintf(stderr, _("The filesystem has %d special inodes."
+					  "Reducing isn't supported.\n\n"),
+					EXT2_FIRST_INO(fs->super));
+			exit(1);
+		}
+		if (rfs->first_ino == EXT2_FIRST_INO(fs->super)) {
+			fprintf(stderr, _("The filesystem already has %d "
+					  "special inodes. Nothing to do!\n\n"),
+					EXT2_FIRST_INO(fs->super));
+			exit(0);
+		}
+		if (mount_flags & EXT2_MF_MOUNTED) {
+			fprintf(stderr, _("Cannot change count of special "
+				"inodes while the filesystem is mounted.\n"));
+			exit(1);
+		}
 	} else if (new_size == ext2fs_blocks_count(fs->super)) {
 		fprintf(stderr, _("The filesystem is already %llu (%dk) "
 			"blocks long.  Nothing to do!\n\n"), new_size,
@@ -532,6 +560,8 @@ int main (int argc, char ** argv)
 			printf(_("Converting the filesystem to 64-bit.\n"));
 		else if (flags & RESIZE_DISABLE_64BIT)
 			printf(_("Converting the filesystem to 32-bit.\n"));
+		else if (flags & RESIZE_SPECIAL_INODES)
+			printf(_("Reserving special inodes.\n"));
 		else
 			printf(_("Resizing the filesystem on "
 				 "%s to %llu (%dk) blocks.\n"),
diff --git a/resize/resize2fs.8.in b/resize/resize2fs.8.in
index 0129bfcafa3b..f22563fe07e1 100644
--- a/resize/resize2fs.8.in
+++ b/resize/resize2fs.8.in
@@ -18,6 +18,10 @@ resize2fs \- ext2/ext3/ext4 file system resizer
 .B \-S
 .I RAID-stride
 ]
+[
+.B \-I
+.I first-inode
+]
 .I device
 [
 .I size
@@ -101,6 +105,10 @@ to resize the filesystem concurrent with changing the 64bit status.
 Turns on the 64bit feature, resizes the group descriptors as necessary, and
 moves other metadata out of the way.
 .TP
+.B \-I \fI <first-inode>
+This changes first normal inode and relocates inuse inodes into vacant slots.
+Inodes below that are reserved for internal use. Reducing isn't supported.
+.TP
 .B \-d \fIdebug-flags
 Turns on various resize2fs debugging features, if they have been compiled
 into the binary.
diff --git a/resize/resize2fs.c b/resize/resize2fs.c
index dead364bf4bf..2fb653b76dd8 100644
--- a/resize/resize2fs.c
+++ b/resize/resize2fs.c
@@ -48,6 +48,7 @@ static errcode_t block_mover(ext2_resize_t rfs);
 static errcode_t inode_scan_and_fix(ext2_resize_t rfs);
 static errcode_t inode_ref_fix(ext2_resize_t rfs);
 static errcode_t move_itables(ext2_resize_t rfs);
+static errcode_t zero_new_special_inodes(ext2_resize_t rfs);
 static errcode_t fix_resize_inode(ext2_filsys fs);
 static errcode_t ext2fs_calculate_summary_stats(ext2_filsys fs);
 static errcode_t fix_sb_journal_backup(ext2_filsys fs);
@@ -112,6 +113,11 @@ errcode_t resize_fs(ext2_filsys fs, ext2_resize_t rfs)
 	if (retval)
 		goto errout;
 
+	if (flags & RESIZE_SPECIAL_INODES) {
+		ext2fs_update_dynamic_rev(rfs->new_fs);
+		EXT2_SB(rfs->new_fs->super)->s_first_ino = rfs->first_ino;
+	}
+
 	init_resource_track(&rtrack, "resize_group_descriptors", fs->io);
 	retval = resize_group_descriptors(rfs);
 	if (retval)
@@ -177,6 +183,12 @@ errcode_t resize_fs(ext2_filsys fs, ext2_resize_t rfs)
 		goto errout;
 	print_resource_track(rfs, &rtrack, fs->io);
 
+	init_resource_track(&rtrack, "zero_new_special_inodes", fs->io);
+	retval = zero_new_special_inodes(rfs);
+	if (retval)
+		goto errout;
+	print_resource_track(rfs, &rtrack, fs->io);
+
 	init_resource_track(&rtrack, "move_itables", fs->io);
 	retval = move_itables(rfs);
 	if (retval)
@@ -1963,7 +1975,8 @@ static errcode_t inode_scan_and_fix(ext2_resize_t rfs)
 
 	if ((rfs->old_fs->group_desc_count <=
 	     rfs->new_fs->group_desc_count) &&
-	    !rfs->bmap)
+	    !rfs->bmap &&
+	    !(rfs->flags & RESIZE_SPECIAL_INODES))
 		return 0;
 
 	set_com_err_hook(quiet_com_err_proc);
@@ -2018,7 +2031,11 @@ static errcode_t inode_scan_and_fix(ext2_resize_t rfs)
 			goto errout;
 
 		new_inode = ino;
-		if (ino <= start_to_move)
+		if (ino >= EXT2_FIRST_INO(rfs->old_fs->super) &&
+		    ino <  EXT2_FIRST_INO(rfs->new_fs->super)) {
+			ext2fs_inode_alloc_stats2(rfs->new_fs, ino, -1,
+						  pb.is_dir);
+		} else if (ino <= start_to_move)
 			goto remap_blocks; /* Don't need to move inode. */
 
 		/*
@@ -2552,6 +2569,37 @@ static errcode_t reserve_sparse_super2_last_group(ext2_resize_t rfs,
 }
 
 /*
+ * Clear new special inodes
+ */
+static errcode_t zero_new_special_inodes(ext2_resize_t rfs)
+{
+	ext2_filsys		fs = rfs->new_fs;
+	int			inode_size;
+	struct ext2_inode	*inode;
+	errcode_t		retval;
+	ext2_ino_t		ino;
+
+	if (!(rfs->flags & RESIZE_SPECIAL_INODES))
+		return 0;
+
+	inode_size = EXT2_INODE_SIZE(fs->super);
+	retval = ext2fs_get_memzero(inode_size, &inode);
+	if (retval)
+		return retval;
+
+	for (ino = EXT2_FIRST_INO(rfs->old_fs->super);
+	     ino < EXT2_FIRST_INO(fs->super); ino++) {
+		/* All special inodes are marked as inuse */
+		ext2fs_inode_alloc_stats2(fs, ino, +1, 0);
+		retval = ext2fs_write_inode_full(fs, ino, inode, inode_size);
+		if (retval)
+			break;
+	}
+	ext2fs_free_mem(&inode);
+	return retval;
+}
+
+/*
  * Fix the resize inode
  */
 static errcode_t fix_resize_inode(ext2_filsys fs)
diff --git a/resize/resize2fs.h b/resize/resize2fs.h
index c5377e2b06c3..84f83b09f237 100644
--- a/resize/resize2fs.h
+++ b/resize/resize2fs.h
@@ -85,6 +85,8 @@ typedef struct ext2_sim_progress *ext2_sim_progmeter;
 #define RESIZE_ENABLE_64BIT		0x0400
 #define RESIZE_DISABLE_64BIT		0x0800
 
+#define RESIZE_SPECIAL_INODES		0x1000
+
 /*
  * This structure is used for keeping track of how much resources have
  * been used for a particular resize2fs pass.
@@ -130,6 +132,7 @@ struct ext2_resize_struct {
 	void		*prog_data;
 
 	blk64_t		new_size;
+	ext2_ino_t	first_ino;
 };
 
 /*


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

* [PATCH RFC v1 3/4] mke2fs: add options extended option for changing first inode
  2015-03-12 16:20 [PATCH RFC v1 0/4] e2fsprogs: reserve more special inodes Konstantin Khlebnikov
  2015-03-12 16:20 ` [PATCH RFC v1 1/4] resize2fs: allocate ext2_resize_t outside of resize_fs Konstantin Khlebnikov
  2015-03-12 16:20 ` [PATCH RFC v1 2/4] resize2fs: add option -I for reserving more special inodes Konstantin Khlebnikov
@ 2015-03-12 16:20 ` Konstantin Khlebnikov
  2015-03-12 19:31   ` Darrick J. Wong
  2015-03-12 16:20 ` [PATCH RFC v1 4/4] e2fsprogs: add test for mke2fs -E first_inode and resize2fs -I Konstantin Khlebnikov
  3 siblings, 1 reply; 9+ messages in thread
From: Konstantin Khlebnikov @ 2015-03-12 16:20 UTC (permalink / raw)
  To: Andreas Dilger, linux-ext4, Theodore Ts'o, Darrick J. Wong; +Cc: Li Xi

All currently reserved special inodes are assigned to some features. Some of
them never been actually implemented so could be reused. But anyway there are
only few special inodes left. Index of first normal inode is already stored in
the super-block thus we can reserve more without changing disk layout.

This patch add extended option 'first_inode' for overriding default first inode
(mostly for debug purpose). Features which want special inodes above 10 could
change first_inode automatically.

Changing default first_inode is possible, but this breaks too much tests where
inode numbers are present in expected output or even hardcoded: for example in
"tst_inline_data".

Signed-off-by: Konstantin Khlebnikov <khlebnikov@yandex-team.ru>
---
 misc/mke2fs.8.in |    8 ++++++++
 misc/mke2fs.c    |   18 ++++++++++++++++++
 2 files changed, 26 insertions(+)

diff --git a/misc/mke2fs.8.in b/misc/mke2fs.8.in
index aeb5caf6e869..13f0c7a2c9d2 100644
--- a/misc/mke2fs.8.in
+++ b/misc/mke2fs.8.in
@@ -369,6 +369,14 @@ as default.
 .TP
 .BI nodiscard
 Do not attempt to discard blocks at mkfs time.
+.TP
+.BI first_inode= inode-number
+This defines first normal inode, lower inodes are reserved for internal use.
+For filesystem revision 0 this valus is fixed to 11, that is default and
+minimal value for revision 1. This could be changed at a later time with the
+.B \-I
+command-line option to
+.BR resize2fs (8).
 @QUOTA_MAN_COMMENT@.TP
 @QUOTA_MAN_COMMENT@.BI quotatype
 @QUOTA_MAN_COMMENT@Specify which quota type ('usr' or 'grp') is to be
diff --git a/misc/mke2fs.c b/misc/mke2fs.c
index ec450adf9e12..73d148206c69 100644
--- a/misc/mke2fs.c
+++ b/misc/mke2fs.c
@@ -1005,6 +1005,23 @@ static void parse_extended_opts(struct ext2_super_block *param,
 			discard = 1;
 		} else if (!strcmp(token, "nodiscard")) {
 			discard = 0;
+		} else if (!strcmp(token, "first_inode")) {
+			if (!arg) {
+				r_usage++;
+				badopt = token;
+				continue;
+			}
+			param->s_first_ino = strtoul(arg, &p, 0);
+			if (*p ||
+			    param->s_first_ino < EXT2_GOOD_OLD_FIRST_INO ||
+			    (param->s_rev_level == EXT2_GOOD_OLD_REV &&
+			     param->s_first_ino != EXT2_GOOD_OLD_FIRST_INO)) {
+				fprintf(stderr,
+					_("Invalid first_ino parameter: %s\n"),
+					arg);
+				r_usage++;
+				continue;
+			}
 		} else if (!strcmp(token, "quotatype")) {
 			if (!arg) {
 				r_usage++;
@@ -1047,6 +1064,7 @@ static void parse_extended_opts(struct ext2_super_block *param,
 			"\ttest_fs\n"
 			"\tdiscard\n"
 			"\tnodiscard\n"
+			"\tfirst_inode=<inode number>\n"
 			"\tquotatype=<usr OR grp>\n\n"),
 			badopt ? badopt : "");
 		free(buf);


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

* [PATCH RFC v1 4/4] e2fsprogs: add test for mke2fs -E first_inode and resize2fs -I
  2015-03-12 16:20 [PATCH RFC v1 0/4] e2fsprogs: reserve more special inodes Konstantin Khlebnikov
                   ` (2 preceding siblings ...)
  2015-03-12 16:20 ` [PATCH RFC v1 3/4] mke2fs: add options extended option for changing first inode Konstantin Khlebnikov
@ 2015-03-12 16:20 ` Konstantin Khlebnikov
  3 siblings, 0 replies; 9+ messages in thread
From: Konstantin Khlebnikov @ 2015-03-12 16:20 UTC (permalink / raw)
  To: Andreas Dilger, linux-ext4, Theodore Ts'o, Darrick J. Wong; +Cc: Li Xi

Test creates new filesystem with 10 special inodes and then reserves next 10.

Signed-off-by: Konstantin Khlebnikov <khlebnikov@yandex-team.ru>
---
 tests/r_resize_special/expect |  292 +++++++++++++++++++++++++++++++++++++++++
 tests/r_resize_special/name   |    1 
 tests/r_resize_special/script |   47 +++++++
 3 files changed, 340 insertions(+)
 create mode 100644 tests/r_resize_special/expect
 create mode 100644 tests/r_resize_special/name
 create mode 100644 tests/r_resize_special/script

diff --git a/tests/r_resize_special/expect b/tests/r_resize_special/expect
new file mode 100644
index 000000000000..8aba1ea0abd5
--- /dev/null
+++ b/tests/r_resize_special/expect
@@ -0,0 +1,292 @@
+mke2fs -E first_inode=11 -q -F -o Linux -b 1024 -g 1024 test.img 16384
+dumpe2fs test.img
+Filesystem volume name:   <none>
+Last mounted on:          <not available>
+Filesystem magic number:  0xEF53
+Filesystem revision #:    1 (dynamic)
+Filesystem features:      ext_attr resize_inode dir_index filetype sparse_super
+Default mount options:    (none)
+Filesystem state:         clean
+Errors behavior:          Continue
+Filesystem OS type:       Linux
+Inode count:              4096
+Block count:              16384
+Reserved block count:     819
+Free blocks:              14277
+Free inodes:              4085
+First block:              1
+Block size:               1024
+Fragment size:            1024
+Reserved GDT blocks:      256
+Blocks per group:         1024
+Fragments per group:      1024
+Inodes per group:         256
+Inode blocks per group:   32
+Mount count:              0
+Check interval:           15552000 (6 months)
+Reserved blocks uid:      0
+Reserved blocks gid:      0
+First inode:              11
+Inode size:	          128
+Default directory hash:   half_md4
+
+
+Group 0: (Blocks 1-1024)
+  Primary superblock at 1, Group descriptors at 2-2
+  Reserved GDT blocks at 3-258
+  Block bitmap at 259 (+258), Inode bitmap at 260 (+259)
+  Inode table at 261-292 (+260)
+  718 free blocks, 245 free inodes, 2 directories
+  Free blocks: 307-1024
+  Free inodes: 12-256
+Group 1: (Blocks 1025-2048)
+  Backup superblock at 1025, Group descriptors at 1026-1026
+  Reserved GDT blocks at 1027-1282
+  Block bitmap at 1283 (+258), Inode bitmap at 1284 (+259)
+  Inode table at 1285-1316 (+260)
+  732 free blocks, 256 free inodes, 0 directories
+  Free blocks: 1317-2048
+  Free inodes: 257-512
+Group 2: (Blocks 2049-3072)
+  Block bitmap at 2049 (+0), Inode bitmap at 2050 (+1)
+  Inode table at 2051-2082 (+2)
+  990 free blocks, 256 free inodes, 0 directories
+  Free blocks: 2083-3072
+  Free inodes: 513-768
+Group 3: (Blocks 3073-4096)
+  Backup superblock at 3073, Group descriptors at 3074-3074
+  Reserved GDT blocks at 3075-3330
+  Block bitmap at 3331 (+258), Inode bitmap at 3332 (+259)
+  Inode table at 3333-3364 (+260)
+  732 free blocks, 256 free inodes, 0 directories
+  Free blocks: 3365-4096
+  Free inodes: 769-1024
+Group 4: (Blocks 4097-5120)
+  Block bitmap at 4097 (+0), Inode bitmap at 4098 (+1)
+  Inode table at 4099-4130 (+2)
+  990 free blocks, 256 free inodes, 0 directories
+  Free blocks: 4131-5120
+  Free inodes: 1025-1280
+Group 5: (Blocks 5121-6144)
+  Backup superblock at 5121, Group descriptors at 5122-5122
+  Reserved GDT blocks at 5123-5378
+  Block bitmap at 5379 (+258), Inode bitmap at 5380 (+259)
+  Inode table at 5381-5412 (+260)
+  732 free blocks, 256 free inodes, 0 directories
+  Free blocks: 5413-6144
+  Free inodes: 1281-1536
+Group 6: (Blocks 6145-7168)
+  Block bitmap at 6145 (+0), Inode bitmap at 6146 (+1)
+  Inode table at 6147-6178 (+2)
+  990 free blocks, 256 free inodes, 0 directories
+  Free blocks: 6179-7168
+  Free inodes: 1537-1792
+Group 7: (Blocks 7169-8192)
+  Backup superblock at 7169, Group descriptors at 7170-7170
+  Reserved GDT blocks at 7171-7426
+  Block bitmap at 7427 (+258), Inode bitmap at 7428 (+259)
+  Inode table at 7429-7460 (+260)
+  732 free blocks, 256 free inodes, 0 directories
+  Free blocks: 7461-8192
+  Free inodes: 1793-2048
+Group 8: (Blocks 8193-9216)
+  Block bitmap at 8193 (+0), Inode bitmap at 8194 (+1)
+  Inode table at 8195-8226 (+2)
+  990 free blocks, 256 free inodes, 0 directories
+  Free blocks: 8227-9216
+  Free inodes: 2049-2304
+Group 9: (Blocks 9217-10240)
+  Backup superblock at 9217, Group descriptors at 9218-9218
+  Reserved GDT blocks at 9219-9474
+  Block bitmap at 9475 (+258), Inode bitmap at 9476 (+259)
+  Inode table at 9477-9508 (+260)
+  732 free blocks, 256 free inodes, 0 directories
+  Free blocks: 9509-10240
+  Free inodes: 2305-2560
+Group 10: (Blocks 10241-11264)
+  Block bitmap at 10241 (+0), Inode bitmap at 10242 (+1)
+  Inode table at 10243-10274 (+2)
+  990 free blocks, 256 free inodes, 0 directories
+  Free blocks: 10275-11264
+  Free inodes: 2561-2816
+Group 11: (Blocks 11265-12288)
+  Block bitmap at 11265 (+0), Inode bitmap at 11266 (+1)
+  Inode table at 11267-11298 (+2)
+  990 free blocks, 256 free inodes, 0 directories
+  Free blocks: 11299-12288
+  Free inodes: 2817-3072
+Group 12: (Blocks 12289-13312)
+  Block bitmap at 12289 (+0), Inode bitmap at 12290 (+1)
+  Inode table at 12291-12322 (+2)
+  990 free blocks, 256 free inodes, 0 directories
+  Free blocks: 12323-13312
+  Free inodes: 3073-3328
+Group 13: (Blocks 13313-14336)
+  Block bitmap at 13313 (+0), Inode bitmap at 13314 (+1)
+  Inode table at 13315-13346 (+2)
+  990 free blocks, 256 free inodes, 0 directories
+  Free blocks: 13347-14336
+  Free inodes: 3329-3584
+Group 14: (Blocks 14337-15360)
+  Block bitmap at 14337 (+0), Inode bitmap at 14338 (+1)
+  Inode table at 14339-14370 (+2)
+  990 free blocks, 256 free inodes, 0 directories
+  Free blocks: 14371-15360
+  Free inodes: 3585-3840
+Group 15: (Blocks 15361-16383)
+  Block bitmap at 15361 (+0), Inode bitmap at 15362 (+1)
+  Inode table at 15363-15394 (+2)
+  989 free blocks, 256 free inodes, 0 directories
+  Free blocks: 15395-16383
+  Free inodes: 3841-4096
+resize2fs -I 21 test.img
+Reserving special inodes.
+The filesystem on test.img is now 16384 (1k) blocks long.
+
+dumpe2fs test.img
+Filesystem volume name:   <none>
+Last mounted on:          <not available>
+Filesystem magic number:  0xEF53
+Filesystem revision #:    1 (dynamic)
+Filesystem features:      ext_attr resize_inode dir_index filetype sparse_super
+Default mount options:    (none)
+Filesystem state:         clean
+Errors behavior:          Continue
+Filesystem OS type:       Linux
+Inode count:              4096
+Block count:              16384
+Reserved block count:     819
+Free blocks:              14277
+Free inodes:              4075
+First block:              1
+Block size:               1024
+Fragment size:            1024
+Reserved GDT blocks:      256
+Blocks per group:         1024
+Fragments per group:      1024
+Inodes per group:         256
+Inode blocks per group:   32
+Mount count:              0
+Check interval:           15552000 (6 months)
+Reserved blocks uid:      0
+Reserved blocks gid:      0
+First inode:              21
+Inode size:	          128
+Default directory hash:   half_md4
+
+
+Group 0: (Blocks 1-1024)
+  Primary superblock at 1, Group descriptors at 2-2
+  Reserved GDT blocks at 3-258
+  Block bitmap at 259 (+258), Inode bitmap at 260 (+259)
+  Inode table at 261-292 (+260)
+  718 free blocks, 235 free inodes, 2 directories
+  Free blocks: 307-1024
+  Free inodes: 22-256
+Group 1: (Blocks 1025-2048)
+  Backup superblock at 1025, Group descriptors at 1026-1026
+  Reserved GDT blocks at 1027-1282
+  Block bitmap at 1283 (+258), Inode bitmap at 1284 (+259)
+  Inode table at 1285-1316 (+260)
+  732 free blocks, 256 free inodes, 0 directories
+  Free blocks: 1317-2048
+  Free inodes: 257-512
+Group 2: (Blocks 2049-3072)
+  Block bitmap at 2049 (+0), Inode bitmap at 2050 (+1)
+  Inode table at 2051-2082 (+2)
+  990 free blocks, 256 free inodes, 0 directories
+  Free blocks: 2083-3072
+  Free inodes: 513-768
+Group 3: (Blocks 3073-4096)
+  Backup superblock at 3073, Group descriptors at 3074-3074
+  Reserved GDT blocks at 3075-3330
+  Block bitmap at 3331 (+258), Inode bitmap at 3332 (+259)
+  Inode table at 3333-3364 (+260)
+  732 free blocks, 256 free inodes, 0 directories
+  Free blocks: 3365-4096
+  Free inodes: 769-1024
+Group 4: (Blocks 4097-5120)
+  Block bitmap at 4097 (+0), Inode bitmap at 4098 (+1)
+  Inode table at 4099-4130 (+2)
+  990 free blocks, 256 free inodes, 0 directories
+  Free blocks: 4131-5120
+  Free inodes: 1025-1280
+Group 5: (Blocks 5121-6144)
+  Backup superblock at 5121, Group descriptors at 5122-5122
+  Reserved GDT blocks at 5123-5378
+  Block bitmap at 5379 (+258), Inode bitmap at 5380 (+259)
+  Inode table at 5381-5412 (+260)
+  732 free blocks, 256 free inodes, 0 directories
+  Free blocks: 5413-6144
+  Free inodes: 1281-1536
+Group 6: (Blocks 6145-7168)
+  Block bitmap at 6145 (+0), Inode bitmap at 6146 (+1)
+  Inode table at 6147-6178 (+2)
+  990 free blocks, 256 free inodes, 0 directories
+  Free blocks: 6179-7168
+  Free inodes: 1537-1792
+Group 7: (Blocks 7169-8192)
+  Backup superblock at 7169, Group descriptors at 7170-7170
+  Reserved GDT blocks at 7171-7426
+  Block bitmap at 7427 (+258), Inode bitmap at 7428 (+259)
+  Inode table at 7429-7460 (+260)
+  732 free blocks, 256 free inodes, 0 directories
+  Free blocks: 7461-8192
+  Free inodes: 1793-2048
+Group 8: (Blocks 8193-9216)
+  Block bitmap at 8193 (+0), Inode bitmap at 8194 (+1)
+  Inode table at 8195-8226 (+2)
+  990 free blocks, 256 free inodes, 0 directories
+  Free blocks: 8227-9216
+  Free inodes: 2049-2304
+Group 9: (Blocks 9217-10240)
+  Backup superblock at 9217, Group descriptors at 9218-9218
+  Reserved GDT blocks at 9219-9474
+  Block bitmap at 9475 (+258), Inode bitmap at 9476 (+259)
+  Inode table at 9477-9508 (+260)
+  732 free blocks, 256 free inodes, 0 directories
+  Free blocks: 9509-10240
+  Free inodes: 2305-2560
+Group 10: (Blocks 10241-11264)
+  Block bitmap at 10241 (+0), Inode bitmap at 10242 (+1)
+  Inode table at 10243-10274 (+2)
+  990 free blocks, 256 free inodes, 0 directories
+  Free blocks: 10275-11264
+  Free inodes: 2561-2816
+Group 11: (Blocks 11265-12288)
+  Block bitmap at 11265 (+0), Inode bitmap at 11266 (+1)
+  Inode table at 11267-11298 (+2)
+  990 free blocks, 256 free inodes, 0 directories
+  Free blocks: 11299-12288
+  Free inodes: 2817-3072
+Group 12: (Blocks 12289-13312)
+  Block bitmap at 12289 (+0), Inode bitmap at 12290 (+1)
+  Inode table at 12291-12322 (+2)
+  990 free blocks, 256 free inodes, 0 directories
+  Free blocks: 12323-13312
+  Free inodes: 3073-3328
+Group 13: (Blocks 13313-14336)
+  Block bitmap at 13313 (+0), Inode bitmap at 13314 (+1)
+  Inode table at 13315-13346 (+2)
+  990 free blocks, 256 free inodes, 0 directories
+  Free blocks: 13347-14336
+  Free inodes: 3329-3584
+Group 14: (Blocks 14337-15360)
+  Block bitmap at 14337 (+0), Inode bitmap at 14338 (+1)
+  Inode table at 14339-14370 (+2)
+  990 free blocks, 256 free inodes, 0 directories
+  Free blocks: 14371-15360
+  Free inodes: 3585-3840
+Group 15: (Blocks 15361-16383)
+  Block bitmap at 15361 (+0), Inode bitmap at 15362 (+1)
+  Inode table at 15363-15394 (+2)
+  989 free blocks, 256 free inodes, 0 directories
+  Free blocks: 15395-16383
+  Free inodes: 3841-4096
+Pass 1: Checking inodes, blocks, and sizes
+Pass 2: Checking directory structure
+Pass 3: Checking directory connectivity
+Pass 4: Checking reference counts
+Pass 5: Checking group summary information
+test_filesys: 21/4096 files (0.0% non-contiguous), 2107/16384 blocks
+Exit status is 0
diff --git a/tests/r_resize_special/name b/tests/r_resize_special/name
new file mode 100644
index 000000000000..6ac3f588bee2
--- /dev/null
+++ b/tests/r_resize_special/name
@@ -0,0 +1 @@
+reserve more special inodes in filesystem
diff --git a/tests/r_resize_special/script b/tests/r_resize_special/script
new file mode 100644
index 000000000000..99abaa3f7a36
--- /dev/null
+++ b/tests/r_resize_special/script
@@ -0,0 +1,47 @@
+if test -x $RESIZE2FS_EXE; then
+
+FSCK_OPT=-yf
+OUT=$test_name.log
+EXP=$test_dir/expect
+cp /dev/null $OUT
+
+dd if=/dev/zero of=$TMPFILE bs=1k count=512 > /dev/null 2>&1
+
+echo mke2fs -E first_inode=11 -q -F -o Linux -b 1024 -g 1024 test.img 16384 > $OUT
+$MKE2FS -E first_inode=11 -q -F -o Linux -b 1024 -g 1024 $TMPFILE 16384 2>&1 |
+	sed -f $cmd_dir/filter.sed -e "s;$TMPFILE;test.img;" >> $OUT
+
+echo dumpe2fs test.img >> $OUT
+$DUMPE2FS $TMPFILE 2>&1 | sed -f $cmd_dir/filter.sed -e '/Block bitmap.*$/N;s/\n  Inode bitmap/, Inode bitmap/g' >> $OUT
+
+echo resize2fs -I 21 test.img>> $OUT
+$RESIZE2FS -I 21 $TMPFILE 2>&1 |
+	sed -f $cmd_dir/filter.sed -e "s;$TMPFILE;test.img;" >> $OUT
+
+echo dumpe2fs test.img >> $OUT
+$DUMPE2FS $TMPFILE 2>&1 | sed -f $cmd_dir/filter.sed -e '/Block bitmap.*$/N;s/\n  Inode bitmap/, Inode bitmap/g' >> $OUT
+
+$FSCK $FSCK_OPT -N test_filesys $TMPFILE > $OUT.new 2>&1
+status=$?
+echo Exit status is $status >> $OUT.new
+sed -f $cmd_dir/filter.sed -e "s;$TMPFILE;test.img;" $OUT.new >> $OUT
+rm -f $OUT.new
+
+rm -f $TMPFILE
+cmp -s $OUT $EXP
+status=$?
+
+if [ "$status" = 0 ] ; then
+	echo "$test_name: $test_description: ok"
+	touch $test_name.ok
+else
+	echo "$test_name: $test_description: failed"
+	diff $DIFF_OPTS $EXP $OUT > $test_name.failed
+	rm -f $test_name.tmp
+fi
+
+unset IMAGE FSCK_OPT OUT EXP
+
+else #if test -x $RESIZE2FS; then
+	echo "$test_name: $test_description: skipped"
+fi


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

* Re: [PATCH RFC v1 2/4] resize2fs: add option -I for reserving more special inodes
  2015-03-12 16:20 ` [PATCH RFC v1 2/4] resize2fs: add option -I for reserving more special inodes Konstantin Khlebnikov
@ 2015-03-12 19:26   ` Darrick J. Wong
  2015-03-13 10:52     ` Konstantin Khlebnikov
  0 siblings, 1 reply; 9+ messages in thread
From: Darrick J. Wong @ 2015-03-12 19:26 UTC (permalink / raw)
  To: Konstantin Khlebnikov
  Cc: Andreas Dilger, linux-ext4, Theodore Ts'o, Li Xi

On Thu, Mar 12, 2015 at 07:20:13PM +0300, Konstantin Khlebnikov wrote:
> Resize2fs relocates last inodes when it shinks filesystem.
> This patch reuses this code for relocating first inodes,
> it adds option '-I' for changing first normal inode.
> 
> Signed-off-by: Konstantin Khlebnikov <khlebnikov@yandex-team.ru>
> ---
>  resize/main.c         |   38 ++++++++++++++++++++++++++++++++----
>  resize/resize2fs.8.in |    8 ++++++++
>  resize/resize2fs.c    |   52 +++++++++++++++++++++++++++++++++++++++++++++++--
>  resize/resize2fs.h    |    3 +++
>  4 files changed, 95 insertions(+), 6 deletions(-)
> 
> diff --git a/resize/main.c b/resize/main.c
> index 16f48d438cb0..eae7146f41ab 100644
> --- a/resize/main.c
> +++ b/resize/main.c
> @@ -41,8 +41,9 @@ static char *device_name, *io_options;
>  
>  static void usage (char *prog)
>  {
> -	fprintf (stderr, _("Usage: %s [-d debug_flags] [-f] [-F] [-M] [-P] "
> -			   "[-p] device [-b|-s|new_size]\n\n"), prog);
> +	fprintf (stderr, _("Usage: %s [-d debug_flags] [-f] [-F] [-M] [-P]"
> +			   "[-p] [-I first_inode] device [-b|-s|new_size]\n\n"),
> +			prog);
>  
>  	exit (1);
>  }
> @@ -213,7 +214,7 @@ int main (int argc, char ** argv)
>  		exit(1);
>  	}
>  
> -	while ((c = getopt(argc, argv, "d:fFhMPpS:bs")) != EOF) {
> +	while ((c = getopt(argc, argv, "d:fFhMPpS:bsI:")) != EOF) {
>  		switch (c) {
>  		case 'h':
>  			usage(program_name);
> @@ -245,6 +246,10 @@ int main (int argc, char ** argv)
>  		case 's':
>  			flags |= RESIZE_DISABLE_64BIT;
>  			break;
> +		case 'I':
> +			flags |= RESIZE_SPECIAL_INODES;
> +			rfs->first_ino = atoi(optarg);
> +			break;
>  		default:
>  			usage(program_name);
>  		}
> @@ -430,7 +435,8 @@ int main (int argc, char ** argv)
>  			new_size &= ~((sys_page_size / blocksize)-1);
>  	}
>  	/* If changing 64bit, don't change the filesystem size. */
> -	if (flags & (RESIZE_DISABLE_64BIT | RESIZE_ENABLE_64BIT)) {
> +	if (flags & (RESIZE_DISABLE_64BIT | RESIZE_ENABLE_64BIT |
> +		     RESIZE_SPECIAL_INODES)) {
>  		new_size = ext2fs_blocks_count(fs->super);
>  	}
>  	if (!EXT2_HAS_INCOMPAT_FEATURE(fs->super,
> @@ -507,6 +513,28 @@ int main (int argc, char ** argv)
>  				"feature.\n"));
>  			exit(1);
>  		}
> +	} else if (flags & RESIZE_SPECIAL_INODES) {
> +		if (rfs->first_ino > fs->super->s_inodes_count) {

An FS with rfs->first_ino == fs->super->s_inodes_count isn't going to be
very useful... presumably you'd want at least one regular inode, right?

> +			fprintf(stderr, _("First inode too big\n"));

"Cannot reserve more than ($s_inodes_count - 1) inodes"?

> +			exit(1);
> +		}
> +		if (rfs->first_ino < EXT2_FIRST_INO(fs->super)) {
> +			fprintf(stderr, _("The filesystem has %d special inodes."
> +					  "Reducing isn't supported.\n\n"),
> +					EXT2_FIRST_INO(fs->super));
> +			exit(1);
> +		}
> +		if (rfs->first_ino == EXT2_FIRST_INO(fs->super)) {
> +			fprintf(stderr, _("The filesystem already has %d "
> +					  "special inodes. Nothing to do!\n\n"),
> +					EXT2_FIRST_INO(fs->super));
> +			exit(0);
> +		}
> +		if (mount_flags & EXT2_MF_MOUNTED) {
> +			fprintf(stderr, _("Cannot change count of special "
> +				"inodes while the filesystem is mounted.\n"));
> +			exit(1);
> +		}
>  	} else if (new_size == ext2fs_blocks_count(fs->super)) {
>  		fprintf(stderr, _("The filesystem is already %llu (%dk) "
>  			"blocks long.  Nothing to do!\n\n"), new_size,
> @@ -532,6 +560,8 @@ int main (int argc, char ** argv)
>  			printf(_("Converting the filesystem to 64-bit.\n"));
>  		else if (flags & RESIZE_DISABLE_64BIT)
>  			printf(_("Converting the filesystem to 32-bit.\n"));
> +		else if (flags & RESIZE_SPECIAL_INODES)
> +			printf(_("Reserving special inodes.\n"));
>  		else
>  			printf(_("Resizing the filesystem on "
>  				 "%s to %llu (%dk) blocks.\n"),
> diff --git a/resize/resize2fs.8.in b/resize/resize2fs.8.in
> index 0129bfcafa3b..f22563fe07e1 100644
> --- a/resize/resize2fs.8.in
> +++ b/resize/resize2fs.8.in
> @@ -18,6 +18,10 @@ resize2fs \- ext2/ext3/ext4 file system resizer
>  .B \-S
>  .I RAID-stride
>  ]
> +[
> +.B \-I
> +.I first-inode
> +]
>  .I device
>  [
>  .I size
> @@ -101,6 +105,10 @@ to resize the filesystem concurrent with changing the 64bit status.
>  Turns on the 64bit feature, resizes the group descriptors as necessary, and
>  moves other metadata out of the way.
>  .TP
> +.B \-I \fI <first-inode>
> +This changes first normal inode and relocates inuse inodes into vacant slots.
> +Inodes below that are reserved for internal use. Reducing isn't supported.

"Increases the number of reserved inodes, moving any in-use inodes into vacant
slots."?

--D

> +.TP
>  .B \-d \fIdebug-flags
>  Turns on various resize2fs debugging features, if they have been compiled
>  into the binary.
> diff --git a/resize/resize2fs.c b/resize/resize2fs.c
> index dead364bf4bf..2fb653b76dd8 100644
> --- a/resize/resize2fs.c
> +++ b/resize/resize2fs.c
> @@ -48,6 +48,7 @@ static errcode_t block_mover(ext2_resize_t rfs);
>  static errcode_t inode_scan_and_fix(ext2_resize_t rfs);
>  static errcode_t inode_ref_fix(ext2_resize_t rfs);
>  static errcode_t move_itables(ext2_resize_t rfs);
> +static errcode_t zero_new_special_inodes(ext2_resize_t rfs);
>  static errcode_t fix_resize_inode(ext2_filsys fs);
>  static errcode_t ext2fs_calculate_summary_stats(ext2_filsys fs);
>  static errcode_t fix_sb_journal_backup(ext2_filsys fs);
> @@ -112,6 +113,11 @@ errcode_t resize_fs(ext2_filsys fs, ext2_resize_t rfs)
>  	if (retval)
>  		goto errout;
>  
> +	if (flags & RESIZE_SPECIAL_INODES) {
> +		ext2fs_update_dynamic_rev(rfs->new_fs);
> +		EXT2_SB(rfs->new_fs->super)->s_first_ino = rfs->first_ino;
> +	}
> +
>  	init_resource_track(&rtrack, "resize_group_descriptors", fs->io);
>  	retval = resize_group_descriptors(rfs);
>  	if (retval)
> @@ -177,6 +183,12 @@ errcode_t resize_fs(ext2_filsys fs, ext2_resize_t rfs)
>  		goto errout;
>  	print_resource_track(rfs, &rtrack, fs->io);
>  
> +	init_resource_track(&rtrack, "zero_new_special_inodes", fs->io);
> +	retval = zero_new_special_inodes(rfs);
> +	if (retval)
> +		goto errout;
> +	print_resource_track(rfs, &rtrack, fs->io);
> +
>  	init_resource_track(&rtrack, "move_itables", fs->io);
>  	retval = move_itables(rfs);
>  	if (retval)
> @@ -1963,7 +1975,8 @@ static errcode_t inode_scan_and_fix(ext2_resize_t rfs)
>  
>  	if ((rfs->old_fs->group_desc_count <=
>  	     rfs->new_fs->group_desc_count) &&
> -	    !rfs->bmap)
> +	    !rfs->bmap &&
> +	    !(rfs->flags & RESIZE_SPECIAL_INODES))
>  		return 0;
>  
>  	set_com_err_hook(quiet_com_err_proc);
> @@ -2018,7 +2031,11 @@ static errcode_t inode_scan_and_fix(ext2_resize_t rfs)
>  			goto errout;
>  
>  		new_inode = ino;
> -		if (ino <= start_to_move)
> +		if (ino >= EXT2_FIRST_INO(rfs->old_fs->super) &&
> +		    ino <  EXT2_FIRST_INO(rfs->new_fs->super)) {
> +			ext2fs_inode_alloc_stats2(rfs->new_fs, ino, -1,
> +						  pb.is_dir);
> +		} else if (ino <= start_to_move)
>  			goto remap_blocks; /* Don't need to move inode. */
>  
>  		/*
> @@ -2552,6 +2569,37 @@ static errcode_t reserve_sparse_super2_last_group(ext2_resize_t rfs,
>  }
>  
>  /*
> + * Clear new special inodes
> + */
> +static errcode_t zero_new_special_inodes(ext2_resize_t rfs)
> +{
> +	ext2_filsys		fs = rfs->new_fs;
> +	int			inode_size;
> +	struct ext2_inode	*inode;
> +	errcode_t		retval;
> +	ext2_ino_t		ino;
> +
> +	if (!(rfs->flags & RESIZE_SPECIAL_INODES))
> +		return 0;
> +
> +	inode_size = EXT2_INODE_SIZE(fs->super);
> +	retval = ext2fs_get_memzero(inode_size, &inode);
> +	if (retval)
> +		return retval;
> +
> +	for (ino = EXT2_FIRST_INO(rfs->old_fs->super);
> +	     ino < EXT2_FIRST_INO(fs->super); ino++) {
> +		/* All special inodes are marked as inuse */
> +		ext2fs_inode_alloc_stats2(fs, ino, +1, 0);
> +		retval = ext2fs_write_inode_full(fs, ino, inode, inode_size);
> +		if (retval)
> +			break;
> +	}
> +	ext2fs_free_mem(&inode);
> +	return retval;
> +}
> +
> +/*
>   * Fix the resize inode
>   */
>  static errcode_t fix_resize_inode(ext2_filsys fs)
> diff --git a/resize/resize2fs.h b/resize/resize2fs.h
> index c5377e2b06c3..84f83b09f237 100644
> --- a/resize/resize2fs.h
> +++ b/resize/resize2fs.h
> @@ -85,6 +85,8 @@ typedef struct ext2_sim_progress *ext2_sim_progmeter;
>  #define RESIZE_ENABLE_64BIT		0x0400
>  #define RESIZE_DISABLE_64BIT		0x0800
>  
> +#define RESIZE_SPECIAL_INODES		0x1000
> +
>  /*
>   * This structure is used for keeping track of how much resources have
>   * been used for a particular resize2fs pass.
> @@ -130,6 +132,7 @@ struct ext2_resize_struct {
>  	void		*prog_data;
>  
>  	blk64_t		new_size;
> +	ext2_ino_t	first_ino;
>  };
>  
>  /*
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-ext4" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* Re: [PATCH RFC v1 3/4] mke2fs: add options extended option for changing first inode
  2015-03-12 16:20 ` [PATCH RFC v1 3/4] mke2fs: add options extended option for changing first inode Konstantin Khlebnikov
@ 2015-03-12 19:31   ` Darrick J. Wong
  0 siblings, 0 replies; 9+ messages in thread
From: Darrick J. Wong @ 2015-03-12 19:31 UTC (permalink / raw)
  To: Konstantin Khlebnikov
  Cc: Andreas Dilger, linux-ext4, Theodore Ts'o, Li Xi

On Thu, Mar 12, 2015 at 07:20:15PM +0300, Konstantin Khlebnikov wrote:
> All currently reserved special inodes are assigned to some features. Some of
> them never been actually implemented so could be reused. But anyway there are
> only few special inodes left. Index of first normal inode is already stored in
> the super-block thus we can reserve more without changing disk layout.
> 
> This patch add extended option 'first_inode' for overriding default first inode
> (mostly for debug purpose). Features which want special inodes above 10 could
> change first_inode automatically.
> 
> Changing default first_inode is possible, but this breaks too much tests where
> inode numbers are present in expected output or even hardcoded: for example in
> "tst_inline_data".

Hmmm, that's going to make things interesting whenever we *do* need to
increase the default # of reserved inodes.

> Signed-off-by: Konstantin Khlebnikov <khlebnikov@yandex-team.ru>
> ---
>  misc/mke2fs.8.in |    8 ++++++++
>  misc/mke2fs.c    |   18 ++++++++++++++++++
>  2 files changed, 26 insertions(+)
> 
> diff --git a/misc/mke2fs.8.in b/misc/mke2fs.8.in
> index aeb5caf6e869..13f0c7a2c9d2 100644
> --- a/misc/mke2fs.8.in
> +++ b/misc/mke2fs.8.in
> @@ -369,6 +369,14 @@ as default.
>  .TP
>  .BI nodiscard
>  Do not attempt to discard blocks at mkfs time.
> +.TP
> +.BI first_inode= inode-number
> +This defines first normal inode, lower inodes are reserved for internal use.
> +For filesystem revision 0 this valus is fixed to 11, that is default and
> +minimal value for revision 1. This could be changed at a later time with the

I doubt there are very many people formatting a rev0 FS these days. :)

"valus" -> "value" above.

> +.B \-I
> +command-line option to
> +.BR resize2fs (8).
>  @QUOTA_MAN_COMMENT@.TP
>  @QUOTA_MAN_COMMENT@.BI quotatype
>  @QUOTA_MAN_COMMENT@Specify which quota type ('usr' or 'grp') is to be
> diff --git a/misc/mke2fs.c b/misc/mke2fs.c
> index ec450adf9e12..73d148206c69 100644
> --- a/misc/mke2fs.c
> +++ b/misc/mke2fs.c
> @@ -1005,6 +1005,23 @@ static void parse_extended_opts(struct ext2_super_block *param,
>  			discard = 1;
>  		} else if (!strcmp(token, "nodiscard")) {
>  			discard = 0;
> +		} else if (!strcmp(token, "first_inode")) {
> +			if (!arg) {
> +				r_usage++;
> +				badopt = token;
> +				continue;
> +			}
> +			param->s_first_ino = strtoul(arg, &p, 0);
> +			if (*p ||
> +			    param->s_first_ino < EXT2_GOOD_OLD_FIRST_INO ||
> +			    (param->s_rev_level == EXT2_GOOD_OLD_REV &&
> +			     param->s_first_ino != EXT2_GOOD_OLD_FIRST_INO)) {
> +				fprintf(stderr,
> +					_("Invalid first_ino parameter: %s\n"),

"Invalid first_inode parameter"; please keep the parameter name consistent in
the program output.

> +					arg);
> +				r_usage++;
> +				continue;
> +			}
>  		} else if (!strcmp(token, "quotatype")) {
>  			if (!arg) {
>  				r_usage++;
> @@ -1047,6 +1064,7 @@ static void parse_extended_opts(struct ext2_super_block *param,
>  			"\ttest_fs\n"
>  			"\tdiscard\n"
>  			"\tnodiscard\n"
> +			"\tfirst_inode=<inode number>\n"
>  			"\tquotatype=<usr OR grp>\n\n"),
>  			badopt ? badopt : "");
>  		free(buf);
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-ext4" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* Re: [PATCH RFC v1 2/4] resize2fs: add option -I for reserving more special inodes
  2015-03-12 19:26   ` Darrick J. Wong
@ 2015-03-13 10:52     ` Konstantin Khlebnikov
  2015-03-13 20:36       ` Darrick J. Wong
  0 siblings, 1 reply; 9+ messages in thread
From: Konstantin Khlebnikov @ 2015-03-13 10:52 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: Andreas Dilger, linux-ext4, Theodore Ts'o, Li Xi

On 12.03.2015 22:26, Darrick J. Wong wrote:
> On Thu, Mar 12, 2015 at 07:20:13PM +0300, Konstantin Khlebnikov wrote:
>> Resize2fs relocates last inodes when it shinks filesystem.
>> This patch reuses this code for relocating first inodes,
>> it adds option '-I' for changing first normal inode.
>>
>> Signed-off-by: Konstantin Khlebnikov <khlebnikov@yandex-team.ru>
>> ---
>>   resize/main.c         |   38 ++++++++++++++++++++++++++++++++----
>>   resize/resize2fs.8.in |    8 ++++++++
>>   resize/resize2fs.c    |   52 +++++++++++++++++++++++++++++++++++++++++++++++--
>>   resize/resize2fs.h    |    3 +++
>>   4 files changed, 95 insertions(+), 6 deletions(-)
>>
>> diff --git a/resize/main.c b/resize/main.c
>> index 16f48d438cb0..eae7146f41ab 100644
>> --- a/resize/main.c
>> +++ b/resize/main.c

-cut

>> @@ -507,6 +513,28 @@ int main (int argc, char ** argv)
>>   				"feature.\n"));
>>   			exit(1);
>>   		}
>> +	} else if (flags & RESIZE_SPECIAL_INODES) {
>> +		if (rfs->first_ino > fs->super->s_inodes_count) {
>
> An FS with rfs->first_ino == fs->super->s_inodes_count isn't going to be
> very useful... presumably you'd want at least one regular inode, right?

In this case there will be exactly one regular inode:
s_inodes_count is index of last inode on the filesystem.

>
>> +			fprintf(stderr, _("First inode too big\n"));
>
> "Cannot reserve more than ($s_inodes_count - 1) inodes"?

So, you're suggest to rephrase option as "reserve special inodes"
instead of "set first normal inode"?

>
>> +			exit(1);
>> +		}
>> +		if (rfs->first_ino < EXT2_FIRST_INO(fs->super)) {
>> +			fprintf(stderr, _("The filesystem has %d special inodes."
>> +					  "Reducing isn't supported.\n\n"),
>> +					EXT2_FIRST_INO(fs->super));
>> +			exit(1);
>> +		}
>> +		if (rfs->first_ino == EXT2_FIRST_INO(fs->super)) {
>> +			fprintf(stderr, _("The filesystem already has %d "
>> +					  "special inodes. Nothing to do!\n\n"),
>> +					EXT2_FIRST_INO(fs->super));
>> +			exit(0);
>> +		}
>> +		if (mount_flags & EXT2_MF_MOUNTED) {
>> +			fprintf(stderr, _("Cannot change count of special "
>> +				"inodes while the filesystem is mounted.\n"));
>> +			exit(1);
>> +		}
>>   	} else if (new_size == ext2fs_blocks_count(fs->super)) {
>>   		fprintf(stderr, _("The filesystem is already %llu (%dk) "
>>   			"blocks long.  Nothing to do!\n\n"), new_size,
>> @@ -532,6 +560,8 @@ int main (int argc, char ** argv)
>>   			printf(_("Converting the filesystem to 64-bit.\n"));
>>   		else if (flags & RESIZE_DISABLE_64BIT)
>>   			printf(_("Converting the filesystem to 32-bit.\n"));
>> +		else if (flags & RESIZE_SPECIAL_INODES)
>> +			printf(_("Reserving special inodes.\n"));
>>   		else
>>   			printf(_("Resizing the filesystem on "
>>   				 "%s to %llu (%dk) blocks.\n"),
>> diff --git a/resize/resize2fs.8.in b/resize/resize2fs.8.in
>> index 0129bfcafa3b..f22563fe07e1 100644
>> --- a/resize/resize2fs.8.in
>> +++ b/resize/resize2fs.8.in
>> @@ -18,6 +18,10 @@ resize2fs \- ext2/ext3/ext4 file system resizer
>>   .B \-S
>>   .I RAID-stride
>>   ]
>> +[
>> +.B \-I
>> +.I first-inode
>> +]
>>   .I device
>>   [
>>   .I size
>> @@ -101,6 +105,10 @@ to resize the filesystem concurrent with changing the 64bit status.
>>   Turns on the 64bit feature, resizes the group descriptors as necessary, and
>>   moves other metadata out of the way.
>>   .TP
>> +.B \-I \fI <first-inode>
>> +This changes first normal inode and relocates inuse inodes into vacant slots.
>> +Inodes below that are reserved for internal use. Reducing isn't supported.
>
> "Increases the number of reserved inodes, moving any in-use inodes into vacant
> slots."?
>
> --D
>
>> +.TP
>>   .B \-d \fIdebug-flags
>>   Turns on various resize2fs debugging features, if they have been compiled
>>   into the binary.
>> diff --git a/resize/resize2fs.c b/resize/resize2fs.c
>> index dead364bf4bf..2fb653b76dd8 100644
>> --- a/resize/resize2fs.c
>> +++ b/resize/resize2fs.c
>> @@ -48,6 +48,7 @@ static errcode_t block_mover(ext2_resize_t rfs);
>>   static errcode_t inode_scan_and_fix(ext2_resize_t rfs);
>>   static errcode_t inode_ref_fix(ext2_resize_t rfs);
>>   static errcode_t move_itables(ext2_resize_t rfs);
>> +static errcode_t zero_new_special_inodes(ext2_resize_t rfs);
>>   static errcode_t fix_resize_inode(ext2_filsys fs);
>>   static errcode_t ext2fs_calculate_summary_stats(ext2_filsys fs);
>>   static errcode_t fix_sb_journal_backup(ext2_filsys fs);
>> @@ -112,6 +113,11 @@ errcode_t resize_fs(ext2_filsys fs, ext2_resize_t rfs)
>>   	if (retval)
>>   		goto errout;
>>
>> +	if (flags & RESIZE_SPECIAL_INODES) {
>> +		ext2fs_update_dynamic_rev(rfs->new_fs);
>> +		EXT2_SB(rfs->new_fs->super)->s_first_ino = rfs->first_ino;
>> +	}
>> +
>>   	init_resource_track(&rtrack, "resize_group_descriptors", fs->io);
>>   	retval = resize_group_descriptors(rfs);
>>   	if (retval)
>> @@ -177,6 +183,12 @@ errcode_t resize_fs(ext2_filsys fs, ext2_resize_t rfs)
>>   		goto errout;
>>   	print_resource_track(rfs, &rtrack, fs->io);
>>
>> +	init_resource_track(&rtrack, "zero_new_special_inodes", fs->io);
>> +	retval = zero_new_special_inodes(rfs);
>> +	if (retval)
>> +		goto errout;
>> +	print_resource_track(rfs, &rtrack, fs->io);
>> +
>>   	init_resource_track(&rtrack, "move_itables", fs->io);
>>   	retval = move_itables(rfs);
>>   	if (retval)
>> @@ -1963,7 +1975,8 @@ static errcode_t inode_scan_and_fix(ext2_resize_t rfs)
>>
>>   	if ((rfs->old_fs->group_desc_count <=
>>   	     rfs->new_fs->group_desc_count) &&
>> -	    !rfs->bmap)
>> +	    !rfs->bmap &&
>> +	    !(rfs->flags & RESIZE_SPECIAL_INODES))
>>   		return 0;
>>
>>   	set_com_err_hook(quiet_com_err_proc);
>> @@ -2018,7 +2031,11 @@ static errcode_t inode_scan_and_fix(ext2_resize_t rfs)
>>   			goto errout;
>>
>>   		new_inode = ino;
>> -		if (ino <= start_to_move)
>> +		if (ino >= EXT2_FIRST_INO(rfs->old_fs->super) &&
>> +		    ino <  EXT2_FIRST_INO(rfs->new_fs->super)) {
>> +			ext2fs_inode_alloc_stats2(rfs->new_fs, ino, -1,
>> +						  pb.is_dir);
>> +		} else if (ino <= start_to_move)
>>   			goto remap_blocks; /* Don't need to move inode. */
>>
>>   		/*
>> @@ -2552,6 +2569,37 @@ static errcode_t reserve_sparse_super2_last_group(ext2_resize_t rfs,
>>   }
>>
>>   /*
>> + * Clear new special inodes
>> + */
>> +static errcode_t zero_new_special_inodes(ext2_resize_t rfs)
>> +{
>> +	ext2_filsys		fs = rfs->new_fs;
>> +	int			inode_size;
>> +	struct ext2_inode	*inode;
>> +	errcode_t		retval;
>> +	ext2_ino_t		ino;
>> +
>> +	if (!(rfs->flags & RESIZE_SPECIAL_INODES))
>> +		return 0;
>> +
>> +	inode_size = EXT2_INODE_SIZE(fs->super);
>> +	retval = ext2fs_get_memzero(inode_size, &inode);
>> +	if (retval)
>> +		return retval;
>> +
>> +	for (ino = EXT2_FIRST_INO(rfs->old_fs->super);
>> +	     ino < EXT2_FIRST_INO(fs->super); ino++) {
>> +		/* All special inodes are marked as inuse */
>> +		ext2fs_inode_alloc_stats2(fs, ino, +1, 0);
>> +		retval = ext2fs_write_inode_full(fs, ino, inode, inode_size);
>> +		if (retval)
>> +			break;
>> +	}
>> +	ext2fs_free_mem(&inode);
>> +	return retval;
>> +}
>> +
>> +/*
>>    * Fix the resize inode
>>    */
>>   static errcode_t fix_resize_inode(ext2_filsys fs)
>> diff --git a/resize/resize2fs.h b/resize/resize2fs.h
>> index c5377e2b06c3..84f83b09f237 100644
>> --- a/resize/resize2fs.h
>> +++ b/resize/resize2fs.h
>> @@ -85,6 +85,8 @@ typedef struct ext2_sim_progress *ext2_sim_progmeter;
>>   #define RESIZE_ENABLE_64BIT		0x0400
>>   #define RESIZE_DISABLE_64BIT		0x0800
>>
>> +#define RESIZE_SPECIAL_INODES		0x1000
>> +
>>   /*
>>    * This structure is used for keeping track of how much resources have
>>    * been used for a particular resize2fs pass.
>> @@ -130,6 +132,7 @@ struct ext2_resize_struct {
>>   	void		*prog_data;
>>
>>   	blk64_t		new_size;
>> +	ext2_ino_t	first_ino;
>>   };
>>
>>   /*
>>
>> --
>> To unsubscribe from this list: send the line "unsubscribe linux-ext4" in
>> the body of a message to majordomo@vger.kernel.org
>> More majordomo info at  http://vger.kernel.org/majordomo-info.html


-- 
Konstantin

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

* Re: [PATCH RFC v1 2/4] resize2fs: add option -I for reserving more special inodes
  2015-03-13 10:52     ` Konstantin Khlebnikov
@ 2015-03-13 20:36       ` Darrick J. Wong
  0 siblings, 0 replies; 9+ messages in thread
From: Darrick J. Wong @ 2015-03-13 20:36 UTC (permalink / raw)
  To: Konstantin Khlebnikov
  Cc: Andreas Dilger, linux-ext4, Theodore Ts'o, Li Xi

On Fri, Mar 13, 2015 at 01:52:33PM +0300, Konstantin Khlebnikov wrote:
> On 12.03.2015 22:26, Darrick J. Wong wrote:
> >On Thu, Mar 12, 2015 at 07:20:13PM +0300, Konstantin Khlebnikov wrote:
> >>Resize2fs relocates last inodes when it shinks filesystem.
> >>This patch reuses this code for relocating first inodes,
> >>it adds option '-I' for changing first normal inode.
> >>
> >>Signed-off-by: Konstantin Khlebnikov <khlebnikov@yandex-team.ru>
> >>---
> >>  resize/main.c         |   38 ++++++++++++++++++++++++++++++++----
> >>  resize/resize2fs.8.in |    8 ++++++++
> >>  resize/resize2fs.c    |   52 +++++++++++++++++++++++++++++++++++++++++++++++--
> >>  resize/resize2fs.h    |    3 +++
> >>  4 files changed, 95 insertions(+), 6 deletions(-)
> >>
> >>diff --git a/resize/main.c b/resize/main.c
> >>index 16f48d438cb0..eae7146f41ab 100644
> >>--- a/resize/main.c
> >>+++ b/resize/main.c
> 
> -cut
> 
> >>@@ -507,6 +513,28 @@ int main (int argc, char ** argv)
> >>  				"feature.\n"));
> >>  			exit(1);
> >>  		}
> >>+	} else if (flags & RESIZE_SPECIAL_INODES) {
> >>+		if (rfs->first_ino > fs->super->s_inodes_count) {
> >
> >An FS with rfs->first_ino == fs->super->s_inodes_count isn't going to be
> >very useful... presumably you'd want at least one regular inode, right?
> 
> In this case there will be exactly one regular inode:
> s_inodes_count is index of last inode on the filesystem.

Yes.  Consider, however, that /lost+found is a regular inode, which means that
you'd have to remove it before you can store a single file on the FS, and fsck
will be unhappy if there's no /lost+found.

Actually come to think of it, this is resize2fs; the increase in first_ino must
be less than the free inode count or you'll later run out of inodes while
moving things around.

> 
> >
> >>+			fprintf(stderr, _("First inode too big\n"));
> >
> >"Cannot reserve more than ($s_inodes_count - 1) inodes"?
> 
> So, you're suggest to rephrase option as "reserve special inodes"
> instead of "set first normal inode"?

I was referring to the words 'inode too big', which could be confused for a
message about the size of the inode itself being too large, instead of the
first non-reserved inode *number* being too large.

Come to think of it, our naming isn't especially consistent -- s_first_ino =>
'first non-reserved inode' => 'special inodes'.  Ho hum.  Ted, do you care
about nomenclature?

--D

> 
> >
> >>+			exit(1);
> >>+		}
> >>+		if (rfs->first_ino < EXT2_FIRST_INO(fs->super)) {
> >>+			fprintf(stderr, _("The filesystem has %d special inodes."
> >>+					  "Reducing isn't supported.\n\n"),
> >>+					EXT2_FIRST_INO(fs->super));
> >>+			exit(1);
> >>+		}
> >>+		if (rfs->first_ino == EXT2_FIRST_INO(fs->super)) {
> >>+			fprintf(stderr, _("The filesystem already has %d "
> >>+					  "special inodes. Nothing to do!\n\n"),
> >>+					EXT2_FIRST_INO(fs->super));
> >>+			exit(0);
> >>+		}
> >>+		if (mount_flags & EXT2_MF_MOUNTED) {
> >>+			fprintf(stderr, _("Cannot change count of special "
> >>+				"inodes while the filesystem is mounted.\n"));
> >>+			exit(1);
> >>+		}
> >>  	} else if (new_size == ext2fs_blocks_count(fs->super)) {
> >>  		fprintf(stderr, _("The filesystem is already %llu (%dk) "
> >>  			"blocks long.  Nothing to do!\n\n"), new_size,
> >>@@ -532,6 +560,8 @@ int main (int argc, char ** argv)
> >>  			printf(_("Converting the filesystem to 64-bit.\n"));
> >>  		else if (flags & RESIZE_DISABLE_64BIT)
> >>  			printf(_("Converting the filesystem to 32-bit.\n"));
> >>+		else if (flags & RESIZE_SPECIAL_INODES)
> >>+			printf(_("Reserving special inodes.\n"));
> >>  		else
> >>  			printf(_("Resizing the filesystem on "
> >>  				 "%s to %llu (%dk) blocks.\n"),
> >>diff --git a/resize/resize2fs.8.in b/resize/resize2fs.8.in
> >>index 0129bfcafa3b..f22563fe07e1 100644
> >>--- a/resize/resize2fs.8.in
> >>+++ b/resize/resize2fs.8.in
> >>@@ -18,6 +18,10 @@ resize2fs \- ext2/ext3/ext4 file system resizer
> >>  .B \-S
> >>  .I RAID-stride
> >>  ]
> >>+[
> >>+.B \-I
> >>+.I first-inode
> >>+]
> >>  .I device
> >>  [
> >>  .I size
> >>@@ -101,6 +105,10 @@ to resize the filesystem concurrent with changing the 64bit status.
> >>  Turns on the 64bit feature, resizes the group descriptors as necessary, and
> >>  moves other metadata out of the way.
> >>  .TP
> >>+.B \-I \fI <first-inode>
> >>+This changes first normal inode and relocates inuse inodes into vacant slots.
> >>+Inodes below that are reserved for internal use. Reducing isn't supported.
> >
> >"Increases the number of reserved inodes, moving any in-use inodes into vacant
> >slots."?
> >
> >--D
> >
> >>+.TP
> >>  .B \-d \fIdebug-flags
> >>  Turns on various resize2fs debugging features, if they have been compiled
> >>  into the binary.
> >>diff --git a/resize/resize2fs.c b/resize/resize2fs.c
> >>index dead364bf4bf..2fb653b76dd8 100644
> >>--- a/resize/resize2fs.c
> >>+++ b/resize/resize2fs.c
> >>@@ -48,6 +48,7 @@ static errcode_t block_mover(ext2_resize_t rfs);
> >>  static errcode_t inode_scan_and_fix(ext2_resize_t rfs);
> >>  static errcode_t inode_ref_fix(ext2_resize_t rfs);
> >>  static errcode_t move_itables(ext2_resize_t rfs);
> >>+static errcode_t zero_new_special_inodes(ext2_resize_t rfs);
> >>  static errcode_t fix_resize_inode(ext2_filsys fs);
> >>  static errcode_t ext2fs_calculate_summary_stats(ext2_filsys fs);
> >>  static errcode_t fix_sb_journal_backup(ext2_filsys fs);
> >>@@ -112,6 +113,11 @@ errcode_t resize_fs(ext2_filsys fs, ext2_resize_t rfs)
> >>  	if (retval)
> >>  		goto errout;
> >>
> >>+	if (flags & RESIZE_SPECIAL_INODES) {
> >>+		ext2fs_update_dynamic_rev(rfs->new_fs);
> >>+		EXT2_SB(rfs->new_fs->super)->s_first_ino = rfs->first_ino;
> >>+	}
> >>+
> >>  	init_resource_track(&rtrack, "resize_group_descriptors", fs->io);
> >>  	retval = resize_group_descriptors(rfs);
> >>  	if (retval)
> >>@@ -177,6 +183,12 @@ errcode_t resize_fs(ext2_filsys fs, ext2_resize_t rfs)
> >>  		goto errout;
> >>  	print_resource_track(rfs, &rtrack, fs->io);
> >>
> >>+	init_resource_track(&rtrack, "zero_new_special_inodes", fs->io);
> >>+	retval = zero_new_special_inodes(rfs);
> >>+	if (retval)
> >>+		goto errout;
> >>+	print_resource_track(rfs, &rtrack, fs->io);
> >>+
> >>  	init_resource_track(&rtrack, "move_itables", fs->io);
> >>  	retval = move_itables(rfs);
> >>  	if (retval)
> >>@@ -1963,7 +1975,8 @@ static errcode_t inode_scan_and_fix(ext2_resize_t rfs)
> >>
> >>  	if ((rfs->old_fs->group_desc_count <=
> >>  	     rfs->new_fs->group_desc_count) &&
> >>-	    !rfs->bmap)
> >>+	    !rfs->bmap &&
> >>+	    !(rfs->flags & RESIZE_SPECIAL_INODES))
> >>  		return 0;
> >>
> >>  	set_com_err_hook(quiet_com_err_proc);
> >>@@ -2018,7 +2031,11 @@ static errcode_t inode_scan_and_fix(ext2_resize_t rfs)
> >>  			goto errout;
> >>
> >>  		new_inode = ino;
> >>-		if (ino <= start_to_move)
> >>+		if (ino >= EXT2_FIRST_INO(rfs->old_fs->super) &&
> >>+		    ino <  EXT2_FIRST_INO(rfs->new_fs->super)) {
> >>+			ext2fs_inode_alloc_stats2(rfs->new_fs, ino, -1,
> >>+						  pb.is_dir);
> >>+		} else if (ino <= start_to_move)
> >>  			goto remap_blocks; /* Don't need to move inode. */
> >>
> >>  		/*
> >>@@ -2552,6 +2569,37 @@ static errcode_t reserve_sparse_super2_last_group(ext2_resize_t rfs,
> >>  }
> >>
> >>  /*
> >>+ * Clear new special inodes
> >>+ */
> >>+static errcode_t zero_new_special_inodes(ext2_resize_t rfs)
> >>+{
> >>+	ext2_filsys		fs = rfs->new_fs;
> >>+	int			inode_size;
> >>+	struct ext2_inode	*inode;
> >>+	errcode_t		retval;
> >>+	ext2_ino_t		ino;
> >>+
> >>+	if (!(rfs->flags & RESIZE_SPECIAL_INODES))
> >>+		return 0;
> >>+
> >>+	inode_size = EXT2_INODE_SIZE(fs->super);
> >>+	retval = ext2fs_get_memzero(inode_size, &inode);
> >>+	if (retval)
> >>+		return retval;
> >>+
> >>+	for (ino = EXT2_FIRST_INO(rfs->old_fs->super);
> >>+	     ino < EXT2_FIRST_INO(fs->super); ino++) {
> >>+		/* All special inodes are marked as inuse */
> >>+		ext2fs_inode_alloc_stats2(fs, ino, +1, 0);
> >>+		retval = ext2fs_write_inode_full(fs, ino, inode, inode_size);
> >>+		if (retval)
> >>+			break;
> >>+	}
> >>+	ext2fs_free_mem(&inode);
> >>+	return retval;
> >>+}
> >>+
> >>+/*
> >>   * Fix the resize inode
> >>   */
> >>  static errcode_t fix_resize_inode(ext2_filsys fs)
> >>diff --git a/resize/resize2fs.h b/resize/resize2fs.h
> >>index c5377e2b06c3..84f83b09f237 100644
> >>--- a/resize/resize2fs.h
> >>+++ b/resize/resize2fs.h
> >>@@ -85,6 +85,8 @@ typedef struct ext2_sim_progress *ext2_sim_progmeter;
> >>  #define RESIZE_ENABLE_64BIT		0x0400
> >>  #define RESIZE_DISABLE_64BIT		0x0800
> >>
> >>+#define RESIZE_SPECIAL_INODES		0x1000
> >>+
> >>  /*
> >>   * This structure is used for keeping track of how much resources have
> >>   * been used for a particular resize2fs pass.
> >>@@ -130,6 +132,7 @@ struct ext2_resize_struct {
> >>  	void		*prog_data;
> >>
> >>  	blk64_t		new_size;
> >>+	ext2_ino_t	first_ino;
> >>  };
> >>
> >>  /*
> >>
> >>--
> >>To unsubscribe from this list: send the line "unsubscribe linux-ext4" in
> >>the body of a message to majordomo@vger.kernel.org
> >>More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 
> 
> -- 
> Konstantin

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

end of thread, other threads:[~2015-03-13 20:37 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-03-12 16:20 [PATCH RFC v1 0/4] e2fsprogs: reserve more special inodes Konstantin Khlebnikov
2015-03-12 16:20 ` [PATCH RFC v1 1/4] resize2fs: allocate ext2_resize_t outside of resize_fs Konstantin Khlebnikov
2015-03-12 16:20 ` [PATCH RFC v1 2/4] resize2fs: add option -I for reserving more special inodes Konstantin Khlebnikov
2015-03-12 19:26   ` Darrick J. Wong
2015-03-13 10:52     ` Konstantin Khlebnikov
2015-03-13 20:36       ` Darrick J. Wong
2015-03-12 16:20 ` [PATCH RFC v1 3/4] mke2fs: add options extended option for changing first inode Konstantin Khlebnikov
2015-03-12 19:31   ` Darrick J. Wong
2015-03-12 16:20 ` [PATCH RFC v1 4/4] e2fsprogs: add test for mke2fs -E first_inode and resize2fs -I Konstantin Khlebnikov

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.