quota: Allow to separately enable quota accounting and enforcing limits
Split DQUOT_USR_ENABLED (and DQUOT_GRP_ENABLED) into DQUOT_USR_USAGE_ENABLED and DQUOT_USR_LIMITS_ENABLED. This way we are able to separately enable / disable whether we should: 1) ignore quotas completely 2) just keep uptodate information about usage 3) actually enforce quota limits This is going to be useful when quota is treated as filesystem metadata - we then want to keep quota information uptodate all the time and just enable / disable limits enforcement. Signed-off-by: Jan Kara <jack@suse.cz> Signed-off-by: Mark Fasheh <mfasheh@suse.com>
This commit is contained in:
@@ -40,11 +40,14 @@ int dquot_mark_dquot_dirty(struct dquot *dquot);
|
||||
|
||||
int vfs_quota_on(struct super_block *sb, int type, int format_id,
|
||||
char *path, int remount);
|
||||
int vfs_quota_enable(struct inode *inode, int type, int format_id,
|
||||
unsigned int flags);
|
||||
int vfs_quota_on_path(struct super_block *sb, int type, int format_id,
|
||||
struct path *path);
|
||||
int vfs_quota_on_mount(struct super_block *sb, char *qf_name,
|
||||
int format_id, int type);
|
||||
int vfs_quota_off(struct super_block *sb, int type, int remount);
|
||||
int vfs_quota_disable(struct super_block *sb, int type, unsigned int flags);
|
||||
int vfs_quota_sync(struct super_block *sb, int type);
|
||||
int vfs_get_dqinfo(struct super_block *sb, int type, struct if_dqinfo *ii);
|
||||
int vfs_set_dqinfo(struct super_block *sb, int type, struct if_dqinfo *ii);
|
||||
@@ -64,26 +67,22 @@ static inline struct mem_dqinfo *sb_dqinfo(struct super_block *sb, int type)
|
||||
* Functions for checking status of quota
|
||||
*/
|
||||
|
||||
static inline int sb_has_quota_enabled(struct super_block *sb, int type)
|
||||
static inline int sb_has_quota_usage_enabled(struct super_block *sb, int type)
|
||||
{
|
||||
if (type == USRQUOTA)
|
||||
return (sb_dqopt(sb)->flags & DQUOT_USR_ENABLED)
|
||||
&& !(sb_dqopt(sb)->flags & DQUOT_USR_SUSPENDED);
|
||||
return (sb_dqopt(sb)->flags & DQUOT_GRP_ENABLED)
|
||||
&& !(sb_dqopt(sb)->flags & DQUOT_GROUP_SUSPENDED);
|
||||
return sb_dqopt(sb)->flags &
|
||||
dquot_state_flag(DQUOT_USAGE_ENABLED, type);
|
||||
}
|
||||
|
||||
static inline int sb_any_quota_enabled(struct super_block *sb)
|
||||
static inline int sb_has_quota_limits_enabled(struct super_block *sb, int type)
|
||||
{
|
||||
return sb_has_quota_enabled(sb, USRQUOTA) ||
|
||||
sb_has_quota_enabled(sb, GRPQUOTA);
|
||||
return sb_dqopt(sb)->flags &
|
||||
dquot_state_flag(DQUOT_LIMITS_ENABLED, type);
|
||||
}
|
||||
|
||||
static inline int sb_has_quota_suspended(struct super_block *sb, int type)
|
||||
{
|
||||
if (type == USRQUOTA)
|
||||
return sb_dqopt(sb)->flags & DQUOT_USR_SUSPENDED;
|
||||
return sb_dqopt(sb)->flags & DQUOT_GRP_SUSPENDED;
|
||||
return sb_dqopt(sb)->flags &
|
||||
dquot_state_flag(DQUOT_SUSPENDED, type);
|
||||
}
|
||||
|
||||
static inline int sb_any_quota_suspended(struct super_block *sb)
|
||||
@@ -92,6 +91,34 @@ static inline int sb_any_quota_suspended(struct super_block *sb)
|
||||
sb_has_quota_suspended(sb, GRPQUOTA);
|
||||
}
|
||||
|
||||
/* Does kernel know about any quota information for given sb + type? */
|
||||
static inline int sb_has_quota_loaded(struct super_block *sb, int type)
|
||||
{
|
||||
/* Currently if anything is on, then quota usage is on as well */
|
||||
return sb_has_quota_usage_enabled(sb, type);
|
||||
}
|
||||
|
||||
static inline int sb_any_quota_loaded(struct super_block *sb)
|
||||
{
|
||||
return sb_has_quota_loaded(sb, USRQUOTA) ||
|
||||
sb_has_quota_loaded(sb, GRPQUOTA);
|
||||
}
|
||||
|
||||
static inline int sb_has_quota_active(struct super_block *sb, int type)
|
||||
{
|
||||
return sb_has_quota_loaded(sb, type) &&
|
||||
!sb_has_quota_suspended(sb, type);
|
||||
}
|
||||
|
||||
static inline int sb_any_quota_active(struct super_block *sb)
|
||||
{
|
||||
return sb_has_quota_active(sb, USRQUOTA) ||
|
||||
sb_has_quota_active(sb, GRPQUOTA);
|
||||
}
|
||||
|
||||
/* For backward compatibility until we remove all users */
|
||||
#define sb_any_quota_enabled(sb) sb_any_quota_active(sb)
|
||||
|
||||
/*
|
||||
* Operations supported for diskquotas.
|
||||
*/
|
||||
@@ -106,7 +133,7 @@ extern struct quotactl_ops vfs_quotactl_ops;
|
||||
static inline void vfs_dq_init(struct inode *inode)
|
||||
{
|
||||
BUG_ON(!inode->i_sb);
|
||||
if (sb_any_quota_enabled(inode->i_sb) && !IS_NOQUOTA(inode))
|
||||
if (sb_any_quota_active(inode->i_sb) && !IS_NOQUOTA(inode))
|
||||
inode->i_sb->dq_op->initialize(inode, -1);
|
||||
}
|
||||
|
||||
@@ -114,7 +141,7 @@ static inline void vfs_dq_init(struct inode *inode)
|
||||
* a transaction (deadlocks possible otherwise) */
|
||||
static inline int vfs_dq_prealloc_space_nodirty(struct inode *inode, qsize_t nr)
|
||||
{
|
||||
if (sb_any_quota_enabled(inode->i_sb)) {
|
||||
if (sb_any_quota_active(inode->i_sb)) {
|
||||
/* Used space is updated in alloc_space() */
|
||||
if (inode->i_sb->dq_op->alloc_space(inode, nr, 1) == NO_QUOTA)
|
||||
return 1;
|
||||
@@ -134,7 +161,7 @@ static inline int vfs_dq_prealloc_space(struct inode *inode, qsize_t nr)
|
||||
|
||||
static inline int vfs_dq_alloc_space_nodirty(struct inode *inode, qsize_t nr)
|
||||
{
|
||||
if (sb_any_quota_enabled(inode->i_sb)) {
|
||||
if (sb_any_quota_active(inode->i_sb)) {
|
||||
/* Used space is updated in alloc_space() */
|
||||
if (inode->i_sb->dq_op->alloc_space(inode, nr, 0) == NO_QUOTA)
|
||||
return 1;
|
||||
@@ -154,7 +181,7 @@ static inline int vfs_dq_alloc_space(struct inode *inode, qsize_t nr)
|
||||
|
||||
static inline int vfs_dq_alloc_inode(struct inode *inode)
|
||||
{
|
||||
if (sb_any_quota_enabled(inode->i_sb)) {
|
||||
if (sb_any_quota_active(inode->i_sb)) {
|
||||
vfs_dq_init(inode);
|
||||
if (inode->i_sb->dq_op->alloc_inode(inode, 1) == NO_QUOTA)
|
||||
return 1;
|
||||
@@ -164,7 +191,7 @@ static inline int vfs_dq_alloc_inode(struct inode *inode)
|
||||
|
||||
static inline void vfs_dq_free_space_nodirty(struct inode *inode, qsize_t nr)
|
||||
{
|
||||
if (sb_any_quota_enabled(inode->i_sb))
|
||||
if (sb_any_quota_active(inode->i_sb))
|
||||
inode->i_sb->dq_op->free_space(inode, nr);
|
||||
else
|
||||
inode_sub_bytes(inode, nr);
|
||||
@@ -178,7 +205,7 @@ static inline void vfs_dq_free_space(struct inode *inode, qsize_t nr)
|
||||
|
||||
static inline void vfs_dq_free_inode(struct inode *inode)
|
||||
{
|
||||
if (sb_any_quota_enabled(inode->i_sb))
|
||||
if (sb_any_quota_active(inode->i_sb))
|
||||
inode->i_sb->dq_op->free_inode(inode, 1);
|
||||
}
|
||||
|
||||
@@ -199,12 +226,12 @@ static inline int vfs_dq_off(struct super_block *sb, int remount)
|
||||
|
||||
#else
|
||||
|
||||
static inline int sb_has_quota_enabled(struct super_block *sb, int type)
|
||||
static inline int sb_has_quota_usage_enabled(struct super_block *sb, int type)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int sb_any_quota_enabled(struct super_block *sb)
|
||||
static inline int sb_has_quota_limits_enabled(struct super_block *sb, int type)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
@@ -219,6 +246,30 @@ static inline int sb_any_quota_suspended(struct super_block *sb)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Does kernel know about any quota information for given sb + type? */
|
||||
static inline int sb_has_quota_loaded(struct super_block *sb, int type)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int sb_any_quota_loaded(struct super_block *sb)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int sb_has_quota_active(struct super_block *sb, int type)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int sb_any_quota_active(struct super_block *sb)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* For backward compatibility until we remove all users */
|
||||
#define sb_any_quota_enabled(sb) sb_any_quota_active(sb)
|
||||
|
||||
/*
|
||||
* NO-OP when quota not configured.
|
||||
*/
|
||||
|
Reference in New Issue
Block a user