/* * 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); }
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; }
/* * 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); }