[v3,7/7] ext2fs: last_oraph 64bit support

Message ID 20180306151835.4842-8-artem.blagodarenko@gmail.com
State New
Headers show
Series
  • 64bit inode e2fsprogs support
Related show

Commit Message

c17828 March 6, 2018, 3:18 p.m.
This patch is required by INODE64 feature. High part of
last_oraph is stored in superblock and accessed using
helper functions.

Lustre-bug: https://jira.hpdd.intel.com/browse/LU-9309
Signed-off-by: Artem Blagodarenko <artem.blagodarenko@gmail.com>
---
 e2fsck/pass1.c              |  4 ++--
 e2fsck/super.c              |  7 ++++---
 lib/e2p/ls.c                |  4 ++--
 lib/ext2fs/ext2_fs.h        |  3 ++-
 lib/ext2fs/ext2fs.h         | 19 +++++++++++++++++++
 lib/ext2fs/swapfs.c         |  1 +
 lib/ext2fs/tst_super_size.c |  3 ++-
 misc/fuse2fs.c              |  2 +-
 8 files changed, 33 insertions(+), 10 deletions(-)

Comments

Andreas Dilger March 8, 2018, 5:53 a.m. | #1
On Mar 6, 2018, at 8:18 AM, Artem Blagodarenko <artem.blagodarenko@gmail.com> wrote:
> 
> This patch is required by INODE64 feature. High part of
> last_oraph is stored in superblock and accessed using
> helper functions.

Typo here and in Subject s/oraph/orphan/

The patch looks reasonable, but I'd suggest to move it before
the INODE64 feature is "supported" so that there isn't a time
when e2fsck thinks it can handle such a filesystem but breaks.

As mentioned previously, I suspect we need a similar patch for
any piece of code that is using "ext2_ino_t", and that is going
to be a lot more than just the orphan handling I think.

Reviewed-by: Andreas Dilger <adilger@dilger.ca>

