[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[2.06 RELEASE PATCH v2 2/4] fs: Use 64-bit type for filesystem timestamp
From: |
Javier Martinez Canillas |
Subject: |
[2.06 RELEASE PATCH v2 2/4] fs: Use 64-bit type for filesystem timestamp |
Date: |
Wed, 12 May 2021 17:46:14 +0200 |
From: Carlos Maiolino <cmaiolino@redhat.com>
Some filesystems nowadays uses 64-bit types for timestamps, so, update
grub_dirhook_info struct to use an grub_int64_t type to store mtime.
This also updates the grub_unixtime2datetime() function to receive a
64-bit timestamp argument and do 64-bit-safe divisions.
All the remaining conversion from 32-bit to 64-bit should be safe, as
32-bit to 64-bit attributions will be implicitly casted. The most
crictical part in the 32-bit to 64-bit conversion is on the function
grub_unixtime2datetime() where it needs to deal with the 64-bit type.
So, for that, the grub_divmod64() helper has been used.
These changes enables the GRUB to support dates beyond y2038.
Signed-off-by: Carlos Maiolino <cmaiolino@redhat.com>
Signed-off-by: Javier Martinez Canillas <javierm@redhat.com>
---
Changes in v2:
- Improve commit message for patch #2 (dkiper).
- Drop Reviewed-by tag from patch #2 (dkiper).
- A few code cleanups for patch #2 (dkiper).
grub-core/fs/affs.c | 2 +-
grub-core/fs/ext2.c | 2 +-
grub-core/fs/fat.c | 4 ++--
grub-core/fs/hfs.c | 2 +-
grub-core/fs/hfsplus.c | 2 +-
grub-core/fs/iso9660.c | 6 +++---
grub-core/fs/nilfs2.c | 2 +-
grub-core/fs/squash4.c | 2 +-
grub-core/fs/ufs.c | 2 +-
grub-core/fs/zfs/zfs.c | 2 +-
grub-core/lib/datetime.c | 14 +++++++++++---
grub-core/net/bootp.c | 2 +-
grub-core/normal/misc.c | 2 +-
grub-core/tests/sleep_test.c | 4 ++--
include/grub/datetime.h | 4 ++--
include/grub/fs.h | 4 ++--
16 files changed, 32 insertions(+), 24 deletions(-)
diff --git a/grub-core/fs/affs.c b/grub-core/fs/affs.c
index 230e26af0f8..cafcd0fba91 100644
--- a/grub-core/fs/affs.c
+++ b/grub-core/fs/affs.c
@@ -641,7 +641,7 @@ grub_affs_label (grub_device_t device, char **label)
}
static grub_err_t
-grub_affs_mtime (grub_device_t device, grub_int32_t *t)
+grub_affs_mtime (grub_device_t device, grub_int64_t *t)
{
struct grub_affs_data *data;
grub_disk_t disk = device->disk;
diff --git a/grub-core/fs/ext2.c b/grub-core/fs/ext2.c
index 848bf939dba..e7dd78e6635 100644
--- a/grub-core/fs/ext2.c
+++ b/grub-core/fs/ext2.c
@@ -1055,7 +1055,7 @@ grub_ext2_uuid (grub_device_t device, char **uuid)
/* Get mtime. */
static grub_err_t
-grub_ext2_mtime (grub_device_t device, grub_int32_t *tm)
+grub_ext2_mtime (grub_device_t device, grub_int64_t *tm)
{
struct grub_ext2_data *data;
grub_disk_t disk = device->disk;
diff --git a/grub-core/fs/fat.c b/grub-core/fs/fat.c
index 7f775a17038..dd82e4ee35d 100644
--- a/grub-core/fs/fat.c
+++ b/grub-core/fs/fat.c
@@ -737,7 +737,7 @@ grub_fat_iterate_dir_next (grub_fshelp_node_t node,
* https://docs.microsoft.com/en-us/windows/win32/fileio/exfat-specification
*/
static int
-grub_exfat_timestamp (grub_uint32_t field, grub_uint8_t msec, grub_int32_t
*nix) {
+grub_exfat_timestamp (grub_uint32_t field, grub_uint8_t msec, grub_int64_t
*nix) {
struct grub_datetime datetime = {
.year = (field >> 25) + 1980,
.month = (field & 0x01E00000) >> 21,
@@ -891,7 +891,7 @@ grub_fat_iterate_dir_next (grub_fshelp_node_t node,
* https://www.ecma-international.org/publications/files/ECMA-ST/Ecma-107.pdf
*/
static int
-grub_fat_timestamp (grub_uint16_t time, grub_uint16_t date, grub_int32_t *nix)
{
+grub_fat_timestamp (grub_uint16_t time, grub_uint16_t date, grub_int64_t *nix)
{
struct grub_datetime datetime = {
.year = (date >> 9) + 1980,
.month = (date & 0x01E0) >> 5,
diff --git a/grub-core/fs/hfs.c b/grub-core/fs/hfs.c
index 9a5b7bbe906..f419965d154 100644
--- a/grub-core/fs/hfs.c
+++ b/grub-core/fs/hfs.c
@@ -1374,7 +1374,7 @@ grub_hfs_label (grub_device_t device, char **label)
}
static grub_err_t
-grub_hfs_mtime (grub_device_t device, grub_int32_t *tm)
+grub_hfs_mtime (grub_device_t device, grub_int64_t *tm)
{
struct grub_hfs_data *data;
diff --git a/grub-core/fs/hfsplus.c b/grub-core/fs/hfsplus.c
index 2a69055c7ec..19c7b336798 100644
--- a/grub-core/fs/hfsplus.c
+++ b/grub-core/fs/hfsplus.c
@@ -1083,7 +1083,7 @@ grub_hfsplus_label (grub_device_t device, char **label)
/* Get mtime. */
static grub_err_t
-grub_hfsplus_mtime (grub_device_t device, grub_int32_t *tm)
+grub_hfsplus_mtime (grub_device_t device, grub_int64_t *tm)
{
struct grub_hfsplus_data *data;
grub_disk_t disk = device->disk;
diff --git a/grub-core/fs/iso9660.c b/grub-core/fs/iso9660.c
index 5ec4433b8f8..ac011950a64 100644
--- a/grub-core/fs/iso9660.c
+++ b/grub-core/fs/iso9660.c
@@ -178,7 +178,7 @@ static grub_dl_t my_mod;
static grub_err_t
-iso9660_to_unixtime (const struct grub_iso9660_date *i, grub_int32_t *nix)
+iso9660_to_unixtime (const struct grub_iso9660_date *i, grub_int64_t *nix)
{
struct grub_datetime datetime;
@@ -206,7 +206,7 @@ iso9660_to_unixtime (const struct grub_iso9660_date *i,
grub_int32_t *nix)
}
static int
-iso9660_to_unixtime2 (const struct grub_iso9660_date2 *i, grub_int32_t *nix)
+iso9660_to_unixtime2 (const struct grub_iso9660_date2 *i, grub_int64_t *nix)
{
struct grub_datetime datetime;
@@ -1107,7 +1107,7 @@ grub_iso9660_uuid (grub_device_t device, char **uuid)
/* Get writing time of filesystem. */
static grub_err_t
-grub_iso9660_mtime (grub_device_t device, grub_int32_t *timebuf)
+grub_iso9660_mtime (grub_device_t device, grub_int64_t *timebuf)
{
struct grub_iso9660_data *data;
grub_disk_t disk = device->disk;
diff --git a/grub-core/fs/nilfs2.c b/grub-core/fs/nilfs2.c
index 9b76982b3b0..3c248a910b4 100644
--- a/grub-core/fs/nilfs2.c
+++ b/grub-core/fs/nilfs2.c
@@ -1186,7 +1186,7 @@ grub_nilfs2_uuid (grub_device_t device, char **uuid)
/* Get mtime. */
static grub_err_t
-grub_nilfs2_mtime (grub_device_t device, grub_int32_t * tm)
+grub_nilfs2_mtime (grub_device_t device, grub_int64_t * tm)
{
struct grub_nilfs2_data *data;
grub_disk_t disk = device->disk;
diff --git a/grub-core/fs/squash4.c b/grub-core/fs/squash4.c
index a5f35c10e2f..6dd731e231e 100644
--- a/grub-core/fs/squash4.c
+++ b/grub-core/fs/squash4.c
@@ -1003,7 +1003,7 @@ grub_squash_close (grub_file_t file)
}
static grub_err_t
-grub_squash_mtime (grub_device_t dev, grub_int32_t *tm)
+grub_squash_mtime (grub_device_t dev, grub_int64_t *tm)
{
struct grub_squash_data *data = 0;
diff --git a/grub-core/fs/ufs.c b/grub-core/fs/ufs.c
index fca46baa19d..34a698b71b8 100644
--- a/grub-core/fs/ufs.c
+++ b/grub-core/fs/ufs.c
@@ -837,7 +837,7 @@ grub_ufs_uuid (grub_device_t device, char **uuid)
/* Get mtime. */
static grub_err_t
-grub_ufs_mtime (grub_device_t device, grub_int32_t *tm)
+grub_ufs_mtime (grub_device_t device, grub_int64_t *tm)
{
struct grub_ufs_data *data = 0;
diff --git a/grub-core/fs/zfs/zfs.c b/grub-core/fs/zfs/zfs.c
index f9e755197c5..cf4d2ab189a 100644
--- a/grub-core/fs/zfs/zfs.c
+++ b/grub-core/fs/zfs/zfs.c
@@ -3771,7 +3771,7 @@ zfs_uuid (grub_device_t device, char **uuid)
}
static grub_err_t
-zfs_mtime (grub_device_t device, grub_int32_t *mt)
+zfs_mtime (grub_device_t device, grub_int64_t *mt)
{
struct grub_zfs_data *data;
grub_zfs_endian_t ub_endian = GRUB_ZFS_UNKNOWN_ENDIAN;
diff --git a/grub-core/lib/datetime.c b/grub-core/lib/datetime.c
index 95b8c9ff5e3..67415a57719 100644
--- a/grub-core/lib/datetime.c
+++ b/grub-core/lib/datetime.c
@@ -17,8 +17,10 @@
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
*/
+#include <stddef.h>
#include <grub/datetime.h>
#include <grub/i18n.h>
+#include <grub/misc.h>
static const char *const grub_weekday_names[] =
{
@@ -60,7 +62,7 @@ grub_get_weekday_name (struct grub_datetime *datetime)
void
-grub_unixtime2datetime (grub_int32_t nix, struct grub_datetime *datetime)
+grub_unixtime2datetime (grub_int64_t nix, struct grub_datetime *datetime)
{
int i;
grub_uint8_t months[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
@@ -75,9 +77,15 @@ grub_unixtime2datetime (grub_int32_t nix, struct
grub_datetime *datetime)
unsigned secs_in_day;
/* Transform C divisions and modulos to mathematical ones */
if (nix < 0)
- days_epoch = -(((unsigned) (SECPERDAY-nix-1)) / SECPERDAY);
+ /*
+ * the division here shouldn't be larger than INT_MAX,
+ * so, it's safe to store the result back in an int
+ */
+ days_epoch = -(grub_divmod64 (((grub_int64_t)(SECPERDAY) - nix - 1),
+ SECPERDAY, NULL));
else
- days_epoch = ((unsigned) nix) / SECPERDAY;
+ days_epoch = grub_divmod64 (nix, SECPERDAY, NULL);
+
secs_in_day = nix - days_epoch * SECPERDAY;
days = days_epoch + 69 * DAYSPERYEAR + 17;
diff --git a/grub-core/net/bootp.c b/grub-core/net/bootp.c
index e33be51f83b..6fb5627025d 100644
--- a/grub-core/net/bootp.c
+++ b/grub-core/net/bootp.c
@@ -468,7 +468,7 @@ send_dhcp_packet (struct grub_net_network_level_interface
*iface)
grub_err_t err;
struct grub_net_bootp_packet *pack;
struct grub_datetime date;
- grub_int32_t t = 0;
+ grub_int64_t t = 0;
struct grub_net_buff *nb;
struct udphdr *udph;
grub_net_network_level_address_t target;
diff --git a/grub-core/normal/misc.c b/grub-core/normal/misc.c
index 8bb6da31fb3..f7e9e3ac4a1 100644
--- a/grub-core/normal/misc.c
+++ b/grub-core/normal/misc.c
@@ -136,7 +136,7 @@ grub_normal_print_device_info (const char *name)
}
if (fs->fs_mtime)
{
- grub_int32_t tm;
+ grub_int64_t tm;
struct grub_datetime datetime;
(fs->fs_mtime) (dev, &tm);
if (grub_errno == GRUB_ERR_NONE)
diff --git a/grub-core/tests/sleep_test.c b/grub-core/tests/sleep_test.c
index 3d11c717cb7..413577f4e9c 100644
--- a/grub-core/tests/sleep_test.c
+++ b/grub-core/tests/sleep_test.c
@@ -32,7 +32,7 @@ static void
sleep_test (void)
{
struct grub_datetime st, en;
- grub_int32_t stu = 0, enu = 0;
+ grub_int64_t stu = 0, enu = 0;
int is_delayok;
grub_test_assert (!grub_get_datetime (&st), "Couldn't retrieve start time");
grub_millisleep (10000);
@@ -45,7 +45,7 @@ sleep_test (void)
if (enu - stu >= 15 && enu - stu <= 17)
is_delayok = 1;
#endif
- grub_test_assert (is_delayok, "Interval out of range: %d", enu-stu);
+ grub_test_assert (is_delayok, "Interval out of range: " PRIdGRUB_INT64_T,
enu - stu);
}
diff --git a/include/grub/datetime.h b/include/grub/datetime.h
index fef281404d7..23ae0791ced 100644
--- a/include/grub/datetime.h
+++ b/include/grub/datetime.h
@@ -48,11 +48,11 @@ grub_err_t grub_set_datetime (struct grub_datetime
*datetime);
int grub_get_weekday (struct grub_datetime *datetime);
const char *grub_get_weekday_name (struct grub_datetime *datetime);
-void grub_unixtime2datetime (grub_int32_t nix,
+void grub_unixtime2datetime (grub_int64_t nix,
struct grub_datetime *datetime);
static inline int
-grub_datetime2unixtime (const struct grub_datetime *datetime, grub_int32_t
*nix)
+grub_datetime2unixtime (const struct grub_datetime *datetime, grub_int64_t
*nix)
{
grub_int32_t ret;
int y4, ay;
diff --git a/include/grub/fs.h b/include/grub/fs.h
index 302e48d4b50..026bc3bb861 100644
--- a/include/grub/fs.h
+++ b/include/grub/fs.h
@@ -39,7 +39,7 @@ struct grub_dirhook_info
unsigned mtimeset:1;
unsigned case_insensitive:1;
unsigned inodeset:1;
- grub_int32_t mtime;
+ grub_int64_t mtime;
grub_uint64_t inode;
};
@@ -81,7 +81,7 @@ struct grub_fs
grub_err_t (*fs_uuid) (grub_device_t device, char **uuid);
/* Get writing time of filesystem. */
- grub_err_t (*fs_mtime) (grub_device_t device, grub_int32_t *timebuf);
+ grub_err_t (*fs_mtime) (grub_device_t device, grub_int64_t *timebuf);
#ifdef GRUB_UTIL
/* Determine sectors available for embedding. */
--
2.31.1