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

Commit ca785ec6 authored by Jan Kara's avatar Jan Kara Committed by Mark Fasheh
Browse files

quota: Introduce DQUOT_QUOTA_SYS_FILE flag



If filesystem can handle quota files as system files hidden from users, we can
skip a lot of cache invalidation, syncing, inode flags setting etc. when
turning quotas on, off and quota_sync. Allow filesystem to indicate that it is
hiding quota files from users by DQUOT_QUOTA_SYS_FILE flag.

Signed-off-by: default avatarJan Kara <jack@suse.cz>
Signed-off-by: default avatarMark Fasheh <mfasheh@suse.com>
parent dcb30695
Loading
Loading
Loading
Loading
+30 −15
Original line number Diff line number Diff line
@@ -1631,6 +1631,11 @@ int vfs_quota_disable(struct super_block *sb, int type, unsigned int flags)
		dqopt->ops[cnt] = NULL;
	}
	mutex_unlock(&dqopt->dqonoff_mutex);

	/* Skip syncing and setting flags if quota files are hidden */
	if (dqopt->flags & DQUOT_QUOTA_SYS_FILE)
		goto put_inodes;

	/* Sync the superblock so that buffers with quota data are written to
	 * disk (and so userspace sees correct data afterwards). */
	if (sb->s_op->sync_fs)
@@ -1655,6 +1660,12 @@ int vfs_quota_disable(struct super_block *sb, int type, unsigned int flags)
				mark_inode_dirty(toputinode[cnt]);
			}
			mutex_unlock(&dqopt->dqonoff_mutex);
		}
	if (sb->s_bdev)
		invalidate_bdev(sb->s_bdev);
put_inodes:
	for (cnt = 0; cnt < MAXQUOTAS; cnt++)
		if (toputinode[cnt]) {
			/* On remount RO, we keep the inode pointer so that we
			 * can reenable quota on the subsequent remount RW. We
			 * have to check 'flags' variable and not use sb_has_
@@ -1667,8 +1678,6 @@ int vfs_quota_disable(struct super_block *sb, int type, unsigned int flags)
			else if (!toputinode[cnt]->i_nlink)
				ret = -EBUSY;
		}
	if (sb->s_bdev)
		invalidate_bdev(sb->s_bdev);
	return ret;
}

@@ -1715,25 +1724,31 @@ static int vfs_load_quota_inode(struct inode *inode, int type, int format_id,
		goto out_fmt;
	}

	/* As we bypass the pagecache we must now flush the inode so that
	 * we see all the changes from userspace... */
	if (!(dqopt->flags & DQUOT_QUOTA_SYS_FILE)) {
		/* As we bypass the pagecache we must now flush the inode so
		 * that we see all the changes from userspace... */
		write_inode_now(inode, 1);
	/* And now flush the block cache so that kernel sees the changes */
		/* And now flush the block cache so that kernel sees the
		 * changes */
		invalidate_bdev(sb->s_bdev);
	}
	mutex_lock(&inode->i_mutex);
	mutex_lock(&dqopt->dqonoff_mutex);
	if (sb_has_quota_loaded(sb, type)) {
		error = -EBUSY;
		goto out_lock;
	}
	/* We don't want quota and atime on quota files (deadlocks possible)
	 * Also nobody should write to the file - we use special IO operations
	 * which ignore the immutable bit. */

	if (!(dqopt->flags & DQUOT_QUOTA_SYS_FILE)) {
		/* We don't want quota and atime on quota files (deadlocks
		 * possible) Also nobody should write to the file - we use
		 * special IO operations which ignore the immutable bit. */
		down_write(&dqopt->dqptr_sem);
		oldflags = inode->i_flags & (S_NOATIME | S_IMMUTABLE | S_NOQUOTA);
		inode->i_flags |= S_NOQUOTA | S_NOATIME | S_IMMUTABLE;
		up_write(&dqopt->dqptr_sem);
		sb->dq_op->drop(inode);
	}

	error = -EIO;
	dqopt->files[type] = igrab(inode);
+3 −0
Original line number Diff line number Diff line
@@ -160,6 +160,9 @@ static void quota_sync_sb(struct super_block *sb, int type)
	int cnt;

	sb->s_qcop->quota_sync(sb, type);

	if (sb_dqopt(sb)->flags & DQUOT_QUOTA_SYS_FILE)
		return;
	/* This is not very clever (and fast) but currently I don't know about
	 * any other simple way of getting quota data to disk and we must get
	 * them there for userspace to be visible... */
+7 −0
Original line number Diff line number Diff line
@@ -332,6 +332,13 @@ enum {
#define DQUOT_SUSPENDED		(1 << _DQUOT_SUSPENDED)
#define DQUOT_STATE_FLAGS	(DQUOT_USAGE_ENABLED | DQUOT_LIMITS_ENABLED | \
				 DQUOT_SUSPENDED)
/* Other quota flags */
#define DQUOT_QUOTA_SYS_FILE	(1 << 6)	/* Quota file is a special
						 * system file and user cannot
						 * touch it. Filesystem is
						 * responsible for setting
						 * S_NOQUOTA, S_NOATIME flags
						 */

static inline unsigned int dquot_state_flag(unsigned int flags, int type)
{