Skip to contentSkip to conversation

e2fsprogs: reserve more special inodes

RFC PATCH In review Konstantin Khlebnikov 2 participants 9 messages Mar 12, 2015 – Mar 13, 2015

lore
Share & tools
lore
#0 lore raw

cover e2fsprogs: reserve more special inodes

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

#1 lore raw

RFC PATCH 1/4 resize2fs: allocate ext2_resize_t outside of resize_fs

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

---
 resize/main.c      |   22 +++++++++++++++++++---
 resize/resize2fs.c |   42 ++++++++++++++----------------------------
 resize/resize2fs.h |    7 +++----
 3 files changed, 36 insertions(+), 35 deletions(-)
resize/main.c +19 -3
index c25de61947f3..16f48d438cb0 100644
@@ -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);
 }
resize/resize2fs.c +14 -28

119 lines not on this page · raw message

resize/resize2fs.h +3 -4
index 829fcd8ea8e1..c5377e2b06c3 100644
@@ -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,
#2 lore raw

RFC PATCH 2/4 resize2fs: add option -I for reserving more special inodes

In reply to Konstantin Khlebnikov

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.

---
 resize/main.c         |   38 ++++++++++++++++++++++++++++++++----
 resize/resize2fs.8.in |    8 ++++++++
 resize/resize2fs.c    |   52 +++++++++++++++++++++++++++++++++++++++++++++++--
 resize/resize2fs.h    |    3 +++
 4 files changed, 95 insertions(+), 6 deletions(-)
resize/main.c +34 -4
index 16f48d438cb0..eae7146f41ab 100644
@@ -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"),
resize/resize2fs.8.in +8 -0
index 0129bfcafa3b..f22563fe07e1 100644
@@ -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.
resize/resize2fs.c +50 -2

88 lines not on this page · raw message

