aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/xfs/xfs_iops.c45
-rw-r--r--fs/xfs/xfs_super.c56
-rw-r--r--fs/xfs/xfs_trace.h2
3 files changed, 46 insertions, 57 deletions
diff --git a/fs/xfs/xfs_iops.c b/fs/xfs/xfs_iops.c
index 1a25fd802798..5439c3f99458 100644
--- a/fs/xfs/xfs_iops.c
+++ b/fs/xfs/xfs_iops.c
@@ -897,6 +897,47 @@ xfs_vn_setattr(
897 return -xfs_setattr_nonsize(XFS_I(dentry->d_inode), iattr, 0); 897 return -xfs_setattr_nonsize(XFS_I(dentry->d_inode), iattr, 0);
898} 898}
899 899
900STATIC int
901xfs_vn_update_time(
902 struct inode *inode,
903 struct timespec *now,
904 int flags)
905{
906 struct xfs_inode *ip = XFS_I(inode);
907 struct xfs_mount *mp = ip->i_mount;
908 struct xfs_trans *tp;
909 int error;
910
911 trace_xfs_update_time(ip);
912
913 tp = xfs_trans_alloc(mp, XFS_TRANS_FSYNC_TS);
914 error = xfs_trans_reserve(tp, 0, XFS_FSYNC_TS_LOG_RES(mp), 0, 0, 0);
915 if (error) {
916 xfs_trans_cancel(tp, 0);
917 return -error;
918 }
919
920 xfs_ilock(ip, XFS_ILOCK_EXCL);
921 if (flags & S_CTIME) {
922 inode->i_ctime = *now;
923 ip->i_d.di_ctime.t_sec = (__int32_t)now->tv_sec;
924 ip->i_d.di_ctime.t_nsec = (__int32_t)now->tv_nsec;
925 }
926 if (flags & S_MTIME) {
927 inode->i_mtime = *now;
928 ip->i_d.di_mtime.t_sec = (__int32_t)now->tv_sec;
929 ip->i_d.di_mtime.t_nsec = (__int32_t)now->tv_nsec;
930 }
931 if (flags & S_ATIME) {
932 inode->i_atime = *now;
933 ip->i_d.di_atime.t_sec = (__int32_t)now->tv_sec;
934 ip->i_d.di_atime.t_nsec = (__int32_t)now->tv_nsec;
935 }
936 xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL);
937 xfs_trans_log_inode(tp, ip, XFS_ILOG_TIMESTAMP);
938 return -xfs_trans_commit(tp, 0);
939}
940
900#define XFS_FIEMAP_FLAGS (FIEMAP_FLAG_SYNC|FIEMAP_FLAG_XATTR) 941#define XFS_FIEMAP_FLAGS (FIEMAP_FLAG_SYNC|FIEMAP_FLAG_XATTR)
901 942
902/* 943/*
@@ -991,6 +1032,7 @@ static const struct inode_operations xfs_inode_operations = {
991 .removexattr = generic_removexattr, 1032 .removexattr = generic_removexattr,
992 .listxattr = xfs_vn_listxattr, 1033 .listxattr = xfs_vn_listxattr,
993 .fiemap = xfs_vn_fiemap, 1034 .fiemap = xfs_vn_fiemap,
1035 .update_time = xfs_vn_update_time,
994}; 1036};
995 1037
996static const struct inode_operations xfs_dir_inode_operations = { 1038static const struct inode_operations xfs_dir_inode_operations = {
@@ -1016,6 +1058,7 @@ static const struct inode_operations xfs_dir_inode_operations = {
1016 .getxattr = generic_getxattr, 1058 .getxattr = generic_getxattr,
1017 .removexattr = generic_removexattr, 1059 .removexattr = generic_removexattr,
1018 .listxattr = xfs_vn_listxattr, 1060 .listxattr = xfs_vn_listxattr,
1061 .update_time = xfs_vn_update_time,
1019}; 1062};
1020 1063
1021static const struct inode_operations xfs_dir_ci_inode_operations = { 1064static const struct inode_operations xfs_dir_ci_inode_operations = {
@@ -1041,6 +1084,7 @@ static const struct inode_operations xfs_dir_ci_inode_operations = {
1041 .getxattr = generic_getxattr, 1084 .getxattr = generic_getxattr,
1042 .removexattr = generic_removexattr, 1085 .removexattr = generic_removexattr,
1043 .listxattr = xfs_vn_listxattr, 1086 .listxattr = xfs_vn_listxattr,
1087 .update_time = xfs_vn_update_time,
1044}; 1088};
1045 1089
1046static const struct inode_operations xfs_symlink_inode_operations = { 1090static const struct inode_operations xfs_symlink_inode_operations = {
@@ -1054,6 +1098,7 @@ static const struct inode_operations xfs_symlink_inode_operations = {
1054 .getxattr = generic_getxattr, 1098 .getxattr = generic_getxattr,
1055 .removexattr = generic_removexattr, 1099 .removexattr = generic_removexattr,
1056 .listxattr = xfs_vn_listxattr, 1100 .listxattr = xfs_vn_listxattr,
1101 .update_time = xfs_vn_update_time,
1057}; 1102};
1058 1103
1059STATIC void 1104STATIC void
diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c
index 07f70e17c745..cb2deb13b063 100644
--- a/fs/xfs/xfs_super.c
+++ b/fs/xfs/xfs_super.c
@@ -868,61 +868,6 @@ xfs_fs_inode_init_once(
868 "xfsino", ip->i_ino); 868 "xfsino", ip->i_ino);
869} 869}
870 870
871/*
872 * This is called by the VFS when dirtying inode metadata. This can happen
873 * for a few reasons, but we only care about timestamp updates, given that
874 * we handled the rest ourselves. In theory no other calls should happen,
875 * but for example generic_write_end() keeps dirtying the inode after
876 * updating i_size. Thus we check that the flags are exactly I_DIRTY_SYNC,
877 * and skip this call otherwise.
878 *
879 * We'll hopefull get a different method just for updating timestamps soon,
880 * at which point this hack can go away, and maybe we'll also get real
881 * error handling here.
882 */
883STATIC void
884xfs_fs_dirty_inode(
885 struct inode *inode,
886 int flags)
887{
888 struct xfs_inode *ip = XFS_I(inode);
889 struct xfs_mount *mp = ip->i_mount;
890 struct xfs_trans *tp;
891 int error;
892
893 if (flags != I_DIRTY_SYNC)
894 return;
895
896 trace_xfs_dirty_inode(ip);
897
898 tp = xfs_trans_alloc(mp, XFS_TRANS_FSYNC_TS);
899 error = xfs_trans_reserve(tp, 0, XFS_FSYNC_TS_LOG_RES(mp), 0, 0, 0);
900 if (error) {
901 xfs_trans_cancel(tp, 0);
902 goto trouble;
903 }
904 xfs_ilock(ip, XFS_ILOCK_EXCL);
905 /*
906 * Grab all the latest timestamps from the Linux inode.
907 */
908 ip->i_d.di_atime.t_sec = (__int32_t)inode->i_atime.tv_sec;
909 ip->i_d.di_atime.t_nsec = (__int32_t)inode->i_atime.tv_nsec;
910 ip->i_d.di_ctime.t_sec = (__int32_t)inode->i_ctime.tv_sec;
911 ip->i_d.di_ctime.t_nsec = (__int32_t)inode->i_ctime.tv_nsec;
912 ip->i_d.di_mtime.t_sec = (__int32_t)inode->i_mtime.tv_sec;
913 ip->i_d.di_mtime.t_nsec = (__int32_t)inode->i_mtime.tv_nsec;
914
915 xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL);
916 xfs_trans_log_inode(tp, ip, XFS_ILOG_TIMESTAMP);
917 error = xfs_trans_commit(tp, 0);
918 if (error)
919 goto trouble;
920 return;
921
922trouble:
923 xfs_warn(mp, "failed to update timestamps for inode 0x%llx", ip->i_ino);
924}
925
926STATIC void 871STATIC void
927xfs_fs_evict_inode( 872xfs_fs_evict_inode(
928 struct inode *inode) 873 struct inode *inode)
@@ -1436,7 +1381,6 @@ xfs_fs_free_cached_objects(
1436static const struct super_operations xfs_super_operations = { 1381static const struct super_operations xfs_super_operations = {
1437 .alloc_inode = xfs_fs_alloc_inode, 1382 .alloc_inode = xfs_fs_alloc_inode,
1438 .destroy_inode = xfs_fs_destroy_inode, 1383 .destroy_inode = xfs_fs_destroy_inode,
1439 .dirty_inode = xfs_fs_dirty_inode,
1440 .evict_inode = xfs_fs_evict_inode, 1384 .evict_inode = xfs_fs_evict_inode,
1441 .drop_inode = xfs_fs_drop_inode, 1385 .drop_inode = xfs_fs_drop_inode,
1442 .put_super = xfs_fs_put_super, 1386 .put_super = xfs_fs_put_super,
diff --git a/fs/xfs/xfs_trace.h b/fs/xfs/xfs_trace.h
index caf5dabfd553..e5795dd6013a 100644
--- a/fs/xfs/xfs_trace.h
+++ b/fs/xfs/xfs_trace.h
@@ -578,8 +578,8 @@ DEFINE_INODE_EVENT(xfs_ioctl_setattr);
578DEFINE_INODE_EVENT(xfs_dir_fsync); 578DEFINE_INODE_EVENT(xfs_dir_fsync);
579DEFINE_INODE_EVENT(xfs_file_fsync); 579DEFINE_INODE_EVENT(xfs_file_fsync);
580DEFINE_INODE_EVENT(xfs_destroy_inode); 580DEFINE_INODE_EVENT(xfs_destroy_inode);
581DEFINE_INODE_EVENT(xfs_dirty_inode);
582DEFINE_INODE_EVENT(xfs_evict_inode); 581DEFINE_INODE_EVENT(xfs_evict_inode);
582DEFINE_INODE_EVENT(xfs_update_time);
583 583
584DEFINE_INODE_EVENT(xfs_dquot_dqalloc); 584DEFINE_INODE_EVENT(xfs_dquot_dqalloc);
585DEFINE_INODE_EVENT(xfs_dquot_dqdetach); 585DEFINE_INODE_EVENT(xfs_dquot_dqdetach);