aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@infradead.org>2011-09-14 10:08:26 -0400
committerAlex Elder <aelder@sgi.com>2011-10-11 22:15:09 -0400
commit87c7bec7fc3377b3873eb3a0f4b603981ea16ebb (patch)
treeabe143d8f76e4d95f2158134913b10fc9be6def1 /fs/xfs
parent1da2f2dbf2d2aaa1b0f6ca2f61fcf07e24eb659b (diff)
xfs: fix buffer flushing during unmount
The code to flush buffers in the umount code is a bit iffy: we first flush all delwri buffers out, but then might be able to queue up a new one when logging the sb counts. On a normal shutdown that one would get flushed out when doing the synchronous superblock write in xfs_unmountfs_writesb, but we skip that one if the filesystem has been shut down. Fix this by moving the delwri list flushing until just before unmounting the log, and while we're at it also remove the superflous delwri list and buffer lru flusing for the rt and log device that can never have cached or delwri buffers. Signed-off-by: Christoph Hellwig <hch@lst.de> Reported-by: Amit Sahrawat <amit.sahrawat83@gmail.com> Tested-by: Amit Sahrawat <amit.sahrawat83@gmail.com> Signed-off-by: Alex Elder <aelder@sgi.com>
Diffstat (limited to 'fs/xfs')
-rw-r--r--fs/xfs/xfs_buf.h1
-rw-r--r--fs/xfs/xfs_mount.c29
2 files changed, 10 insertions, 20 deletions
diff --git a/fs/xfs/xfs_buf.h b/fs/xfs/xfs_buf.h
index c23826685d3..200f59138b8 100644
--- a/fs/xfs/xfs_buf.h
+++ b/fs/xfs/xfs_buf.h
@@ -318,7 +318,6 @@ extern struct list_head *xfs_get_buftarg_list(void);
318#define xfs_getsize_buftarg(buftarg) block_size((buftarg)->bt_bdev) 318#define xfs_getsize_buftarg(buftarg) block_size((buftarg)->bt_bdev)
319#define xfs_readonly_buftarg(buftarg) bdev_read_only((buftarg)->bt_bdev) 319#define xfs_readonly_buftarg(buftarg) bdev_read_only((buftarg)->bt_bdev)
320 320
321#define xfs_binval(buftarg) xfs_flush_buftarg(buftarg, 1)
322#define XFS_bflush(buftarg) xfs_flush_buftarg(buftarg, 1) 321#define XFS_bflush(buftarg) xfs_flush_buftarg(buftarg, 1)
323 322
324#endif /* __XFS_BUF_H__ */ 323#endif /* __XFS_BUF_H__ */
diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c
index a957e437bee..e8fe1cb5409 100644
--- a/fs/xfs/xfs_mount.c
+++ b/fs/xfs/xfs_mount.c
@@ -44,9 +44,6 @@
44#include "xfs_trace.h" 44#include "xfs_trace.h"
45 45
46 46
47STATIC void xfs_unmountfs_wait(xfs_mount_t *);
48
49
50#ifdef HAVE_PERCPU_SB 47#ifdef HAVE_PERCPU_SB
51STATIC void xfs_icsb_balance_counter(xfs_mount_t *, xfs_sb_field_t, 48STATIC void xfs_icsb_balance_counter(xfs_mount_t *, xfs_sb_field_t,
52 int); 49 int);
@@ -1496,11 +1493,6 @@ xfs_unmountfs(
1496 */ 1493 */
1497 xfs_log_force(mp, XFS_LOG_SYNC); 1494 xfs_log_force(mp, XFS_LOG_SYNC);
1498 1495
1499 xfs_binval(mp->m_ddev_targp);
1500 if (mp->m_rtdev_targp) {
1501 xfs_binval(mp->m_rtdev_targp);
1502 }
1503
1504 /* 1496 /*
1505 * Unreserve any blocks we have so that when we unmount we don't account 1497 * Unreserve any blocks we have so that when we unmount we don't account
1506 * the reserved free space as used. This is really only necessary for 1498 * the reserved free space as used. This is really only necessary for
@@ -1526,7 +1518,16 @@ xfs_unmountfs(
1526 xfs_warn(mp, "Unable to update superblock counters. " 1518 xfs_warn(mp, "Unable to update superblock counters. "
1527 "Freespace may not be correct on next mount."); 1519 "Freespace may not be correct on next mount.");
1528 xfs_unmountfs_writesb(mp); 1520 xfs_unmountfs_writesb(mp);
1529 xfs_unmountfs_wait(mp); /* wait for async bufs */ 1521
1522 /*
1523 * Make sure all buffers have been flushed and completed before
1524 * unmounting the log.
1525 */
1526 error = xfs_flush_buftarg(mp->m_ddev_targp, 1);
1527 if (error)
1528 xfs_warn(mp, "%d busy buffers during unmount.", error);
1529 xfs_wait_buftarg(mp->m_ddev_targp);
1530
1530 xfs_log_unmount_write(mp); 1531 xfs_log_unmount_write(mp);
1531 xfs_log_unmount(mp); 1532 xfs_log_unmount(mp);
1532 xfs_uuid_unmount(mp); 1533 xfs_uuid_unmount(mp);
@@ -1537,16 +1538,6 @@ xfs_unmountfs(
1537 xfs_free_perag(mp); 1538 xfs_free_perag(mp);
1538} 1539}
1539 1540
1540STATIC void
1541xfs_unmountfs_wait(xfs_mount_t *mp)
1542{
1543 if (mp->m_logdev_targp != mp->m_ddev_targp)
1544 xfs_wait_buftarg(mp->m_logdev_targp);
1545 if (mp->m_rtdev_targp)
1546 xfs_wait_buftarg(mp->m_rtdev_targp);
1547 xfs_wait_buftarg(mp->m_ddev_targp);
1548}
1549
1550int 1541int
1551xfs_fs_writable(xfs_mount_t *mp) 1542xfs_fs_writable(xfs_mount_t *mp)
1552{ 1543{