2022-04-15 13:43:22

by Chung-Chiang Cheng

[permalink] [raw]
Subject: [PATCH v3 3/3] fat: report creation time in statx

creation time is no longer mixed with change time. Add a in-memory
field for it, and report it in statx if supported.

Signed-off-by: Chung-Chiang Cheng <[email protected]>
---
fs/fat/fat.h | 1 +
fs/fat/file.c | 14 +++++++++++---
fs/fat/inode.c | 12 ++++++++++--
3 files changed, 22 insertions(+), 5 deletions(-)

diff --git a/fs/fat/fat.h b/fs/fat/fat.h
index 508b4f2a1ffb..e4409ee82ea9 100644
--- a/fs/fat/fat.h
+++ b/fs/fat/fat.h
@@ -126,6 +126,7 @@ struct msdos_inode_info {
struct hlist_node i_fat_hash; /* hash by i_location */
struct hlist_node i_dir_hash; /* hash by i_logstart */
struct rw_semaphore truncate_lock; /* protect bmap against truncate */
+ struct timespec64 i_crtime; /* File creation (birth) time */
struct inode vfs_inode;
};

diff --git a/fs/fat/file.c b/fs/fat/file.c
index 178c1dde3488..7a4f617d4928 100644
--- a/fs/fat/file.c
+++ b/fs/fat/file.c
@@ -399,13 +399,21 @@ int fat_getattr(struct user_namespace *mnt_userns, const struct path *path,
struct kstat *stat, u32 request_mask, unsigned int flags)
{
struct inode *inode = d_inode(path->dentry);
+ struct msdos_sb_info *sbi = MSDOS_SB(inode->i_sb);
+
generic_fillattr(mnt_userns, inode, stat);
- stat->blksize = MSDOS_SB(inode->i_sb)->cluster_size;
+ stat->blksize = sbi->cluster_size;

- if (MSDOS_SB(inode->i_sb)->options.nfs == FAT_NFS_NOSTALE_RO) {
+ if (sbi->options.nfs == FAT_NFS_NOSTALE_RO) {
/* Use i_pos for ino. This is used as fileid of nfs. */
- stat->ino = fat_i_pos_read(MSDOS_SB(inode->i_sb), inode);
+ stat->ino = fat_i_pos_read(sbi, inode);
}
+
+ if (sbi->options.isvfat && request_mask & STATX_BTIME) {
+ stat->result_mask |= STATX_BTIME;
+ stat->btime = MSDOS_I(inode)->i_crtime;
+ }
+
return 0;
}
EXPORT_SYMBOL_GPL(fat_getattr);
diff --git a/fs/fat/inode.c b/fs/fat/inode.c
index f2ac55cd4ea4..23fac3181fa7 100644
--- a/fs/fat/inode.c
+++ b/fs/fat/inode.c
@@ -568,10 +568,14 @@ int fat_fill_inode(struct inode *inode, struct msdos_dir_entry *de)

fat_time_fat2unix(sbi, &inode->i_mtime, de->time, de->date, 0);
inode->i_ctime = inode->i_mtime;
- if (sbi->options.isvfat)
+ if (sbi->options.isvfat) {
fat_time_fat2unix(sbi, &inode->i_atime, 0, de->adate, 0);
- else
+ fat_time_fat2unix(sbi, &MSDOS_I(inode)->i_crtime, de->ctime,
+ de->cdate, de->ctime_cs);
+ } else {
fat_truncate_atime(sbi, &inode->i_mtime, &inode->i_atime);
+ fat_truncate_crtime(sbi, &inode->i_mtime, &MSDOS_I(inode)->i_crtime);
+ }

return 0;
}
@@ -756,6 +760,8 @@ static struct inode *fat_alloc_inode(struct super_block *sb)
ei->i_logstart = 0;
ei->i_attrs = 0;
ei->i_pos = 0;
+ ei->i_crtime.tv_sec = 0;
+ ei->i_crtime.tv_nsec = 0;

