aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJan Kara <jack@suse.cz>2008-09-30 11:53:37 -0400
committerMark Fasheh <mfasheh@suse.com>2009-01-05 11:36:57 -0500
commitca785ec66b991e9ca74dd9840fc014487ad095e1 (patch)
tree271c7b36123e9c16f455ecd96352d24ecd20423c
parentdcb30695f2cac86b71417629a6fe8042b4fe2ab2 (diff)
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>
-rw-r--r--fs/dquot.c45
-rw-r--r--fs/quota.c3
-rw-r--r--include/linux/quota.h7
3 files changed, 40 insertions, 15 deletions
diff --git a/fs/dquot.c b/fs/dquot.c
index 7569633efe0e..74185c34a4f0 100644
--- a/fs/dquot.c
+++ b/fs/dquot.c
@@ -1631,6 +1631,11 @@ int vfs_quota_disable(struct super_block *sb, int type, unsigned int flags)
1631 dqopt->ops[cnt] = NULL; 1631 dqopt->ops[cnt] = NULL;
1632 } 1632 }
1633 mutex_unlock(&dqopt->dqonoff_mutex); 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 /* Sync the superblock so that buffers with quota data are written to 1639 /* Sync the superblock so that buffers with quota data are written to
1635 * disk (and so userspace sees correct data afterwards). */ 1640 * disk (and so userspace sees correct data afterwards). */
1636 if (sb->s_op->sync_fs) 1641 if (sb->s_op->sync_fs)
@@ -1655,6 +1660,12 @@ int vfs_quota_disable(struct super_block *sb, int type, unsigned int flags)
1655 mark_inode_dirty(toputinode[cnt]); 1660 mark_inode_dirty(toputinode[cnt]);
1656 } 1661 }
1657 mutex_unlock(&dqopt->dqonoff_mutex); 1662 mutex_unlock(&dqopt->dqonoff_mutex);
1663 }
1664 if (sb->s_bdev)
1665 invalidate_bdev(sb->s_bdev);
1666put_inodes:
1667 for (cnt = 0; cnt < MAXQUOTAS; cnt++)
1668 if (toputinode[cnt]) {
1658 /* On remount RO, we keep the inode pointer so that we 1669 /* On remount RO, we keep the inode pointer so that we
1659 * can reenable quota on the subsequent remount RW. We 1670 * can reenable quota on the subsequent remount RW. We
1660 * have to check 'flags' variable and not use sb_has_ 1671 * 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)
1667 else if (!toputinode[cnt]->i_nlink) 1678 else if (!toputinode[cnt]->i_nlink)
1668 ret = -EBUSY; 1679 ret = -EBUSY;
1669 } 1680 }
1670 if (sb->s_bdev)
1671 invalidate_bdev(sb->s_bdev);
1672 return ret; 1681 return ret;
1673} 1682}
1674 1683
@@ -1715,25 +1724,31 @@ static int vfs_load_quota_inode(struct inode *inode, int type, int format_id,
1715 goto out_fmt; 1724 goto out_fmt;
1716 } 1725 }
1717 1726
1718 /* As we bypass the pagecache we must now flush the inode so that 1727 if (!(dqopt->flags & DQUOT_QUOTA_SYS_FILE)) {
1719 * we see all the changes from userspace... */ 1728 /* As we bypass the pagecache we must now flush the inode so
1720 write_inode_now(inode, 1); 1729 * that we see all the changes from userspace... */
1721 /* And now flush the block cache so that kernel sees the changes */ 1730 write_inode_now(inode, 1);
1722 invalidate_bdev(sb->s_bdev); 1731 /* And now flush the block cache so that kernel sees the
1732 * changes */
1733 invalidate_bdev(sb->s_bdev);
1734 }
1723 mutex_lock(&inode->i_mutex); 1735 mutex_lock(&inode->i_mutex);
1724 mutex_lock(&dqopt->dqonoff_mutex); 1736 mutex_lock(&dqopt->dqonoff_mutex);
1725 if (sb_has_quota_loaded(sb, type)) { 1737 if (sb_has_quota_loaded(sb, type)) {
1726 error = -EBUSY; 1738 error = -EBUSY;
1727 goto out_lock; 1739 goto out_lock;
1728 } 1740 }
1729 /* We don't want quota and atime on quota files (deadlocks possible) 1741
1730 * Also nobody should write to the file - we use special IO operations 1742 if (!(dqopt->flags & DQUOT_QUOTA_SYS_FILE)) {
1731 * which ignore the immutable bit. */ 1743 /* We don't want quota and atime on quota files (deadlocks
1732 down_write(&dqopt->dqptr_sem); 1744 * possible) Also nobody should write to the file - we use
1733 oldflags = inode->i_flags & (S_NOATIME | S_IMMUTABLE | S_NOQUOTA); 1745 * special IO operations which ignore the immutable bit. */
1734 inode->i_flags |= S_NOQUOTA | S_NOATIME | S_IMMUTABLE; 1746 down_write(&dqopt->dqptr_sem);
1735 up_write(&dqopt->dqptr_sem); 1747 oldflags = inode->i_flags & (S_NOATIME | S_IMMUTABLE | S_NOQUOTA);
1736 sb->dq_op->drop(inode); 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 error = -EIO; 1753 error = -EIO;
1739 dqopt->files[type] = igrab(inode); 1754 dqopt->files[type] = igrab(inode);
diff --git a/fs/quota.c b/fs/quota.c
index 8678d9f35ee9..4a8c94f05f76 100644
--- a/fs/quota.c
+++ b/fs/quota.c
@@ -160,6 +160,9 @@ static void quota_sync_sb(struct super_block *sb, int type)
160 int cnt; 160 int cnt;
161 161
162 sb->s_qcop->quota_sync(sb, type); 162 sb->s_qcop->quota_sync(sb, type);
163
164 if (sb_dqopt(sb)->flags & DQUOT_QUOTA_SYS_FILE)
165 return;
163 /* This is not very clever (and fast) but currently I don't know about 166 /* This is not very clever (and fast) but currently I don't know about
164 * any other simple way of getting quota data to disk and we must get 167 * any other simple way of getting quota data to disk and we must get
165 * them there for userspace to be visible... */ 168 * them there for userspace to be visible... */
diff --git a/include/linux/quota.h b/include/linux/quota.h
index 93717abcd35b..80b8807b4988 100644
--- a/include/linux/quota.h
+++ b/include/linux/quota.h
@@ -332,6 +332,13 @@ enum {
332#define DQUOT_SUSPENDED (1 << _DQUOT_SUSPENDED) 332#define DQUOT_SUSPENDED (1 << _DQUOT_SUSPENDED)
333#define DQUOT_STATE_FLAGS (DQUOT_USAGE_ENABLED | DQUOT_LIMITS_ENABLED | \ 333#define DQUOT_STATE_FLAGS (DQUOT_USAGE_ENABLED | DQUOT_LIMITS_ENABLED | \
334 DQUOT_SUSPENDED) 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
336static inline unsigned int dquot_state_flag(unsigned int flags, int type) 343static inline unsigned int dquot_state_flag(unsigned int flags, int type)
337{ 344{