debugfs: teach seti and freei to free a block of inodes
In order to the inode allocation functions, it's useful to set and
clear a range of inodes.
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
diff --git a/debugfs/debugfs.8.in b/debugfs/debugfs.8.in
index 08d9068..ea3375e 100644
--- a/debugfs/debugfs.8.in
+++ b/debugfs/debugfs.8.in
@@ -311,9 +311,12 @@
can be found in the file system. The chunk size must be a power of two
and be larger than the file system block size.
.TP
-.I freei filespec
+.I freei filespec [num]
Free the inode specified by
.IR filespec .
+If
+.I num
+is specified, also clear num-1 inodes after the specified inode.
.TP
.I help
Print a list of commands understood by
@@ -506,10 +509,12 @@
has value
.I value.
.TP
-.I seti filespec
+.I seti filespec [num]
Mark inode
.I filespec
-as in use in the inode bitmap.
+as in use in the inode bitmap. If
+.I num
+is specified, also set num-1 inodes after the specified inode.
.TP
.I set_inode_field filespec field value
Modify the inode specified by
diff --git a/debugfs/debugfs.c b/debugfs/debugfs.c
index 574759b..e82dddb 100644
--- a/debugfs/debugfs.c
+++ b/debugfs/debugfs.c
@@ -994,29 +994,61 @@
void do_freei(int argc, char *argv[])
{
- ext2_ino_t inode;
+ unsigned int len = 1;
+ int err = 0;
+ ext2_ino_t inode;
- if (common_inode_args_process(argc, argv, &inode,
- CHECK_FS_RW | CHECK_FS_BITMAPS))
+ if (common_args_process(argc, argv, 2, 3, argv[0], "<file> [num]",
+ CHECK_FS_RW | CHECK_FS_BITMAPS))
+ return 1;
+ if (check_fs_read_write(argv[0]))
return;
- if (!ext2fs_test_inode_bitmap2(current_fs->inode_map,inode))
+ inode = string_to_inode(argv[1]);
+ if (!inode)
+ return;
+
+ if (argc == 3) {
+ len = parse_ulong(argv[2], argv[0], "length", &err);
+ if (err)
+ return;
+ }
+
+ if (len == 1 &&
+ !ext2fs_test_inode_bitmap2(current_fs->inode_map,inode))
com_err(argv[0], 0, "Warning: inode already clear");
- ext2fs_unmark_inode_bitmap2(current_fs->inode_map,inode);
+ while (len-- > 0)
+ ext2fs_unmark_inode_bitmap2(current_fs->inode_map, inode);
ext2fs_mark_ib_dirty(current_fs);
}
void do_seti(int argc, char *argv[])
{
- ext2_ino_t inode;
+ unsigned int len = 1;
+ int err = 0;
+ ext2_ino_t inode;
- if (common_inode_args_process(argc, argv, &inode,
- CHECK_FS_RW | CHECK_FS_BITMAPS))
+ if (common_args_process(argc, argv, 2, 3, argv[0], "<file> [num]",
+ CHECK_FS_RW | CHECK_FS_BITMAPS))
+ return;
+ if (check_fs_read_write(argv[0]))
return;
- if (ext2fs_test_inode_bitmap2(current_fs->inode_map,inode))
+ inode = string_to_inode(argv[1]);
+ if (!inode)
+ return;
+
+ if (argc == 3) {
+ len = parse_ulong(argv[2], argv[0], "length", &err);
+ if (err)
+ return;
+ }
+
+ if ((len == 1) &&
+ ext2fs_test_inode_bitmap2(current_fs->inode_map,inode))
com_err(argv[0], 0, "Warning: inode already set");
- ext2fs_mark_inode_bitmap2(current_fs->inode_map,inode);
+ while (len-- > 0)
+ ext2fs_mark_inode_bitmap2(current_fs->inode_map, inode++);
ext2fs_mark_ib_dirty(current_fs);
}
#endif /* READ_ONLY */