From 56246f9ae4cfa95b460f9dfbcfb1b772d85db046 Mon Sep 17 00:00:00 2001 From: Eric Sandeen Date: Sun, 16 May 2010 09:00:00 -0400 Subject: quota: use flags interface for dquot alloc/free space Switch __dquot_alloc_space and __dquot_free_space to take flags to indicate whether to warn and/or to reserve (or free reserve). This is slightly more readable at the callpoints, and makes it cleaner to add a "nofail" option in the next patch. Signed-off-by: Eric Sandeen Signed-off-by: "Theodore Ts'o" --- fs/quota/dquot.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'fs/quota/dquot.c') diff --git a/fs/quota/dquot.c b/fs/quota/dquot.c index 788b5802a7c..8c40c07797a 100644 --- a/fs/quota/dquot.c +++ b/fs/quota/dquot.c @@ -1488,11 +1488,12 @@ static void inode_decr_space(struct inode *inode, qsize_t number, int reserve) /* * This operation can block, but only after everything is updated */ -int __dquot_alloc_space(struct inode *inode, qsize_t number, - int warn, int reserve) +int __dquot_alloc_space(struct inode *inode, qsize_t number, int flags) { int cnt, ret = 0; char warntype[MAXQUOTAS]; + int warn = flags & DQUOT_SPACE_WARN; + int reserve = flags & DQUOT_SPACE_RESERVE; /* * First test before acquiring mutex - solves deadlocks when we @@ -1612,10 +1613,11 @@ EXPORT_SYMBOL(dquot_claim_space_nodirty); /* * This operation can block, but only after everything is updated */ -void __dquot_free_space(struct inode *inode, qsize_t number, int reserve) +void __dquot_free_space(struct inode *inode, qsize_t number, int flags) { unsigned int cnt; char warntype[MAXQUOTAS]; + int reserve = flags & DQUOT_SPACE_RESERVE; /* First test before acquiring mutex - solves deadlocks when we * re-enter the quota code and are already holding the mutex */ -- cgit v1.2.3 From 0e05842bc117ea70ceb979cca798fd026879951b Mon Sep 17 00:00:00 2001 From: Eric Sandeen Date: Sun, 16 May 2010 10:00:00 -0400 Subject: quota: add the option to not fail with EDQUOT in block 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 Signed-off-by: "Theodore Ts'o" --- fs/quota/dquot.c | 3 ++- include/linux/quotaops.h | 12 ++++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) (limited to 'fs/quota/dquot.c') diff --git a/fs/quota/dquot.c b/fs/quota/dquot.c index 8c40c07797a..df6832ec17c 100644 --- a/fs/quota/dquot.c +++ b/fs/quota/dquot.c @@ -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 @@ -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; } diff --git a/include/linux/quotaops.h b/include/linux/quotaops.h index 9edd53c2498..f8dbeb0fe0c 100644 --- a/include/linux/quotaops.h +++ b/include/linux/quotaops.h @@ -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) { @@ -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; @@ -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); -- cgit v1.2.3