Here, we actually have a problem in 2038 or at the latest in 2106 when
the lc_expiry variable on the wire protocol overflows, including on
64-bit architectures.

I'm changing the internal implementation so it only compares the lower
31 bits of the current time, using the algorithm from time_before(),
which should work as long as nothing tries to directly access lc_expiry.

Signed-off-by: Arnd Bergmann <a...@arndb.de>
---
 .../staging/lustre/lustre/include/lustre/lustre_idl.h    |  1 +
 drivers/staging/lustre/lustre/include/lustre_capa.h      | 16 ++++++++++------
 2 files changed, 11 insertions(+), 6 deletions(-)

diff --git a/drivers/staging/lustre/lustre/include/lustre/lustre_idl.h 
b/drivers/staging/lustre/lustre/include/lustre/lustre_idl.h
index d20e199eb770..e0cec23e8344 100644
--- a/drivers/staging/lustre/lustre/include/lustre/lustre_idl.h
+++ b/drivers/staging/lustre/lustre/include/lustre/lustre_idl.h
@@ -3478,6 +3478,7 @@ struct lustre_capa {
        __u32      lc_flags;       /** HMAC algorithm & flags */
        __u32      lc_keyid;       /** key# used for the capability */
        __u32      lc_timeout;     /** capa timeout value (sec) */
+/* FIXME: y2038 time_t overflow: */
        __u32      lc_expiry;      /** expiry time (sec) */
        __u8        lc_hmac[CAPA_HMAC_MAX_LEN];   /** HMAC */
 } __attribute__((packed));
diff --git a/drivers/staging/lustre/lustre/include/lustre_capa.h 
b/drivers/staging/lustre/lustre/include/lustre_capa.h
index 11bcdb935443..b75f7308d777 100644
--- a/drivers/staging/lustre/lustre/include/lustre_capa.h
+++ b/drivers/staging/lustre/lustre/include/lustre_capa.h
@@ -266,20 +266,24 @@ static inline __u64 capa_open_opc(int mode)
 
 static inline void set_capa_expiry(struct obd_capa *ocapa)
 {
-       unsigned long expiry = cfs_time_sub((unsigned 
long)ocapa->c_capa.lc_expiry,
-                                        get_seconds());
-       ocapa->c_expiry = cfs_time_add(cfs_time_current(),
-                                      cfs_time_seconds(expiry));
+       u32 expiry = ocapa->c_capa.lc_expiry - (u32)ktime_get_real_seconds();
+       ocapa->c_expiry = jiffies + expiry * HZ;
 }
 
 static inline int capa_is_expired_sec(struct lustre_capa *capa)
 {
-       return (capa->lc_expiry - get_seconds() <= 0);
+       /*
+        * workaround for y2038 problem: do the same as time_before, but
+        * use 32-bit arithmetic, because lc_expiry is transmitted as a 32-bit
+        * variable on the wire
+        */
+       s32 diff = capa->lc_expiry - (u32)ktime_get_real_seconds();
+       return diff <= 0;
 }
 
 static inline int capa_is_expired(struct obd_capa *ocapa)
 {
-       return time_before_eq(ocapa->c_expiry, cfs_time_current());
+       return time_before_eq(ocapa->c_expiry, jiffies);
 }
 
 static inline int capa_opc_supported(struct lustre_capa *capa, __u64 opc)
-- 
2.1.0.rc2

_______________________________________________
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel

Reply via email to