|
@@ -897,6 +897,47 @@ xfs_vn_setattr(
|
|
|
return -xfs_setattr_nonsize(XFS_I(dentry->d_inode), iattr, 0);
|
|
|
}
|
|
|
|
|
|
+STATIC int
|
|
|
+xfs_vn_update_time(
|
|
|
+ struct inode *inode,
|
|
|
+ struct timespec *now,
|
|
|
+ int flags)
|
|
|
+{
|
|
|
+ struct xfs_inode *ip = XFS_I(inode);
|
|
|
+ struct xfs_mount *mp = ip->i_mount;
|
|
|
+ struct xfs_trans *tp;
|
|
|
+ int error;
|
|
|
+
|
|
|
+ trace_xfs_update_time(ip);
|
|
|
+
|
|
|
+ tp = xfs_trans_alloc(mp, XFS_TRANS_FSYNC_TS);
|
|
|
+ error = xfs_trans_reserve(tp, 0, XFS_FSYNC_TS_LOG_RES(mp), 0, 0, 0);
|
|
|
+ if (error) {
|
|
|
+ xfs_trans_cancel(tp, 0);
|
|
|
+ return -error;
|
|
|
+ }
|
|
|
+
|
|
|
+ xfs_ilock(ip, XFS_ILOCK_EXCL);
|
|
|
+ if (flags & S_CTIME) {
|
|
|
+ inode->i_ctime = *now;
|
|
|
+ ip->i_d.di_ctime.t_sec = (__int32_t)now->tv_sec;
|
|
|
+ ip->i_d.di_ctime.t_nsec = (__int32_t)now->tv_nsec;
|
|
|
+ }
|
|
|
+ if (flags & S_MTIME) {
|
|
|
+ inode->i_mtime = *now;
|
|
|
+ ip->i_d.di_mtime.t_sec = (__int32_t)now->tv_sec;
|
|
|
+ ip->i_d.di_mtime.t_nsec = (__int32_t)now->tv_nsec;
|
|
|
+ }
|
|
|
+ if (flags & S_ATIME) {
|
|
|
+ inode->i_atime = *now;
|
|
|
+ ip->i_d.di_atime.t_sec = (__int32_t)now->tv_sec;
|
|
|
+ ip->i_d.di_atime.t_nsec = (__int32_t)now->tv_nsec;
|
|
|
+ }
|
|
|
+ xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL);
|
|
|
+ xfs_trans_log_inode(tp, ip, XFS_ILOG_TIMESTAMP);
|
|
|
+ return -xfs_trans_commit(tp, 0);
|
|
|
+}
|
|
|
+
|
|
|
#define XFS_FIEMAP_FLAGS (FIEMAP_FLAG_SYNC|FIEMAP_FLAG_XATTR)
|
|
|
|
|
|
/*
|
|
@@ -991,6 +1032,7 @@ static const struct inode_operations xfs_inode_operations = {
|
|
|
.removexattr = generic_removexattr,
|
|
|
.listxattr = xfs_vn_listxattr,
|
|
|
.fiemap = xfs_vn_fiemap,
|
|
|
+ .update_time = xfs_vn_update_time,
|
|
|
};
|
|
|
|
|
|
static const struct inode_operations xfs_dir_inode_operations = {
|
|
@@ -1016,6 +1058,7 @@ static const struct inode_operations xfs_dir_inode_operations = {
|
|
|
.getxattr = generic_getxattr,
|
|
|
.removexattr = generic_removexattr,
|
|
|
.listxattr = xfs_vn_listxattr,
|
|
|
+ .update_time = xfs_vn_update_time,
|
|
|
};
|
|
|
|
|
|
static const struct inode_operations xfs_dir_ci_inode_operations = {
|
|
@@ -1041,6 +1084,7 @@ static const struct inode_operations xfs_dir_ci_inode_operations = {
|
|
|
.getxattr = generic_getxattr,
|
|
|
.removexattr = generic_removexattr,
|
|
|
.listxattr = xfs_vn_listxattr,
|
|
|
+ .update_time = xfs_vn_update_time,
|
|
|
};
|
|
|
|
|
|
static const struct inode_operations xfs_symlink_inode_operations = {
|
|
@@ -1054,6 +1098,7 @@ static const struct inode_operations xfs_symlink_inode_operations = {
|
|
|
.getxattr = generic_getxattr,
|
|
|
.removexattr = generic_removexattr,
|
|
|
.listxattr = xfs_vn_listxattr,
|
|
|
+ .update_time = xfs_vn_update_time,
|
|
|
};
|
|
|
|
|
|
STATIC void
|