From: Frank Sorenson <sorenson@redhat.com>
To: linux-fsdevel@vger.kernel.org
Cc: hirofumi@mail.parknet.co.jp
Subject: [PATCH 3/4] fat: add functions to update and truncate the timestamps appropriately
Date: Sat, 22 Sep 2018 15:19:58 -0500 [thread overview]
Message-ID: <20180922201959.10477-4-sorenson@redhat.com> (raw)
In-Reply-To: <20180922201959.10477-1-sorenson@redhat.com>
Add the fat-specific inode_operation ->update_time() and
fat_truncate_time() function to truncate the inode timestamps
with the appropriate granularity.
Signed-off-by: Frank Sorenson <sorenson@redhat.com>
---
fs/fat/fat.h | 2 ++
fs/fat/file.c | 1 +
fs/fat/misc.c | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++++
fs/fat/namei_msdos.c | 1 +
fs/fat/namei_vfat.c | 1 +
5 files changed, 67 insertions(+)
diff --git a/fs/fat/fat.h b/fs/fat/fat.h
index c40f7e69f078..6201c6bdb5f9 100644
--- a/fs/fat/fat.h
+++ b/fs/fat/fat.h
@@ -428,6 +428,8 @@ 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/misc.c b/fs/fat/misc.c
index 58580c7e558e..42c4fb063287 100644
--- a/fs/fat/misc.c
+++ b/fs/fat/misc.c
@@ -255,6 +255,68 @@ void fat_time_unix2fat(struct msdos_sb_info *sbi, struct timespec64 *ts,
}
EXPORT_SYMBOL_GPL(fat_time_unix2fat);
+/*
+ * 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)
+ */
+noinline 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) {
+ int offset = fat_tz_offset(sbi);
+ long seconds;
+
+ seconds = now->tv_sec;
+ seconds -= (now->tv_sec - offset) % 86400;
+
+ inode->i_atime = (struct timespec64){ seconds, 0 };
+ }
+ if (flags & S_CTIME) {
+ if (sbi->options.isvfat)
+ inode->i_ctime = *now;
+ else
+ inode->i_ctime = (struct timespec64){ now->tv_sec & ~1, 0 };
+ }
+ if (flags & S_MTIME)
+ inode->i_mtime = (struct timespec64){ now->tv_sec & ~1, 0 };
+ 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;
+
+ if (inode->i_ino == MSDOS_ROOT_INO)
+ return 0;
+ fat_truncate_time(inode, now, flags);
+
+ if ((flags & (S_ATIME | S_CTIME | S_MTIME)) &&
+ !(inode->i_sb->s_flags & SB_LAZYTIME))
+ 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
next prev parent reply other threads:[~2018-09-23 2:14 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-09-22 20:19 [PATCH V3 0/4] fat: timestamp updates Frank Sorenson
2018-09-22 20:19 ` [PATCH 1/4] fat: set the s_time_gran for msdos or vfat mounts Frank Sorenson
2018-09-22 20:19 ` [PATCH 2/4] fat: create function to calculate timezone offset Frank Sorenson
2018-09-22 20:19 ` Frank Sorenson [this message]
2018-09-22 20:19 ` [PATCH 4/4] fat: change timestamp updates to fat_update_time or fat_truncate_time Frank Sorenson
2018-09-23 10:31 ` [PATCH V3 0/4] fat: timestamp updates OGAWA Hirofumi
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20180922201959.10477-4-sorenson@redhat.com \
--to=sorenson@redhat.com \
--cc=hirofumi@mail.parknet.co.jp \
--cc=linux-fsdevel@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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).