For NFSv2 and NFSv3, timestamps are stored using 32-bit entities
and overflow in y2038. For historic reasons we truncate the
64-bit timestamps by converting from a timespec64 to a timespec
first.

Remove this unnecessary conversion step and do the truncation
in the final functions that take a timestamp.

This is transparent to users, but avoids one of the last uses
of 'timespec' and lets us remove it later.

Signed-off-by: Arnd Bergmann <a...@arndb.de>
---
 fs/nfs/nfs2xdr.c        | 31 +++++++++++++------------------
 fs/nfs/nfs3xdr.c        | 12 ++++--------
 include/linux/nfs_xdr.h |  2 +-
 3 files changed, 18 insertions(+), 27 deletions(-)

diff --git a/fs/nfs/nfs2xdr.c b/fs/nfs/nfs2xdr.c
index d4e144712034..0b8399fee8f7 100644
--- a/fs/nfs/nfs2xdr.c
+++ b/fs/nfs/nfs2xdr.c
@@ -209,9 +209,9 @@ static int decode_fhandle(struct xdr_stream *xdr, struct 
nfs_fh *fh)
  *             unsigned int useconds;
  *     };
  */
-static __be32 *xdr_encode_time(__be32 *p, const struct timespec *timep)
+static __be32 *xdr_encode_time(__be32 *p, const struct timespec64 *timep)
 {
-       *p++ = cpu_to_be32(timep->tv_sec);
+       *p++ = cpu_to_be32((u32)timep->tv_sec);
        if (timep->tv_nsec != 0)
                *p++ = cpu_to_be32(timep->tv_nsec / NSEC_PER_USEC);
        else
@@ -227,7 +227,7 @@ static __be32 *xdr_encode_time(__be32 *p, const struct 
timespec *timep)
  * Illustrated" by Brent Callaghan, Addison-Wesley, ISBN 0-201-32750-5.
  */
 static __be32 *xdr_encode_current_server_time(__be32 *p,
-                                             const struct timespec *timep)
+                                             const struct timespec64 *timep)
 {
        *p++ = cpu_to_be32(timep->tv_sec);
        *p++ = cpu_to_be32(1000000);
@@ -339,7 +339,6 @@ static __be32 *xdr_time_not_set(__be32 *p)
 static void encode_sattr(struct xdr_stream *xdr, const struct iattr *attr,
                struct user_namespace *userns)
 {
-       struct timespec ts;
        __be32 *p;
 
        p = xdr_reserve_space(xdr, NFS_sattr_sz << 2);
@@ -361,21 +360,17 @@ static void encode_sattr(struct xdr_stream *xdr, const 
struct iattr *attr,
        else
                *p++ = cpu_to_be32(NFS2_SATTR_NOT_SET);
 
-       if (attr->ia_valid & ATTR_ATIME_SET) {
-               ts = timespec64_to_timespec(attr->ia_atime);
-               p = xdr_encode_time(p, &ts);
-       } else if (attr->ia_valid & ATTR_ATIME) {
-               ts = timespec64_to_timespec(attr->ia_atime);
-               p = xdr_encode_current_server_time(p, &ts);
-       } else
+       if (attr->ia_valid & ATTR_ATIME_SET)
+               p = xdr_encode_time(p, &attr->ia_atime);
+       else if (attr->ia_valid & ATTR_ATIME)
+               p = xdr_encode_current_server_time(p, &attr->ia_atime);
+       else
                p = xdr_time_not_set(p);
-       if (attr->ia_valid & ATTR_MTIME_SET) {
-               ts = timespec64_to_timespec(attr->ia_atime);
-               xdr_encode_time(p, &ts);
-       } else if (attr->ia_valid & ATTR_MTIME) {
-               ts = timespec64_to_timespec(attr->ia_mtime);
-               xdr_encode_current_server_time(p, &ts);
-       } else
+       if (attr->ia_valid & ATTR_MTIME_SET)
+               xdr_encode_time(p, &attr->ia_atime);
+       else if (attr->ia_valid & ATTR_MTIME)
+               xdr_encode_current_server_time(p, &attr->ia_mtime);
+       else
                xdr_time_not_set(p);
 }
 
diff --git a/fs/nfs/nfs3xdr.c b/fs/nfs/nfs3xdr.c
index 2a16bbda3937..927eb680f161 100644
--- a/fs/nfs/nfs3xdr.c
+++ b/fs/nfs/nfs3xdr.c
@@ -456,9 +456,9 @@ static void zero_nfs_fh3(struct nfs_fh *fh)
  *             uint32  nseconds;
  *     };
  */
-static __be32 *xdr_encode_nfstime3(__be32 *p, const struct timespec *timep)
+static __be32 *xdr_encode_nfstime3(__be32 *p, const struct timespec64 *timep)
 {
-       *p++ = cpu_to_be32(timep->tv_sec);
+       *p++ = cpu_to_be32((u32)timep->tv_sec);
        *p++ = cpu_to_be32(timep->tv_nsec);
        return p;
 }
@@ -533,7 +533,6 @@ static __be32 *xdr_decode_nfstime3(__be32 *p, struct 
timespec64 *timep)
 static void encode_sattr3(struct xdr_stream *xdr, const struct iattr *attr,
                struct user_namespace *userns)
 {
-       struct timespec ts;
        u32 nbytes;
        __be32 *p;
 
@@ -583,10 +582,8 @@ static void encode_sattr3(struct xdr_stream *xdr, const 
struct iattr *attr,
                *p++ = xdr_zero;
 
        if (attr->ia_valid & ATTR_ATIME_SET) {
-               struct timespec ts;
                *p++ = xdr_two;
-               ts = timespec64_to_timespec(attr->ia_atime);
-               p = xdr_encode_nfstime3(p, &ts);
+               p = xdr_encode_nfstime3(p, &attr->ia_atime);
        } else if (attr->ia_valid & ATTR_ATIME) {
                *p++ = xdr_one;
        } else
@@ -594,8 +591,7 @@ static void encode_sattr3(struct xdr_stream *xdr, const 
struct iattr *attr,
 
        if (attr->ia_valid & ATTR_MTIME_SET) {
                *p++ = xdr_two;
-               ts = timespec64_to_timespec(attr->ia_mtime);
-               xdr_encode_nfstime3(p, &ts);
+               xdr_encode_nfstime3(p, &attr->ia_mtime);
        } else if (attr->ia_valid & ATTR_MTIME) {
                *p = xdr_one;
        } else
diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h
index db5c01001937..22bc6613474e 100644
--- a/include/linux/nfs_xdr.h
+++ b/include/linux/nfs_xdr.h
@@ -869,7 +869,7 @@ struct nfs3_sattrargs {
        struct nfs_fh *         fh;
        struct iattr *          sattr;
        unsigned int            guard;
-       struct timespec         guardtime;
+       struct timespec64       guardtime;
 };
 
 struct nfs3_diropargs {
-- 
2.20.0

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

Reply via email to