Skip to content

Commit 9ebc6ef

Browse files
deepa-hubNeilBrown
authored andcommitted
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>
1 parent 3312c95 commit 9ebc6ef

3 files changed

Lines changed: 12 additions & 12 deletions

File tree

drivers/md/md.c

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1200,13 +1200,13 @@ static void super_90_sync(struct mddev *mddev, struct md_rdev *rdev)
12001200
memcpy(&sb->set_uuid2, mddev->uuid+8, 4);
12011201
memcpy(&sb->set_uuid3, mddev->uuid+12,4);
12021202

1203-
sb->ctime = mddev->ctime;
1203+
sb->ctime = clamp_t(time64_t, mddev->ctime, 0, U32_MAX);
12041204
sb->level = mddev->level;
12051205
sb->size = mddev->dev_sectors / 2;
12061206
sb->raid_disks = mddev->raid_disks;
12071207
sb->md_minor = mddev->md_minor;
12081208
sb->not_persistent = 0;
1209-
sb->utime = mddev->utime;
1209+
sb->utime = clamp_t(time64_t, mddev->utime, 0, U32_MAX);
12101210
sb->state = 0;
12111211
sb->events_hi = (mddev->events>>32);
12121212
sb->events_lo = (u32)mddev->events;
@@ -1547,8 +1547,8 @@ static int super_1_validate(struct mddev *mddev, struct md_rdev *rdev)
15471547
mddev->patch_version = 0;
15481548
mddev->external = 0;
15491549
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);
15521552
mddev->level = le32_to_cpu(sb->level);
15531553
mddev->clevel[0] = 0;
15541554
mddev->layout = le32_to_cpu(sb->layout);
@@ -2336,7 +2336,7 @@ void md_update_sb(struct mddev *mddev, int force_change)
23362336

23372337
spin_lock(&mddev->lock);
23382338

2339-
mddev->utime = get_seconds();
2339+
mddev->utime = ktime_get_real_seconds();
23402340

23412341
if (test_and_clear_bit(MD_CHANGE_DEVS, &mddev->flags))
23422342
force_change = 1;
@@ -5843,7 +5843,7 @@ static int get_array_info(struct mddev *mddev, void __user *arg)
58435843
info.major_version = mddev->major_version;
58445844
info.minor_version = mddev->minor_version;
58455845
info.patch_version = MD_PATCHLEVEL_VERSION;
5846-
info.ctime = mddev->ctime;
5846+
info.ctime = clamp_t(time64_t, mddev->ctime, 0, U32_MAX);
58475847
info.level = mddev->level;
58485848
info.size = mddev->dev_sectors / 2;
58495849
if (info.size != mddev->dev_sectors / 2) /* overflow */
@@ -5853,7 +5853,7 @@ static int get_array_info(struct mddev *mddev, void __user *arg)
58535853
info.md_minor = mddev->md_minor;
58545854
info.not_persistent= !mddev->persistent;
58555855

5856-
info.utime = mddev->utime;
5856+
info.utime = clamp_t(time64_t, mddev->utime, 0, U32_MAX);
58575857
info.state = 0;
58585858
if (mddev->in_sync)
58595859
info.state = (1<<MD_SB_CLEAN);
@@ -6353,13 +6353,13 @@ static int set_array_info(struct mddev *mddev, mdu_array_info_t *info)
63536353
/* ensure mddev_put doesn't delete this now that there
63546354
* is some minimal configuration.
63556355
*/
6356-
mddev->ctime = get_seconds();
6356+
mddev->ctime = ktime_get_real_seconds();
63576357
return 0;
63586358
}
63596359
mddev->major_version = MD_MAJOR_VERSION;
63606360
mddev->minor_version = MD_MINOR_VERSION;
63616361
mddev->patch_version = MD_PATCHLEVEL_VERSION;
6362-
mddev->ctime = get_seconds();
6362+
mddev->ctime = ktime_get_real_seconds();
63636363

63646364
mddev->level = info->level;
63656365
mddev->clevel[0] = 0;

drivers/md/md.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -264,7 +264,7 @@ struct mddev {
264264
* managed externally */
265265
char metadata_type[17]; /* externally set*/
266266
int chunk_sectors;
267-
time_t ctime, utime;
267+
time64_t ctime, utime;
268268
int level, layout;
269269
char clevel[16];
270270
int raid_disks;

include/uapi/linux/raid/md_u.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ typedef struct mdu_array_info_s {
8080
int major_version;
8181
int minor_version;
8282
int patch_version;
83-
int ctime;
83+
unsigned int ctime;
8484
int level;
8585
int size;
8686
int nr_disks;
@@ -91,7 +91,7 @@ typedef struct mdu_array_info_s {
9191
/*
9292
* Generic state information
9393
*/
94-
int utime; /* 0 Superblock update time */
94+
unsigned int utime; /* 0 Superblock update time */
9595
int state; /* 1 State bits (clean, ...) */
9696
int active_disks; /* 2 Number of currently active disks */
9797
int working_disks; /* 3 Number of working disks */

0 commit comments

Comments
 (0)