The current representation of inode times in struct inode, struct iattr,
struct kstat: struct timespec are not y2038 safe.

Add provision to convert them to use 64 bit times in the future.

struct inode uses struct inode time to maintain same size for times
across 32 bit and 64 bit architectures. structs iattr and kstat have no
such requirement since these data types are only used to pass values in
and out of vfs layer.

In addition, inode_time is defined as packed and aligned to a 4 byte
boundary to make the structure use 12 bytes each instead of 16 bytes. This
will help save RAM space as inode structure is cached in memory. The
other structures are transient and such a change would not be beneficial.

Signed-off-by: Deepa Dinamani <deepa.ker...@gmail.com>
---
 include/linux/fs.h   | 33 ++++++++++++++++++++++++++-------
 include/linux/stat.h | 12 +++++++++---
 2 files changed, 35 insertions(+), 10 deletions(-)

diff --git a/include/linux/fs.h b/include/linux/fs.h
index ab8799c..c56068f 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -245,13 +245,19 @@ typedef void (dax_iodone_t)(struct buffer_head *bh_map, 
int uptodate);
  */
 struct iattr {
        unsigned int    ia_valid;
-       umode_t         ia_mode;
-       kuid_t          ia_uid;
-       kgid_t          ia_gid;
-       loff_t          ia_size;
-       struct timespec ia_atime;
-       struct timespec ia_mtime;
-       struct timespec ia_ctime;
+       umode_t                 ia_mode;
+       kuid_t                  ia_uid;
+       kgid_t                  ia_gid;
+       loff_t                  ia_size;
+#ifdef CONFIG_FS_USES_64BIT_TIME
+       struct timespec64       ia_atime;
+       struct timespec64       ia_mtime;
+       struct timespec64       ia_ctime;
+#else
+       struct timespec         ia_atime;
+       struct timespec         ia_mtime;
+       struct timespec         ia_ctime;
+#endif
 
        /*
         * Not an attribute, but an auxiliary info for filesystems wanting to
@@ -616,9 +622,15 @@ struct inode {
        };
        dev_t                   i_rdev;
        loff_t                  i_size;
+#ifdef CONFIG_FS_USES_64BIT_TIME
+       struct inode_time       i_atime;
+       struct inode_time       i_mtime;
+       struct inode_time       i_ctime;
+#else
        struct timespec         i_atime;
        struct timespec         i_mtime;
        struct timespec         i_ctime;
+#endif
        spinlock_t              i_lock; /* i_blocks, i_bytes, maybe i_size */
        unsigned short          i_bytes;
        unsigned int            i_blkbits;
@@ -679,10 +691,17 @@ struct inode {
        void                    *i_private; /* fs or device private pointer */
 };
 
+#ifdef CONFIG_FS_USES_64BIT_TIME
+#define FS_INODE_SET_XTIME(xtime, inode, ts64) \
+       ((inode)->i_##xtime = timespec64_to_inode_time(ts64))
+#define FS_INODE_GET_XTIME(xtime, inode)       \
+       (inode_time_to_timespec64((inode)->i_##xtime))
+#else
 #define FS_INODE_SET_XTIME(xtime, inode, ts)   \
        ((inode)->i_##xtime = (ts))
 #define FS_INODE_GET_XTIME(xtime, inode)       \
        ((inode)->i_##xtime)
+#endif
 
 static inline int inode_unhashed(struct inode *inode)
 {
diff --git a/include/linux/stat.h b/include/linux/stat.h
index 075cb0c..e3443a9 100644
--- a/include/linux/stat.h
+++ b/include/linux/stat.h
@@ -27,9 +27,15 @@ struct kstat {
        kgid_t          gid;
        dev_t           rdev;
        loff_t          size;
-       struct timespec  atime;
-       struct timespec mtime;
-       struct timespec ctime;
+#ifdef CONFIG_FS_USES_64BIT_TIME
+       struct timespec64       atime;
+       struct timespec64       mtime;
+       struct timespec64       ctime;
+#else
+       struct timespec         atime;
+       struct timespec         mtime;
+       struct timespec         ctime;
+#endif
        unsigned long   blksize;
        unsigned long long      blocks;
 };
-- 
1.9.1

_______________________________________________
Y2038 mailing list
Y2038@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/y2038

Reply via email to