diff options
author | Arnd Bergmann | 2019-08-30 18:12:15 +0200 |
---|---|---|
committer | Arnd Bergmann | 2019-08-30 18:12:15 +0200 |
commit | 9d14545b05f9eed69fbd4af14b927a462324ea19 (patch) | |
tree | 7f17946e0cd3675828ae73c84feb4adad522f65d /fs/ext4 | |
parent | a55aa89aab90fae7c815b0551b07be37db359d76 (diff) | |
parent | 5ad32b3acded06183f40806f76b030c3143017bb (diff) |
Merge branch 'limits' of https://github.com/deepa-hub/vfs into y2038
The series is an update and a more complete version of the
previously posted series at
https://lore.kernel.org/linux-fsdevel/20180122020426.2988-1-deepa.kernel@gmail.com/
Thanks to Arnd Bergmann for doing a few preliminary reviews.
They helped me fix a few issues I had overlooked.
The limits (sometimes granularity also) for the filesystems updated here are according to the
following table:
File system Time type Start year Expiration year Granularity
cramfs fixed 0 0
romfs fixed 0 0
pstore ascii seconds (27 digit ascii) S64_MIN S64_MAX 1
coda INT64 S64_MIN S64_MAX 1
omfs 64-bit milliseconds 0 U64_MAX/ 1000 NSEC_PER_MSEC
befs unsigned 48-bit seconds 0 0xffffffffffff alloc_super
bfs unsigned 32-bit seconds 0 U32_MAX alloc_super
efs unsigned 32-bit seconds 0 U32_MAX alloc_super
ext2 signed 32-bit seconds S32_MIN S32_MAX alloc_super
ext3 signed 32-bit seconds S32_MIN S32_MAX alloc_super
ext4 (old) signed 32-bit seconds S32_MIN S32_MAX alloc_super
ext4 (extra) 34-bit seconds, 30-bit ns S32_MIN 0x37fffffff 1
freevxfs u32 secs/usecs 0 U32_MAX alloc_super
jffs2 unsigned 32-bit seconds 0 U32_MAX alloc_super
jfs unsigned 32-bit seconds/ns 0 U32_MAX 1
minix unsigned 32-bit seconds 0 U32_MAX alloc_super
qnx4 unsigned 32-bit seconds 0 U32_MAX alloc_super
qnx6 unsigned 32-bit seconds 0 U32_MAX alloc_super
reiserfs unsigned 32-bit seconds 0 U32_MAX alloc_super
squashfs unsigned 32-bit seconds 0 U32_MAX alloc_super
ufs1 signed 32-bit seconds S32_MIN S32_MAX NSEC_PER_SEC
ufs2 signed 64-bit seconds/u32 ns S64_MIN S64_MAX 1
xfs signed 32-bit seconds/ns S32_MIN S32_MAX 1
ceph unsigned 32-bit second/ns 0 U32_MAX 1000
sysv unsigned 32-bit seconds 0 U32_MAX alloc_super
affs u32 day, min, ticks 1978 u32_max days NSEC_PER_SEC
nfsv2 unsigned 32-bit seconds/ns 0 U32_MAX 1
nfsv3 unsigned 32-bit seconds/ns 0 U32_MAX 1000
nfsv4 u64 seconds/u32 ns S64_MIN S64_MAX 1000
isofs u8 year since 1900 (fixable) 1900 2155 alloc_super
hpfs unsigned 32-bit seconds 1970 2106 alloc_super
fat 7-bit years, 2s resolution 1980 2107
cifs (smb) 7-bit years 1980 2107
cifs (modern) 64-bit 100ns since 1601 1601 30828
9p (9P2000) unsigned 32-bit seconds 1970 2106
9p (9P2000.L) signed 64-bit seconds, ns 1970 S64_MAX
Granularity column filled in by the alloc_super() in the above table indicates that
the granularity is NSEC_PER_SEC.
Note that anything not mentioned above still has the default limits
S64_MIN..S64_MAX.
The patches in the series are as structured below:
1. Add vfs support to maintain the limits per filesystem.
2. Add a new timestamp_truncate() api for clamping timestamps
according to the filesystem limits.
3. Add a warning for mount syscall to indicate the impending
expiry of timestamps.
4. Modify utimes to clamp the timestamps.
5. Fill in limits for filesystems.
A test for checking file system timestamp limits has been posted
at https://www.spinics.net/lists/fstests/msg12262.html
Changes since v8:
* Dropped orangefs patch because of ongoing discussion
* Dropped adfs patch because a conflict with Russell's ADFS series
Changes since v7:
* Dropped fat modifications from timespec_truncate patch
* Leverage timestamp_truncate function in utimes
* Added a fix for pstore ramoops timestamps
* Added ext4 warning for inodes without room for extended timestamps.
* Made mount warning more human readable
Changes since v6:
* No change in mount behavior because of expiry of timestamps.
* Included limits for more filesystems.
Changes since v5:
* Dropped y2038-specific changes
Changes since v4:
* Added documentation for boot param
Changes since v3:
* Remove redundant initializations in libfs.c
* Change early_param to __setup similar to other root mount options.
* Fix documentation warning
Changes since v2:
* Introduce early boot param override for checks.
* Drop afs patch for timestamp limits.
Changes since v1:
* return EROFS on mount errors
* fix mtime copy/paste error in utimes
* 'limits' of https://github.com/deepa-hub/vfs:
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
Link: https://lore.kernel.org/lkml/20190730014924.2193-1-deepa.kernel@gmail.com/
Link: https://lore.kernel.org/lkml/20190830154744.4868-1-deepa.kernel@gmail.com/
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Diffstat (limited to 'fs/ext4')
-rw-r--r-- | fs/ext4/ext4.h | 10 | ||||
-rw-r--r-- | fs/ext4/super.c | 17 |
2 files changed, 24 insertions, 3 deletions
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h index bf660aa7a9e0..9e3ae3be3de9 100644 --- a/fs/ext4/ext4.h +++ b/fs/ext4/ext4.h @@ -828,11 +828,15 @@ static inline void ext4_decode_extra_time(struct timespec64 *time, #define EXT4_INODE_SET_XTIME(xtime, inode, raw_inode) \ do { \ - (raw_inode)->xtime = cpu_to_le32((inode)->xtime.tv_sec); \ if (EXT4_FITS_IN_INODE(raw_inode, EXT4_I(inode), xtime ## _extra)) {\ + (raw_inode)->xtime = cpu_to_le32((inode)->xtime.tv_sec); \ (raw_inode)->xtime ## _extra = \ ext4_encode_extra_time(&(inode)->xtime); \ } \ + else {\ + (raw_inode)->xtime = cpu_to_le32(clamp_t(int32_t, (inode)->xtime.tv_sec, S32_MIN, S32_MAX)); \ + ext4_warning_inode(inode, "inode does not support timestamps beyond 2038"); \ + } \ } while (0) #define EXT4_EINODE_SET_XTIME(xtime, einode, raw_inode) \ @@ -1632,6 +1636,10 @@ static inline void ext4_clear_state_flags(struct ext4_inode_info *ei) #define EXT4_GOOD_OLD_INODE_SIZE 128 +#define EXT4_EXTRA_TIMESTAMP_MAX (((s64)1 << 34) - 1 + S32_MIN) +#define EXT4_NON_EXTRA_TIMESTAMP_MAX S32_MAX +#define EXT4_TIMESTAMP_MIN S32_MIN + /* * Feature set definitions */ diff --git a/fs/ext4/super.c b/fs/ext4/super.c index 4079605d437a..3ea2d60f33aa 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -4035,8 +4035,21 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) sbi->s_inode_size); goto failed_mount; } - if (sbi->s_inode_size > EXT4_GOOD_OLD_INODE_SIZE) - sb->s_time_gran = 1 << (EXT4_EPOCH_BITS - 2); + /* + * i_atime_extra is the last extra field available for [acm]times in + * struct ext4_inode. Checking for that field should suffice to ensure + * we have extra space for all three. + */ + if (sbi->s_inode_size >= offsetof(struct ext4_inode, i_atime_extra) + + sizeof(((struct ext4_inode *)0)->i_atime_extra)) { + sb->s_time_gran = 1; + sb->s_time_max = EXT4_EXTRA_TIMESTAMP_MAX; + } else { + sb->s_time_gran = NSEC_PER_SEC; + sb->s_time_max = EXT4_NON_EXTRA_TIMESTAMP_MAX; + } + + sb->s_time_min = EXT4_TIMESTAMP_MIN; } sbi->s_desc_size = le16_to_cpu(es->s_desc_size); |