return &ei->vfs_inode;
}
@@ -887,6 +893,8 @@ static int __fat_write_inode(struct inode *inode, int wait)
&raw_entry->date, NULL);
if (sbi->options.isvfat) {
__le16 atime;
+ fat_time_unix2fat(sbi, &MSDOS_I(inode)->i_crtime, &raw_entry->ctime,
+ &raw_entry->cdate, &raw_entry->ctime_cs);
fat_time_unix2fat(sbi, &inode->i_atime, &atime,
&raw_entry->adate, NULL);
}
--
2.34.1


2022-04-16 01:53:57

by OGAWA Hirofumi

[permalink] [raw]
Subject: Re: [PATCH v3 3/3] fat: report creation time in statx

Chung-Chiang Cheng <[email protected]> writes:

> @@ -568,10 +568,14 @@ int fat_fill_inode(struct inode *inode, struct msdos_dir_entry *de)
>
> fat_time_fat2unix(sbi, &inode->i_mtime, de->time, de->date, 0);
> inode->i_ctime = inode->i_mtime;
> - if (sbi->options.isvfat)
> + if (sbi->options.isvfat) {
> fat_time_fat2unix(sbi, &inode->i_atime, 0, de->adate, 0);
> - else
> + fat_time_fat2unix(sbi, &MSDOS_I(inode)->i_crtime, de->ctime,
> + de->cdate, de->ctime_cs);
> + } else {
> fat_truncate_atime(sbi, &inode->i_mtime, &inode->i_atime);
> + fat_truncate_crtime(sbi, &inode->i_mtime, &MSDOS_I(inode)->i_crtime);
> + }

Probably, nothing worth to update i_crtime here, right?

Thanks.
--
OGAWA Hirofumi <[email protected]>

2022-04-22 17:36:48

by Chung-Chiang Cheng

[permalink] [raw]
Subject: Re: [PATCH v3 3/3] fat: report creation time in statx

> > + } else {
> > fat_truncate_atime(sbi, &inode->i_mtime, &inode->i_atime);
> > + fat_truncate_crtime(sbi, &inode->i_mtime, &MSDOS_I(inode)->i_crtime);
> > + }
>
> Probably, nothing worth to update i_crtime here, right?
>

That's right. I also miss truncating the create-time for newly created
files in vfat. I will add it back in the next patch. It will be the only
location that calls fat_truncate_crtime().

@@ -781,11 +782,12 @@ static int vfat_create(struct user_namespace
*mnt_userns, struct inode *dir,
}
inode_inc_iversion(inode);
fat_truncate_time(inode, &ts, S_ATIME|S_CTIME|S_MTIME);
+ fat_truncate_crtime(...)


I also have a question. If msdos doesn't support create-time, why does the
original fat_truncate_time() truncate it to a 2-sec granularity?

if (flags & S_CTIME) {
if (sbi->options.isvfat)
inode->i_ctime = fat_timespec64_trunc_10ms(*now);
else
inode->i_ctime = fat_timespec64_trunc_2secs(*now);
}

This logic was introduced in 6bb885ecd746 (fat: add functions to update
and truncate timestamps appropriately"), and seems not for change-time.
Should I remove it?

Thanks.

2022-04-22 18:38:28

by OGAWA Hirofumi

[permalink] [raw]
Subject: Re: [PATCH v3 3/3] fat: report creation time in statx

Chung-Chiang Cheng <[email protected]> writes:

>
> I also have a question. If msdos doesn't support create-time, why does the
> original fat_truncate_time() truncate it to a 2-sec granularity?
>
> if (flags & S_CTIME) {
> if (sbi->options.isvfat)
> inode->i_ctime = fat_timespec64_trunc_10ms(*now);
> else
> inode->i_ctime = fat_timespec64_trunc_2secs(*now);
> }
>
> This logic was introduced in 6bb885ecd746 (fat: add functions to update
> and truncate timestamps appropriately"), and seems not for change-time.
> Should I remove it?

Hm, not sure.

However, ctime/atime is not stored into backing storage in
__fat_write_inode() and loaded if !isvfat (if I'm not missing
something). So I think we don't need it for creation time.

Thanks.
--
OGAWA Hirofumi <[email protected]>