aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_super.c
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@infradead.org>2012-02-29 04:53:52 -0500
committerBen Myers <bpm@sgi.com>2012-03-13 18:01:15 -0400
commit8a9c9980f24f6d86e0ec0150ed35fba45d0c9f88 (patch)
treedf976343a603bad7e6bdc20db31c64f752312434 /fs/xfs/xfs_super.c
parent281627df3eb55e1b729b9bb06fff5ff112929646 (diff)
xfs: log timestamp updates
Timestamps on regular files are the last metadata that XFS does not update transactionally. Now that we use the delaylog mode exclusively and made the log scode scale extremly well there is no need to bypass that code for timestamp updates. Logging all updates allows to drop a lot of code, and will allow for further performance improvements later on. Note that this patch drops optimized handling of fdatasync - it will be added back in a separate commit. Reviewed-by: Dave Chinner <dchinner@redhat.com> Signed-off-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Mark Tinguely <tinguely@sgi.com> Signed-off-by: Ben Myers <bpm@sgi.com>
Diffstat (limited to 'fs/xfs/xfs_super.c')
-rw-r--r--fs/xfs/xfs_super.c108
1 files changed, 37 insertions, 71 deletions
diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c
index c7f7bc2855a4..e602c8c67c5c 100644
--- a/fs/xfs/xfs_super.c
+++ b/fs/xfs/xfs_super.c
@@ -863,91 +863,58 @@ xfs_fs_inode_init_once(
863} 863}
864 864
865/* 865/*
866 * Dirty the XFS inode when mark_inode_dirty_sync() is called so that 866 * This is called by the VFS when dirtying inode metadata. This can happen
867 * we catch unlogged VFS level updates to the inode. 867 * for a few reasons, but we only care about timestamp updates, given that
868 * we handled the rest ourselves. In theory no other calls should happen,
869 * but for example generic_write_end() keeps dirtying the inode after
870 * updating i_size. Thus we check that the flags are exactly I_DIRTY_SYNC,
871 * and skip this call otherwise.
868 * 872 *
869 * We need the barrier() to maintain correct ordering between unlogged 873 * We'll hopefull get a different method just for updating timestamps soon,
870 * updates and the transaction commit code that clears the i_update_core 874 * at which point this hack can go away, and maybe we'll also get real
871 * field. This requires all updates to be completed before marking the 875 * error handling here.
872 * inode dirty.
873 */ 876 */
874STATIC void 877STATIC void
875xfs_fs_dirty_inode( 878xfs_fs_dirty_inode(
876 struct inode *inode,
877 int flags)
878{
879 barrier();
880 XFS_I(inode)->i_update_core = 1;
881}
882
883STATIC int
884xfs_fs_write_inode(
885 struct inode *inode, 879 struct inode *inode,
886 struct writeback_control *wbc) 880 int flags)
887{ 881{
888 struct xfs_inode *ip = XFS_I(inode); 882 struct xfs_inode *ip = XFS_I(inode);
889 struct xfs_mount *mp = ip->i_mount; 883 struct xfs_mount *mp = ip->i_mount;
890 int error = EAGAIN; 884 struct xfs_trans *tp;
891 885 int error;
892 trace_xfs_write_inode(ip);
893
894 if (XFS_FORCED_SHUTDOWN(mp))
895 return -XFS_ERROR(EIO);
896
897 if (wbc->sync_mode == WB_SYNC_ALL || wbc->for_kupdate) {
898 /*
899 * Make sure the inode has made it it into the log. Instead
900 * of forcing it all the way to stable storage using a
901 * synchronous transaction we let the log force inside the
902 * ->sync_fs call do that for thus, which reduces the number
903 * of synchronous log forces dramatically.
904 */
905 error = xfs_log_dirty_inode(ip, NULL, 0);
906 if (error)
907 goto out;
908 return 0;
909 } else {
910 if (!ip->i_update_core)
911 return 0;
912 886
913 /* 887 if (flags != I_DIRTY_SYNC)
914 * We make this non-blocking if the inode is contended, return 888 return;
915 * EAGAIN to indicate to the caller that they did not succeed.
916 * This prevents the flush path from blocking on inodes inside
917 * another operation right now, they get caught later by
918 * xfs_sync.
919 */
920 if (!xfs_ilock_nowait(ip, XFS_ILOCK_SHARED))
921 goto out;
922 889
923 if (xfs_ipincount(ip) || !xfs_iflock_nowait(ip)) 890 trace_xfs_dirty_inode(ip);
924 goto out_unlock;
925 891
926 /* 892 tp = xfs_trans_alloc(mp, XFS_TRANS_FSYNC_TS);
927 * Now we have the flush lock and the inode is not pinned, we 893 error = xfs_trans_reserve(tp, 0, XFS_FSYNC_TS_LOG_RES(mp), 0, 0, 0);
928 * can check if the inode is really clean as we know that 894 if (error) {
929 * there are no pending transaction completions, it is not 895 xfs_trans_cancel(tp, 0);
930 * waiting on the delayed write queue and there is no IO in 896 goto trouble;
931 * progress.
932 */
933 if (xfs_inode_clean(ip)) {
934 xfs_ifunlock(ip);
935 error = 0;
936 goto out_unlock;
937 }
938 error = xfs_iflush(ip, SYNC_TRYLOCK);
939 } 897 }
940 898 xfs_ilock(ip, XFS_ILOCK_EXCL);
941 out_unlock:
942 xfs_iunlock(ip, XFS_ILOCK_SHARED);
943 out:
944 /* 899 /*
945 * if we failed to write out the inode then mark 900 * Grab all the latest timestamps from the Linux inode.
946 * it dirty again so we'll try again later.
947 */ 901 */
902 ip->i_d.di_atime.t_sec = (__int32_t)inode->i_atime.tv_sec;
903 ip->i_d.di_atime.t_nsec = (__int32_t)inode->i_atime.tv_nsec;
904 ip->i_d.di_ctime.t_sec = (__int32_t)inode->i_ctime.tv_sec;
905 ip->i_d.di_ctime.t_nsec = (__int32_t)inode->i_ctime.tv_nsec;
906 ip->i_d.di_mtime.t_sec = (__int32_t)inode->i_mtime.tv_sec;
907 ip->i_d.di_mtime.t_nsec = (__int32_t)inode->i_mtime.tv_nsec;
908
909 xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL);
910 xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
911 error = xfs_trans_commit(tp, 0);
948 if (error) 912 if (error)
949 xfs_mark_inode_dirty_sync(ip); 913 goto trouble;
950 return -error; 914 return;
915
916trouble:
917 xfs_warn(mp, "failed to update timestamps for inode 0x%llx", ip->i_ino);
951} 918}
952 919
953STATIC void 920STATIC void
@@ -1466,7 +1433,6 @@ static const struct super_operations xfs_super_operations = {
1466 .alloc_inode = xfs_fs_alloc_inode, 1433 .alloc_inode = xfs_fs_alloc_inode,
1467 .destroy_inode = xfs_fs_destroy_inode, 1434 .destroy_inode = xfs_fs_destroy_inode,
1468 .dirty_inode = xfs_fs_dirty_inode, 1435 .dirty_inode = xfs_fs_dirty_inode,
1469 .write_inode = xfs_fs_write_inode,
1470 .evict_inode = xfs_fs_evict_inode, 1436 .evict_inode = xfs_fs_evict_inode,
1471 .put_super = xfs_fs_put_super, 1437 .put_super = xfs_fs_put_super,
1472 .sync_fs = xfs_fs_sync_fs, 1438 .sync_fs = xfs_fs_sync_fs,