resize/resize2fs.h +3 -0
index c5377e2b06c3..84f83b09f237 100644
@@ -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;
 };
 
 /*
#6 lore raw

RFC PATCH 3/4 mke2fs: add options extended option for changing first inode

In reply to Konstantin Khlebnikov

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

---
 misc/mke2fs.8.in |    8 ++++++++
 misc/mke2fs.c    |   18 ++++++++++++++++++
 2 files changed, 26 insertions(+)
misc/mke2fs.8.in +8 -0
index aeb5caf6e869..13f0c7a2c9d2 100644
@@ -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).
 @[email protected]
 @[email protected] quotatype
 @QUOTA_MAN_COMMENT@Specify which quota type ('usr' or 'grp') is to be
misc/mke2fs.c +18 -0
index ec450adf9e12..73d148206c69 100644
@@ -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);
#8 lore raw

RFC PATCH 4/4 e2fsprogs: add test for mke2fs -E first_inode and resize2fs -I

In reply to Konstantin Khlebnikov

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

---
 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
tests/r_resize_special/expect new file +292 -0
new file mode 100644
index 000000000000..8aba1ea0abd5
@@ -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
tests/r_resize_special/name new file +1 -0
new file mode 100644
index 000000000000..6ac3f588bee2
@@ -0,0 +1 @@
+reserve more special inodes in filesystem
tests/r_resize_special/script new file +47 -0

47 lines not on this page · raw message

#3 lore raw

Re: [PATCH RFC v1 2/4] resize2fs: add option -I for reserving more special inodes

In reply to Konstantin Khlebnikov
Quoted 59 lines · Konstantin Khlebnikov

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.

---
 resize/main.c         |   38 ++++++++++++++++++++++++++++++++----
 resize/resize2fs.8.in |    8 ++++++++
 resize/resize2fs.c    |   52 +++++++++++++++++++++++++++++++++++++++++++++++--
 resize/resize2fs.h    |    3 +++
 4 files changed, 95 insertions(+), 6 deletions(-)
resize/main.c +10 -4
index 16f48d438cb0..eae7146f41ab 100644
@@ -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,

resize/main.c int main (int argc, char ** argv) · line 517

Quoted 5 lines
resize/main.c +2 -0
@@ -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?

resize/main.c int main (int argc, char ** argv) · line 518

Quoted 1 line
resize/main.c +1 -0
+			fprintf(stderr, _("First inode too big\n"));

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

Quoted 47 lines
resize/main.c +21 -0
+			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"),
resize/resize2fs.8.in +4 -0
index 0129bfcafa3b..f22563fe07e1 100644
@@ -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

resize/resize2fs.8.in to resize the filesystem concurrent with changing the 64bit status. · line 110

Quoted 6 lines
resize/resize2fs.8.in +3 -0
@@ -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

Quoted 128 lines
resize/resize2fs.8.in +1 -0
+.TP
 .B \-d \fIdebug-flags
 Turns on various resize2fs debugging features, if they have been compiled
 into the binary.
resize/resize2fs.c +50 -2
index dead364bf4bf..2fb653b76dd8 100644
@@ -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)
resize/resize2fs.h +3 -1
index c5377e2b06c3..84f83b09f237 100644
@@ -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 [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html

#7 lore raw

Re: [PATCH RFC v1 3/4] mke2fs: add options extended option for changing first inode

In reply to Konstantin Khlebnikov
Quoted 5 lines · Konstantin Khlebnikov

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.

Quoted 7 lines

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.

Quoted 11 lines
---
 misc/mke2fs.8.in |    8 ++++++++
 misc/mke2fs.c    |   18 ++++++++++++++++++
 2 files changed, 26 insertions(+)
misc/mke2fs.8.in +0 -0
index aeb5caf6e869..13f0c7a2c9d2 100644

misc/mke2fs.8.in as default. · line 376

Quoted 8 lines
misc/mke2fs.8.in +5 -0
@@ -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.

Quoted 17 lines
misc/mke2fs.8.in +3 -0
+.B \-I
+command-line option to
+.BR resize2fs (8).
 @[email protected]
 @[email protected] quotatype
 @QUOTA_MAN_COMMENT@Specify which quota type ('usr' or 'grp') is to be
misc/mke2fs.c +3 -0
index ec450adf9e12..73d148206c69 100644
@@ -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++;

misc/mke2fs.c static void parse_extended_opts(struct ext2_super_block *param, · line 1020

Quoted 10 lines
misc/mke2fs.c +10 -0
+				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.

Quoted 20 lines
misc/mke2fs.c +5 -1
+					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 [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html

#4 lore raw

Re: [PATCH RFC v1 2/4] resize2fs: add option -I for reserving more special inodes

In reply to Darrick J. Wong
Quoted 13 lines · Darrick J. Wong
Quoted 12 lines · Konstantin Khlebnikov

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.

---
  resize/main.c         |   38 ++++++++++++++++++++++++++++++++----
  resize/resize2fs.8.in |    8 ++++++++
  resize/resize2fs.c    |   52 +++++++++++++++++++++++++++++++++++++++++++++++--
  resize/resize2fs.h    |    3 +++
  4 files changed, 95 insertions(+), 6 deletions(-)
Quoted 4 lines

resize/main.c

Quoted 4 lines
resize/main.c +0 -0
index 16f48d438cb0..eae7146f41ab 100644

-cut

Quoted 9 lines

resize/main.c int main (int argc, char ** argv) · line 517

Quoted 6 lines
resize/main.c +2 -0
@@ -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.

Quoted 4 lines

resize/main.c int main (int argc, char ** argv) · line 518

Quoted 2 lines
resize/main.c +1 -0
+			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"?

Quoted 188 lines
Quoted 48 lines
resize/main.c +21 -0
+			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"),
resize/resize2fs.8.in +4 -0
index 0129bfcafa3b..f22563fe07e1 100644
@@ -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

resize/resize2fs.8.in to resize the filesystem concurrent with changing the 64bit status. · line 110

Quoted 6 lines
resize/resize2fs.8.in +3 -0
@@ -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

Quoted 128 lines
resize/resize2fs.8.in +1 -0
+.TP
  .B \-d \fIdebug-flags
  Turns on various resize2fs debugging features, if they have been compiled
  into the binary.
resize/resize2fs.c +50 -2
index dead364bf4bf..2fb653b76dd8 100644
@@ -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)
resize/resize2fs.h +3 -1
index c5377e2b06c3..84f83b09f237 100644
@@ -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 [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html

Signature · 1 line
Konstantin
#5 lore raw

Re: [PATCH RFC v1 2/4] resize2fs: add option -I for reserving more special inodes

Quoted 31 lines · Konstantin Khlebnikov
Quoted 13 lines · Darrick J. Wong
Quoted 12 lines · Konstantin Khlebnikov

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.

---
 resize/main.c         |   38 ++++++++++++++++++++++++++++++++----
 resize/resize2fs.8.in |    8 ++++++++
 resize/resize2fs.c    |   52 +++++++++++++++++++++++++++++++++++++++++++++++--
 resize/resize2fs.h    |    3 +++
 4 files changed, 95 insertions(+), 6 deletions(-)
Quoted 4 lines

resize/main.c

Quoted 4 lines
resize/main.c +0 -0
index 16f48d438cb0..eae7146f41ab 100644

-cut

Quoted 9 lines

resize/main.c int main (int argc, char ** argv) · line 517

Quoted 6 lines
resize/main.c +2 -0
@@ -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?

Quoted 2 lines

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.

Quoted 8 lines
Quoted 5 lines

resize/main.c int main (int argc, char ** argv) · line 518

Quoted 3 lines
resize/main.c +1 -0
+			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

Quoted 193 lines
Quoted 189 lines
Quoted 49 lines
resize/main.c +21 -0
+			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"),
resize/resize2fs.8.in +4 -0
index 0129bfcafa3b..f22563fe07e1 100644
@@ -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

resize/resize2fs.8.in to resize the filesystem concurrent with changing the 64bit status. · line 110

Quoted 6 lines
resize/resize2fs.8.in +3 -0
@@ -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

Quoted 128 lines
resize/resize2fs.8.in +1 -0
+.TP
 .B \-d \fIdebug-flags
 Turns on various resize2fs debugging features, if they have been compiled
 into the binary.
resize/resize2fs.c +50 -2
index dead364bf4bf..2fb653b76dd8 100644
@@ -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)
resize/resize2fs.h +3 -1
index c5377e2b06c3..84f83b09f237 100644
@@ -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 [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html

Signature · 1 line
Konstantin