> Lustre-bug: https://jira.hpdd.intel.com/browse/LU-9309
> Signed-off-by: Artem Blagodarenko <artem.blagodarenko@gmail.com>
> ---
> e2fsck/pass1.c              |  4 ++--
> e2fsck/super.c              |  7 ++++---
> lib/e2p/ls.c                |  4 ++--
> lib/ext2fs/ext2_fs.h        |  3 ++-
> lib/ext2fs/ext2fs.h         | 19 +++++++++++++++++++
> lib/ext2fs/swapfs.c         |  1 +
> lib/ext2fs/tst_super_size.c |  3 ++-
> misc/fuse2fs.c              |  2 +-
> 8 files changed, 33 insertions(+), 10 deletions(-)
> 
> diff --git a/e2fsck/pass1.c b/e2fsck/pass1.c
> index 24f8e215..20823724 100644
> --- a/e2fsck/pass1.c
> +++ b/e2fsck/pass1.c
> @@ -1301,8 +1301,8 @@ void e2fsck_pass1(e2fsck_t ctx)
> 	 * ext3 mount code won't get confused.
> 	 */
> 	if (!(ctx->options & E2F_OPT_READONLY)) {
> -		if (fs->super->s_last_orphan) {
> -			fs->super->s_last_orphan = 0;
> +		if (ext2fs_get_last_orphan(fs->super)) {
> +			ext2fs_set_last_orphan(fs->super, 0);
> 			ext2fs_mark_super_dirty(fs);
> 		}
> 	}
> diff --git a/e2fsck/super.c b/e2fsck/super.c
> index 7183755c..e1ba8887 100644
> --- a/e2fsck/super.c
> +++ b/e2fsck/super.c
> @@ -248,19 +248,20 @@ static int release_inode_blocks(e2fsck_t ctx, ext2_ino_t ino,
> static int release_orphan_inodes(e2fsck_t ctx)
> {
> 	ext2_filsys fs = ctx->fs;
> -	ext2_ino_t	ino, next_ino;
> +	ext2_ino64_t	ino, next_ino;
> 	struct ext2_inode inode;
> 	struct problem_context pctx;
> 	char *block_buf;
> 
> -	if ((ino = fs->super->s_last_orphan) == 0)
> +	ino = ext2fs_get_last_orphan(fs->super);
> +	if (ino == 0)
> 		return 0;
> 
> 	/*
> 	 * Win or lose, we won't be using the head of the orphan inode
> 	 * list again.
> 	 */
> -	fs->super->s_last_orphan = 0;
> +	ext2fs_set_last_orphan(fs->super, 0);
> 	ext2fs_mark_super_dirty(fs);
> 
> 	/*
> diff --git a/lib/e2p/ls.c b/lib/e2p/ls.c
> index 91a3b0ae..5300b126 100644
> --- a/lib/e2p/ls.c
> +++ b/lib/e2p/ls.c
> @@ -377,9 +377,9 @@ void list_super2(struct ext2_super_block * sb, FILE *f)
> 	if (sb->s_journal_dev)
> 		fprintf(f, "Journal device:	          0x%04x\n",
> 			sb->s_journal_dev);
> -	if (sb->s_last_orphan)
> +	if (ext2fs_get_last_orphan(sb))
> 		fprintf(f, "First orphan inode:       %u\n",
> -			sb->s_last_orphan);
> +			ext2fs_get_last_orphan(sb));
> 	if (ext2fs_has_feature_dir_index(sb) ||
> 	    sb->s_def_hash_version)
> 		fprintf(f, "Default directory hash:   %s\n",
> diff --git a/lib/ext2fs/ext2_fs.h b/lib/ext2fs/ext2_fs.h
> index 1fadae53..f528400b 100644
> --- a/lib/ext2fs/ext2_fs.h
> +++ b/lib/ext2fs/ext2_fs.h
> @@ -740,7 +740,8 @@ struct ext2_super_block {
> 	__le32	s_inodes_count_hi;	/* high part of inode count */
> 	__le32	s_free_inodes_count_hi;	/* Free inodes count */
> 	__le32	s_prj_quota_inum_hi;	/* high part of project quota inode */
> -	__le32	s_reserved[95];		/* Padding to the end of the block */
> +	__le32  s_last_orphan_hi;       /* high part of last orphan */
> +	__le32	s_reserved[94];		/* Padding to the end of the block */
> 	__u32	s_checksum;		/* crc32c(superblock) */
> };
> 
> diff --git a/lib/ext2fs/ext2fs.h b/lib/ext2fs/ext2fs.h
> index f5deb650..2e479249 100644
> --- a/lib/ext2fs/ext2fs.h
> +++ b/lib/ext2fs/ext2fs.h
> @@ -2085,6 +2085,25 @@ static inline void ext2fs_set_free_inodes_count(struct ext2_super_block *sb,
> 	sb->s_free_inodes_count = val;
> }
> 
> +static inline ext2_ino64_t
> +ext2fs_get_last_orphan(struct ext2_super_block *sb)
> +{
> +	ext2_ino64_t last_orphan = sb->s_last_orphan;
> +
> +	if (ext2fs_has_feature_inode64(sb))
> +		last_orphan |= (ext2_ino64_t)sb->s_last_orphan_hi << 32;
> +	return last_orphan;
> +}
> +
> +static inline void ext2fs_set_last_orphan(struct ext2_super_block *sb,
> +						ext2_ino64_t val)
> +{
> +	if (ext2fs_has_feature_inode64(sb))
> +		sb->s_last_orphan_hi = (__u32)(val >> 32);
> +	sb->s_last_orphan = val;
> +}
> +
> +
> static inline void ext2fs_inc_free_inodes_count(struct ext2_super_block *sb)
> {
> 	__u64 val = ext2fs_get_free_inodes_count(sb);
> diff --git a/lib/ext2fs/swapfs.c b/lib/ext2fs/swapfs.c
> index 4243e65a..07e4e77d 100644
> --- a/lib/ext2fs/swapfs.c
> +++ b/lib/ext2fs/swapfs.c
> @@ -85,6 +85,7 @@ void ext2fs_swap_super(struct ext2_super_block * sb)
> 	sb->s_overhead_blocks = ext2fs_swab32(sb->s_overhead_blocks);
> 	sb->s_inodes_count_hi = ext2fs_swab32(sb->s_inodes_count_hi);
> 	sb->s_free_inodes_count_hi = ext2fs_swab32(sb->s_free_inodes_count_hi);
> +	sb->s_last_orphan_hi = ext2fs_swab32(sb->s_last_orphan_hi);
> 	sb->s_checksum = ext2fs_swab32(sb->s_checksum);
> 
> 	for (i=0; i < 4; i++)
> diff --git a/lib/ext2fs/tst_super_size.c b/lib/ext2fs/tst_super_size.c
> index 1fa49bb2..0908e254 100644
> --- a/lib/ext2fs/tst_super_size.c
> +++ b/lib/ext2fs/tst_super_size.c
> @@ -145,7 +145,8 @@ int main(int argc, char **argv)
> 	check_field(s_inodes_count_hi, 4);
> 	check_field(s_free_inodes_count_hi, 4);
> 	check_field(s_prj_quota_inum_hi, 4);
> -	check_field(s_reserved, 95 * 4);
> +	check_field(s_last_orphan_hi, 4);
> +	check_field(s_reserved, 94 * 4);
> 	check_field(s_checksum, 4);
> 	do_field("Superblock end", 0, 0, cur_offset, 1024);
> #endif
> diff --git a/misc/fuse2fs.c b/misc/fuse2fs.c
> index bb21e2b4..7c3f3b52 100644
> --- a/misc/fuse2fs.c
> +++ b/misc/fuse2fs.c
> @@ -3822,7 +3822,7 @@ int main(int argc, char *argv[])
> 		      global_fs->super->s_checkinterval) <= time(0))
> 		printf("%s", _("Warning: Check time reached; running e2fsck "
> 		       "is recommended.\n"));
> -	if (global_fs->super->s_last_orphan)
> +	if (ext2fs_get_last_orphan(global_fs->super))
> 		printf("%s",
> 		       _("Orphans detected; running e2fsck is recommended.\n"));
> 
> --
> 2.14.3 (Apple Git-98)
> 


Cheers, Andreas

Patch

diff --git a/e2fsck/pass1.c b/e2fsck/pass1.c
index 24f8e215..20823724 100644
--- a/e2fsck/pass1.c
+++ b/e2fsck/pass1.c
@@ -1301,8 +1301,8 @@  void e2fsck_pass1(e2fsck_t ctx)
 	 * ext3 mount code won't get confused.
 	 */
 	if (!(ctx->options & E2F_OPT_READONLY)) {
-		if (fs->super->s_last_orphan) {
-			fs->super->s_last_orphan = 0;
+		if (ext2fs_get_last_orphan(fs->super)) {
+			ext2fs_set_last_orphan(fs->super, 0);
 			ext2fs_mark_super_dirty(fs);
 		}
 	}
diff --git a/e2fsck/super.c b/e2fsck/super.c
index 7183755c..e1ba8887 100644
--- a/e2fsck/super.c
+++ b/e2fsck/super.c
@@ -248,19 +248,20 @@  static int release_inode_blocks(e2fsck_t ctx, ext2_ino_t ino,
 static int release_orphan_inodes(e2fsck_t ctx)
 {
 	ext2_filsys fs = ctx->fs;
-	ext2_ino_t	ino, next_ino;
+	ext2_ino64_t	ino, next_ino;
 	struct ext2_inode inode;
 	struct problem_context pctx;
 	char *block_buf;
 
-	if ((ino = fs->super->s_last_orphan) == 0)
+	ino = ext2fs_get_last_orphan(fs->super);
+	if (ino == 0)
 		return 0;
 
 	/*
 	 * Win or lose, we won't be using the head of the orphan inode
 	 * list again.
 	 */
-	fs->super->s_last_orphan = 0;
+	ext2fs_set_last_orphan(fs->super, 0);
 	ext2fs_mark_super_dirty(fs);
 
 	/*
diff --git a/lib/e2p/ls.c b/lib/e2p/ls.c
index 91a3b0ae..5300b126 100644
--- a/lib/e2p/ls.c
+++ b/lib/e2p/ls.c
@@ -377,9 +377,9 @@  void list_super2(struct ext2_super_block * sb, FILE *f)
 	if (sb->s_journal_dev)
 		fprintf(f, "Journal device:	          0x%04x\n",
 			sb->s_journal_dev);
-	if (sb->s_last_orphan)
+	if (ext2fs_get_last_orphan(sb))
 		fprintf(f, "First orphan inode:       %u\n",
-			sb->s_last_orphan);
+			ext2fs_get_last_orphan(sb));
 	if (ext2fs_has_feature_dir_index(sb) ||
 	    sb->s_def_hash_version)
 		fprintf(f, "Default directory hash:   %s\n",
diff --git a/lib/ext2fs/ext2_fs.h b/lib/ext2fs/ext2_fs.h
index 1fadae53..f528400b 100644
--- a/lib/ext2fs/ext2_fs.h
+++ b/lib/ext2fs/ext2_fs.h
@@ -740,7 +740,8 @@  struct ext2_super_block {
 	__le32	s_inodes_count_hi;	/* high part of inode count */
 	__le32	s_free_inodes_count_hi;	/* Free inodes count */
 	__le32	s_prj_quota_inum_hi;	/* high part of project quota inode */
-	__le32	s_reserved[95];		/* Padding to the end of the block */
+	__le32  s_last_orphan_hi;       /* high part of last orphan */
+	__le32	s_reserved[94];		/* Padding to the end of the block */
 	__u32	s_checksum;		/* crc32c(superblock) */
 };
 
diff --git a/lib/ext2fs/ext2fs.h b/lib/ext2fs/ext2fs.h
index f5deb650..2e479249 100644
--- a/lib/ext2fs/ext2fs.h
+++ b/lib/ext2fs/ext2fs.h
@@ -2085,6 +2085,25 @@  static inline void ext2fs_set_free_inodes_count(struct ext2_super_block *sb,
 	sb->s_free_inodes_count = val;
 }
 
+static inline ext2_ino64_t
+ext2fs_get_last_orphan(struct ext2_super_block *sb)
+{
+	ext2_ino64_t last_orphan = sb->s_last_orphan;
+
+	if (ext2fs_has_feature_inode64(sb))
+		last_orphan |= (ext2_ino64_t)sb->s_last_orphan_hi << 32;
+	return last_orphan;
+}
+
+static inline void ext2fs_set_last_orphan(struct ext2_super_block *sb,
+						ext2_ino64_t val)
+{
+	if (ext2fs_has_feature_inode64(sb))
+		sb->s_last_orphan_hi = (__u32)(val >> 32);
+	sb->s_last_orphan = val;
+}
+
+
 static inline void ext2fs_inc_free_inodes_count(struct ext2_super_block *sb)
 {
 	__u64 val = ext2fs_get_free_inodes_count(sb);
diff --git a/lib/ext2fs/swapfs.c b/lib/ext2fs/swapfs.c
index 4243e65a..07e4e77d 100644
--- a/lib/ext2fs/swapfs.c
+++ b/lib/ext2fs/swapfs.c
@@ -85,6 +85,7 @@  void ext2fs_swap_super(struct ext2_super_block * sb)
 	sb->s_overhead_blocks = ext2fs_swab32(sb->s_overhead_blocks);
 	sb->s_inodes_count_hi = ext2fs_swab32(sb->s_inodes_count_hi);
 	sb->s_free_inodes_count_hi = ext2fs_swab32(sb->s_free_inodes_count_hi);
+	sb->s_last_orphan_hi = ext2fs_swab32(sb->s_last_orphan_hi);
 	sb->s_checksum = ext2fs_swab32(sb->s_checksum);
 
 	for (i=0; i < 4; i++)
diff --git a/lib/ext2fs/tst_super_size.c b/lib/ext2fs/tst_super_size.c
index 1fa49bb2..0908e254 100644
--- a/lib/ext2fs/tst_super_size.c
+++ b/lib/ext2fs/tst_super_size.c
@@ -145,7 +145,8 @@  int main(int argc, char **argv)
 	check_field(s_inodes_count_hi, 4);
 	check_field(s_free_inodes_count_hi, 4);
 	check_field(s_prj_quota_inum_hi, 4);
-	check_field(s_reserved, 95 * 4);
+	check_field(s_last_orphan_hi, 4);
+	check_field(s_reserved, 94 * 4);
 	check_field(s_checksum, 4);
 	do_field("Superblock end", 0, 0, cur_offset, 1024);
 #endif
diff --git a/misc/fuse2fs.c b/misc/fuse2fs.c
index bb21e2b4..7c3f3b52 100644
--- a/misc/fuse2fs.c
+++ b/misc/fuse2fs.c
@@ -3822,7 +3822,7 @@  int main(int argc, char *argv[])
 		      global_fs->super->s_checkinterval) <= time(0))
 		printf("%s", _("Warning: Check time reached; running e2fsck "
 		       "is recommended.\n"));
-	if (global_fs->super->s_last_orphan)
+	if (ext2fs_get_last_orphan(global_fs->super))
 		printf("%s",
 		       _("Orphans detected; running e2fsck is recommended.\n"));