Skip to content

Commit

Permalink
quota: add the option to not fail with EDQUOT in block
Browse files Browse the repository at this point in the history
To simplify metadata tracking for delalloc writes, ext4
will simply claim metadata blocks at allocation time, without
first speculatively reserving the worst case and then freeing
what was not used.

To do this, we need a mechanism to track allocations in
the quota subsystem, but potentially allow that allocation
to actually go over quota.

This patch adds a DQUOT_SPACE_NOFAIL flag and function
variants for this purpose.

Signed-off-by: Eric Sandeen <sandeen@redhat.com>
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
  • Loading branch information
Eric Sandeen authored and Theodore Ts'o committed May 16, 2010
1 parent 56246f9 commit 0e05842
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 1 deletion.
3 changes: 2 additions & 1 deletion fs/quota/dquot.c
Original file line number Diff line number Diff line change
Expand Up @@ -1494,6 +1494,7 @@ int __dquot_alloc_space(struct inode *inode, qsize_t number, int flags)
char warntype[MAXQUOTAS];
int warn = flags & DQUOT_SPACE_WARN;
int reserve = flags & DQUOT_SPACE_RESERVE;
int nofail = flags & DQUOT_SPACE_NOFAIL;

/*
* First test before acquiring mutex - solves deadlocks when we
Expand All @@ -1514,7 +1515,7 @@ int __dquot_alloc_space(struct inode *inode, qsize_t number, int flags)
continue;
ret = check_bdq(inode->i_dquot[cnt], number, !warn,
warntype+cnt);
if (ret) {
if (ret && !nofail) {
spin_unlock(&dq_data_lock);
goto out_flush_warn;
}
Expand Down
12 changes: 12 additions & 0 deletions include/linux/quotaops.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

#define DQUOT_SPACE_WARN 0x1
#define DQUOT_SPACE_RESERVE 0x2
#define DQUOT_SPACE_NOFAIL 0x4

static inline struct quota_info *sb_dqopt(struct super_block *sb)
{
Expand Down Expand Up @@ -262,6 +263,12 @@ static inline int dquot_alloc_space_nodirty(struct inode *inode, qsize_t nr)
return __dquot_alloc_space(inode, nr, DQUOT_SPACE_WARN);
}

static inline void dquot_alloc_space_nofail(struct inode *inode, qsize_t nr)
{
__dquot_alloc_space(inode, nr, DQUOT_SPACE_WARN|DQUOT_SPACE_NOFAIL);
mark_inode_dirty(inode);
}

static inline int dquot_alloc_space(struct inode *inode, qsize_t nr)
{
int ret;
Expand All @@ -277,6 +284,11 @@ static inline int dquot_alloc_block_nodirty(struct inode *inode, qsize_t nr)
return dquot_alloc_space_nodirty(inode, nr << inode->i_blkbits);
}

static inline void dquot_alloc_block_nofail(struct inode *inode, qsize_t nr)
{
dquot_alloc_space_nofail(inode, nr << inode->i_blkbits);
}

static inline int dquot_alloc_block(struct inode *inode, qsize_t nr)
{
return dquot_alloc_space(inode, nr << inode->i_blkbits);
Expand Down

0 comments on commit 0e05842

Please sign in to comment.