Commit 2eb323cb authored by Anton Altaparmakov's avatar Anton Altaparmakov

NTFS: - Modify fs/ntfs/time.c::ntfs2utc(), get_current_ntfs_time(), and

        utc2ntfs() to work with struct timespec instead of time_t on the
        Linux UTC time side thus preserving the full precision of the NTFS
        time and only loosing up to 99 nano-seconds in the Linux UTC time.
      - Move fs/ntfs/time.c to fs/ntfs/time.h and make the time functions
        static inline.
parent d3497ef6
...@@ -22,6 +22,12 @@ ToDo: ...@@ -22,6 +22,12 @@ ToDo:
2.1.8 - WIP. 2.1.8 - WIP.
- Use get_bh() instead of manual atomic_inc() in fs/ntfs/compress.c. - Use get_bh() instead of manual atomic_inc() in fs/ntfs/compress.c.
- Modify fs/ntfs/time.c::ntfs2utc(), get_current_ntfs_time(), and
utc2ntfs() to work with struct timespec instead of time_t on the
Linux UTC time side thus preserving the full precision of the NTFS
time and only loosing up to 99 nano-seconds in the Linux UTC time.
- Move fs/ntfs/time.c to fs/ntfs/time.h and make the time functions
static inline.
2.1.7 - Enable NFS exporting of mounted NTFS volumes. 2.1.7 - Enable NFS exporting of mounted NTFS volumes.
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
obj-$(CONFIG_NTFS_FS) += ntfs.o obj-$(CONFIG_NTFS_FS) += ntfs.o
ntfs-objs := aops.o attrib.o compress.o debug.o dir.o file.o inode.o mft.o \ ntfs-objs := aops.o attrib.o compress.o debug.o dir.o file.o inode.o mft.o \
mst.o namei.o super.o sysctl.o time.o unistr.o upcase.o mst.o namei.o super.o sysctl.o unistr.o upcase.o
EXTRA_CFLAGS = -DNTFS_VERSION=\"2.1.8-WIP\" EXTRA_CFLAGS = -DNTFS_VERSION=\"2.1.8-WIP\"
......
...@@ -29,6 +29,7 @@ ...@@ -29,6 +29,7 @@
#include "dir.h" #include "dir.h"
#include "inode.h" #include "inode.h"
#include "attrib.h" #include "attrib.h"
#include "time.h"
/** /**
* ntfs_attr - ntfs in memory attribute structure * ntfs_attr - ntfs in memory attribute structure
...@@ -590,21 +591,18 @@ static int ntfs_read_locked_inode(struct inode *vi) ...@@ -590,21 +591,18 @@ static int ntfs_read_locked_inode(struct inode *vi)
* mtime is the last change of the data within the file. Not changed * mtime is the last change of the data within the file. Not changed
* when only metadata is changed, e.g. a rename doesn't affect mtime. * when only metadata is changed, e.g. a rename doesn't affect mtime.
*/ */
vi->i_mtime.tv_sec = ntfs2utc(si->last_data_change_time); vi->i_mtime = ntfs2utc(si->last_data_change_time);
vi->i_mtime.tv_nsec = 0;
/* /*
* ctime is the last change of the metadata of the file. This obviously * ctime is the last change of the metadata of the file. This obviously
* always changes, when mtime is changed. ctime can be changed on its * always changes, when mtime is changed. ctime can be changed on its
* own, mtime is then not changed, e.g. when a file is renamed. * own, mtime is then not changed, e.g. when a file is renamed.
*/ */
vi->i_ctime.tv_sec = ntfs2utc(si->last_mft_change_time); vi->i_ctime = ntfs2utc(si->last_mft_change_time);
vi->i_ctime.tv_nsec = 0;
/* /*
* Last access to the data within the file. Not changed during a rename * Last access to the data within the file. Not changed during a rename
* for example but changed whenever the file is written to. * for example but changed whenever the file is written to.
*/ */
vi->i_atime.tv_sec = ntfs2utc(si->last_access_time); vi->i_atime = ntfs2utc(si->last_access_time);
vi->i_atime.tv_nsec = 0;
/* Find the attribute list attribute if present. */ /* Find the attribute list attribute if present. */
reinit_attr_search_ctx(ctx); reinit_attr_search_ctx(ctx);
...@@ -2029,4 +2027,3 @@ int ntfs_setattr(struct dentry *dentry, struct iattr *attr) ...@@ -2029,4 +2027,3 @@ int ntfs_setattr(struct dentry *dentry, struct iattr *attr)
} }
#endif #endif
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* ntfs.h - Defines for NTFS Linux kernel driver. Part of the Linux-NTFS * ntfs.h - Defines for NTFS Linux kernel driver. Part of the Linux-NTFS
* project. * project.
* *
* Copyright (c) 2001,2002 Anton Altaparmakov. * Copyright (c) 2001-2004 Anton Altaparmakov.
* Copyright (C) 2002 Richard Russon. * Copyright (C) 2002 Richard Russon.
* *
* This program/include file is free software; you can redistribute it and/or * This program/include file is free software; you can redistribute it and/or
...@@ -180,11 +180,6 @@ extern int post_read_mst_fixup(NTFS_RECORD *b, const u32 size); ...@@ -180,11 +180,6 @@ extern int post_read_mst_fixup(NTFS_RECORD *b, const u32 size);
extern int pre_write_mst_fixup(NTFS_RECORD *b, const u32 size); extern int pre_write_mst_fixup(NTFS_RECORD *b, const u32 size);
extern void post_write_mst_fixup(NTFS_RECORD *b); extern void post_write_mst_fixup(NTFS_RECORD *b);
/* From fs/ntfs/time.c */
extern inline s64 utc2ntfs(const time_t time);
extern inline s64 get_current_ntfs_time(void);
extern time_t ntfs2utc(const s64 time);
/* From fs/ntfs/unistr.c */ /* From fs/ntfs/unistr.c */
extern BOOL ntfs_are_names_equal(const uchar_t *s1, size_t s1_len, extern BOOL ntfs_are_names_equal(const uchar_t *s1, size_t s1_len,
const uchar_t *s2, size_t s2_len, const uchar_t *s2, size_t s2_len,
......
/* /*
* time.c - NTFS time conversion functions. Part of the Linux-NTFS project. * time.h - NTFS time conversion functions. Part of the Linux-NTFS project.
* *
* Copyright (c) 2001 Anton Altaparmakov. * Copyright (c) 2001-2004 Anton Altaparmakov.
* *
* This program/include file is free software; you can redistribute it and/or * This program/include file is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as published * modify it under the terms of the GNU General Public License as published
...@@ -19,31 +19,40 @@ ...@@ -19,31 +19,40 @@
* Foundation,Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * Foundation,Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/ */
#include <linux/sched.h> /* For CURRENT_TIME. */ #ifndef _LINUX_NTFS_TIME_H
#define _LINUX_NTFS_TIME_H
#include <linux/time.h> /* For current_kernel_time(). */
#include <asm/div64.h> /* For do_div(). */ #include <asm/div64.h> /* For do_div(). */
#include "ntfs.h" #include "endian.h"
#define NTFS_TIME_OFFSET ((s64)(369 * 365 + 89) * 24 * 3600 * 10000000) #define NTFS_TIME_OFFSET ((s64)(369 * 365 + 89) * 24 * 3600 * 10000000)
/** /**
* utc2ntfs - convert Linux time to NTFS time * utc2ntfs - convert Linux UTC time to NTFS time
* @time: Linux time to convert to NTFS * @ts: Linux UTC time to convert to NTFS time
* *
* Convert the Linux time @time to its corresponding NTFS time and return that * Convert the Linux UTC time @ts to its corresponding NTFS time and return
* in little endian format. * that in little endian format.
* *
* Linux stores time in a long at present and measures it as the number of * Linux stores time in a struct timespec consisting of a time_t (long at
* 1-second intervals since 1st January 1970, 00:00:00 UTC. * present) tv_sec and a long tv_nsec where tv_sec is the number of 1-second
* intervals since 1st January 1970, 00:00:00 UTC and tv_nsec is the number of
* 1-nano-second intervals since the value of tv_sec.
* *
* NTFS uses Microsoft's standard time format which is stored in a s64 and is * NTFS uses Microsoft's standard time format which is stored in a s64 and is
* measured as the number of 100 nano-second intervals since 1st January 1601, * measured as the number of 100-nano-second intervals since 1st January 1601,
* 00:00:00 UTC. * 00:00:00 UTC.
*/ */
inline s64 utc2ntfs(const time_t time) static inline s64 utc2ntfs(const struct timespec ts)
{ {
/* Convert to 100ns intervals and then add the NTFS time offset. */ /*
return cpu_to_sle64((s64)time * 10000000 + NTFS_TIME_OFFSET); * Convert the seconds to 100ns intervals, add the nano-seconds
* converted to 100ns intervals, and then add the NTFS time offset.
*/
return cpu_to_sle64((s64)ts.tv_sec * 10000000 + ts.tv_nsec / 100 +
NTFS_TIME_OFFSET);
} }
/** /**
...@@ -52,31 +61,40 @@ inline s64 utc2ntfs(const time_t time) ...@@ -52,31 +61,40 @@ inline s64 utc2ntfs(const time_t time)
* Get the current time from the Linux kernel, convert it to its corresponding * Get the current time from the Linux kernel, convert it to its corresponding
* NTFS time and return that in little endian format. * NTFS time and return that in little endian format.
*/ */
inline s64 get_current_ntfs_time(void) static inline s64 get_current_ntfs_time(void)
{ {
/* ignores leap second */ return utc2ntfs(current_kernel_time());
return utc2ntfs(get_seconds()) + xtime.tv_nsec/1000;
} }
/** /**
* ntfs2utc - convert NTFS time to Linux time * ntfs2utc - convert NTFS time to Linux time
* @time: NTFS time (little endian) to convert to Linux * @time: NTFS time (little endian) to convert to Linux UTC
* *
* Convert the little endian NTFS time @time to its corresponding Linux time * Convert the little endian NTFS time @time to its corresponding Linux UTC
* and return that in cpu format. * time and return that in cpu format.
* *
* Linux stores time in a long at present and measures it as the number of * Linux stores time in a struct timespec consisting of a time_t (long at
* 1-second intervals since 1st January 1970, 00:00:00 UTC. * present) tv_sec and a long tv_nsec where tv_sec is the number of 1-second
* intervals since 1st January 1970, 00:00:00 UTC and tv_nsec is the number of
* 1-nano-second intervals since the value of tv_sec.
* *
* NTFS uses Microsoft's standard time format which is stored in a s64 and is * NTFS uses Microsoft's standard time format which is stored in a s64 and is
* measured as the number of 100 nano-second intervals since 1st January 1601, * measured as the number of 100 nano-second intervals since 1st January 1601,
* 00:00:00 UTC. * 00:00:00 UTC.
*/ */
inline time_t ntfs2utc(const s64 time) static inline struct timespec ntfs2utc(const s64 time)
{ {
/* Subtract the NTFS time offset, then convert to 1s intervals. */ struct timespec ts;
/* Subtract the NTFS time offset. */
s64 t = sle64_to_cpu(time) - NTFS_TIME_OFFSET; s64 t = sle64_to_cpu(time) - NTFS_TIME_OFFSET;
do_div(t, 10000000); /*
return (time_t)t; * Convert the time to 1-second intervals and the remainder to
* 1-nano-second intervals.
*/
ts.tv_nsec = do_div(t, 10000000) * 100;
ts.tv_sec = t;
return ts;
} }
#endif /* _LINUX_NTFS_TIME_H */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment