aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_mount.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/xfs/xfs_mount.c')
-rw-r--r--fs/xfs/xfs_mount.c56
1 files changed, 12 insertions, 44 deletions
diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c
index 1ffead4b2296..385a3b11d3dd 100644
--- a/fs/xfs/xfs_mount.c
+++ b/fs/xfs/xfs_mount.c
@@ -22,6 +22,7 @@
22#include "xfs_log.h" 22#include "xfs_log.h"
23#include "xfs_inum.h" 23#include "xfs_inum.h"
24#include "xfs_trans.h" 24#include "xfs_trans.h"
25#include "xfs_trans_priv.h"
25#include "xfs_sb.h" 26#include "xfs_sb.h"
26#include "xfs_ag.h" 27#include "xfs_ag.h"
27#include "xfs_dir2.h" 28#include "xfs_dir2.h"
@@ -1475,15 +1476,15 @@ xfs_unmountfs(
1475 xfs_log_force(mp, XFS_LOG_SYNC); 1476 xfs_log_force(mp, XFS_LOG_SYNC);
1476 1477
1477 /* 1478 /*
1478 * Do a delwri reclaim pass first so that as many dirty inodes are 1479 * Flush all pending changes from the AIL.
1479 * queued up for IO as possible. Then flush the buffers before making 1480 */
1480 * a synchronous path to catch all the remaining inodes are reclaimed. 1481 xfs_ail_push_all_sync(mp->m_ail);
1481 * This makes the reclaim process as quick as possible by avoiding 1482
1482 * synchronous writeout and blocking on inodes already in the delwri 1483 /*
1483 * state as much as possible. 1484 * And reclaim all inodes. At this point there should be no dirty
1485 * inode, and none should be pinned or locked, but use synchronous
1486 * reclaim just to be sure.
1484 */ 1487 */
1485 xfs_reclaim_inodes(mp, 0);
1486 xfs_flush_buftarg(mp->m_ddev_targp, 1);
1487 xfs_reclaim_inodes(mp, SYNC_WAIT); 1488 xfs_reclaim_inodes(mp, SYNC_WAIT);
1488 1489
1489 xfs_qm_unmount(mp); 1490 xfs_qm_unmount(mp);
@@ -1519,15 +1520,12 @@ xfs_unmountfs(
1519 if (error) 1520 if (error)
1520 xfs_warn(mp, "Unable to update superblock counters. " 1521 xfs_warn(mp, "Unable to update superblock counters. "
1521 "Freespace may not be correct on next mount."); 1522 "Freespace may not be correct on next mount.");
1522 xfs_unmountfs_writesb(mp);
1523 1523
1524 /* 1524 /*
1525 * Make sure all buffers have been flushed and completed before 1525 * At this point we might have modified the superblock again and thus
1526 * unmounting the log. 1526 * added an item to the AIL, thus flush it again.
1527 */ 1527 */
1528 error = xfs_flush_buftarg(mp->m_ddev_targp, 1); 1528 xfs_ail_push_all_sync(mp->m_ail);
1529 if (error)
1530 xfs_warn(mp, "%d busy buffers during unmount.", error);
1531 xfs_wait_buftarg(mp->m_ddev_targp); 1529 xfs_wait_buftarg(mp->m_ddev_targp);
1532 1530
1533 xfs_log_unmount_write(mp); 1531 xfs_log_unmount_write(mp);
@@ -1588,36 +1586,6 @@ xfs_log_sbcount(xfs_mount_t *mp)
1588 return error; 1586 return error;
1589} 1587}
1590 1588
1591int
1592xfs_unmountfs_writesb(xfs_mount_t *mp)
1593{
1594 xfs_buf_t *sbp;
1595 int error = 0;
1596
1597 /*
1598 * skip superblock write if fs is read-only, or
1599 * if we are doing a forced umount.
1600 */
1601 if (!((mp->m_flags & XFS_MOUNT_RDONLY) ||
1602 XFS_FORCED_SHUTDOWN(mp))) {
1603
1604 sbp = xfs_getsb(mp, 0);
1605
1606 XFS_BUF_UNDONE(sbp);
1607 XFS_BUF_UNREAD(sbp);
1608 xfs_buf_delwri_dequeue(sbp);
1609 XFS_BUF_WRITE(sbp);
1610 XFS_BUF_UNASYNC(sbp);
1611 ASSERT(sbp->b_target == mp->m_ddev_targp);
1612 xfsbdstrat(mp, sbp);
1613 error = xfs_buf_iowait(sbp);
1614 if (error)
1615 xfs_buf_ioerror_alert(sbp, __func__);
1616 xfs_buf_relse(sbp);
1617 }
1618 return error;
1619}
1620
1621/* 1589/*
1622 * xfs_mod_sb() can be used to copy arbitrary changes to the 1590 * xfs_mod_sb() can be used to copy arbitrary changes to the
1623 * in-core superblock into the superblock buffer to be logged. 1591 * in-core superblock into the superblock buffer to be logged.