xref: /openbmc/linux/fs/ntfs/time.h (revision a1d312de)
1a1d312deSThomas Gleixner /* SPDX-License-Identifier: GPL-2.0-or-later */
21da177e4SLinus Torvalds /*
31da177e4SLinus Torvalds  * time.h - NTFS time conversion functions.  Part of the Linux-NTFS project.
41da177e4SLinus Torvalds  *
5d8ec785eSAnton Altaparmakov  * Copyright (c) 2001-2005 Anton Altaparmakov
61da177e4SLinus Torvalds  */
71da177e4SLinus Torvalds 
81da177e4SLinus Torvalds #ifndef _LINUX_NTFS_TIME_H
91da177e4SLinus Torvalds #define _LINUX_NTFS_TIME_H
101da177e4SLinus Torvalds 
111da177e4SLinus Torvalds #include <linux/time.h>		/* For current_kernel_time(). */
121da177e4SLinus Torvalds #include <asm/div64.h>		/* For do_div(). */
131da177e4SLinus Torvalds 
141da177e4SLinus Torvalds #include "endian.h"
151da177e4SLinus Torvalds 
161da177e4SLinus Torvalds #define NTFS_TIME_OFFSET ((s64)(369 * 365 + 89) * 24 * 3600 * 10000000)
171da177e4SLinus Torvalds 
181da177e4SLinus Torvalds /**
191da177e4SLinus Torvalds  * utc2ntfs - convert Linux UTC time to NTFS time
201da177e4SLinus Torvalds  * @ts:		Linux UTC time to convert to NTFS time
211da177e4SLinus Torvalds  *
221da177e4SLinus Torvalds  * Convert the Linux UTC time @ts to its corresponding NTFS time and return
231da177e4SLinus Torvalds  * that in little endian format.
241da177e4SLinus Torvalds  *
25bcf451ecSArnd Bergmann  * Linux stores time in a struct timespec64 consisting of a time64_t tv_sec
26bcf451ecSArnd Bergmann  * and a long tv_nsec where tv_sec is the number of 1-second intervals since
27bcf451ecSArnd Bergmann  * 1st January 1970, 00:00:00 UTC and tv_nsec is the number of 1-nano-second
28bcf451ecSArnd Bergmann  * intervals since the value of tv_sec.
291da177e4SLinus Torvalds  *
301da177e4SLinus Torvalds  * NTFS uses Microsoft's standard time format which is stored in a s64 and is
311da177e4SLinus Torvalds  * measured as the number of 100-nano-second intervals since 1st January 1601,
321da177e4SLinus Torvalds  * 00:00:00 UTC.
331da177e4SLinus Torvalds  */
utc2ntfs(const struct timespec64 ts)34bcf451ecSArnd Bergmann static inline sle64 utc2ntfs(const struct timespec64 ts)
351da177e4SLinus Torvalds {
361da177e4SLinus Torvalds 	/*
371da177e4SLinus Torvalds 	 * Convert the seconds to 100ns intervals, add the nano-seconds
381da177e4SLinus Torvalds 	 * converted to 100ns intervals, and then add the NTFS time offset.
391da177e4SLinus Torvalds 	 */
401da177e4SLinus Torvalds 	return cpu_to_sle64((s64)ts.tv_sec * 10000000 + ts.tv_nsec / 100 +
411da177e4SLinus Torvalds 			NTFS_TIME_OFFSET);
421da177e4SLinus Torvalds }
431da177e4SLinus Torvalds 
441da177e4SLinus Torvalds /**
451da177e4SLinus Torvalds  * get_current_ntfs_time - get the current time in little endian NTFS format
461da177e4SLinus Torvalds  *
471da177e4SLinus Torvalds  * Get the current time from the Linux kernel, convert it to its corresponding
481da177e4SLinus Torvalds  * NTFS time and return that in little endian format.
491da177e4SLinus Torvalds  */
get_current_ntfs_time(void)501da177e4SLinus Torvalds static inline sle64 get_current_ntfs_time(void)
511da177e4SLinus Torvalds {
52bcf451ecSArnd Bergmann 	struct timespec64 ts;
53bcf451ecSArnd Bergmann 
54bcf451ecSArnd Bergmann 	ktime_get_coarse_real_ts64(&ts);
55bcf451ecSArnd Bergmann 	return utc2ntfs(ts);
561da177e4SLinus Torvalds }
571da177e4SLinus Torvalds 
581da177e4SLinus Torvalds /**
591da177e4SLinus Torvalds  * ntfs2utc - convert NTFS time to Linux time
601da177e4SLinus Torvalds  * @time:	NTFS time (little endian) to convert to Linux UTC
611da177e4SLinus Torvalds  *
621da177e4SLinus Torvalds  * Convert the little endian NTFS time @time to its corresponding Linux UTC
631da177e4SLinus Torvalds  * time and return that in cpu format.
641da177e4SLinus Torvalds  *
65bcf451ecSArnd Bergmann  * Linux stores time in a struct timespec64 consisting of a time64_t tv_sec
66bcf451ecSArnd Bergmann  * and a long tv_nsec where tv_sec is the number of 1-second intervals since
67bcf451ecSArnd Bergmann  * 1st January 1970, 00:00:00 UTC and tv_nsec is the number of 1-nano-second
68bcf451ecSArnd Bergmann  * intervals since the value of tv_sec.
691da177e4SLinus Torvalds  *
701da177e4SLinus Torvalds  * NTFS uses Microsoft's standard time format which is stored in a s64 and is
711da177e4SLinus Torvalds  * measured as the number of 100 nano-second intervals since 1st January 1601,
721da177e4SLinus Torvalds  * 00:00:00 UTC.
731da177e4SLinus Torvalds  */
ntfs2utc(const sle64 time)74bcf451ecSArnd Bergmann static inline struct timespec64 ntfs2utc(const sle64 time)
751da177e4SLinus Torvalds {
76bcf451ecSArnd Bergmann 	struct timespec64 ts;
771da177e4SLinus Torvalds 
781da177e4SLinus Torvalds 	/* Subtract the NTFS time offset. */
79d8ec785eSAnton Altaparmakov 	u64 t = (u64)(sle64_to_cpu(time) - NTFS_TIME_OFFSET);
801da177e4SLinus Torvalds 	/*
811da177e4SLinus Torvalds 	 * Convert the time to 1-second intervals and the remainder to
821da177e4SLinus Torvalds 	 * 1-nano-second intervals.
831da177e4SLinus Torvalds 	 */
841da177e4SLinus Torvalds 	ts.tv_nsec = do_div(t, 10000000) * 100;
851da177e4SLinus Torvalds 	ts.tv_sec = t;
861da177e4SLinus Torvalds 	return ts;
871da177e4SLinus Torvalds }
881da177e4SLinus Torvalds 
891da177e4SLinus Torvalds #endif /* _LINUX_NTFS_TIME_H */
90