Commit ca785ec66b991e9ca74dd9840fc014487ad095e1
Committed by
Mark Fasheh
1 parent
dcb30695f2
Exists in
master
and in
4 other branches
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
fs/dquot.c
... | ... | @@ -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); |
fs/quota.c
... | ... | @@ -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 | { |