aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@infradead.org>2011-11-19 13:13:39 -0500
committerGreg Kroah-Hartman <gregkh@suse.de>2011-11-26 12:10:07 -0500
commitae6c19cd6c32f88b2d8549984ff2a5fcdcc932b2 (patch)
tree130f035ba9104d9316c3e7de73cc10e10810d940 /fs/xfs
parent7d7e5d33408819c084528dcff139fc4564c7bdda (diff)
xfs: fix ->write_inode return values
patch 58d84c4ee0389ddeb86238d5d8359a982c9f7a5b upstream. Currently we always redirty an inode that was attempted to be written out synchronously but has been cleaned by an AIL pushed internall, which is rather bogus. Fix that by doing the i_update_core check early on and return 0 for it. Also include async calls for it, as doing any work for those is just as pointless. While we're at it also fix the sign for the EIO return in case of a filesystem shutdown, and fix the completely non-sensical locking around xfs_log_inode. Signed-off-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Dave Chinner <dchinner@redhat.com> Signed-off-by: Alex Elder <aelder@sgi.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'fs/xfs')
-rw-r--r--fs/xfs/linux-2.6/xfs_super.c34
1 files changed, 9 insertions, 25 deletions
diff --git a/fs/xfs/linux-2.6/xfs_super.c b/fs/xfs/linux-2.6/xfs_super.c
index 347cae965e8..28de70b9122 100644
--- a/fs/xfs/linux-2.6/xfs_super.c
+++ b/fs/xfs/linux-2.6/xfs_super.c
@@ -878,33 +878,17 @@ xfs_log_inode(
878 struct xfs_trans *tp; 878 struct xfs_trans *tp;
879 int error; 879 int error;
880 880
881 xfs_iunlock(ip, XFS_ILOCK_SHARED);
882 tp = xfs_trans_alloc(mp, XFS_TRANS_FSYNC_TS); 881 tp = xfs_trans_alloc(mp, XFS_TRANS_FSYNC_TS);
883 error = xfs_trans_reserve(tp, 0, XFS_FSYNC_TS_LOG_RES(mp), 0, 0, 0); 882 error = xfs_trans_reserve(tp, 0, XFS_FSYNC_TS_LOG_RES(mp), 0, 0, 0);
884
885 if (error) { 883 if (error) {
886 xfs_trans_cancel(tp, 0); 884 xfs_trans_cancel(tp, 0);
887 /* we need to return with the lock hold shared */
888 xfs_ilock(ip, XFS_ILOCK_SHARED);
889 return error; 885 return error;
890 } 886 }
891 887
892 xfs_ilock(ip, XFS_ILOCK_EXCL); 888 xfs_ilock(ip, XFS_ILOCK_EXCL);
893 889 xfs_trans_ijoin_ref(tp, ip, XFS_ILOCK_EXCL);
894 /*
895 * Note - it's possible that we might have pushed ourselves out of the
896 * way during trans_reserve which would flush the inode. But there's
897 * no guarantee that the inode buffer has actually gone out yet (it's
898 * delwri). Plus the buffer could be pinned anyway if it's part of
899 * an inode in another recent transaction. So we play it safe and
900 * fire off the transaction anyway.
901 */
902 xfs_trans_ijoin(tp, ip);
903 xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); 890 xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
904 error = xfs_trans_commit(tp, 0); 891 return xfs_trans_commit(tp, 0);
905 xfs_ilock_demote(ip, XFS_ILOCK_EXCL);
906
907 return error;
908} 892}
909 893
910STATIC int 894STATIC int
@@ -919,7 +903,9 @@ xfs_fs_write_inode(
919 trace_xfs_write_inode(ip); 903 trace_xfs_write_inode(ip);
920 904
921 if (XFS_FORCED_SHUTDOWN(mp)) 905 if (XFS_FORCED_SHUTDOWN(mp))
922 return XFS_ERROR(EIO); 906 return -XFS_ERROR(EIO);
907 if (!ip->i_update_core)
908 return 0;
923 909
924 if (wbc->sync_mode == WB_SYNC_ALL) { 910 if (wbc->sync_mode == WB_SYNC_ALL) {
925 /* 911 /*
@@ -930,12 +916,10 @@ xfs_fs_write_inode(
930 * of synchronous log foces dramatically. 916 * of synchronous log foces dramatically.
931 */ 917 */
932 xfs_ioend_wait(ip); 918 xfs_ioend_wait(ip);
933 xfs_ilock(ip, XFS_ILOCK_SHARED); 919 error = xfs_log_inode(ip);
934 if (ip->i_update_core) { 920 if (error)
935 error = xfs_log_inode(ip); 921 goto out;
936 if (error) 922 return 0;
937 goto out_unlock;
938 }
939 } else { 923 } else {
940 /* 924 /*
941 * We make this non-blocking if the inode is contended, return 925 * We make this non-blocking if the inode is contended, return