Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 76bf105c authored by David Chinner's avatar David Chinner Committed by Lachlan McIlroy
Browse files

[XFS] Move remaining quiesce code.



With all the other filesystem sync code it in xfs_sync.c including the
data quiesce code, it makes sense to move the remaining quiesce code to
the same place.

SGI-PV: 988140

SGI-Modid: xfs-linux-melb:xfs-kern:32312a

Signed-off-by: default avatarDavid Chinner <david@fromorbit.com>
Signed-off-by: default avatarLachlan McIlroy <lachlan@sgi.com>
Signed-off-by: default avatarChristoph Hellwig <hch@infradead.org>
parent a4e4c4f4
Loading
Loading
Loading
Loading
+3 −3
Original line number Diff line number Diff line
@@ -1212,7 +1212,7 @@ xfs_fs_remount(
	/* rw -> ro */
	if (!(mp->m_flags & XFS_MOUNT_RDONLY) && (*flags & MS_RDONLY)) {
		xfs_quiesce_data(mp);
		xfs_attr_quiesce(mp);
		xfs_quiesce_attr(mp);
		mp->m_flags |= XFS_MOUNT_RDONLY;
	}

@@ -1230,7 +1230,7 @@ xfs_fs_lockfs(
{
	struct xfs_mount	*mp = XFS_M(sb);

	xfs_attr_quiesce(mp);
	xfs_quiesce_attr(mp);
	xfs_fs_log_dummy(mp);
}

+55 −0
Original line number Diff line number Diff line
@@ -357,6 +357,61 @@ xfs_quiesce_data(
	return error;
}

STATIC void
xfs_quiesce_fs(
	struct xfs_mount	*mp)
{
	int	count = 0, pincount;

	xfs_flush_buftarg(mp->m_ddev_targp, 0);
	xfs_finish_reclaim_all(mp, 0, XFS_IFLUSH_DELWRI_ELSE_ASYNC);

	/*
	 * This loop must run at least twice.  The first instance of the loop
	 * will flush most meta data but that will generate more meta data
	 * (typically directory updates).  Which then must be flushed and
	 * logged before we can write the unmount record.
	 */
	do {
		xfs_sync_inodes(mp, SYNC_ATTR|SYNC_WAIT);
		pincount = xfs_flush_buftarg(mp->m_ddev_targp, 1);
		if (!pincount) {
			delay(50);
			count++;
		}
	} while (count < 2);
}

/*
 * Second stage of a quiesce. The data is already synced, now we have to take
 * care of the metadata. New transactions are already blocked, so we need to
 * wait for any remaining transactions to drain out before proceding.
 */
void
xfs_quiesce_attr(
	struct xfs_mount	*mp)
{
	int	error = 0;

	/* wait for all modifications to complete */
	while (atomic_read(&mp->m_active_trans) > 0)
		delay(100);

	/* flush inodes and push all remaining buffers out to disk */
	xfs_quiesce_fs(mp);

	ASSERT_ALWAYS(atomic_read(&mp->m_active_trans) == 0);

	/* Push the superblock and write an unmount record */
	error = xfs_log_sbcount(mp, 1);
	if (error)
		xfs_fs_cmn_err(CE_WARN, mp,
				"xfs_attr_quiesce: failed to log sb changes. "
				"Frozen image may not be consistent.");
	xfs_log_unmount_write(mp);
	xfs_unmountfs_writesb(mp);
}

/*
 * Enqueue a work item to be picked up by the vfs xfssyncd thread.
 * Doing this has two advantages:
+1 −0
Original line number Diff line number Diff line
@@ -40,6 +40,7 @@ int xfs_sync_inodes(struct xfs_mount *mp, int flags);
int xfs_sync_fsdata(struct xfs_mount *mp, int flags);

int xfs_quiesce_data(struct xfs_mount *mp);
void xfs_quiesce_attr(struct xfs_mount *mp);

void xfs_flush_inode(struct xfs_inode *ip);
void xfs_flush_device(struct xfs_inode *ip);
+0 −55
Original line number Diff line number Diff line
@@ -59,61 +59,6 @@
#include "xfs_sync.h"


STATIC void
xfs_quiesce_fs(
	xfs_mount_t		*mp)
{
	int			count = 0, pincount;

	xfs_flush_buftarg(mp->m_ddev_targp, 0);
	xfs_finish_reclaim_all(mp, 0, XFS_IFLUSH_DELWRI_ELSE_ASYNC);

	/*
	 * This loop must run at least twice.  The first instance of the loop
	 * will flush most meta data but that will generate more meta data
	 * (typically directory updates).  Which then must be flushed and
	 * logged before we can write the unmount record.
	 */
	do {
		xfs_sync_inodes(mp, SYNC_ATTR|SYNC_WAIT);
		pincount = xfs_flush_buftarg(mp->m_ddev_targp, 1);
		if (!pincount) {
			delay(50);
			count++;
		}
	} while (count < 2);
}

/*
 * Second stage of a quiesce. The data is already synced, now we have to take
 * care of the metadata. New transactions are already blocked, so we need to
 * wait for any remaining transactions to drain out before proceding.
 */
void
xfs_attr_quiesce(
	xfs_mount_t	*mp)
{
	int	error = 0;

	/* wait for all modifications to complete */
	while (atomic_read(&mp->m_active_trans) > 0)
		delay(100);

	/* flush inodes and push all remaining buffers out to disk */
	xfs_quiesce_fs(mp);

	ASSERT_ALWAYS(atomic_read(&mp->m_active_trans) == 0);

	/* Push the superblock and write an unmount record */
	error = xfs_log_sbcount(mp, 1);
	if (error)
		xfs_fs_cmn_err(CE_WARN, mp,
				"xfs_attr_quiesce: failed to log sb changes. "
				"Frozen image may not be consistent.");
	xfs_log_unmount_write(mp);
	xfs_unmountfs_writesb(mp);
}

/*
 * xfs_unmount_flush implements a set of flush operation on special
 * inodes, which are needed as a separate set of operations so that
+0 −1
Original line number Diff line number Diff line
@@ -10,6 +10,5 @@ struct xfs_mount_args;

void xfs_do_force_shutdown(struct xfs_mount *mp, int flags, char *fname,
		int lnnum);
void xfs_attr_quiesce(struct xfs_mount *mp);

#endif /* _XFS_VFSOPS_H */