Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drivers: md: use ktime_get_real_seconds()

get_seconds() API is not y2038 safe on 32 bit systems and the API
is deprecated. Replace it with calls to ktime_get_real_seconds()
API instead. Change mddev structure types to time64_t accordingly.

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.
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.

Clamp the tim64_t timestamps to positive values with a max of U32_MAX
when returning from GET_ARRAY_INFO ioctl to accommodate above changes
in the data type of timestamps to unsigned int.

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. Remove the truncation of the bits while
writing to or reading from these from the disk.

Signed-off-by: Deepa Dinamani <deepa.kernel@gmail.com>
Reviewed-by: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: NeilBrown <neilb@suse.com>

authored by

Deepa Dinamani and committed by
NeilBrown
9ebc6ef1 3312c951

+12 -12
+9 -9
drivers/md/md.c
··· 1200 1200 memcpy(&sb->set_uuid2, mddev->uuid+8, 4); 1201 1201 memcpy(&sb->set_uuid3, mddev->uuid+12,4); 1202 1202 1203 - sb->ctime = mddev->ctime; 1203 + sb->ctime = clamp_t(time64_t, mddev->ctime, 0, U32_MAX); 1204 1204 sb->level = mddev->level; 1205 1205 sb->size = mddev->dev_sectors / 2; 1206 1206 sb->raid_disks = mddev->raid_disks; 1207 1207 sb->md_minor = mddev->md_minor; 1208 1208 sb->not_persistent = 0; 1209 - sb->utime = mddev->utime; 1209 + sb->utime = clamp_t(time64_t, mddev->utime, 0, U32_MAX); 1210 1210 sb->state = 0; 1211 1211 sb->events_hi = (mddev->events>>32); 1212 1212 sb->events_lo = (u32)mddev->events; ··· 1547 1547 mddev->patch_version = 0; 1548 1548 mddev->external = 0; 1549 1549 mddev->chunk_sectors = le32_to_cpu(sb->chunksize); 1550 - mddev->ctime = le64_to_cpu(sb->ctime) & ((1ULL << 32)-1); 1551 - mddev->utime = le64_to_cpu(sb->utime) & ((1ULL << 32)-1); 1550 + mddev->ctime = le64_to_cpu(sb->ctime); 1551 + mddev->utime = le64_to_cpu(sb->utime); 1552 1552 mddev->level = le32_to_cpu(sb->level); 1553 1553 mddev->clevel[0] = 0; 1554 1554 mddev->layout = le32_to_cpu(sb->layout); ··· 2336 2336 2337 2337 spin_lock(&mddev->lock); 2338 2338 2339 - mddev->utime = get_seconds(); 2339 + mddev->utime = ktime_get_real_seconds(); 2340 2340 2341 2341 if (test_and_clear_bit(MD_CHANGE_DEVS, &mddev->flags)) 2342 2342 force_change = 1; ··· 5843 5843 info.major_version = mddev->major_version; 5844 5844 info.minor_version = mddev->minor_version; 5845 5845 info.patch_version = MD_PATCHLEVEL_VERSION; 5846 - info.ctime = mddev->ctime; 5846 + info.ctime = clamp_t(time64_t, mddev->ctime, 0, U32_MAX); 5847 5847 info.level = mddev->level; 5848 5848 info.size = mddev->dev_sectors / 2; 5849 5849 if (info.size != mddev->dev_sectors / 2) /* overflow */ ··· 5853 5853 info.md_minor = mddev->md_minor; 5854 5854 info.not_persistent= !mddev->persistent; 5855 5855 5856 - info.utime = mddev->utime; 5856 + info.utime = clamp_t(time64_t, mddev->utime, 0, U32_MAX); 5857 5857 info.state = 0; 5858 5858 if (mddev->in_sync) 5859 5859 info.state = (1<<MD_SB_CLEAN); ··· 6353 6353 /* ensure mddev_put doesn't delete this now that there 6354 6354 * is some minimal configuration. 6355 6355 */ 6356 - mddev->ctime = get_seconds(); 6356 + mddev->ctime = ktime_get_real_seconds(); 6357 6357 return 0; 6358 6358 } 6359 6359 mddev->major_version = MD_MAJOR_VERSION; 6360 6360 mddev->minor_version = MD_MINOR_VERSION; 6361 6361 mddev->patch_version = MD_PATCHLEVEL_VERSION; 6362 - mddev->ctime = get_seconds(); 6362 + mddev->ctime = ktime_get_real_seconds(); 6363 6363 6364 6364 mddev->level = info->level; 6365 6365 mddev->clevel[0] = 0;
+1 -1
drivers/md/md.h
··· 264 264 * managed externally */ 265 265 char metadata_type[17]; /* externally set*/ 266 266 int chunk_sectors; 267 - time_t ctime, utime; 267 + time64_t ctime, utime; 268 268 int level, layout; 269 269 char clevel[16]; 270 270 int raid_disks;
+2 -2
include/uapi/linux/raid/md_u.h
··· 80 80 int major_version; 81 81 int minor_version; 82 82 int patch_version; 83 - int ctime; 83 + unsigned int ctime; 84 84 int level; 85 85 int size; 86 86 int nr_disks; ··· 91 91 /* 92 92 * Generic state information 93 93 */ 94 - int utime; /* 0 Superblock update time */ 94 + unsigned int utime; /* 0 Superblock update time */ 95 95 int state; /* 1 State bits (clean, ...) */ 96 96 int active_disks; /* 2 Number of currently active disks */ 97 97 int working_disks; /* 3 Number of working disks */