* [PATCH V5 0/4] fat: timestamp updates
@ 2018-10-01 3:33 Frank Sorenson
2018-10-01 3:33 ` [PATCH V5 1/4] fat: create a function to calculate the timezone offest Frank Sorenson
` (4 more replies)
0 siblings, 5 replies; 6+ messages in thread
From: Frank Sorenson @ 2018-10-01 3:33 UTC (permalink / raw)
To: linux-fsdevel; +Cc: hirofumi
fat/msdos timestamps are stored on-disk with several different
granularities, some of them lower resolution than timespec64_trunc()
can provide. In addition, they are only truncated as they are
written to disk, so the timestamps in-memory for new or modified
files/directories may be different from the same timestamps after
a remount, as the now-truncated times are re-read from the on-disk
format.
These patches allow finer granularity for the timestamps where
possible and add fat-specific ->update_time inode operation and
fat_truncate_time functions to truncate each timestamp correctly,
giving consistent times across remounts.
V5 changes
corrected some patch breakage and style issues
V4 changes
corrected to use fat_truncate_time() and keep mark_inode_dirty()
set s_time_gran to 1ns unconditionally
add i_version support to update_time()
fix atime bug with localtime
Frank Sorenson (4):
fat: create a function to calculate the timezone offest
fat: add functions to update and truncate timestamps appropriately
fat: change timestamp updates to use fat_truncate_time
fat: truncate inode timestamp updates in setattr
fs/fat/dir.c | 2 +-
fs/fat/fat.h | 4 +++
fs/fat/file.c | 17 ++++++++--
fs/fat/inode.c | 9 ++++--
fs/fat/misc.c | 91 ++++++++++++++++++++++++++++++++++++++++++++++++----
fs/fat/namei_msdos.c | 17 +++++-----
fs/fat/namei_vfat.c | 15 +++++----
7 files changed, 128 insertions(+), 27 deletions(-)
--
2.13.6
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH V5 1/4] fat: create a function to calculate the timezone offest
2018-10-01 3:33 [PATCH V5 0/4] fat: timestamp updates Frank Sorenson
@ 2018-10-01 3:33 ` Frank Sorenson
2018-10-01 3:33 ` [PATCH V5 2/4] fat: add functions to update and truncate timestamps appropriately Frank Sorenson
` (3 subsequent siblings)
4 siblings, 0 replies; 6+ messages in thread
From: Frank Sorenson @ 2018-10-01 3:33 UTC (permalink / raw)
To: linux-fsdevel; +Cc: hirofumi
Move the calculation of the number of seconds in the timezone
offset to a common function.
Signed-off-by: Frank Sorenson <sorenson@redhat.com>
---
fs/fat/misc.c | 16 +++++++++-------
1 file changed, 9 insertions(+), 7 deletions(-)
diff --git a/fs/fat/misc.c b/fs/fat/misc.c
index 573836dcaefc..2eca073fe785 100644
--- a/fs/fat/misc.c
+++ b/fs/fat/misc.c
@@ -185,6 +185,13 @@ static long days_in_year[] = {
0, 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 0, 0, 0,
};
+static inline int fat_tz_offset(struct msdos_sb_info *sbi)
+{
+ return (sbi->options.tz_set ?
+ -sbi->options.time_offset :
+ sys_tz.tz_minuteswest) * SECS_PER_MIN;
+}
+
/* Convert a FAT time/date pair to a UNIX date (seconds since 1 1 70). */
void fat_time_fat2unix(struct msdos_sb_info *sbi, struct timespec64 *ts,
__le16 __time, __le16 __date, u8 time_cs)
@@ -210,10 +217,7 @@ void fat_time_fat2unix(struct msdos_sb_info *sbi, struct timespec64 *ts,
+ days_in_year[month] + day
+ DAYS_DELTA) * SECS_PER_DAY;
- if (!sbi->options.tz_set)
- second += sys_tz.tz_minuteswest * SECS_PER_MIN;
- else
- second -= sbi->options.time_offset * SECS_PER_MIN;
+ second += fat_tz_offset(sbi);
if (time_cs) {
ts->tv_sec = second + (time_cs / 100);
@@ -229,9 +233,7 @@ void fat_time_unix2fat(struct msdos_sb_info *sbi, struct timespec64 *ts,
__le16 *time, __le16 *date, u8 *time_cs)
{
struct tm tm;
- time64_to_tm(ts->tv_sec,
- (sbi->options.tz_set ? sbi->options.time_offset :
- -sys_tz.tz_minuteswest) * SECS_PER_MIN, &tm);
+ time64_to_tm(ts->tv_sec, -fat_tz_offset(sbi), &tm);
/* FAT can only support year between 1980 to 2107 */
if (tm.tm_year < 1980 - 1900) {
--
2.13.6
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH V5 2/4] fat: add functions to update and truncate timestamps appropriately
2018-10-01 3:33 [PATCH V5 0/4] fat: timestamp updates Frank Sorenson
2018-10-01 3:33 ` [PATCH V5 1/4] fat: create a function to calculate the timezone offest Frank Sorenson
@ 2018-10-01 3:33 ` Frank Sorenson
2018-10-01 3:33 ` [PATCH V5 3/4] fat: change timestamp updates to use fat_truncate_time Frank Sorenson
` (2 subsequent siblings)
4 siblings, 0 replies; 6+ messages in thread
From: Frank Sorenson @ 2018-10-01 3:33 UTC (permalink / raw)
To: linux-fsdevel; +Cc: hirofumi
Add the fat-specific inode_operation ->update_time() and
fat_truncate_time() function to truncate the inode timestamps
from 1 nanosecond to the appropriate granularity.
Signed-off-by: Frank Sorenson <sorenson@redhat.com>
---
fs/fat/fat.h | 4 +++
fs/fat/file.c | 1 +
fs/fat/inode.c | 5 ++++
fs/fat/misc.c | 75 ++++++++++++++++++++++++++++++++++++++++++++++++++++
fs/fat/namei_msdos.c | 1 +
fs/fat/namei_vfat.c | 1 +
6 files changed, 87 insertions(+)
diff --git a/fs/fat/fat.h b/fs/fat/fat.h
index 9d7d2d5da28b..4e1b2f6df5e6 100644
--- a/fs/fat/fat.h
+++ b/fs/fat/fat.h
@@ -416,6 +416,10 @@ extern void fat_time_fat2unix(struct msdos_sb_info *sbi, struct timespec64 *ts,
__le16 __time, __le16 __date, u8 time_cs);
extern void fat_time_unix2fat(struct msdos_sb_info *sbi, struct timespec64 *ts,
__le16 *time, __le16 *date, u8 *time_cs);
+extern int fat_truncate_time(struct inode *inode, struct timespec64 *now,
+ int flags);
+extern int fat_update_time(struct inode *inode, struct timespec64 *now,
+ int flags);
extern int fat_sync_bhs(struct buffer_head **bhs, int nr_bhs);
int fat_cache_init(void);
diff --git a/fs/fat/file.c b/fs/fat/file.c
index 4f3d72fb1e60..19b6b0566411 100644
--- a/fs/fat/file.c
+++ b/fs/fat/file.c
@@ -552,4 +552,5 @@ EXPORT_SYMBOL_GPL(fat_setattr);
const struct inode_operations fat_file_inode_operations = {
.setattr = fat_setattr,
.getattr = fat_getattr,
+ .update_time = fat_update_time,
};
diff --git a/fs/fat/inode.c b/fs/fat/inode.c
index d6b81e31f9f5..3bf60f19b6d3 100644
--- a/fs/fat/inode.c
+++ b/fs/fat/inode.c
@@ -1626,6 +1626,11 @@ int fat_fill_super(struct super_block *sb, void *data, int silent, int isvfat,
sb->s_magic = MSDOS_SUPER_MAGIC;
sb->s_op = &fat_sops;
sb->s_export_op = &fat_export_ops;
+ /*
+ * fat timestamps are complex and truncated by fat itself, so
+ * we set 1 here to be fast
+ */
+ sb->s_time_gran = 1;
mutex_init(&sbi->nfs_build_inode_lock);
ratelimit_state_init(&sbi->ratelimit, DEFAULT_RATELIMIT_INTERVAL,
DEFAULT_RATELIMIT_BURST);
diff --git a/fs/fat/misc.c b/fs/fat/misc.c
index 2eca073fe785..fce0a76f3f1e 100644
--- a/fs/fat/misc.c
+++ b/fs/fat/misc.c
@@ -7,6 +7,7 @@
*/
#include "fat.h"
+#include <linux/iversion.h>
/*
* fat_fs_error reports a file system problem that might indicate fa data
@@ -265,6 +266,80 @@ void fat_time_unix2fat(struct msdos_sb_info *sbi, struct timespec64 *ts,
}
EXPORT_SYMBOL_GPL(fat_time_unix2fat);
+static inline struct timespec64 fat_timespec64_trunc_2secs(struct timespec64 ts)
+{
+ return (struct timespec64){ ts.tv_sec & ~1ULL, 0 };
+}
+/*
+ * truncate the various times with appropriate granularity:
+ * root inode:
+ * all times always 0
+ * all other inodes:
+ * mtime - 2 seconds
+ * ctime
+ * msdos - 2 seconds
+ * vfat - 10 milliseconds
+ * atime - 24 hours (00:00:00 in local timezone)
+ */
+int fat_truncate_time(struct inode *inode, struct timespec64 *now, int flags)
+{
+ struct msdos_sb_info *sbi = MSDOS_SB(inode->i_sb);
+ struct timespec64 ts;
+
+ if (inode->i_ino == MSDOS_ROOT_INO)
+ return 0;
+
+ if (now == NULL) {
+ now = &ts;
+ ts = current_time(inode);
+ }
+
+ if (flags & S_ATIME) {
+ /* to localtime */
+ time64_t seconds = now->tv_sec - fat_tz_offset(sbi);
+ s32 remainder;
+
+ div_s64_rem(seconds, SECS_PER_DAY, &remainder);
+ /* to day boundary, and back to unix time */
+ seconds = seconds + fat_tz_offset(sbi) - remainder;
+
+ inode->i_atime = (struct timespec64){ seconds, 0 };
+ }
+ if (flags & S_CTIME) {
+ if (sbi->options.isvfat)
+ inode->i_ctime = timespec64_trunc(*now, 10000000);
+ else
+ inode->i_ctime = fat_timespec64_trunc_2secs(*now);
+ }
+ if (flags & S_MTIME)
+ inode->i_mtime = fat_timespec64_trunc_2secs(*now);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(fat_truncate_time);
+
+int fat_update_time(struct inode *inode, struct timespec64 *now, int flags)
+{
+ int iflags = I_DIRTY_TIME;
+ bool dirty = false;
+
+ if (inode->i_ino == MSDOS_ROOT_INO)
+ return 0;
+
+ fat_truncate_time(inode, now, flags);
+ if (flags & S_VERSION)
+ dirty = inode_maybe_inc_iversion(inode, false);
+ if ((flags & (S_ATIME | S_CTIME | S_MTIME)) &&
+ !(inode->i_sb->s_flags & SB_LAZYTIME))
+ dirty = true;
+
+ if (dirty)
+ iflags |= I_DIRTY_SYNC;
+ __mark_inode_dirty(inode, iflags);
+ return 0;
+}
+EXPORT_SYMBOL_GPL(fat_update_time);
+
int fat_sync_bhs(struct buffer_head **bhs, int nr_bhs)
{
int i, err = 0;
diff --git a/fs/fat/namei_msdos.c b/fs/fat/namei_msdos.c
index efb8c40c9d27..effbdd5fbf6e 100644
--- a/fs/fat/namei_msdos.c
+++ b/fs/fat/namei_msdos.c
@@ -637,6 +637,7 @@ static const struct inode_operations msdos_dir_inode_operations = {
.rename = msdos_rename,
.setattr = fat_setattr,
.getattr = fat_getattr,
+ .update_time = fat_update_time,
};
static void setup(struct super_block *sb)
diff --git a/fs/fat/namei_vfat.c b/fs/fat/namei_vfat.c
index 82cd1e69cbdf..1daa57cf4bf3 100644
--- a/fs/fat/namei_vfat.c
+++ b/fs/fat/namei_vfat.c
@@ -1032,6 +1032,7 @@ static const struct inode_operations vfat_dir_inode_operations = {
.rename = vfat_rename,
.setattr = fat_setattr,
.getattr = fat_getattr,
+ .update_time = fat_update_time,
};
static void setup(struct super_block *sb)
--
2.13.6
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH V5 3/4] fat: change timestamp updates to use fat_truncate_time
2018-10-01 3:33 [PATCH V5 0/4] fat: timestamp updates Frank Sorenson
2018-10-01 3:33 ` [PATCH V5 1/4] fat: create a function to calculate the timezone offest Frank Sorenson
2018-10-01 3:33 ` [PATCH V5 2/4] fat: add functions to update and truncate timestamps appropriately Frank Sorenson
@ 2018-10-01 3:33 ` Frank Sorenson
2018-10-01 3:33 ` [PATCH V5 4/4] fat: truncate inode timestamp updates in setattr Frank Sorenson
2018-10-01 8:14 ` [PATCH V5 0/4] fat: timestamp updates OGAWA Hirofumi
4 siblings, 0 replies; 6+ messages in thread
From: Frank Sorenson @ 2018-10-01 3:33 UTC (permalink / raw)
To: linux-fsdevel; +Cc: hirofumi
Convert the inode timestamp updates to use fat_truncate_time.
Signed-off-by: Frank Sorenson <sorenson@redhat.com>
---
fs/fat/dir.c | 2 +-
fs/fat/file.c | 4 ++--
fs/fat/inode.c | 4 ++--
fs/fat/namei_msdos.c | 16 ++++++++--------
fs/fat/namei_vfat.c | 14 +++++++-------
5 files changed, 20 insertions(+), 20 deletions(-)
diff --git a/fs/fat/dir.c b/fs/fat/dir.c
index 7f5f3699fc6c..1f9bad2c06c7 100644
--- a/fs/fat/dir.c
+++ b/fs/fat/dir.c
@@ -1071,7 +1071,7 @@ int fat_remove_entries(struct inode *dir, struct fat_slot_info *sinfo)
}
}
- dir->i_mtime = dir->i_atime = current_time(dir);
+ fat_truncate_time(dir, NULL, S_ATIME|S_MTIME);
if (IS_DIRSYNC(dir))
(void)fat_sync_inode(dir);
else
diff --git a/fs/fat/file.c b/fs/fat/file.c
index 19b6b0566411..4b5438405415 100644
--- a/fs/fat/file.c
+++ b/fs/fat/file.c
@@ -227,7 +227,7 @@ static int fat_cont_expand(struct inode *inode, loff_t size)
if (err)
goto out;
- inode->i_ctime = inode->i_mtime = current_time(inode);
+ fat_truncate_time(inode, NULL, S_CTIME|S_MTIME);
mark_inode_dirty(inode);
if (IS_SYNC(inode)) {
int err2;
@@ -330,7 +330,7 @@ static int fat_free(struct inode *inode, int skip)
MSDOS_I(inode)->i_logstart = 0;
}
MSDOS_I(inode)->i_attrs |= ATTR_ARCH;
- inode->i_ctime = inode->i_mtime = current_time(inode);
+ fat_truncate_time(inode, NULL, S_CTIME|S_MTIME);
if (wait) {
err = fat_sync_inode(inode);
if (err) {
diff --git a/fs/fat/inode.c b/fs/fat/inode.c
index 3bf60f19b6d3..c0b5b5c3373b 100644
--- a/fs/fat/inode.c
+++ b/fs/fat/inode.c
@@ -244,7 +244,7 @@ static int fat_write_end(struct file *file, struct address_space *mapping,
if (err < len)
fat_write_failed(mapping, pos + len);
if (!(err < 0) && !(MSDOS_I(inode)->i_attrs & ATTR_ARCH)) {
- inode->i_mtime = inode->i_ctime = current_time(inode);
+ fat_truncate_time(inode, NULL, S_CTIME|S_MTIME);
MSDOS_I(inode)->i_attrs |= ATTR_ARCH;
mark_inode_dirty(inode);
}
@@ -564,7 +564,7 @@ int fat_fill_inode(struct inode *inode, struct msdos_dir_entry *de)
de->cdate, de->ctime_cs);
fat_time_fat2unix(sbi, &inode->i_atime, 0, de->adate, 0);
} else
- inode->i_ctime = inode->i_atime = inode->i_mtime;
+ fat_truncate_time(inode, &inode->i_mtime, S_ATIME|S_CTIME);
return 0;
}
diff --git a/fs/fat/namei_msdos.c b/fs/fat/namei_msdos.c
index effbdd5fbf6e..f2cd365a4e86 100644
--- a/fs/fat/namei_msdos.c
+++ b/fs/fat/namei_msdos.c
@@ -250,7 +250,7 @@ static int msdos_add_entry(struct inode *dir, const unsigned char *name,
if (err)
return err;
- dir->i_ctime = dir->i_mtime = *ts;
+ fat_truncate_time(dir, ts, S_CTIME|S_MTIME);
if (IS_DIRSYNC(dir))
(void)fat_sync_inode(dir);
else
@@ -294,7 +294,7 @@ static int msdos_create(struct inode *dir, struct dentry *dentry, umode_t mode,
err = PTR_ERR(inode);
goto out;
}
- inode->i_mtime = inode->i_atime = inode->i_ctime = ts;
+ fat_truncate_time(inode, &ts, S_ATIME|S_CTIME|S_MTIME);
/* timestamp is already written, so mark_inode_dirty() is unneeded. */
d_instantiate(dentry, inode);
@@ -327,7 +327,7 @@ static int msdos_rmdir(struct inode *dir, struct dentry *dentry)
drop_nlink(dir);
clear_nlink(inode);
- inode->i_ctime = current_time(inode);
+ fat_truncate_time(inode, NULL, S_CTIME);
fat_detach(inode);
out:
mutex_unlock(&MSDOS_SB(sb)->s_lock);
@@ -380,7 +380,7 @@ static int msdos_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
goto out;
}
set_nlink(inode, 2);
- inode->i_mtime = inode->i_atime = inode->i_ctime = ts;
+ fat_truncate_time(inode, &ts, S_ATIME|S_CTIME|S_MTIME);
/* timestamp is already written, so mark_inode_dirty() is unneeded. */
d_instantiate(dentry, inode);
@@ -413,7 +413,7 @@ static int msdos_unlink(struct inode *dir, struct dentry *dentry)
if (err)
goto out;
clear_nlink(inode);
- inode->i_ctime = current_time(inode);
+ fat_truncate_time(inode, NULL, S_CTIME);
fat_detach(inode);
out:
mutex_unlock(&MSDOS_SB(sb)->s_lock);
@@ -478,7 +478,7 @@ static int do_msdos_rename(struct inode *old_dir, unsigned char *old_name,
mark_inode_dirty(old_inode);
inode_inc_iversion(old_dir);
- old_dir->i_ctime = old_dir->i_mtime = current_time(old_dir);
+ fat_truncate_time(old_dir, NULL, S_CTIME|S_MTIME);
if (IS_DIRSYNC(old_dir))
(void)fat_sync_inode(old_dir);
else
@@ -538,7 +538,7 @@ static int do_msdos_rename(struct inode *old_dir, unsigned char *old_name,
if (err)
goto error_dotdot;
inode_inc_iversion(old_dir);
- old_dir->i_ctime = old_dir->i_mtime = ts;
+ fat_truncate_time(old_dir, &ts, S_CTIME|S_MTIME);
if (IS_DIRSYNC(old_dir))
(void)fat_sync_inode(old_dir);
else
@@ -548,7 +548,7 @@ static int do_msdos_rename(struct inode *old_dir, unsigned char *old_name,
drop_nlink(new_inode);
if (is_dir)
drop_nlink(new_inode);
- new_inode->i_ctime = ts;
+ fat_truncate_time(new_inode, &ts, S_CTIME);
}
out:
brelse(sinfo.bh);
diff --git a/fs/fat/namei_vfat.c b/fs/fat/namei_vfat.c
index 1daa57cf4bf3..996c8c25e9c6 100644
--- a/fs/fat/namei_vfat.c
+++ b/fs/fat/namei_vfat.c
@@ -678,7 +678,7 @@ static int vfat_add_entry(struct inode *dir, const struct qstr *qname,
goto cleanup;
/* update timestamp */
- dir->i_ctime = dir->i_mtime = dir->i_atime = *ts;
+ fat_truncate_time(dir, ts, S_CTIME|S_MTIME);
if (IS_DIRSYNC(dir))
(void)fat_sync_inode(dir);
else
@@ -779,7 +779,7 @@ static int vfat_create(struct inode *dir, struct dentry *dentry, umode_t mode,
goto out;
}
inode_inc_iversion(inode);
- inode->i_mtime = inode->i_atime = inode->i_ctime = ts;
+ fat_truncate_time(inode, &ts, S_ATIME|S_CTIME|S_MTIME);
/* timestamp is already written, so mark_inode_dirty() is unneeded. */
d_instantiate(dentry, inode);
@@ -810,7 +810,7 @@ static int vfat_rmdir(struct inode *dir, struct dentry *dentry)
drop_nlink(dir);
clear_nlink(inode);
- inode->i_mtime = inode->i_atime = current_time(inode);
+ fat_truncate_time(inode, NULL, S_ATIME|S_MTIME);
fat_detach(inode);
vfat_d_version_set(dentry, inode_query_iversion(dir));
out:
@@ -836,7 +836,7 @@ static int vfat_unlink(struct inode *dir, struct dentry *dentry)
if (err)
goto out;
clear_nlink(inode);
- inode->i_mtime = inode->i_atime = current_time(inode);
+ fat_truncate_time(inode, NULL, S_ATIME|S_MTIME);
fat_detach(inode);
vfat_d_version_set(dentry, inode_query_iversion(dir));
out:
@@ -876,7 +876,7 @@ static int vfat_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
}
inode_inc_iversion(inode);
set_nlink(inode, 2);
- inode->i_mtime = inode->i_atime = inode->i_ctime = ts;
+ fat_truncate_time(inode, &ts, S_ATIME|S_CTIME|S_MTIME);
/* timestamp is already written, so mark_inode_dirty() is unneeded. */
d_instantiate(dentry, inode);
@@ -969,7 +969,7 @@ static int vfat_rename(struct inode *old_dir, struct dentry *old_dentry,
if (err)
goto error_dotdot;
inode_inc_iversion(old_dir);
- old_dir->i_ctime = old_dir->i_mtime = ts;
+ fat_truncate_time(old_dir, &ts, S_CTIME|S_MTIME);
if (IS_DIRSYNC(old_dir))
(void)fat_sync_inode(old_dir);
else
@@ -979,7 +979,7 @@ static int vfat_rename(struct inode *old_dir, struct dentry *old_dentry,
drop_nlink(new_inode);
if (is_dir)
drop_nlink(new_inode);
- new_inode->i_ctime = ts;
+ fat_truncate_time(new_inode, &ts, S_CTIME);
}
out:
brelse(sinfo.bh);
--
2.13.6
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH V5 4/4] fat: truncate inode timestamp updates in setattr
2018-10-01 3:33 [PATCH V5 0/4] fat: timestamp updates Frank Sorenson
` (2 preceding siblings ...)
2018-10-01 3:33 ` [PATCH V5 3/4] fat: change timestamp updates to use fat_truncate_time Frank Sorenson
@ 2018-10-01 3:33 ` Frank Sorenson
2018-10-01 8:14 ` [PATCH V5 0/4] fat: timestamp updates OGAWA Hirofumi
4 siblings, 0 replies; 6+ messages in thread
From: Frank Sorenson @ 2018-10-01 3:33 UTC (permalink / raw)
To: linux-fsdevel; +Cc: hirofumi
setattr_copy can't truncate timestamps correctly for
msdos/vfat, so truncate and copy them ourselves.
Signed-off-by: Frank Sorenson <sorenson@redhat.com>
---
fs/fat/file.c | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/fs/fat/file.c b/fs/fat/file.c
index 4b5438405415..13935ee99e1e 100644
--- a/fs/fat/file.c
+++ b/fs/fat/file.c
@@ -542,6 +542,18 @@ int fat_setattr(struct dentry *dentry, struct iattr *attr)
up_write(&MSDOS_I(inode)->truncate_lock);
}
+ /*
+ * setattr_copy can't truncate these appropriately, so we'll
+ * copy them ourselves
+ */
+ if (attr->ia_valid & ATTR_ATIME)
+ fat_truncate_time(inode, &attr->ia_atime, S_ATIME);
+ if (attr->ia_valid & ATTR_CTIME)
+ fat_truncate_time(inode, &attr->ia_ctime, S_CTIME);
+ if (attr->ia_valid & ATTR_MTIME)
+ fat_truncate_time(inode, &attr->ia_mtime, S_MTIME);
+ attr->ia_valid &= ~(ATTR_ATIME|ATTR_CTIME|ATTR_MTIME);
+
setattr_copy(inode, attr);
mark_inode_dirty(inode);
out:
--
2.13.6
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH V5 0/4] fat: timestamp updates
2018-10-01 3:33 [PATCH V5 0/4] fat: timestamp updates Frank Sorenson
` (3 preceding siblings ...)
2018-10-01 3:33 ` [PATCH V5 4/4] fat: truncate inode timestamp updates in setattr Frank Sorenson
@ 2018-10-01 8:14 ` OGAWA Hirofumi
4 siblings, 0 replies; 6+ messages in thread
From: OGAWA Hirofumi @ 2018-10-01 8:14 UTC (permalink / raw)
To: Andrew Morton; +Cc: Frank Sorenson, linux-fsdevel
Frank Sorenson <sorenson@redhat.com> writes:
> fat/msdos timestamps are stored on-disk with several different
> granularities, some of them lower resolution than timespec64_trunc()
> can provide. In addition, they are only truncated as they are
> written to disk, so the timestamps in-memory for new or modified
> files/directories may be different from the same timestamps after
> a remount, as the now-truncated times are re-read from the on-disk
> format.
>
> These patches allow finer granularity for the timestamps where
> possible and add fat-specific ->update_time inode operation and
> fat_truncate_time functions to truncate each timestamp correctly,
> giving consistent times across remounts.
Whole patches needs to apply at once, so IMO this is better to be one
patch though. Looks good to me.
Acked-by: OGAWA Hirofumi <hirofumi@mail.parknet.co.jp>
Thanks.
--
OGAWA Hirofumi <hirofumi@mail.parknet.co.jp>
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2018-10-01 14:50 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-10-01 3:33 [PATCH V5 0/4] fat: timestamp updates Frank Sorenson
2018-10-01 3:33 ` [PATCH V5 1/4] fat: create a function to calculate the timezone offest Frank Sorenson
2018-10-01 3:33 ` [PATCH V5 2/4] fat: add functions to update and truncate timestamps appropriately Frank Sorenson
2018-10-01 3:33 ` [PATCH V5 3/4] fat: change timestamp updates to use fat_truncate_time Frank Sorenson
2018-10-01 3:33 ` [PATCH V5 4/4] fat: truncate inode timestamp updates in setattr Frank Sorenson
2018-10-01 8:14 ` [PATCH V5 0/4] fat: timestamp updates OGAWA Hirofumi
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).