[PATCH 25/37] staging/lustre: partially use time64_t for capa expiry

Arnd Bergmann arnd at arndb.de
Wed Sep 23 19:13:48 UTC 2015


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 <arnd at 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



More information about the devel mailing list