e2fsprogs: Support for orphan file feature
v6 cover e2fsprogs: Support for orphan file feature
Hello,
This is the fifth version of support for orphan file feature in e2fsprogs.
I've rebased it on top of maint branch as Ted already merged initial fixes. I've also fixed up some issues Ted has already found. I'm not aware of any outstanding issue with the series, xfstests pass fine with it.
Changes since v5:
* Fix e2fsck handling of orphan file when metadata checksums are disabled
Changes since v4:
* Make sure we consistently speak about orphan_file and orphan_present feature, not flag, in error messages.
* Do not make orphan_file feature default yet
* Make sure mke2fs does not complain if orphan_file feature got enabled by the profile but user decided to disable journal.
* Fixed up value of ORPHAN_PRESENT feature
* Fixed several introduced -Wall warnings
* Fixed e2fsck errorcodes
* Rebased on top of current maint branch (some patches already merged)
Changes since v3:
* updated to compute checksum also from physical block
Changes since v2:
* rebased onto current master branch
* fixed various bugs I've spotted during testing
* added support for debugfs, dumpe2fs, e2image
* changed code to use dynamically allocated inode number instead of fixed one
Honza
Previous versions:
PATCH v6 1/5 libext2fs: Support for orphan file feature
Add support for creating and deleting orphan file and a couple of utility functions that will be used in other tools.
--- lib/e2p/feature.c | 4 + lib/ext2fs/Makefile.in | 2 + lib/ext2fs/ext2_fs.h | 16 ++- lib/ext2fs/ext2fs.h | 36 ++++- lib/ext2fs/orphan.c | 273 ++++++++++++++++++++++++++++++++++++ lib/ext2fs/swapfs.c | 3 +- lib/ext2fs/tst_super_size.c | 3 +- lib/support/mkquota.c | 3 +- 8 files changed, 332 insertions(+), 8 deletions(-) create mode 100644 lib/ext2fs/orphan.c
lib/e2p/feature.c +4 -0
@@ -49,6 +49,8 @@ static struct feature feature_list[] = { "fast_commit" }, {E2P_FEATURE_COMPAT ,EXT4_FEATURE_COMPAT_STABLE_INODES , "stable_inodes" }, + { E2P_FEATURE_COMPAT, EXT4_FEATURE_COMPAT_ORPHAN_FILE, + "orphan_file" }, { E2P_FEATURE_RO_INCOMPAT, EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER, "sparse_super" },
@@ -80,6 +82,8 @@ static struct feature feature_list[] = { "shared_blocks"}, {E2P_FEATURE_RO_INCOMPAT ,EXT4_FEATURE_RO_COMPAT_VERITY , "verity"}, + { E2P_FEATURE_RO_INCOMPAT, EXT4_FEATURE_RO_COMPAT_ORPHAN_PRESENT, + "orphan_present" }, { E2P_FEATURE_INCOMPAT, EXT2_FEATURE_INCOMPAT_COMPRESSION, "compression" },
lib/ext2fs/Makefile.in +2 -0
@@ -115,6 +115,7 @@ OBJS= $(DEBUGFS_LIB_OBJS) $(RESIZE_LIB_OBJS) $(E2IMAGE_LIB_OBJS) \ newdir.o \ nls_utf8.o \ openfs.o \ + orphan.o \ progress.o \ punch.o \ qcow2.o \
@@ -198,6 +199,7 @@ SRCS= ext2_err.c \ $(srcdir)/newdir.c \ $(srcdir)/nls_utf8.c \ $(srcdir)/openfs.c \ + $(srcdir)/orphan.c \ $(srcdir)/progress.c \ $(srcdir)/punch.c \ $(srcdir)/qcow2.c \
lib/ext2fs/ext2_fs.h +14 -2
@@ -773,7 +773,8 @@ struct ext2_super_block {__u8 s_last_error_errcode;/*27c*/ __le16 s_encoding;/* Filename charset encoding */ __le16 s_encoding_flags;/* Filename charset encoding flags */ -__le32 s_reserved[95 ];/* Padding to the end of the block */ +__le32 s_orphan_file_inum;/* Inode for tracking orphan inodes */ +__le32 s_reserved[94 ];/* Padding to the end of the block */ /*3fc*/ __u32 s_checksum;/* crc32c(superblock) */ };
@@ -828,7 +829,7 @@ struct ext2_super_block {#define EXT4_FEATURE_COMPAT_SPARSE_SUPER2 0x0200#define EXT4_FEATURE_COMPAT_FAST_COMMIT 0x0400#define EXT4_FEATURE_COMPAT_STABLE_INODES 0x0800 - +#define EXT4_FEATURE_COMPAT_ORPHAN_FILE 0x1000#define EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER 0x0001#define EXT2_FEATURE_RO_COMPAT_LARGE_FILE 0x0002
@@ -851,6 +852,7 @@ struct ext2_super_block {#define EXT4_FEATURE_RO_COMPAT_PROJECT 0x2000/* Project quota */ #define EXT4_FEATURE_RO_COMPAT_SHARED_BLOCKS 0x4000#define EXT4_FEATURE_RO_COMPAT_VERITY 0x8000 +#define EXT4_FEATURE_RO_COMPAT_ORPHAN_PRESENT 0x10000#define EXT2_FEATURE_INCOMPAT_COMPRESSION 0x0001#define EXT2_FEATURE_INCOMPAT_FILETYPE 0x0002
@@ -931,6 +933,7 @@ EXT4_FEATURE_COMPAT_FUNCS(exclude_bitmap, 2, EXCLUDE_BITMAP) EXT4_FEATURE_COMPAT_FUNCS(sparse_super2, 4, SPARSE_SUPER2) EXT4_FEATURE_COMPAT_FUNCS(fast_commit, 4, FAST_COMMIT) EXT4_FEATURE_COMPAT_FUNCS(stable_inodes, 4, STABLE_INODES) +EXT4_FEATURE_COMPAT_FUNCS(orphan_file, 4, ORPHAN_FILE) EXT4_FEATURE_RO_COMPAT_FUNCS(sparse_super, 2, SPARSE_SUPER)EXT4_FEATURE_RO_COMPAT_FUNCS (large_file,2 ,LARGE_FILE )
@@ -947,6 +950,7 @@ EXT4_FEATURE_RO_COMPAT_FUNCS(readonly, 4, READONLY) EXT4_FEATURE_RO_COMPAT_FUNCS(project, 4, PROJECT) EXT4_FEATURE_RO_COMPAT_FUNCS(shared_blocks, 4, SHARED_BLOCKS) EXT4_FEATURE_RO_COMPAT_FUNCS(verity, 4, VERITY) +EXT4_FEATURE_RO_COMPAT_FUNCS(orphan_present, 4, ORPHAN_PRESENT) EXT4_FEATURE_INCOMPAT_FUNCS(compression, 2, COMPRESSION)EXT4_FEATURE_INCOMPAT_FUNCS (filetype,2 ,FILETYPE )
@@ -1114,6 +1118,14 @@ static inline unsigned int ext2fs_dir_rec_len(__u8 name_len,return rec_len; } +#define EXT4_ORPHAN_BLOCK_MAGIC 0x0b10ca04 + +/* Structure at the tail of orphan block */ +struct ext4_orphan_block_tail { +__u32 ob_magic; +__u32 ob_checksum; +}; +/* * Constants for ext4's extended time encoding */
lib/ext2fs/ext2fs.h +33 -3
@@ -632,7 +632,8 @@ typedef struct ext2_icount *ext2_icount_t; EXT2_FEATURE_COMPAT_EXT_ATTR|\ EXT4_FEATURE_COMPAT_SPARSE_SUPER2|\ EXT4_FEATURE_COMPAT_FAST_COMMIT|\ - EXT4_FEATURE_COMPAT_STABLE_INODES) + EXT4_FEATURE_COMPAT_STABLE_INODES|\ + EXT4_FEATURE_COMPAT_ORPHAN_FILE)#ifdef CONFIG_MMP #define EXT4_LIB_INCOMPAT_MMP EXT4_FEATURE_INCOMPAT_MMP
@@ -667,7 +668,8 @@ typedef struct ext2_icount *ext2_icount_t;EXT4_FEATURE_RO_COMPAT_READONLY |\EXT4_FEATURE_RO_COMPAT_PROJECT |\EXT4_FEATURE_RO_COMPAT_SHARED_BLOCKS |\ - EXT4_FEATURE_RO_COMPAT_VERITY) +EXT4_FEATURE_RO_COMPAT_VERITY |\ + EXT4_FEATURE_RO_COMPAT_ORPHAN_PRESENT)/* * These features are only allowed if EXT2_FLAG_SOFTSUPP_FEATURES is passed
@@ -1699,6 +1701,19 @@ errcode_t ext2fs_get_data_io(ext2_filsys fs, io_channel *old_io);errcode_t ext2fs_set_data_io (ext2_filsys fs,io_channel new_io);errcode_t ext2fs_rewrite_to_io (ext2_filsys fs,io_channel new_io); +/* orphan.c */ +extern errcode_t ext2fs_create_orphan_file (ext2_filsys fs,blk_t num_blocks); +extern errcode_t ext2fs_truncate_orphan_file (ext2_filsys fs); +extern e2_blkcnt_t ext2fs_default_orphan_file_blocks (ext2_filsys fs); +extern __u32 ext2fs_do_orphan_file_block_csum (ext2_filsys fs,ext2_ino_t ino, +__u32 gen,blk64_t blk, +char *buf); +extern errcode_t ext2fs_orphan_file_block_csum_set (ext2_filsys fs, +ext2_ino_t ino,blk64_t blk, +char *buf); +extern int ext2fs_orphan_file_block_csum_verify (ext2_filsys fs,ext2_ino_t ino, +blk64_t blk,char *buf); +/* get_pathname.c */ extern errcode_t ext2fs_get_pathname (ext2_filsys fs,ext2_ino_t dir,ext2_ino_t ino,char **name);
@@ -1852,7 +1867,9 @@ extern int ext2fs_dirent_file_type(const struct ext2_dir_entry *entry);extern void ext2fs_dirent_set_file_type (struct ext2_dir_entry *entry,int type);extern struct ext2_inode *ext2fs_inode (struct ext2_inode_large * large_inode);extern const struct ext2_inode *ext2fs_const_inode (const struct ext2_inode_large * large_inode); - +extern int ext2fs_inodes_per_orphan_block (ext2_filsys fs); +extern struct ext4_orphan_block_tail *ext2fs_orphan_block_tail (ext2_filsys fs, +char *buf);#endif /*
@@ -2162,6 +2179,19 @@ ext2fs_const_inode(const struct ext2_inode_large * large_inode)return (const struct ext2_inode *) large_inode; } +_INLINE_ int ext2fs_inodes_per_orphan_block(ext2_filsys fs) +{ +return (fs->blocksize -sizeof (struct ext4_orphan_block_tail )) / +sizeof (__u32); +} + +_INLINE_ struct ext4_orphan_block_tail * +ext2fs_orphan_block_tail (ext2_filsys fs,char *buf) +{ +return (struct ext4_orphan_block_tail *)(buf + fs->blocksize - +sizeof (struct ext4_orphan_block_tail )); +} +#undef _INLINE_#endif
lib/ext2fs/orphan.c new file +273 -0
273 lines not on this page · raw message
lib/ext2fs/swapfs.c +2 -1
@@ -131,8 +131,9 @@ void ext2fs_swap_super(struct ext2_super_block * sb)/* s_*_time_hi are __u8 and does not need swabbing */ sb->s_encoding =ext2fs_swab16 (sb->s_encoding); sb->s_encoding_flags =ext2fs_swab16 (sb->s_encoding_flags); + sb->s_orphan_file_inum =ext2fs_swab32 (sb->s_orphan_file_inum);/* catch when new fields are used from s_reserved */ -EXT2FS_BUILD_BUG_ON (sizeof (sb->s_reserved) !=95 *sizeof (__le32)); +EXT2FS_BUILD_BUG_ON (sizeof (sb->s_reserved) !=94 *sizeof (__le32)); sb->s_checksum =ext2fs_swab32 (sb->s_checksum); }
lib/ext2fs/tst_super_size.c +2 -1
@@ -152,7 +152,8 @@ int main(int argc, char **argv)check_field (s_last_error_errcode,1 );check_field (s_encoding,2 );check_field (s_encoding_flags,2 ); -check_field (s_reserved,95 *4 ); +check_field (s_orphan_file_inum,4 ); +check_field (s_reserved,94 *4 );check_field (s_checksum,4 );do_field ("Superblock end" ,0 ,0 , cur_offset,1024 );#endif
lib/support/mkquota.c +2 -1
@@ -507,7 +507,8 @@ errcode_t quota_compute_usage(quota_ctx_t qctx)continue ;if (ino ==EXT2_ROOT_INO || (ino >=EXT2_FIRST_INODE (fs->super) && - ino !=quota_type2inum (PRJQUOTA , fs->super))) { + ino !=quota_type2inum (PRJQUOTA , fs->super) && + ino != fs->super->s_orphan_file_inum)) { space =ext2fs_get_stat_i_blocks (fs,EXT2_INODE (inode)) <<9 ;quota_data_add (qctx, inode, ino, space);
Signature · 1 line
2.26.2
Theodore Ts'o
AppliedRe: [PATCH 1/5] libext2fs: Support for orphan file feature
Quoted 4 lines · Jan Kara
Add support for creating and deleting orphan file and a couple of utility functions that will be used in other tools.
Applied, thanks!
[1/5] libext2fs: Support for orphan file feature
commit: 1d551c68123c0e13259670991a099995031de0a1
[2/5] mke2fs: Add support for orphan_file feature
commit: 818da4a904893f539e9e746f0f9378db626359ba
[3/5] e2fsck: Add support for handling orphan file
commit: d0c52ffb0be829c7a5b42181ede1f5fbb1daf97e
[4/5] tune2fs: Add support for orphan_file feature
commit: 795101dd0f7bd227a57332fef02a46fd4975011f
[5/5] dumpe2fs, debugfs, e2image: Add support for orphan file
commit: a8f525888f608d6966e49637ed62c88887177532Best regards,
Signature · 1 line
Theodore Ts'o <[email protected]>
PATCH v6 2/5 mke2fs: Add support for orphan_file feature
In reply to Jan Kara--- misc/mke2fs.8.in | 5 +++++ misc/mke2fs.c | 53 +++++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 55 insertions(+), 3 deletions(-)
misc/mke2fs.8.in +5 -0
@@ -403,6 +403,11 @@ file system to change based on the user running \fBmke2fs\fR. Set a flag in the file system superblock indicating that it may be mounted using experimental kernel code, such as the ext4dev file system. .TP +.BI orphan_file_size= size +Set size of the file for tracking unlinked but still open inodes and inodes +with truncate in progress. Larger file allows for better scalability, reserving +a few blocks per cpu is ideal. +.TP .B discard Attempt to discard blocks at mkfs time (discarding blocks initially is useful on solid state devices and sparse / thin-provisioned storage). When the device
misc/mke2fs.c +50 -3
89 lines not on this page · raw message
Signature · 1 line
2.26.2
PATCH v6 3/5 e2fsck: Add support for handling orphan file
In reply to Jan Kara--- e2fsck/e2fsck.h | 1 + e2fsck/pass1.c | 27 ++++ e2fsck/pass2.c | 3 +- e2fsck/pass4.c | 2 +- e2fsck/problem.c | 79 ++++++++++ e2fsck/problem.h | 46 ++++++ e2fsck/super.c | 365 +++++++++++++++++++++++++++++++++++++++++------ e2fsck/unix.c | 72 +++++++++- 8 files changed, 548 insertions(+), 47 deletions(-)
e2fsck/e2fsck.h +1 -0
@@ -656,6 +656,7 @@ void sigcatcher_setup(void);void check_super_block (e2fsck_t ctx);int check_backup_super_block (e2fsck_t ctx);void check_resize_inode (e2fsck_t ctx); +int check_init_orphan_file (e2fsck_t ctx);/* util.c */ extern void *e2fsck_allocate_memory(e2fsck_t ctx, unsigned long size,
e2fsck/pass1.c +27 -0
@@ -1778,6 +1778,32 @@ void e2fsck_pass1(e2fsck_t ctx) inode_size, "pass1"); failed_csum =0 ; } + }else if (ino == fs->super->s_orphan_file_inum) { +ext2fs_mark_inode_bitmap2 (ctx->inode_used_map, ino); +if (ext2fs_has_feature_orphan_file (fs->super)) { +if (!LINUX_S_ISREG (inode->i_mode) && +fix_problem (ctx,PR_1_ORPHAN_FILE_BAD_MODE , + &pctx)) { + inode->i_mode =LINUX_S_IFREG ; +e2fsck_write_inode (ctx, ino, inode, +"pass1" ); + failed_csum =0 ; + } +check_blocks (ctx, &pctx, block_buf,NULL ); +FINISH_INODE_LOOP (ctx, ino, &pctx, failed_csum); +continue ; + } +if ((inode->i_links_count || + inode->i_blocks || inode->i_block[0 ]) && +fix_problem (ctx,PR_1_ORPHAN_FILE_NOT_CLEAR , + &pctx)) { +memset (inode,0 , inode_size); +ext2fs_icount_store (ctx->inode_link_info, ino, +0 ); +e2fsck_write_inode_full (ctx, ino, inode, + inode_size,"pass1" ); + failed_csum =0 ; + } }else if (ino <EXT2_FIRST_INODE (fs->super)) {problem_t problem =0 ;
@@ -3482,6 +3508,7 @@ static void check_blocks(e2fsck_t ctx, struct problem_context *pctx, }if (ino !=quota_type2inum (PRJQUOTA , fs->super) && + ino != fs->super->s_orphan_file_inum && (ino ==EXT2_ROOT_INO || ino >=EXT2_FIRST_INODE (ctx->fs->super)) && !(inode->i_flags &EXT4_EA_INODE_FL )) { quota_data_add(ctx->qctx, (struct ext2_inode_large *) inode,
e2fsck/pass2.c +2 -1
@@ -1444,7 +1444,8 @@ skip_checksum: (dirent->inode > fs->super->s_inodes_count) || (dirent->inode == fs->super->s_usr_quota_inum) || (dirent->inode == fs->super->s_grp_quota_inum) || - (dirent->inode == fs->super->s_prj_quota_inum)) { + (dirent->inode == fs->super->s_prj_quota_inum) || + (dirent->inode == fs->super->s_orphan_file_inum)) { problem = PR_2_BAD_INO; } else if (ctx->inode_bb_map && (ext2fs_test_inode_bitmap2(ctx->inode_bb_map,
e2fsck/pass4.c +1 -1
@@ -192,7 +192,7 @@ void e2fsck_pass4(e2fsck_t ctx) goto errout; }if (i ==quota_type2inum (PRJQUOTA , ctx->fs->super) || - i ==EXT2_BAD_INO || + i == fs->super->s_orphan_file_inum || i ==EXT2_BAD_INO || (i >EXT2_ROOT_INO && i <EXT2_FIRST_INODE (fs->super)))continue ; if (!(ext2fs_test_inode_bitmap2(ctx->inode_used_map, i)) ||
e2fsck/problem.c +79 -0
97 lines not on this page · raw message
e2fsck/problem.h +46 -0
64 lines not on this page · raw message
e2fsck/super.c +322 -43
411 lines not on this page · raw message
e2fsck/unix.c +70 -2
91 lines not on this page · raw message
Signature · 1 line
2.26.2
PATCH v6 4/5 tune2fs: Add support for orphan_file feature
In reply to Jan Kara--- misc/tune2fs.8.in | 5 +++ misc/tune2fs.c | 90 +++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 93 insertions(+), 2 deletions(-)
misc/tune2fs.8.in +5 -0
@@ -257,6 +257,11 @@ program. This superblock setting is only honored in 2.6.35+ kernels; and not at all by the ext2 and ext3 file system drivers. .TP +.BI orphan_file_size= size +Set size of the file for tracking unlinked but still open inodes and inodes +with truncate in progress. Larger file allows for better scalability, reserving +a few blocks per cpu is ideal. +.TP .B force_fsck Set a flag in the file system superblock indicating that errors have been found. This will force fsck to run at the next mount.
misc/tune2fs.c +88 -2
126 lines not on this page · raw message
Signature · 1 line
2.26.2
PATCH v6 5/5 dumpe2fs, debugfs, e2image: Add support for orphan file
In reply to Jan KaraPrint inode number of orphan file in outputs, dump e2image file to filesystem image.
--- debugfs/set_fields.c | 1 + lib/e2p/ls.c | 3 +++ misc/e2image.c | 3 ++- 3 files changed, 6 insertions(+), 1 deletion(-)
debugfs/set_fields.c +1 -0
@@ -183,6 +183,7 @@ static struct field_set_info super_fields[] = { { "lpf_ino", &set_sb.s_lpf_ino, NULL, 4, parse_uint }, { "checksum_seed", &set_sb.s_checksum_seed, NULL, 4, parse_uint }, { "encoding", &set_sb.s_encoding, NULL, 2, parse_encoding }, + { "orphan_file_inum", &set_sb.s_orphan_file_inum, NULL, 4, parse_uint }, { 0, 0, 0, 0 } };
lib/e2p/ls.c +3 -0
@@ -482,6 +482,9 @@ void list_super2(struct ext2_super_block * sb, FILE *f)if (ext2fs_has_feature_casefold (sb))fprintf (f,"Character encoding: %s\n" ,e2p_encoding2str (sb->s_encoding)); +if (ext2fs_has_feature_orphan_file (sb)) +fprintf (f,"Orphan file inode: %u\n" , + sb->s_orphan_file_inum); }void list_super (struct ext2_super_block * s)
misc/e2image.c +2 -1
@@ -1370,7 +1370,8 @@ static void write_raw_image_file(ext2_filsys fs, int fd, int type, int flags, ino == fs->super->s_journal_inum || ino == quota_type2inum(USRQUOTA, fs->super) || ino == quota_type2inum(GRPQUOTA, fs->super) || - ino == quota_type2inum(PRJQUOTA, fs->super)) { + ino == quota_type2inum(PRJQUOTA, fs->super) || + ino == fs->super->s_orphan_file_inum) { retval =ext2fs_block_iterate3 (fs, ino,BLOCK_FLAG_READ_ONLY , block_buf, process_dir_block, &pb);
Signature · 1 line
2.26.2