ext4: fix quota charging for shared xattr blocks
ext4_xattr_block_set() calls dquot_alloc_block() to charge for an xattr block when new references are made. However if dquot_initialize() hasn't been called on an inode, request for charging is effectively ignored because ext4_inode_info->i_dquot is not initialized yet. Add dquot_initialize() to call paths that lead to ext4_xattr_block_set(). Signed-off-by: Tahsin Erdogan <tahsin@google.com> Signed-off-by: Theodore Ts'o <tytso@mit.edu> Reviewed-by: Jan Kara <jack@suse.cz>
This commit is contained in:
Родитель
c41d342b39
Коммит
b8cb5a545c
|
@ -4,6 +4,7 @@
|
|||
* Copyright (C) 2001-2003 Andreas Gruenbacher, <agruen@suse.de>
|
||||
*/
|
||||
|
||||
#include <linux/quotaops.h>
|
||||
#include "ext4_jbd2.h"
|
||||
#include "ext4.h"
|
||||
#include "xattr.h"
|
||||
|
@ -232,6 +233,9 @@ ext4_set_acl(struct inode *inode, struct posix_acl *acl, int type)
|
|||
handle_t *handle;
|
||||
int error, retries = 0;
|
||||
|
||||
error = dquot_initialize(inode);
|
||||
if (error)
|
||||
return error;
|
||||
retry:
|
||||
handle = ext4_journal_start(inode, EXT4_HT_XATTR,
|
||||
ext4_jbd2_credits_xattr(inode));
|
||||
|
|
|
@ -1174,6 +1174,9 @@ static int ext4_set_context(struct inode *inode, const void *ctx, size_t len,
|
|||
return res;
|
||||
}
|
||||
|
||||
res = dquot_initialize(inode);
|
||||
if (res)
|
||||
return res;
|
||||
retry:
|
||||
handle = ext4_journal_start(inode, EXT4_HT_MISC,
|
||||
ext4_jbd2_credits_xattr(inode));
|
||||
|
|
|
@ -888,6 +888,8 @@ inserted:
|
|||
else {
|
||||
u32 ref;
|
||||
|
||||
WARN_ON_ONCE(dquot_initialize_needed(inode));
|
||||
|
||||
/* The old block is released after updating
|
||||
the inode. */
|
||||
error = dquot_alloc_block(inode,
|
||||
|
@ -954,6 +956,8 @@ inserted:
|
|||
/* We need to allocate a new block */
|
||||
ext4_fsblk_t goal, block;
|
||||
|
||||
WARN_ON_ONCE(dquot_initialize_needed(inode));
|
||||
|
||||
goal = ext4_group_first_block_no(sb,
|
||||
EXT4_I(inode)->i_block_group);
|
||||
|
||||
|
@ -1166,6 +1170,7 @@ ext4_xattr_set_handle(handle_t *handle, struct inode *inode, int name_index,
|
|||
return -EINVAL;
|
||||
if (strlen(name) > 255)
|
||||
return -ERANGE;
|
||||
|
||||
ext4_write_lock_xattr(inode, &no_expand);
|
||||
|
||||
error = ext4_reserve_inode_write(handle, inode, &is.iloc);
|
||||
|
@ -1267,6 +1272,9 @@ ext4_xattr_set(struct inode *inode, int name_index, const char *name,
|
|||
int error, retries = 0;
|
||||
int credits = ext4_jbd2_credits_xattr(inode);
|
||||
|
||||
error = dquot_initialize(inode);
|
||||
if (error)
|
||||
return error;
|
||||
retry:
|
||||
handle = ext4_journal_start(inode, EXT4_HT_XATTR, credits);
|
||||
if (IS_ERR(handle)) {
|
||||
|
|
|
@ -1512,6 +1512,22 @@ int dquot_initialize(struct inode *inode)
|
|||
}
|
||||
EXPORT_SYMBOL(dquot_initialize);
|
||||
|
||||
bool dquot_initialize_needed(struct inode *inode)
|
||||
{
|
||||
struct dquot **dquots;
|
||||
int i;
|
||||
|
||||
if (!dquot_active(inode))
|
||||
return false;
|
||||
|
||||
dquots = i_dquot(inode);
|
||||
for (i = 0; i < MAXQUOTAS; i++)
|
||||
if (!dquots[i] && sb_has_quota_active(inode->i_sb, i))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
EXPORT_SYMBOL(dquot_initialize_needed);
|
||||
|
||||
/*
|
||||
* Release all quotas referenced by inode.
|
||||
*
|
||||
|
|
|
@ -44,6 +44,7 @@ void inode_sub_rsv_space(struct inode *inode, qsize_t number);
|
|||
void inode_reclaim_rsv_space(struct inode *inode, qsize_t number);
|
||||
|
||||
int dquot_initialize(struct inode *inode);
|
||||
bool dquot_initialize_needed(struct inode *inode);
|
||||
void dquot_drop(struct inode *inode);
|
||||
struct dquot *dqget(struct super_block *sb, struct kqid qid);
|
||||
static inline struct dquot *dqgrab(struct dquot *dquot)
|
||||
|
@ -207,6 +208,11 @@ static inline int dquot_initialize(struct inode *inode)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static inline bool dquot_initialize_needed(struct inode *inode)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline void dquot_drop(struct inode *inode)
|
||||
{
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче