Пример #1
0
/*
 * 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 proceeding.
 */
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);

	/*
	 * Just warn here till VFS can correctly support
	 * read-only remount without racing.
	 */
	WARN_ON(atomic_read(&mp->m_active_trans) != 0);

	/* Push the superblock and write an unmount record */
	error = xfs_log_sbcount(mp, 1);
	if (error)
		xfs_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);
}
Пример #2
0
STATIC int
xfs_mntupdate(
	bhv_desc_t			*bdp,
	int				*flags,
	struct xfs_mount_args		*args)
{
	struct vfs	*vfsp = bhvtovfs(bdp);
	xfs_mount_t	*mp = XFS_BHVTOM(bdp);
	int		pincount, error;
	int		count = 0;

	if (args->flags & XFSMNT_NOATIME)
		mp->m_flags |= XFS_MOUNT_NOATIME;
	else
		mp->m_flags &= ~XFS_MOUNT_NOATIME;

	if (!(vfsp->vfs_flag & VFS_RDONLY)) {
		VFS_SYNC(vfsp, SYNC_FSDATA|SYNC_BDFLUSH|SYNC_ATTR, NULL, error);
	}

	if (*flags & MS_RDONLY) {
		xfs_refcache_purge_mp(mp);
		xfs_flush_buftarg(mp->m_ddev_targp, 0);
		xfs_finish_reclaim_all(mp, 0);

		/* 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 {
			VFS_SYNC(vfsp, REMOUNT_READONLY_FLAGS, NULL, error);
			pincount = xfs_flush_buftarg(mp->m_ddev_targp, 1);
			if (!pincount) {
				delay(50);
				count++;
			}
		} while (count < 2);

		/* Ok now write out an unmount record */
		xfs_log_unmount_write(mp);
		xfs_unmountfs_writesb(mp);
		vfsp->vfs_flag |= VFS_RDONLY;
	} else {
		vfsp->vfs_flag &= ~VFS_RDONLY;
	}

	return 0;
}
Пример #3
0
/*
 * 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 proceeding.
 */
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);

	/* reclaim inodes to do any IO before the freeze completes */
	xfs_reclaim_inodes(mp, 0);
	xfs_reclaim_inodes(mp, SYNC_WAIT);

	/* flush all pending changes from the AIL */
	xfs_ail_push_all_sync(mp->m_ail);

	/*
	 * Just warn here till VFS can correctly support
	 * read-only remount without racing.
	 */
	WARN_ON(atomic_read(&mp->m_active_trans) != 0);

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

	/*
	 * At this point we might have modified the superblock again and thus
	 * added an item to the AIL, thus flush it again.
	 */
	xfs_ail_push_all_sync(mp->m_ail);

	/*
	 * The superblock buffer is uncached and xfsaild_push() will lock and
	 * set the XBF_ASYNC flag on the buffer. We cannot do xfs_buf_iowait()
	 * here but a lock on the superblock buffer will block until iodone()
	 * has completed.
	 */
	xfs_buf_lock(mp->m_sb_bp);
	xfs_buf_unlock(mp->m_sb_bp);
}
void
xfs_quiesce_attr(
	struct xfs_mount	*mp)
{
	int	error = 0;

	
	while (atomic_read(&mp->m_active_trans) > 0)
		delay(100);

	
	xfs_quiesce_fs(mp);

	WARN_ON(atomic_read(&mp->m_active_trans) != 0);

	
	error = xfs_log_sbcount(mp);
	if (error)
		xfs_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);
}