コード例 #1
0
/*
 * xfs sync routine for internal use
 *
 * This routine supports all of the flags defined for the generic VFS_SYNC
 * interface as explained above under xfs_sync.  In the interests of not
 * changing interfaces within the 6.5 family, additional internallly-
 * required functions are specified within a separate xflags parameter,
 * only available by calling this routine.
 *
 */
int
xfs_syncsub(
	xfs_mount_t	*mp,
	int		flags,
	int             xflags,
	int             *bypassed)
{
	int		error = 0;
	int		last_error = 0;
	uint		log_flags = XFS_LOG_FORCE;
	xfs_buf_t	*bp;
	xfs_buf_log_item_t	*bip;

	/*
	 * Sync out the log.  This ensures that the log is periodically
	 * flushed even if there is not enough activity to fill it up.
	 */
	if (flags & SYNC_WAIT)
		log_flags |= XFS_LOG_SYNC;

	xfs_log_force(mp, (xfs_lsn_t)0, log_flags);

	if (flags & (SYNC_ATTR|SYNC_DELWRI)) {
		if (flags & SYNC_BDFLUSH)
			xfs_finish_reclaim_all(mp, 1);
		else
			error = xfs_sync_inodes(mp, flags, xflags, bypassed);
	}

	/*
	 * Flushing out dirty data above probably generated more
	 * log activity, so if this isn't vfs_sync() then flush
	 * the log again.
	 */
	if (flags & SYNC_DELWRI) {
		xfs_log_force(mp, (xfs_lsn_t)0, log_flags);
	}

	if (flags & SYNC_FSDATA) {
		/*
		 * If this is vfs_sync() then only sync the superblock
		 * if we can lock it without sleeping and it is not pinned.
		 */
		if (flags & SYNC_BDFLUSH) {
			bp = xfs_getsb(mp, XFS_BUF_TRYLOCK);
			if (bp != NULL) {
				bip = XFS_BUF_FSPRIVATE(bp,xfs_buf_log_item_t*);
				if ((bip != NULL) &&
				    xfs_buf_item_dirty(bip)) {
					if (!(XFS_BUF_ISPINNED(bp))) {
						XFS_BUF_ASYNC(bp);
						error = xfs_bwrite(mp, bp);
					} else {
						xfs_buf_relse(bp);
					}
				} else {
					xfs_buf_relse(bp);
				}
			}
		} else {
コード例 #2
0
STATIC int
xfs_fs_quota_sync(
	struct super_block	*sb,
	int			type)
{
	struct xfs_mount	*mp = XFS_M(sb);

	if (!XFS_IS_QUOTA_RUNNING(mp))
		return -ENOSYS;
	return -xfs_sync_inodes(mp, SYNC_DELWRI);
}
コード例 #3
0
/*
 * The main distribution switch of all XFS quotactl system calls.
 */
int
xfs_qm_quotactl(
	struct bhv_desc *bdp,
	int		cmd,
	int		id,
	xfs_caddr_t	addr)
{
	xfs_mount_t	*mp;
	bhv_vfs_t	*vfsp;
	int		error;

	vfsp = bhvtovfs(bdp);
	mp = XFS_VFSTOM(vfsp);

	ASSERT(addr != NULL || cmd == Q_XQUOTASYNC);

	/*
	 * The following commands are valid even when quotaoff.
	 */
	switch (cmd) {
	case Q_XQUOTARM:
		/*
		 * Truncate quota files. quota must be off.
		 */
		if (XFS_IS_QUOTA_ON(mp))
			return XFS_ERROR(EINVAL);
		if (vfsp->vfs_flag & VFS_RDONLY)
			return XFS_ERROR(EROFS);
		return (xfs_qm_scall_trunc_qfiles(mp,
			       xfs_qm_import_qtype_flags(*(uint *)addr)));

	case Q_XGETQSTAT:
		/*
		 * Get quota status information.
		 */
		return (xfs_qm_scall_getqstat(mp, (fs_quota_stat_t *)addr));

	case Q_XQUOTAON:
		/*
		 * QUOTAON - enabling quota enforcement.
		 * Quota accounting must be turned on at mount time.
		 */
		if (vfsp->vfs_flag & VFS_RDONLY)
			return XFS_ERROR(EROFS);
		return (xfs_qm_scall_quotaon(mp,
					  xfs_qm_import_flags(*(uint *)addr)));

	case Q_XQUOTAOFF:
		if (vfsp->vfs_flag & VFS_RDONLY)
			return XFS_ERROR(EROFS);
		break;

	case Q_XQUOTASYNC:
		return (xfs_sync_inodes(mp, SYNC_DELWRI, NULL));

	default:
		break;
	}

	if (! XFS_IS_QUOTA_ON(mp))
		return XFS_ERROR(ESRCH);

	switch (cmd) {
	case Q_XQUOTAOFF:
		if (vfsp->vfs_flag & VFS_RDONLY)
			return XFS_ERROR(EROFS);
		error = xfs_qm_scall_quotaoff(mp,
					    xfs_qm_import_flags(*(uint *)addr),
					    B_FALSE);
		break;

	case Q_XGETQUOTA:
		error = xfs_qm_scall_getquota(mp, (xfs_dqid_t)id, XFS_DQ_USER,
					(fs_disk_quota_t *)addr);
		break;
	case Q_XGETGQUOTA:
		error = xfs_qm_scall_getquota(mp, (xfs_dqid_t)id, XFS_DQ_GROUP,
					(fs_disk_quota_t *)addr);
		break;
	case Q_XGETPQUOTA:
		error = xfs_qm_scall_getquota(mp, (xfs_dqid_t)id, XFS_DQ_PROJ,
					(fs_disk_quota_t *)addr);
		break;

	case Q_XSETQLIM:
		if (vfsp->vfs_flag & VFS_RDONLY)
			return XFS_ERROR(EROFS);
		error = xfs_qm_scall_setqlim(mp, (xfs_dqid_t)id, XFS_DQ_USER,
					     (fs_disk_quota_t *)addr);
		break;
	case Q_XSETGQLIM:
		if (vfsp->vfs_flag & VFS_RDONLY)
			return XFS_ERROR(EROFS);
		error = xfs_qm_scall_setqlim(mp, (xfs_dqid_t)id, XFS_DQ_GROUP,
					     (fs_disk_quota_t *)addr);
		break;
	case Q_XSETPQLIM:
		if (vfsp->vfs_flag & VFS_RDONLY)
			return XFS_ERROR(EROFS);
		error = xfs_qm_scall_setqlim(mp, (xfs_dqid_t)id, XFS_DQ_PROJ,
					     (fs_disk_quota_t *)addr);
		break;

	default:
		error = XFS_ERROR(EINVAL);
		break;
	}

	return (error);
}