diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2019-09-19 19:42:37 +0300 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2019-09-19 19:42:37 +0300 |
commit | cfb82e1df8b7c76991ea12958855897c2fb4debc (patch) | |
tree | 7419ef2cef9ec1ea43b78619af6ddd3471152a44 /fs/namespace.c | |
parent | b41dae061bbd722b9d7fa828f35d22035b218e18 (diff) | |
parent | cba465b4f9820b0d929822a70341dde14909fc18 (diff) | |
download | linux-cfb82e1df8b7c76991ea12958855897c2fb4debc.tar.xz |
Merge tag 'y2038-vfs' of git://git.kernel.org/pub/scm/linux/kernel/git/arnd/playground
Pull y2038 vfs updates from Arnd Bergmann:
"Add inode timestamp clamping.
This series from Deepa Dinamani adds a per-superblock minimum/maximum
timestamp limit for a file system, and clamps timestamps as they are
written, to avoid random behavior from integer overflow as well as
having different time stamps on disk vs in memory.
At mount time, a warning is now printed for any file system that can
represent current timestamps but not future timestamps more than 30
years into the future, similar to the arbitrary 30 year limit that was
added to settimeofday().
This was picked as a compromise to warn users to migrate to other file
systems (e.g. ext4 instead of ext3) when they need the file system to
survive beyond 2038 (or similar limits in other file systems), but not
get in the way of normal usage"
* tag 'y2038-vfs' of git://git.kernel.org/pub/scm/linux/kernel/git/arnd/playground:
ext4: Reduce ext4 timestamp warnings
isofs: Initialize filesystem timestamp ranges
pstore: fs superblock limits
fs: omfs: Initialize filesystem timestamp ranges
fs: hpfs: Initialize filesystem timestamp ranges
fs: ceph: Initialize filesystem timestamp ranges
fs: sysv: Initialize filesystem timestamp ranges
fs: affs: Initialize filesystem timestamp ranges
fs: fat: Initialize filesystem timestamp ranges
fs: cifs: Initialize filesystem timestamp ranges
fs: nfs: Initialize filesystem timestamp ranges
ext4: Initialize timestamps limits
9p: Fill min and max timestamps in sb
fs: Fill in max and min timestamps in superblock
utimes: Clamp the timestamps before update
mount: Add mount warning for impending timestamp expiry
timestamp_truncate: Replace users of timespec64_trunc
vfs: Add timestamp_truncate() api
vfs: Add file timestamp range support
Diffstat (limited to 'fs/namespace.c')
-rw-r--r-- | fs/namespace.c | 33 |
1 files changed, 32 insertions, 1 deletions
diff --git a/fs/namespace.c b/fs/namespace.c index 227f7b343034..93c043245c46 100644 --- a/fs/namespace.c +++ b/fs/namespace.c @@ -2466,6 +2466,26 @@ static void set_mount_attributes(struct mount *mnt, unsigned int mnt_flags) unlock_mount_hash(); } +static void mnt_warn_timestamp_expiry(struct path *mountpoint, struct vfsmount *mnt) +{ + struct super_block *sb = mnt->mnt_sb; + + if (!__mnt_is_readonly(mnt) && + (ktime_get_real_seconds() + TIME_UPTIME_SEC_MAX > sb->s_time_max)) { + char *buf = (char *)__get_free_page(GFP_KERNEL); + char *mntpath = buf ? d_path(mountpoint, buf, PAGE_SIZE) : ERR_PTR(-ENOMEM); + struct tm tm; + + time64_to_tm(sb->s_time_max, 0, &tm); + + pr_warn("Mounted %s file system at %s supports timestamps until %04ld (0x%llx)\n", + sb->s_type->name, mntpath, + tm.tm_year+1900, (unsigned long long)sb->s_time_max); + + free_page((unsigned long)buf); + } +} + /* * Handle reconfiguration of the mountpoint only without alteration of the * superblock it refers to. This is triggered by specifying MS_REMOUNT|MS_BIND @@ -2491,6 +2511,9 @@ static int do_reconfigure_mnt(struct path *path, unsigned int mnt_flags) if (ret == 0) set_mount_attributes(mnt, mnt_flags); up_write(&sb->s_umount); + + mnt_warn_timestamp_expiry(path, &mnt->mnt); + return ret; } @@ -2531,6 +2554,9 @@ static int do_remount(struct path *path, int ms_flags, int sb_flags, } up_write(&sb->s_umount); } + + mnt_warn_timestamp_expiry(path, &mnt->mnt); + put_fs_context(fc); return err; } @@ -2739,8 +2765,13 @@ static int do_new_mount_fc(struct fs_context *fc, struct path *mountpoint, return PTR_ERR(mnt); error = do_add_mount(real_mount(mnt), mountpoint, mnt_flags); - if (error < 0) + if (error < 0) { mntput(mnt); + return error; + } + + mnt_warn_timestamp_expiry(mountpoint, mnt); + return error; } |