Since NTFS supports user-settable file creation timestamps, map provenance time (ptime) to NTFS file creation time (crtime) by using the newly introduced ptime API (in commit "vfs: add provenance time (ptime)"). To do this, update ntfs_fileattr_[gs]et(), ntfs_getattr() and make it persist to disk in ni_write_inode(). The timestamp is now retrievable by using file_getattr() or statx(), and is settable by using file_setattr() with the FS_XFLAG_PTIME flag. Assisted-by: Gemini:3.8-flash-high antigravity-cli-1.4.7 Signed-off-by: koraynilay --- fs/ntfs3/file.c | 14 ++++++++++++-- fs/ntfs3/frecord.c | 8 +++++++- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/fs/ntfs3/file.c b/fs/ntfs3/file.c index 1624f9b014e0..b334449e9beb 100644 --- a/fs/ntfs3/file.c +++ b/fs/ntfs3/file.c @@ -124,6 +124,10 @@ int ntfs_fileattr_get(struct dentry *dentry, struct file_kattr *fa) fileattr_fill_flags(fa, flags); + fa->fsx_ptime.tv_sec = ni->i_crtime.tv_sec; + fa->fsx_ptime.tv_nsec = ni->i_crtime.tv_nsec; + fa->fsx_xflags |= FS_XFLAG_PTIME; + return 0; } @@ -142,7 +146,7 @@ int ntfs_fileattr_set(const struct mnt_idmap *idmap, struct dentry *dentry, if (unlikely(is_bad_ni(ni))) return -EINVAL; - if (fileattr_has_fsx(fa)) + if (fileattr_has_fsx_mask(fa, FS_XFLAG_PTIME)) return -EOPNOTSUPP; if (flags & ~(FS_IMMUTABLE_FL | FS_APPEND_FL | FS_NODUMP_FL)) @@ -154,6 +158,11 @@ int ntfs_fileattr_set(const struct mnt_idmap *idmap, struct dentry *dentry, if (flags & FS_APPEND_FL) new_fl |= S_APPEND; + if (fa->fsx_xflags & FS_XFLAG_PTIME) { + ni->i_crtime.tv_sec = fa->fsx_ptime.tv_sec; + ni->i_crtime.tv_nsec = fa->fsx_ptime.tv_nsec; + } + inode_set_flags(inode, new_fl, S_IMMUTABLE | S_APPEND); /* Save nodump flag to return in ntfs_getattr. */ @@ -275,8 +284,9 @@ int ntfs_getattr(const struct mnt_idmap *idmap, const struct path *path, if (unlikely(is_bad_ni(ni))) return -EINVAL; - stat->result_mask |= STATX_BTIME; + stat->result_mask |= (STATX_BTIME | STATX_PTIME); stat->btime = ni->i_crtime; + stat->ptime = ni->i_crtime; stat->blksize = ni->mi.sbi->cluster_size; /* 512, 1K, ..., 2M */ if (inode->i_flags & S_IMMUTABLE) diff --git a/fs/ntfs3/frecord.c b/fs/ntfs3/frecord.c index 16ac847de48d..5e4f743a5930 100644 --- a/fs/ntfs3/frecord.c +++ b/fs/ntfs3/frecord.c @@ -3215,6 +3215,13 @@ int ni_write_inode(struct inode *inode, int sync, const char *hint) } /* Update the access times if they have changed. */ + ts = ni->i_crtime; + dup.cr_time = kernel2nt(&ts); + if (std->cr_time != dup.cr_time) { + std->cr_time = dup.cr_time; + modified = true; + } + ts = inode_get_mtime(inode); dup.m_time = kernel2nt(&ts); if (std->m_time != dup.m_time) { @@ -3250,7 +3257,6 @@ int ni_write_inode(struct inode *inode, int sync, const char *hint) (modified || (ni->ni_flags & NI_FLAG_UPDATE_PARENT)) /* Avoid __wait_on_freeing_inode(inode). */ && (sb->s_flags & SB_ACTIVE)) { - dup.cr_time = std->cr_time; /* Not critical if this function fail. */ re_dirty = ni_update_parent(ni, &dup, sync); -- 2.56.0