1 /* SPDX-License-Identifier: GPL-2.0-or-later */ 2 /* 3 * NTFS time conversion functions. 4 * 5 * Copyright (c) 2001-2005 Anton Altaparmakov 6 */ 7 8 #ifndef _LINUX_NTFS_TIME_H 9 #define _LINUX_NTFS_TIME_H 10 11 #include <linux/time.h> 12 #include <asm/div64.h> /* For do_div(). */ 13 14 #define NTFS_TIME_OFFSET ((s64)(369 * 365 + 89) * 24 * 3600) 15 16 /* 17 * utc2ntfs - convert Linux UTC time to NTFS time 18 * @ts: Linux UTC time to convert to NTFS time 19 * 20 * Convert the Linux UTC time @ts to its corresponding NTFS time and return 21 * that in little endian format. 22 * 23 * Linux stores time in a struct timespec64 consisting of a time64_t tv_sec 24 * and a long tv_nsec where tv_sec is the number of 1-second intervals since 25 * 1st January 1970, 00:00:00 UTC and tv_nsec is the number of 1-nano-second 26 * intervals since the value of tv_sec. 27 * 28 * NTFS uses Microsoft's standard time format which is stored in a s64 and is 29 * measured as the number of 100-nano-second intervals since 1st January 1601, 30 * 00:00:00 UTC. 31 */ 32 static inline __le64 utc2ntfs(const struct timespec64 ts) 33 { 34 /* 35 * Convert the seconds to 100ns intervals, add the nano-seconds 36 * converted to 100ns intervals, and then add the NTFS time offset. 37 */ 38 return cpu_to_le64((u64)(ts.tv_sec + NTFS_TIME_OFFSET) * 10000000 + 39 ts.tv_nsec / 100); 40 } 41 42 /* 43 * get_current_ntfs_time - get the current time in little endian NTFS format 44 * 45 * Get the current time from the Linux kernel, convert it to its corresponding 46 * NTFS time and return that in little endian format. 47 */ 48 static inline __le64 get_current_ntfs_time(void) 49 { 50 struct timespec64 ts; 51 52 ktime_get_coarse_real_ts64(&ts); 53 return utc2ntfs(ts); 54 } 55 56 /* 57 * ntfs2utc - convert NTFS time to Linux time 58 * @time: NTFS time (little endian) to convert to Linux UTC 59 * 60 * Convert the little endian NTFS time @time to its corresponding Linux UTC 61 * time and return that in cpu format. 62 * 63 * Linux stores time in a struct timespec64 consisting of a time64_t tv_sec 64 * and a long tv_nsec where tv_sec is the number of 1-second intervals since 65 * 1st January 1970, 00:00:00 UTC and tv_nsec is the number of 1-nano-second 66 * intervals since the value of tv_sec. 67 * 68 * NTFS uses Microsoft's standard time format which is stored in a s64 and is 69 * measured as the number of 100 nano-second intervals since 1st January 1601, 70 * 00:00:00 UTC. 71 */ 72 static inline struct timespec64 ntfs2utc(const __le64 time) 73 { 74 struct timespec64 ts; 75 s32 t32; 76 77 /* Subtract the NTFS time offset. */ 78 s64 t = le64_to_cpu(time) - NTFS_TIME_OFFSET * 10000000; 79 /* 80 * Convert the time to 1-second intervals and the remainder to 81 * 1-nano-second intervals. 82 */ 83 ts.tv_sec = div_s64_rem(t, 10000000, &t32); 84 ts.tv_nsec = t32 * 100; 85 return ts; 86 } 87 #endif /* _LINUX_NTFS_TIME_H */ 88