summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDeepa Dinamani <deepa.kernel@gmail.com>2015-12-08 15:10:21 -0800
committerNeilBrown <neilb@suse.com>2015-12-16 12:43:25 +1100
commit26714713cd2bad9e0bf7f4669f6cc4659ceaab6c (patch)
tree80a554e170d086802976123e14380f46b554abe3
parentdbfbca430080de55ce70ba1fcdec44173a0ddc02 (diff)
downloadmdadm-26714713cd2bad9e0bf7f4669f6cc4659ceaab6c.tar.gz
mdadm: Change timestamps to unsigned data type.
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>
-rwxr-xr-x[-rw-r--r--]Grow.c4
-rw-r--r--md_u.h4
-rwxr-xr-x[-rw-r--r--]mdadm.h25
3 files changed, 29 insertions, 4 deletions
diff --git a/Grow.c b/Grow.c
index 80d7b22..ee48c36 100644..100755
--- 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 76068d6..f570a34 100644
--- 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
index 5d5e97f..840a359 100644..100755
--- a/mdadm.h
+++ b/mdadm.h
@@ -189,6 +189,31 @@ struct dlm_lksb {
#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
* "unnecessary" pointer comparison.