Right now, when populating a filesystem with the prototype file, generated inodes will have timestamps set at the creation time. This change enables more accurate filesystem initialization by preserving original file timestamps during inode creation rather than defaulting to the current time. This patch leverages the xfs_protofile changes in order to carry the reference to the original files for files other than regular ones. Signed-off-by: Luca Di Maio <luca.dimaio1@xxxxxxxxx> --- mkfs/proto.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/mkfs/proto.c b/mkfs/proto.c index 6dd3a20..ed76155 100644 --- a/mkfs/proto.c +++ b/mkfs/proto.c @@ -352,6 +352,15 @@ writefile( libxfs_trans_ijoin(tp, ip, 0); ip->i_disk_size = statbuf.st_size; + + /* Copy timestamps from source file to destination inode */ + VFS_I(ip)->__i_atime.tv_sec = statbuf.st_atime; + VFS_I(ip)->__i_mtime.tv_sec = statbuf.st_mtime; + VFS_I(ip)->__i_ctime.tv_sec = statbuf.st_ctime; + VFS_I(ip)->__i_atime.tv_nsec = statbuf.st_atim.tv_nsec; + VFS_I(ip)->__i_mtime.tv_nsec = statbuf.st_mtim.tv_nsec; + VFS_I(ip)->__i_ctime.tv_nsec = statbuf.st_ctim.tv_nsec; + libxfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); error = -libxfs_trans_commit(tp); if (error) @@ -689,6 +698,7 @@ parseproto( char *fname = NULL; struct xfs_name xname; struct xfs_parent_args *ppargs = NULL; + struct stat statbuf; memset(&creds, 0, sizeof(creds)); mstr = getstr(pp); @@ -823,10 +833,23 @@ parseproto( ppargs = newpptr(mp); majdev = getnum(getstr(pp), 0, 0, false); mindev = getnum(getstr(pp), 0, 0, false); + fd = newregfile(pp, &fname); error = creatproto(&tp, pip, mode | S_IFCHR, IRIX_MKDEV(majdev, mindev), &creds, fsxp, &ip); if (error) fail(_("Inode allocation failed"), error); + + /* Copy timestamps from source file to destination inode */ + error = fstat(fd, &statbuf); + if (error < 0) + fail(_("unable to stat file to copyin"), errno); + VFS_I(ip)->__i_atime.tv_sec = statbuf.st_atime; + VFS_I(ip)->__i_mtime.tv_sec = statbuf.st_mtime; + VFS_I(ip)->__i_ctime.tv_sec = statbuf.st_ctime; + VFS_I(ip)->__i_atime.tv_nsec = statbuf.st_atim.tv_nsec; + VFS_I(ip)->__i_mtime.tv_nsec = statbuf.st_mtim.tv_nsec; + VFS_I(ip)->__i_ctime.tv_nsec = statbuf.st_ctim.tv_nsec; + libxfs_trans_ijoin(tp, pip, 0); xname.type = XFS_DIR3_FT_CHRDEV; newdirent(mp, tp, pip, &xname, ip, ppargs); @@ -846,6 +869,7 @@ parseproto( break; case IF_SYMLINK: buf = getstr(pp); + char* orig = getstr(pp); len = (int)strlen(buf); tp = getres(mp, XFS_B_TO_FSB(mp, len)); ppargs = newpptr(mp); @@ -854,11 +878,24 @@ parseproto( if (error) fail(_("Inode allocation failed"), error); writesymlink(tp, ip, buf, len); + + /* Copy timestamps from source file to destination inode */ + error = lstat(orig, &statbuf); + if (error < 0) + fail(_("unable to stat file to copyin"), errno); + VFS_I(ip)->__i_atime.tv_sec = statbuf.st_atime; + VFS_I(ip)->__i_mtime.tv_sec = statbuf.st_mtime; + VFS_I(ip)->__i_ctime.tv_sec = statbuf.st_ctime; + VFS_I(ip)->__i_atime.tv_nsec = statbuf.st_atim.tv_nsec; + VFS_I(ip)->__i_mtime.tv_nsec = statbuf.st_mtim.tv_nsec; + VFS_I(ip)->__i_ctime.tv_nsec = statbuf.st_ctim.tv_nsec; + libxfs_trans_ijoin(tp, pip, 0); xname.type = XFS_DIR3_FT_SYMLINK; newdirent(mp, tp, pip, &xname, ip, ppargs); break; case IF_DIRECTORY: + fd = newregfile(pp, &fname); tp = getres(mp, 0); error = creatproto(&tp, pip, mode | S_IFDIR, 0, &creds, fsxp, &ip); @@ -878,6 +915,18 @@ parseproto( libxfs_trans_log_inode(tp, pip, XFS_ILOG_CORE); } newdirectory(mp, tp, ip, pip); + + /* Copy timestamps from source file to destination inode */ + error = stat(fname, &statbuf); + if (error < 0) + fail(_("unable to stat file to copyin"), errno); + VFS_I(ip)->__i_atime.tv_sec = statbuf.st_atime; + VFS_I(ip)->__i_mtime.tv_sec = statbuf.st_mtime; + VFS_I(ip)->__i_ctime.tv_sec = statbuf.st_ctime; + VFS_I(ip)->__i_atime.tv_nsec = statbuf.st_atim.tv_nsec; + VFS_I(ip)->__i_mtime.tv_nsec = statbuf.st_mtim.tv_nsec; + VFS_I(ip)->__i_ctime.tv_nsec = statbuf.st_ctim.tv_nsec; + libxfs_trans_log_inode(tp, ip, flags); error = -libxfs_trans_commit(tp); if (error) -- 2.49.0