aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@infradead.org>2011-08-27 01:57:55 -0400
committerAlex Elder <aelder@sgi.com>2011-09-01 10:46:11 -0400
commit58d84c4ee0389ddeb86238d5d8359a982c9f7a5b (patch)
treec43d68e71407f45b4ecde6c2602d979ca1d03c34 /fs
parent866e4ed77448a0c311e1b055eb72ea05423fd799 (diff)
xfs: fix ->write_inode return values
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> (cherry picked from commit 297db93bb74cf687510313eb235a7aec14d67e97) Signed-off-by: Alex Elder <aelder@sgi.com>
Diffstat (limited to 'fs')
-rw-r--r--fs/xfs/xfs_super.c34
1 files changed, 9 insertions, 25 deletions
diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c
index c1b022f20d35..2366c54cc4fa 100644
--- a/fs/xfs/xfs_super.c
+++ b/fs/xfs/xfs_super.c
@@ -879,33 +879,17 @@ xfs_log_inode(
879 struct xfs_trans *tp; 879 struct xfs_trans *tp;
880 int error; 880 int error;
881 881
882 xfs_iunlock(ip, XFS_ILOCK_SHARED);
883 tp = xfs_trans_alloc(mp, XFS_TRANS_FSYNC_TS); 882 tp = xfs_trans_alloc(mp, XFS_TRANS_FSYNC_TS);
884 error = xfs_trans_reserve(tp, 0, XFS_FSYNC_TS_LOG_RES(mp), 0, 0, 0); 883 error = xfs_trans_reserve(tp, 0, XFS_FSYNC_TS_LOG_RES(mp), 0, 0, 0);
885
886 if (error) { 884 if (error) {
887 xfs_trans_cancel(tp, 0); 885 xfs_trans_cancel(tp, 0);
888 /* we need to return with the lock hold shared */
889 xfs_ilock(ip, XFS_ILOCK_SHARED);
890 return error; 886 return error;
891 } 887 }
892 888
893 xfs_ilock(ip, XFS_ILOCK_EXCL); 889 xfs_ilock(ip, XFS_ILOCK_EXCL);
894 890 xfs_trans_ijoin_ref(tp, ip, XFS_ILOCK_EXCL);
895 /*
896 * Note - it's possible that we might have pushed ourselves out of the
897 * way during trans_reserve which would flush the inode. But there's
898 * no guarantee that the inode buffer has actually gone out yet (it's
899 * delwri). Plus the buffer could be pinned anyway if it's part of
900 * an inode in another recent transaction. So we play it safe and
901 * fire off the transaction anyway.
902 */
903 xfs_trans_ijoin(tp, ip);
904 xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); 891 xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
905 error = xfs_trans_commit(tp, 0); 892 return xfs_trans_commit(tp, 0);
906 xfs_ilock_demote(ip, XFS_ILOCK_EXCL);
907
908 return error;
909} 893}
910 894
911STATIC int 895STATIC int
@@ -920,7 +904,9 @@ xfs_fs_write_inode(
920 trace_xfs_write_inode(ip); 904 trace_xfs_write_inode(ip);
921 905
922 if (XFS_FORCED_SHUTDOWN(mp)) 906 if (XFS_FORCED_SHUTDOWN(mp))
923 return XFS_ERROR(EIO); 907 return -XFS_ERROR(EIO);
908 if (!ip->i_update_core)
909 return 0;
924 910
925 if (wbc->sync_mode == WB_SYNC_ALL) { 911 if (wbc->sync_mode == WB_SYNC_ALL) {
926 /* 912 /*
@@ -931,12 +917,10 @@ xfs_fs_write_inode(
931 * of synchronous log foces dramatically. 917 * of synchronous log foces dramatically.
932 */ 918 */
933 xfs_ioend_wait(ip); 919 xfs_ioend_wait(ip);
934 xfs_ilock(ip, XFS_ILOCK_SHARED); 920 error = xfs_log_inode(ip);
935 if (ip->i_update_core) { 921 if (error)
936 error = xfs_log_inode(ip); 922 goto out;
937 if (error) 923 return 0;
938 goto out_unlock;
939 }
940 } else { 924 } else {
941 /* 925 /*
942 * We make this non-blocking if the inode is contended, return 926 * We make this non-blocking if the inode is contended, return