Commit ca785ec66b991e9ca74dd9840fc014487ad095e1

Authored by Jan Kara
Committed by Mark Fasheh
1 parent dcb30695f2

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: Jan Kara <jack@suse.cz>
Signed-off-by: Mark Fasheh <mfasheh@suse.com>

Showing 3 changed files with 40 additions and 15 deletions Side-by-side Diff

... ... @@ -1631,6 +1631,11 @@
1631 1631 dqopt->ops[cnt] = NULL;
1632 1632 }
1633 1633 mutex_unlock(&dqopt->dqonoff_mutex);
  1634 +
  1635 + /* Skip syncing and setting flags if quota files are hidden */
  1636 + if (dqopt->flags & DQUOT_QUOTA_SYS_FILE)
  1637 + goto put_inodes;
  1638 +
1634 1639 /* Sync the superblock so that buffers with quota data are written to
1635 1640 * disk (and so userspace sees correct data afterwards). */
1636 1641 if (sb->s_op->sync_fs)
... ... @@ -1655,6 +1660,12 @@
1655 1660 mark_inode_dirty(toputinode[cnt]);
1656 1661 }
1657 1662 mutex_unlock(&dqopt->dqonoff_mutex);
  1663 + }
  1664 + if (sb->s_bdev)
  1665 + invalidate_bdev(sb->s_bdev);
  1666 +put_inodes:
  1667 + for (cnt = 0; cnt < MAXQUOTAS; cnt++)
  1668 + if (toputinode[cnt]) {
1658 1669 /* On remount RO, we keep the inode pointer so that we
1659 1670 * can reenable quota on the subsequent remount RW. We
1660 1671 * have to check 'flags' variable and not use sb_has_
... ... @@ -1667,8 +1678,6 @@
1667 1678 else if (!toputinode[cnt]->i_nlink)
1668 1679 ret = -EBUSY;
1669 1680 }
1670   - if (sb->s_bdev)
1671   - invalidate_bdev(sb->s_bdev);
1672 1681 return ret;
1673 1682 }
1674 1683  
1675 1684  
... ... @@ -1715,25 +1724,31 @@
1715 1724 goto out_fmt;
1716 1725 }
1717 1726  
1718   - /* As we bypass the pagecache we must now flush the inode so that
1719   - * we see all the changes from userspace... */
1720   - write_inode_now(inode, 1);
1721   - /* And now flush the block cache so that kernel sees the changes */
1722   - invalidate_bdev(sb->s_bdev);
  1727 + if (!(dqopt->flags & DQUOT_QUOTA_SYS_FILE)) {
  1728 + /* As we bypass the pagecache we must now flush the inode so
  1729 + * that we see all the changes from userspace... */
  1730 + write_inode_now(inode, 1);
  1731 + /* And now flush the block cache so that kernel sees the
  1732 + * changes */
  1733 + invalidate_bdev(sb->s_bdev);
  1734 + }
1723 1735 mutex_lock(&inode->i_mutex);
1724 1736 mutex_lock(&dqopt->dqonoff_mutex);
1725 1737 if (sb_has_quota_loaded(sb, type)) {
1726 1738 error = -EBUSY;
1727 1739 goto out_lock;
1728 1740 }
1729   - /* We don't want quota and atime on quota files (deadlocks possible)
1730   - * Also nobody should write to the file - we use special IO operations
1731   - * which ignore the immutable bit. */
1732   - down_write(&dqopt->dqptr_sem);
1733   - oldflags = inode->i_flags & (S_NOATIME | S_IMMUTABLE | S_NOQUOTA);
1734   - inode->i_flags |= S_NOQUOTA | S_NOATIME | S_IMMUTABLE;
1735   - up_write(&dqopt->dqptr_sem);
1736   - sb->dq_op->drop(inode);
  1741 +
  1742 + if (!(dqopt->flags & DQUOT_QUOTA_SYS_FILE)) {
  1743 + /* We don't want quota and atime on quota files (deadlocks
  1744 + * possible) Also nobody should write to the file - we use
  1745 + * special IO operations which ignore the immutable bit. */
  1746 + down_write(&dqopt->dqptr_sem);
  1747 + oldflags = inode->i_flags & (S_NOATIME | S_IMMUTABLE | S_NOQUOTA);
  1748 + inode->i_flags |= S_NOQUOTA | S_NOATIME | S_IMMUTABLE;
  1749 + up_write(&dqopt->dqptr_sem);
  1750 + sb->dq_op->drop(inode);
  1751 + }
1737 1752  
1738 1753 error = -EIO;
1739 1754 dqopt->files[type] = igrab(inode);
... ... @@ -160,6 +160,9 @@
160 160 int cnt;
161 161  
162 162 sb->s_qcop->quota_sync(sb, type);
  163 +
  164 + if (sb_dqopt(sb)->flags & DQUOT_QUOTA_SYS_FILE)
  165 + return;
163 166 /* This is not very clever (and fast) but currently I don't know about
164 167 * any other simple way of getting quota data to disk and we must get
165 168 * them there for userspace to be visible... */
include/linux/quota.h
... ... @@ -332,6 +332,13 @@
332 332 #define DQUOT_SUSPENDED (1 << _DQUOT_SUSPENDED)
333 333 #define DQUOT_STATE_FLAGS (DQUOT_USAGE_ENABLED | DQUOT_LIMITS_ENABLED | \
334 334 DQUOT_SUSPENDED)
  335 +/* Other quota flags */
  336 +#define DQUOT_QUOTA_SYS_FILE (1 << 6) /* Quota file is a special
  337 + * system file and user cannot
  338 + * touch it. Filesystem is
  339 + * responsible for setting
  340 + * S_NOQUOTA, S_NOATIME flags
  341 + */
335 342  
336 343 static inline unsigned int dquot_state_flag(unsigned int flags, int type)
337 344 {