Re: [PATCH] ext2: support 64 bit time
Hello, I have changed just a couple minor things and pushed, thanks! Samuel Milos Nikic, le mar. 27 janv. 2026 09:38:39 -0800, a ecrit: > Hey Samuel, > > Here it is with these two things changed. > > I simplified this and added a comment: > /* > * We need enough space for ctime, mtime, atime and extra fields. > * i_crtime follows immediately after i_atime_extra, so its offset > * gives us the total size required for the timestamps we support. > */ > #define EXT2_INODE_EXTRA_TIME_SIZE offsetof (struct ext2_inode_extra, > i_crtime) > > Let me know if something else is needed. > > Thanks, > Milos > > > On Tue, Jan 27, 2026 at 12:13 AM Samuel Thibault <[1][email protected]> > wrote: > > Just a quick thought: > > Milos Nikic, le lun. 26 janv. 2026 23:06:01 -0800, a ecrit: > > index daa49543..6460db35 100644 > > --- a/ext2fs/ext2_fs.h > > +++ b/ext2fs/ext2_fs.h > > @@ -278,6 +278,18 @@ struct ext2_inode { > > } osd2; /* OS dependent 2 */ > > }; > > > > +struct ext2_inode_extra { > > + __u16 i_extra_isize; /* Size of this extra record */ > > + __u16 i_checksum_hi; /* Upper 16-bits of inode checksum */ > > + __u32 i_ctime_extra; /* Extra ctime bits (nanos + epoch) */ > > + __u32 i_mtime_extra; /* Extra mtime bits (nanos + epoch) */ > > + __u32 i_atime_extra; /* Extra atime bits (nanos + epoch) */ > > Thinking about it: since we increase the inode size to 32B, we have to > fill these fields: i_extra_isize and i_checksum_hi > > > + __u32 i_crtime; /* File creation time (Birth time) */ > > + __u32 i_crtime_extra; /* Extra crtime bits */ > > + __u32 i_version_hi; /* High 32 bits of 64-bit version */ > > + __u32 i_projid; /* Project ID */ > > +}; > > + > > #define i_size_high i_dir_acl > > > > #define i_translator osd1.hurd1.h_i_translator > > @@ -425,10 +437,13 @@ struct ext2_super_block { > > #define EXT2_GOOD_OLD_REV 0 /* The good old (original) format > * > / > > #define EXT2_DYNAMIC_REV 1 /* V2 format w/ dynamic inode > sizes > */ > > > > -#define EXT2_CURRENT_REV EXT2_GOOD_OLD_REV > > +#define EXT2_CURRENT_REV EXT2_DYNAMIC_REV > > #define EXT2_MAX_SUPP_REV EXT2_DYNAMIC_REV > > > > #define EXT2_GOOD_OLD_INODE_SIZE 128 > > +#define EXT2_INODE_EXTENT_SIZE \ > > Put some "TIME" in the name so it's clear what size we are talking > about. We may have more fields to look at. > > > + (offsetof (struct ext2_inode_extra, i_mtime_extra) + \ > > + sizeof (((struct ext2_inode_extra *)0)->i_mtime_extra)) > > > > /* > > * Feature set definitions > > > References: > > [1] mailto:[email protected] > From a33cf00e3eac8867c1d6d77a33cd576bd12b5503 Mon Sep 17 00:00:00 2001 > From: Milos Nikic > Date: Mon, 26 Jan 2026 22:32:02 -0800 > Subject: [PATCH] ext2: support 64 bit time > > Implemented at ext4 spec we now support timestamps after 2038 and > to a nano precision. Backward compatible (works as before on systems that are > formatted to 128) > if node size is larger it supports extra time precision > > To test (inside Hurd): > dd if=/dev/zero of=test.img bs=1M count=100 > sudo mke2fs -I 256 -v test.img > sudo settrans -ca /mnt /hurd/ext2fs.static test.img > sudo touch -d '2045-01-01 12:34:56.789123456' /mnt/precision_test > stat /mnt/precision_test > File: /mnt/precision_test > Size: 0 Blocks: 0 IO Block: 8192 regular empty file > Device: 3,1 Inode: 13 Links: 1 > Access: (0644/-rw-r--r--) Uid: (0/root) Gid: (0/root) > Access: 2045-01-01 12:34:56.789123456 + > Modify: 2045-01-01 12:34:56.789123456 + > Change: 2026-01-24 06:23:58.318082000 + > --- > ext2fs/ext2_fs.h | 20 ++- > ext2fs/ext2fs.h | 9 ++--- > ext2fs/hyper.c | 11 -- > ext2fs/ialloc.c | 2 +- > ext2fs/inode.c | 93 ++-- > 5 files changed, 101 insertions(+), 34 deletions(-) > > diff --git a/ext2fs/ext2_fs.h b/ext2fs/ext2_fs.h > index daa49543..195e9b6b 100644 > --- a/ext2fs/ext2_fs.h > +++ b/ext2fs/ext2_fs.h > @@ -278,6 +278,18 @@ struct ext2_inode { > } osd2; /* OS dependent 2 */ > }; > > +struct ext2_inode_extra { > + __u16 i_extra_isize; /* Size of this extra record */ > + __u16 i_checksum_hi; /* Upper 16-bits of inode checksum */ > + __u32 i_ctime_extra; /* Extra ctime bits (nanos + epoch) */ > + __u32 i_mtime_extra; /* Extra mtime bits (nanos + epoch) */ > + __u32 i_atime_extra; /* Extra atime bits (nanos + epoch) */ > + __u32 i_crtime;/* File creation time (Birth time) */ > + __u32 i_crtime_extra; /* Extra crtime bits */ > + __u32 i_version_hi;/* High 32 bits of 64-bit version */ >
Re: [PATCH] ext2: support 64 bit time
Hey Samuel,
Here it is with these two things changed.
I simplified this and added a comment:
/*
* We need enough space for ctime, mtime, atime and extra fields.
* i_crtime follows immediately after i_atime_extra, so its offset
* gives us the total size required for the timestamps we support.
*/
#define EXT2_INODE_EXTRA_TIME_SIZE offsetof (struct ext2_inode_extra,
i_crtime)
Let me know if something else is needed.
Thanks,
Milos
On Tue, Jan 27, 2026 at 12:13 AM Samuel Thibault
wrote:
> Just a quick thought:
>
> Milos Nikic, le lun. 26 janv. 2026 23:06:01 -0800, a ecrit:
> > index daa49543..6460db35 100644
> > --- a/ext2fs/ext2_fs.h
> > +++ b/ext2fs/ext2_fs.h
> > @@ -278,6 +278,18 @@ struct ext2_inode {
> > } osd2; /* OS dependent 2 */
> > };
> >
> > +struct ext2_inode_extra {
> > + __u16 i_extra_isize; /* Size of this extra record */
> > + __u16 i_checksum_hi; /* Upper 16-bits of inode checksum */
> > + __u32 i_ctime_extra; /* Extra ctime bits (nanos + epoch) */
> > + __u32 i_mtime_extra; /* Extra mtime bits (nanos + epoch) */
> > + __u32 i_atime_extra; /* Extra atime bits (nanos + epoch) */
>
> Thinking about it: since we increase the inode size to 32B, we have to
> fill these fields: i_extra_isize and i_checksum_hi
>
> > + __u32 i_crtime;/* File creation time (Birth time) */
> > + __u32 i_crtime_extra; /* Extra crtime bits */
> > + __u32 i_version_hi;/* High 32 bits of 64-bit version */
> > + __u32 i_projid;/* Project ID */
> > +};
> > +
> > #define i_size_high i_dir_acl
> >
> > #define i_translator osd1.hurd1.h_i_translator
> > @@ -425,10 +437,13 @@ struct ext2_super_block {
> > #define EXT2_GOOD_OLD_REV0 /* The good old (original) format
> */
> > #define EXT2_DYNAMIC_REV 1 /* V2 format w/ dynamic inode
> sizes */
> >
> > -#define EXT2_CURRENT_REV EXT2_GOOD_OLD_REV
> > +#define EXT2_CURRENT_REV EXT2_DYNAMIC_REV
> > #define EXT2_MAX_SUPP_REVEXT2_DYNAMIC_REV
> >
> > #define EXT2_GOOD_OLD_INODE_SIZE 128
> > +#define EXT2_INODE_EXTENT_SIZE \
>
> Put some "TIME" in the name so it's clear what size we are talking
> about. We may have more fields to look at.
>
> > +(offsetof (struct ext2_inode_extra, i_mtime_extra) + \
> > + sizeof (((struct ext2_inode_extra *)0)->i_mtime_extra))
> >
> > /*
> > * Feature set definitions
>
From a33cf00e3eac8867c1d6d77a33cd576bd12b5503 Mon Sep 17 00:00:00 2001
From: Milos Nikic
Date: Mon, 26 Jan 2026 22:32:02 -0800
Subject: [PATCH] ext2: support 64 bit time
Implemented at ext4 spec we now support timestamps after 2038 and
to a nano precision. Backward compatible (works as before on systems that are formatted to 128)
if node size is larger it supports extra time precision
To test (inside Hurd):
dd if=/dev/zero of=test.img bs=1M count=100
sudo mke2fs -I 256 -v test.img
sudo settrans -ca /mnt /hurd/ext2fs.static test.img
sudo touch -d '2045-01-01 12:34:56.789123456' /mnt/precision_test
stat /mnt/precision_test
File: /mnt/precision_test
Size: 0 Blocks: 0 IO Block: 8192 regular empty file
Device: 3,1 Inode: 13 Links: 1
Access: (0644/-rw-r--r--) Uid: (0/root) Gid: (0/root)
Access: 2045-01-01 12:34:56.789123456 +
Modify: 2045-01-01 12:34:56.789123456 +
Change: 2026-01-24 06:23:58.318082000 +
---
ext2fs/ext2_fs.h | 20 ++-
ext2fs/ext2fs.h | 9 ++---
ext2fs/hyper.c | 11 --
ext2fs/ialloc.c | 2 +-
ext2fs/inode.c | 93 ++--
5 files changed, 101 insertions(+), 34 deletions(-)
diff --git a/ext2fs/ext2_fs.h b/ext2fs/ext2_fs.h
index daa49543..195e9b6b 100644
--- a/ext2fs/ext2_fs.h
+++ b/ext2fs/ext2_fs.h
@@ -278,6 +278,18 @@ struct ext2_inode {
} osd2;/* OS dependent 2 */
};
+struct ext2_inode_extra {
+ __u16 i_extra_isize; /* Size of this extra record */
+ __u16 i_checksum_hi; /* Upper 16-bits of inode checksum */
+ __u32 i_ctime_extra; /* Extra ctime bits (nanos + epoch) */
+ __u32 i_mtime_extra; /* Extra mtime bits (nanos + epoch) */
+ __u32 i_atime_extra; /* Extra atime bits (nanos + epoch) */
+ __u32 i_crtime;/* File creation time (Birth time) */
+ __u32 i_crtime_extra; /* Extra crtime bits */
+ __u32 i_version_hi;/* High 32 bits of 64-bit version */
+ __u32 i_projid;/* Project ID */
+};
+
#define i_size_high i_dir_acl
#define i_translator osd1.hurd1.h_i_translator
@@ -425,10 +437,16 @@ struct ext2_super_block {
#define EXT2_GOOD_OLD_REV 0 /* The good old (original) format */
#define EXT2_DYNAMIC_REV 1 /* V2 format w/ dynamic inode sizes */
-#define EXT2_CURRENT_REV EXT2_GOOD_OLD_REV
+#define EXT2_CURRENT_REV EXT2_DYNAMIC_REV
#define EXT2_MAX_SUPP_REV EXT2_DYNAMIC_REV
#define EXT2_GOOD_OLD_INODE_SIZE 128
+/*
+ * We need enough space for ctime, mtime, atime and extra fields.
+ * i_crtime follows immediately after i_atime_extra, so its offset
Re: [PATCH] ext2: support 64 bit time
Just a quick thought:
Milos Nikic, le lun. 26 janv. 2026 23:06:01 -0800, a ecrit:
> index daa49543..6460db35 100644
> --- a/ext2fs/ext2_fs.h
> +++ b/ext2fs/ext2_fs.h
> @@ -278,6 +278,18 @@ struct ext2_inode {
> } osd2; /* OS dependent 2 */
> };
>
> +struct ext2_inode_extra {
> + __u16 i_extra_isize; /* Size of this extra record */
> + __u16 i_checksum_hi; /* Upper 16-bits of inode checksum */
> + __u32 i_ctime_extra; /* Extra ctime bits (nanos + epoch) */
> + __u32 i_mtime_extra; /* Extra mtime bits (nanos + epoch) */
> + __u32 i_atime_extra; /* Extra atime bits (nanos + epoch) */
Thinking about it: since we increase the inode size to 32B, we have to
fill these fields: i_extra_isize and i_checksum_hi
> + __u32 i_crtime;/* File creation time (Birth time) */
> + __u32 i_crtime_extra; /* Extra crtime bits */
> + __u32 i_version_hi;/* High 32 bits of 64-bit version */
> + __u32 i_projid;/* Project ID */
> +};
> +
> #define i_size_high i_dir_acl
>
> #define i_translator osd1.hurd1.h_i_translator
> @@ -425,10 +437,13 @@ struct ext2_super_block {
> #define EXT2_GOOD_OLD_REV0 /* The good old (original) format */
> #define EXT2_DYNAMIC_REV 1 /* V2 format w/ dynamic inode sizes */
>
> -#define EXT2_CURRENT_REV EXT2_GOOD_OLD_REV
> +#define EXT2_CURRENT_REV EXT2_DYNAMIC_REV
> #define EXT2_MAX_SUPP_REVEXT2_DYNAMIC_REV
>
> #define EXT2_GOOD_OLD_INODE_SIZE 128
> +#define EXT2_INODE_EXTENT_SIZE \
Put some "TIME" in the name so it's clear what size we are talking
about. We may have more fields to look at.
> +(offsetof (struct ext2_inode_extra, i_mtime_extra) + \
> + sizeof (((struct ext2_inode_extra *)0)->i_mtime_extra))
>
> /*
> * Feature set definitions
Re: [PATCH] ext2: support 64 bit time
Hello Samuel,
Thanks for the feedback its greatly appreciated.
Here is the file, let me know if i miss to address anything.
Kind regards,
Milos
On Mon, Jan 26, 2026 at 4:22 PM Samuel Thibault
wrote:
> Hello,
>
> Thanks for working on this!
>
> Milos Nikic, le ven. 23 janv. 2026 22:55:23 -0800, a ecrit:
> > diff --git a/ext2fs/ext2fs.h b/ext2fs/ext2fs.h
> > index 62ee9f77..eea85d1d 100644
> > --- a/ext2fs/ext2fs.h
> > +++ b/ext2fs/ext2fs.h
> > @@ -427,9 +427,14 @@ dino_ref (ino_t inum)
> >unsigned long bg_num = (inum - 1) / inodes_per_group;
> >unsigned long group_inum = (inum - 1) % inodes_per_group;
> >struct ext2_group_desc *bg = group_desc (bg_num);
> > + uint16_t inode_size = le16toh (sblock->s_inode_size);
> > + if (inode_size == 0)
> > +inode_size = EXT2_GOOD_OLD_INODE_SIZE; /* Fallback for old volumes
> */
> > + unsigned long inodes_per_blk = block_size / inode_size;
> > - block_t block = le32toh (bg->bg_inode_table) + (group_inum /
> inodes_per_block);
> > + block_t block = le32toh (bg->bg_inode_table) + (group_inum /
> inodes_per_blk);
>
> Mmm, is EXT2_INODE_SIZE not already putting the right value in
> inodes_per_block?
>
> > - struct ext2_inode *inode = disk_cache_block_ref (block);
> > + void *block_ptr = disk_cache_block_ref (block);
> > - inode += group_inum % inodes_per_block;
> > + size_t offset = (group_inum % inodes_per_blk) * inode_size;
>
> We'd probably want to make inode_size a global variable so we don't have
> to recompute it all the time while it is constant for the opened FS.
>
> > + struct ext2_inode *inode = (struct ext2_inode *)((char *)block_ptr +
> offset);
> >ext2_debug ("(%llu) = %p", inum, inode);
> >return inode;
> > }
>
> > diff --git a/ext2fs/inode.c b/ext2fs/inode.c
> > index dc309ac8..0fe07748 100644
> > --- a/ext2fs/inode.c
> > +++ b/ext2fs/inode.c
> > @@ -106,6 +106,36 @@ diskfs_new_hardrefs (struct node *np)
> > {
> >allow_pager_softrefs (np);
> > }
> > +
> > +static inline void
> > +ext2_decode_extra_time (uint32_t legacy_sec, uint32_t extra,
> > +time_t *sec, long *nsec)
> > +{
> > + /* Epoch extension (bits 32 and 33) */
> > + *sec = (time_t)legacy_sec + (((time_t)extra & 0x3) << 32);
>
> Urgl, so they just multiplied by 4 the lifetime of the ext2 format... :/
>
> > + /* Nanoseconds (bits 2 through 31) */
> > + *nsec = (long)(extra >> 2);
> > +}
> > +
> > +static inline uint32_t
> > +ext2_encode_extra_time (time_t sec, long nsec)
> > +{
> > + uint32_t extra;
> > + /* Pack nanoseconds into the upper 30 bits */
> > + extra = (uint32_t)(nsec << 2);
> > + /* Pack bits 32 and 33 of seconds into the lower 2 bits */
> > + extra |= (uint32_t)((sec >> 32) & 0x3);
> > + return extra;
> > +}
> > +
> > +/* Helper to check if the current filesystem supports extended inodes */
> > +static inline int
> > +ext2_has_extra_inodes (struct ext2_super_block *sb)
> > +{
> > + return (le32toh (sb->s_rev_level) > EXT2_GOOD_OLD_REV
> > + && le16toh (sb->s_inode_size) > EXT2_GOOD_OLD_INODE_SIZE);
> > +}
> > +
> >
> > /* The user must define this function if she wants to use the node
> > cache. Read stat information out of the on-disk node. */
> > @@ -136,23 +166,31 @@ diskfs_user_read_node (struct node *np, struct
> lookup_context *ctx)
> >st->st_gen = le32toh (di->i_generation);
> >
> >st->st_atim.tv_sec = le32toh (di->i_atime);
> > -#ifdef not_yet
> > - /* ``struct ext2_inode'' doesn't do better than sec. precision yet.
> */
> > -#else
> > - st->st_atim.tv_nsec = 0;
> > -#endif
> >st->st_mtim.tv_sec = le32toh (di->i_mtime);
> > -#ifdef not_yet
> > - /* ``struct ext2_inode'' doesn't do better than sec. precision yet.
> */
> > -#else
> > - st->st_mtim.tv_nsec = 0;
> > -#endif
> >st->st_ctim.tv_sec = le32toh (di->i_ctime);
> > -#ifdef not_yet
> > - /* ``struct ext2_inode'' doesn't do better than sec. precision yet.
> */
> > -#else
> > - st->st_ctim.tv_nsec = 0;
> > -#endif
> > + st->st_atim.tv_nsec = st->st_mtim.tv_nsec = st->st_ctim.tv_nsec = 0;
> > + if (ext2_has_extra_inodes (sblock))
> > +{
> > + struct ext2_inode_extra *di_extra =
> > + (struct ext2_inode_extra *) ((char *) di +
> EXT2_GOOD_OLD_INODE_SIZE);
> > +
> > + /* Only decode if the inode actually uses the extra space
> (i_extra_isize)
> > + The i_extra_isize tells us how many extra bytes are used in THIS
> inode. */
> > + if (le16toh (di_extra->i_extra_isize) >= 32) /* Enough room for
> all 3 extra timestamps */
>
> Better use offsetof() + sizeof() to make it really obvious that we are
> checking for the last required field, rather than a magic number 32.
>
> > + {
> > + ext2_decode_extra_time (le32toh (di->i_atime), le32toh
> (di_extra->i_atime_extra),
> > +&st->st_atim.tv_sec,
> &st->st_atim.tv_nsec);
> > + ext2_decode_extra_time (le32toh (di->i_ctime), le32toh
> (di_extra->i_ctime_extra),
> > +
Re: [PATCH] ext2: support 64 bit time
Hello,
Thanks for working on this!
Milos Nikic, le ven. 23 janv. 2026 22:55:23 -0800, a ecrit:
> diff --git a/ext2fs/ext2fs.h b/ext2fs/ext2fs.h
> index 62ee9f77..eea85d1d 100644
> --- a/ext2fs/ext2fs.h
> +++ b/ext2fs/ext2fs.h
> @@ -427,9 +427,14 @@ dino_ref (ino_t inum)
>unsigned long bg_num = (inum - 1) / inodes_per_group;
>unsigned long group_inum = (inum - 1) % inodes_per_group;
>struct ext2_group_desc *bg = group_desc (bg_num);
> + uint16_t inode_size = le16toh (sblock->s_inode_size);
> + if (inode_size == 0)
> +inode_size = EXT2_GOOD_OLD_INODE_SIZE; /* Fallback for old volumes */
> + unsigned long inodes_per_blk = block_size / inode_size;
> - block_t block = le32toh (bg->bg_inode_table) + (group_inum /
> inodes_per_block);
> + block_t block = le32toh (bg->bg_inode_table) + (group_inum /
> inodes_per_blk);
Mmm, is EXT2_INODE_SIZE not already putting the right value in
inodes_per_block?
> - struct ext2_inode *inode = disk_cache_block_ref (block);
> + void *block_ptr = disk_cache_block_ref (block);
> - inode += group_inum % inodes_per_block;
> + size_t offset = (group_inum % inodes_per_blk) * inode_size;
We'd probably want to make inode_size a global variable so we don't have
to recompute it all the time while it is constant for the opened FS.
> + struct ext2_inode *inode = (struct ext2_inode *)((char *)block_ptr +
> offset);
>ext2_debug ("(%llu) = %p", inum, inode);
>return inode;
> }
> diff --git a/ext2fs/inode.c b/ext2fs/inode.c
> index dc309ac8..0fe07748 100644
> --- a/ext2fs/inode.c
> +++ b/ext2fs/inode.c
> @@ -106,6 +106,36 @@ diskfs_new_hardrefs (struct node *np)
> {
>allow_pager_softrefs (np);
> }
> +
> +static inline void
> +ext2_decode_extra_time (uint32_t legacy_sec, uint32_t extra,
> +time_t *sec, long *nsec)
> +{
> + /* Epoch extension (bits 32 and 33) */
> + *sec = (time_t)legacy_sec + (((time_t)extra & 0x3) << 32);
Urgl, so they just multiplied by 4 the lifetime of the ext2 format... :/
> + /* Nanoseconds (bits 2 through 31) */
> + *nsec = (long)(extra >> 2);
> +}
> +
> +static inline uint32_t
> +ext2_encode_extra_time (time_t sec, long nsec)
> +{
> + uint32_t extra;
> + /* Pack nanoseconds into the upper 30 bits */
> + extra = (uint32_t)(nsec << 2);
> + /* Pack bits 32 and 33 of seconds into the lower 2 bits */
> + extra |= (uint32_t)((sec >> 32) & 0x3);
> + return extra;
> +}
> +
> +/* Helper to check if the current filesystem supports extended inodes */
> +static inline int
> +ext2_has_extra_inodes (struct ext2_super_block *sb)
> +{
> + return (le32toh (sb->s_rev_level) > EXT2_GOOD_OLD_REV
> + && le16toh (sb->s_inode_size) > EXT2_GOOD_OLD_INODE_SIZE);
> +}
> +
>
> /* The user must define this function if she wants to use the node
> cache. Read stat information out of the on-disk node. */
> @@ -136,23 +166,31 @@ diskfs_user_read_node (struct node *np, struct
> lookup_context *ctx)
>st->st_gen = le32toh (di->i_generation);
>
>st->st_atim.tv_sec = le32toh (di->i_atime);
> -#ifdef not_yet
> - /* ``struct ext2_inode'' doesn't do better than sec. precision yet. */
> -#else
> - st->st_atim.tv_nsec = 0;
> -#endif
>st->st_mtim.tv_sec = le32toh (di->i_mtime);
> -#ifdef not_yet
> - /* ``struct ext2_inode'' doesn't do better than sec. precision yet. */
> -#else
> - st->st_mtim.tv_nsec = 0;
> -#endif
>st->st_ctim.tv_sec = le32toh (di->i_ctime);
> -#ifdef not_yet
> - /* ``struct ext2_inode'' doesn't do better than sec. precision yet. */
> -#else
> - st->st_ctim.tv_nsec = 0;
> -#endif
> + st->st_atim.tv_nsec = st->st_mtim.tv_nsec = st->st_ctim.tv_nsec = 0;
> + if (ext2_has_extra_inodes (sblock))
> +{
> + struct ext2_inode_extra *di_extra =
> + (struct ext2_inode_extra *) ((char *) di + EXT2_GOOD_OLD_INODE_SIZE);
> +
> + /* Only decode if the inode actually uses the extra space
> (i_extra_isize)
> + The i_extra_isize tells us how many extra bytes are used in THIS
> inode. */
> + if (le16toh (di_extra->i_extra_isize) >= 32) /* Enough room for all 3
> extra timestamps */
Better use offsetof() + sizeof() to make it really obvious that we are
checking for the last required field, rather than a magic number 32.
> + {
> + ext2_decode_extra_time (le32toh (di->i_atime), le32toh
> (di_extra->i_atime_extra),
> +&st->st_atim.tv_sec, &st->st_atim.tv_nsec);
> + ext2_decode_extra_time (le32toh (di->i_ctime), le32toh
> (di_extra->i_ctime_extra),
> +&st->st_ctim.tv_sec, &st->st_ctim.tv_nsec);
> + ext2_decode_extra_time (le32toh (di->i_mtime), le32toh
> (di_extra->i_mtime_extra),
> +&st->st_mtim.tv_sec, &st->st_mtim.tv_nsec);
> + info->i_atime_extra = le32toh (di_extra->i_atime_extra);
> + info->i_ctime_extra = le32toh (di_extra->i_ctime_extra);
> + info->i_mtime_extra = le32toh (di_extra->i_mtime_extra);
