diff options
Diffstat (limited to 'fs')
-rw-r--r-- | fs/ext4/ext4.h | 51 |
1 files changed, 44 insertions, 7 deletions
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h index 750063f7a50c..cc7ca4e87144 100644 --- a/fs/ext4/ext4.h +++ b/fs/ext4/ext4.h | |||
@@ -26,6 +26,7 @@ | |||
26 | #include <linux/seqlock.h> | 26 | #include <linux/seqlock.h> |
27 | #include <linux/mutex.h> | 27 | #include <linux/mutex.h> |
28 | #include <linux/timer.h> | 28 | #include <linux/timer.h> |
29 | #include <linux/version.h> | ||
29 | #include <linux/wait.h> | 30 | #include <linux/wait.h> |
30 | #include <linux/blockgroup_lock.h> | 31 | #include <linux/blockgroup_lock.h> |
31 | #include <linux/percpu_counter.h> | 32 | #include <linux/percpu_counter.h> |
@@ -727,19 +728,55 @@ struct move_extent { | |||
727 | <= (EXT4_GOOD_OLD_INODE_SIZE + \ | 728 | <= (EXT4_GOOD_OLD_INODE_SIZE + \ |
728 | (einode)->i_extra_isize)) \ | 729 | (einode)->i_extra_isize)) \ |
729 | 730 | ||
731 | /* | ||
732 | * We use an encoding that preserves the times for extra epoch "00": | ||
733 | * | ||
734 | * extra msb of adjust for signed | ||
735 | * epoch 32-bit 32-bit tv_sec to | ||
736 | * bits time decoded 64-bit tv_sec 64-bit tv_sec valid time range | ||
737 | * 0 0 1 -0x80000000..-0x00000001 0x000000000 1901-12-13..1969-12-31 | ||
738 | * 0 0 0 0x000000000..0x07fffffff 0x000000000 1970-01-01..2038-01-19 | ||
739 | * 0 1 1 0x080000000..0x0ffffffff 0x100000000 2038-01-19..2106-02-07 | ||
740 | * 0 1 0 0x100000000..0x17fffffff 0x100000000 2106-02-07..2174-02-25 | ||
741 | * 1 0 1 0x180000000..0x1ffffffff 0x200000000 2174-02-25..2242-03-16 | ||
742 | * 1 0 0 0x200000000..0x27fffffff 0x200000000 2242-03-16..2310-04-04 | ||
743 | * 1 1 1 0x280000000..0x2ffffffff 0x300000000 2310-04-04..2378-04-22 | ||
744 | * 1 1 0 0x300000000..0x37fffffff 0x300000000 2378-04-22..2446-05-10 | ||
745 | * | ||
746 | * Note that previous versions of the kernel on 64-bit systems would | ||
747 | * incorrectly use extra epoch bits 1,1 for dates between 1901 and | ||
748 | * 1970. e2fsck will correct this, assuming that it is run on the | ||
749 | * affected filesystem before 2242. | ||
750 | */ | ||
751 | |||
730 | static inline __le32 ext4_encode_extra_time(struct timespec *time) | 752 | static inline __le32 ext4_encode_extra_time(struct timespec *time) |
731 | { | 753 | { |
732 | return cpu_to_le32((sizeof(time->tv_sec) > 4 ? | 754 | u32 extra = sizeof(time->tv_sec) > 4 ? |
733 | (time->tv_sec >> 32) & EXT4_EPOCH_MASK : 0) | | 755 | ((time->tv_sec - (s32)time->tv_sec) >> 32) & EXT4_EPOCH_MASK : 0; |
734 | ((time->tv_nsec << EXT4_EPOCH_BITS) & EXT4_NSEC_MASK)); | 756 | return cpu_to_le32(extra | (time->tv_nsec << EXT4_EPOCH_BITS)); |
735 | } | 757 | } |
736 | 758 | ||
737 | static inline void ext4_decode_extra_time(struct timespec *time, __le32 extra) | 759 | static inline void ext4_decode_extra_time(struct timespec *time, __le32 extra) |
738 | { | 760 | { |
739 | if (sizeof(time->tv_sec) > 4) | 761 | if (unlikely(sizeof(time->tv_sec) > 4 && |
740 | time->tv_sec |= (__u64)(le32_to_cpu(extra) & EXT4_EPOCH_MASK) | 762 | (extra & cpu_to_le32(EXT4_EPOCH_MASK)))) { |
741 | << 32; | 763 | #if LINUX_VERSION_CODE < KERNEL_VERSION(4,20,0) |
742 | time->tv_nsec = (le32_to_cpu(extra) & EXT4_NSEC_MASK) >> EXT4_EPOCH_BITS; | 764 | /* Handle legacy encoding of pre-1970 dates with epoch |
765 | * bits 1,1. We assume that by kernel version 4.20, | ||
766 | * everyone will have run fsck over the affected | ||
767 | * filesystems to correct the problem. (This | ||
768 | * backwards compatibility may be removed before this | ||
769 | * time, at the discretion of the ext4 developers.) | ||
770 | */ | ||
771 | u64 extra_bits = le32_to_cpu(extra) & EXT4_EPOCH_MASK; | ||
772 | if (extra_bits == 3 && ((time->tv_sec) & 0x80000000) != 0) | ||
773 | extra_bits = 0; | ||
774 | time->tv_sec += extra_bits << 32; | ||
775 | #else | ||
776 | time->tv_sec += (u64)(le32_to_cpu(extra) & EXT4_EPOCH_MASK) << 32; | ||
777 | #endif | ||
778 | } | ||
779 | time->tv_nsec = (le32_to_cpu(extra) & EXT4_NSEC_MASK) >> EXT4_EPOCH_BITS; | ||
743 | } | 780 | } |
744 | 781 | ||
745 | #define EXT4_INODE_SET_XTIME(xtime, inode, raw_inode) \ | 782 | #define EXT4_INODE_SET_XTIME(xtime, inode, raw_inode) \ |