exfat: truncate atimes to 2s granularity
exfat atimes are restricted to only 2s granularity so after we set an atime, round it down to the nearest 2s and set the sub-second component of the timestamp to 0. Signed-off-by: Eric Sandeen <sandeen@sandeen.net> Signed-off-by: Namjae Jeon <namjae.jeon@samsung.com>
This commit is contained in:
parent
b0333de3ff
commit
09241c144b
@ -519,6 +519,7 @@ void exfat_msg(struct super_block *sb, const char *lv, const char *fmt, ...)
|
||||
|
||||
void exfat_get_entry_time(struct exfat_sb_info *sbi, struct timespec64 *ts,
|
||||
u8 tz, __le16 time, __le16 date, u8 time_ms);
|
||||
void exfat_truncate_atime(struct timespec64 *ts);
|
||||
void exfat_set_entry_time(struct exfat_sb_info *sbi, struct timespec64 *ts,
|
||||
u8 *tz, __le16 *time, __le16 *date, u8 *time_ms);
|
||||
unsigned short exfat_calc_chksum_2byte(void *data, int len,
|
||||
|
2
file.c
2
file.c
@ -300,6 +300,7 @@ int exfat_getattr(struct vfsmount *mnt, struct dentry *dentry,
|
||||
#endif
|
||||
|
||||
generic_fillattr(inode, stat);
|
||||
exfat_truncate_atime(&stat->atime);
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0)
|
||||
stat->result_mask |= STATX_BTIME;
|
||||
stat->btime.tv_sec = ei->i_crtime.tv_sec;
|
||||
@ -374,6 +375,7 @@ int exfat_setattr(struct dentry *dentry, struct iattr *attr)
|
||||
}
|
||||
|
||||
setattr_copy(inode, attr);
|
||||
exfat_truncate_atime(&inode->i_atime);
|
||||
mark_inode_dirty(inode);
|
||||
|
||||
out:
|
||||
|
10
misc.c
10
misc.c
@ -94,7 +94,8 @@ void exfat_get_entry_time(struct exfat_sb_info *sbi, struct timespec64 *ts,
|
||||
if (time_ms) {
|
||||
ts->tv_sec += time_ms / 100;
|
||||
ts->tv_nsec = (time_ms % 100) * 10 * NSEC_PER_MSEC;
|
||||
}
|
||||
} else
|
||||
ts->tv_nsec = 0;
|
||||
|
||||
if (tz & EXFAT_TZ_VALID)
|
||||
/* Adjust timezone to UTC0. */
|
||||
@ -134,6 +135,13 @@ void exfat_set_entry_time(struct exfat_sb_info *sbi, struct timespec64 *ts,
|
||||
*tz = EXFAT_TZ_VALID;
|
||||
}
|
||||
|
||||
/* atime has only a 2-second resolution */
|
||||
void exfat_truncate_atime(struct timespec64 *ts)
|
||||
{
|
||||
ts->tv_sec = round_down(ts->tv_sec, 2);
|
||||
ts->tv_nsec = 0;
|
||||
}
|
||||
|
||||
unsigned short exfat_calc_chksum_2byte(void *data, int len,
|
||||
unsigned short chksum, int type)
|
||||
{
|
||||
|
7
namei.c
7
namei.c
@ -629,6 +629,7 @@ static int exfat_create(struct inode *dir, struct dentry *dentry, umode_t mode,
|
||||
inode->i_mtime = inode->i_atime = inode->i_ctime =
|
||||
EXFAT_I(inode)->i_crtime = CURRENT_TIME_SEC;
|
||||
#endif
|
||||
exfat_truncate_atime(&inode->i_atime);
|
||||
/* timestamp is already written, so mark_inode_dirty() is unneeded. */
|
||||
|
||||
d_instantiate(dentry, inode);
|
||||
@ -908,6 +909,7 @@ static int exfat_unlink(struct inode *dir, struct dentry *dentry)
|
||||
#else
|
||||
dir->i_mtime = dir->i_atime = CURRENT_TIME_SEC;
|
||||
#endif
|
||||
exfat_truncate_atime(&dir->i_atime);
|
||||
if (IS_DIRSYNC(dir))
|
||||
exfat_sync_inode(dir);
|
||||
else
|
||||
@ -919,6 +921,7 @@ static int exfat_unlink(struct inode *dir, struct dentry *dentry)
|
||||
#else
|
||||
inode->i_mtime = inode->i_atime = CURRENT_TIME_SEC;
|
||||
#endif
|
||||
exfat_truncate_atime(&inode->i_atime);
|
||||
exfat_unhash_inode(inode);
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 16, 0)
|
||||
exfat_d_version_set(dentry, inode_query_iversion(dir));
|
||||
@ -983,6 +986,7 @@ static int exfat_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
|
||||
inode->i_mtime = inode->i_atime = inode->i_ctime =
|
||||
EXFAT_I(inode)->i_crtime = CURRENT_TIME_SEC;
|
||||
#endif
|
||||
exfat_truncate_atime(&inode->i_atime);
|
||||
/* timestamp is already written, so mark_inode_dirty() is unneeded. */
|
||||
|
||||
d_instantiate(dentry, inode);
|
||||
@ -1104,6 +1108,7 @@ static int exfat_rmdir(struct inode *dir, struct dentry *dentry)
|
||||
#else
|
||||
dir->i_mtime = dir->i_atime = CURRENT_TIME_SEC;
|
||||
#endif
|
||||
exfat_truncate_atime(&dir->i_atime);
|
||||
if (IS_DIRSYNC(dir))
|
||||
exfat_sync_inode(dir);
|
||||
else
|
||||
@ -1116,6 +1121,7 @@ static int exfat_rmdir(struct inode *dir, struct dentry *dentry)
|
||||
#else
|
||||
inode->i_mtime = inode->i_atime = CURRENT_TIME_SEC;
|
||||
#endif
|
||||
exfat_truncate_atime(&inode->i_atime);
|
||||
exfat_unhash_inode(inode);
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 16, 0)
|
||||
exfat_d_version_set(dentry, inode_query_iversion(dir));
|
||||
@ -1494,6 +1500,7 @@ static int exfat_rename(struct inode *old_dir, struct dentry *old_dentry,
|
||||
new_dir->i_ctime = new_dir->i_mtime = new_dir->i_atime =
|
||||
EXFAT_I(new_dir)->i_crtime = CURRENT_TIME_SEC;
|
||||
#endif
|
||||
exfat_truncate_atime(&new_dir->i_atime);
|
||||
if (IS_DIRSYNC(new_dir))
|
||||
exfat_sync_inode(new_dir);
|
||||
else
|
||||
|
Loading…
Reference in New Issue
Block a user