Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

fat: report creation time in statx

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

Link: https://lkml.kernel.org/r/20220503152536.2503003-3-cccheng@synology.com
Signed-off-by: Chung-Chiang Cheng <cccheng@synology.com>
Acked-by: OGAWA Hirofumi <hirofumi@mail.parknet.co.jp>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>

authored by

Chung-Chiang Cheng and committed by
akpm
30abce05 0f9d1481

+21 -6
+1
fs/fat/fat.h
··· 126 126 struct hlist_node i_fat_hash; /* hash by i_location */ 127 127 struct hlist_node i_dir_hash; /* hash by i_logstart */ 128 128 struct rw_semaphore truncate_lock; /* protect bmap against truncate */ 129 + struct timespec64 i_crtime; /* File creation (birth) time */ 129 130 struct inode vfs_inode; 130 131 }; 131 132
+12 -4
fs/fat/file.c
··· 399 399 struct kstat *stat, u32 request_mask, unsigned int flags) 400 400 { 401 401 struct inode *inode = d_inode(path->dentry); 402 - generic_fillattr(mnt_userns, inode, stat); 403 - stat->blksize = MSDOS_SB(inode->i_sb)->cluster_size; 402 + struct msdos_sb_info *sbi = MSDOS_SB(inode->i_sb); 404 403 405 - if (MSDOS_SB(inode->i_sb)->options.nfs == FAT_NFS_NOSTALE_RO) { 404 + generic_fillattr(mnt_userns, inode, stat); 405 + stat->blksize = sbi->cluster_size; 406 + 407 + if (sbi->options.nfs == FAT_NFS_NOSTALE_RO) { 406 408 /* Use i_pos for ino. This is used as fileid of nfs. */ 407 - stat->ino = fat_i_pos_read(MSDOS_SB(inode->i_sb), inode); 409 + stat->ino = fat_i_pos_read(sbi, inode); 408 410 } 411 + 412 + if (sbi->options.isvfat && request_mask & STATX_BTIME) { 413 + stat->result_mask |= STATX_BTIME; 414 + stat->btime = MSDOS_I(inode)->i_crtime; 415 + } 416 + 409 417 return 0; 410 418 } 411 419 EXPORT_SYMBOL_GPL(fat_getattr);
+8 -2
fs/fat/inode.c
··· 568 568 569 569 fat_time_fat2unix(sbi, &inode->i_mtime, de->time, de->date, 0); 570 570 inode->i_ctime = inode->i_mtime; 571 - if (sbi->options.isvfat) 571 + if (sbi->options.isvfat) { 572 572 fat_time_fat2unix(sbi, &inode->i_atime, 0, de->adate, 0); 573 - else 573 + fat_time_fat2unix(sbi, &MSDOS_I(inode)->i_crtime, de->ctime, 574 + de->cdate, de->ctime_cs); 575 + } else 574 576 inode->i_atime = fat_truncate_atime(sbi, &inode->i_mtime); 575 577 576 578 return 0; ··· 758 756 ei->i_logstart = 0; 759 757 ei->i_attrs = 0; 760 758 ei->i_pos = 0; 759 + ei->i_crtime.tv_sec = 0; 760 + ei->i_crtime.tv_nsec = 0; 761 761 762 762 return &ei->vfs_inode; 763 763 } ··· 893 889 __le16 atime; 894 890 fat_time_unix2fat(sbi, &inode->i_atime, &atime, 895 891 &raw_entry->adate, NULL); 892 + fat_time_unix2fat(sbi, &MSDOS_I(inode)->i_crtime, &raw_entry->ctime, 893 + &raw_entry->cdate, &raw_entry->ctime_cs); 896 894 } 897 895 spin_unlock(&sbi->inode_hash_lock); 898 896 mark_buffer_dirty(bh);