]> git.ipfire.org Git - thirdparty/mdadm.git/commitdiff
mdadm: Change timestamps to unsigned data type.
authorDeepa Dinamani <deepa.kernel@gmail.com>
Tue, 8 Dec 2015 23:10:21 +0000 (15:10 -0800)
committerNeilBrown <neilb@suse.com>
Wed, 16 Dec 2015 01:43:25 +0000 (12:43 +1100)
32 bit signed timestamps will overflow in the year 2038.

Change the user interface mdu_array_info_s structure timestamps:
ctime and utime values used in ioctls GET_ARRAY_INFO and
SET_ARRAY_INFO to unsigned int. This will extend the field to last
until the year 2106.

Add time_after/time_before and supporting typecheck from
the kernel to take care of unsigned time wraparound.

The long term plan is to get rid of ctime and utime values in
this structure as this information can be read from the on-disk
meta data directly.

v0.90 on disk meta data uses u32 for maintaining time stamps.
So this will also last until year 2106.
Assumption is that the usage of v0.90 will be deprecated by
year 2106.

Timestamp fields in the on disk meta data for v1.0 version already
use 64 bit data types.

Signed-off-by: NeilBrown <neilb@suse.com>
Grow.c [changed mode: 0644->0755]
md_u.h
mdadm.h [changed mode: 0644->0755]

diff --git a/Grow.c b/Grow.c
old mode 100644 (file)
new mode 100755 (executable)
index 80d7b22..ee48c36
--- a/Grow.c
+++ b/Grow.c
@@ -4503,8 +4503,8 @@ int Grow_restart(struct supertype *st, struct mdinfo *info, int *fdlist, int cnt
                 * sometimes they aren't... So allow considerable flexability in matching, and allow
                 * this test to be overridden by an environment variable.
                 */
-               if (info->array.utime > (int)__le64_to_cpu(bsb.mtime) + 2*60*60 ||
-                   info->array.utime < (int)__le64_to_cpu(bsb.mtime) - 10*60) {
+               if(time_after(info->array.utime, (unsigned int)__le64_to_cpu(bsb.mtime) + 2*60*60) ||
+                  time_before(info->array.utime, (unsigned int)__le64_to_cpu(bsb.mtime) - 10*60)) {
                        if (check_env("MDADM_GROW_ALLOW_OLD")) {
                                pr_err("accepting backup with timestamp %lu for array with timestamp %lu\n",
                                        (unsigned long)__le64_to_cpu(bsb.mtime),
diff --git a/md_u.h b/md_u.h
index 76068d647ffe7ca1a6ba6873bd344e6159d060bd..f570a346923ce6c1fef2c88254f5bce592737aae 100644 (file)
--- a/md_u.h
+++ b/md_u.h
@@ -59,7 +59,7 @@ typedef struct mdu_array_info_s {
        int major_version;
        int minor_version;
        int patch_version;
-       int ctime;
+       unsigned int ctime;
        int level;
        int size;
        int nr_disks;
@@ -70,7 +70,7 @@ typedef struct mdu_array_info_s {
        /*
         * Generic state information
         */
-       int utime;              /*  0 Superblock update time                  */
+       unsigned int utime;     /*  0 Superblock update time                  */
        int state;              /*  1 State bits (clean, ...)                 */
        int active_disks;       /*  2 Number of currently active disks        */
        int working_disks;      /*  3 Number of working disks                 */
diff --git a/mdadm.h b/mdadm.h
old mode 100644 (file)
new mode 100755 (executable)
index 5d5e97f..840a359
--- a/mdadm.h
+++ b/mdadm.h
@@ -188,6 +188,31 @@ struct dlm_lksb {
 #endif
 #endif /* __KLIBC__ */
 
+/*
+  * Check at compile time that something is of a particular type.
+  * Always evaluates to 1 so you may use it easily in comparisons.
+*/
+
+#define typecheck(type,x) \
+({        type __dummy; \
+          typeof(x) __dummy2; \
+          (void)(&__dummy == &__dummy2); \
+          1; \
+})
+
+/*
+ *  These inlines deal with timer wrapping correctly.
+ *
+ * time_after(a,b) returns true if the time a is after time b.
+*/
+
+#define time_after(a,b)        \
+        (typecheck(unsigned int, a) && \
+         typecheck(unsigned int, b) && \
+         ((int)((b) - (a)) < 0))
+
+#define time_before(a,b)        time_after(b,a)
+
 /*
  * min()/max()/clamp() macros that also do
  * strict type-checking.. See the