===================================================================
@@ -849,19 +849,18 @@ static inline void dquot_resv_space(stru
/*
* Claim reserved quota space
*/
-static int dquot_claim_reserved_space(struct dquot *dquot,
+static void dquot_claim_reserved_space(struct dquot *dquot,
qsize_t number)
{
- if (dquot->dq_dqb.dqb_rsvspace < number) {
- printk(KERN_WARNING "Reserved quota %llu is not enough for"
- "request %llu bytes\n",
- (unsigned long long)dquot->dq_dqb.dqb_rsvspace, number);
- return 1;
- }
-
+ WARN_ON(dquot->dq_dqb.dqb_rsvspace < number);
dquot->dq_dqb.dqb_curspace += number;
dquot->dq_dqb.dqb_rsvspace -= number;
- return 0;
+}
+
+static inline
+void dquot_free_reserved_space(struct dquot *dquot, qsize_t number)
+{
+ dquot->dq_dqb.dqb_rsvspace -= number;
}
static inline void dquot_decr_inodes(struct dquot *dquot, qsize_t number)
@@ -1344,34 +1343,32 @@ int dquot_claim_space(struct inode *inod
if (IS_NOQUOTA(inode)) {
inode_add_bytes(inode, number);
- return ret;
+ goto out;
}
down_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
if (IS_NOQUOTA(inode)) {
up_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
inode_add_bytes(inode, number);
- return ret;
+ goto out;
}
+ spin_lock(&dq_data_lock);
/* Claim reserved quotas to allocated quotas */
for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
if (inode->i_dquot[cnt] != NODQUOT)
- ret = dquot_claim_reserved_space(inode->i_dquot[cnt],
+ dquot_claim_reserved_space(inode->i_dquot[cnt],
number);
}
- if (ret == NO_QUOTA) {
- up_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
- return ret;
- }
+ /* Update inode bytes */
+ inode_add_bytes(inode, number);
+ spin_unlock(&dq_data_lock);
/* Dirtify all the dquots - this can block when journalling */
for (cnt = 0; cnt < MAXQUOTAS; cnt++)
if (inode->i_dquot[cnt])
mark_dquot_dirty(inode->i_dquot[cnt]);
up_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
-
- /* Update inode bytes */
- inode_add_bytes(inode, number);
+out:
return ret;
}
@@ -1390,13 +1387,15 @@ void dquot_release_reserved_space(struct
if (IS_NOQUOTA(inode))
goto out_unlock;
+ spin_lock(&dq_data_lock);
/* Release reserved dquots */
for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
if (inode->i_dquot[cnt] != NODQUOT) {
dquot = inode->i_dquot[cnt];
- dquot->dq_dqb.dqb_rsvspace -= number;
+ dquot_free_reserved_space(dquot, number);
}
}
+ spin_unlock(&dq_data_lock);
out_unlock:
up_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
@@ -1533,7 +1532,8 @@ int dquot_free_inode(const struct inode
*/
int dquot_transfer(struct inode *inode, struct iattr *iattr)
{
- qsize_t space;
+ qsize_t space, cur_space;
+ qsize_t rsv_space = 0;
struct dquot *transfer_from[MAXQUOTAS];
struct dquot *transfer_to[MAXQUOTAS];
int cnt, ret = NO_QUOTA, chuid = (iattr->ia_valid & ATTR_UID) && inode->i_uid != iattr->ia_uid,
@@ -1574,12 +1574,16 @@ int dquot_transfer(struct inode *inode,
}
}
spin_lock(&dq_data_lock);
- space = inode_get_bytes(inode);
+ space = cur_space = inode_get_bytes(inode);
/* Build the transfer_from list and check the limits */
for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
if (transfer_to[cnt] == NODQUOT)
continue;
transfer_from[cnt] = inode->i_dquot[cnt];
+ if (!rsv_space) {
+ rsv_space = transfer_from[cnt]->dq_dqb.dqb_rsvspace;
+ space += rsv_space;
+ }
if (check_idq(transfer_to[cnt], 1, warntype_to + cnt) ==
NO_QUOTA || check_bdq(transfer_to[cnt], space, 0,
warntype_to + cnt) == NO_QUOTA)
@@ -1603,11 +1607,13 @@ int dquot_transfer(struct inode *inode,
warntype_from_space[cnt] =
info_bdq_free(transfer_from[cnt], space);
dquot_decr_inodes(transfer_from[cnt], 1);
- dquot_decr_space(transfer_from[cnt], space);
+ dquot_decr_space(transfer_from[cnt], cur_space);
+ dquot_free_reserved_space(transfer_from[cnt], rsv_space);
}
dquot_incr_inodes(transfer_to[cnt], 1);
- dquot_incr_space(transfer_to[cnt], space);
+ dquot_incr_space(transfer_to[cnt], cur_space);
+ dquot_resv_space(transfer_to[cnt], rsv_space);
inode->i_dquot[cnt] = transfer_to[cnt];
}
===================================================================
@@ -434,7 +434,7 @@ static inline int vfs_dq_claim_block(str
}
static inline
-void vfs_dq_release_reservation(struct inode *inode, qsize_t nr)
+void vfs_dq_release_reservation_block(struct inode *inode, qsize_t nr)
{
vfs_dq_release_reservation_space(inode, nr << inode->i_blkbits);
}
@@ -467,8 +467,6 @@ static inline void vfs_dq_free_block(str
#define DQUOT_ALLOC_BLOCK_NODIRTY(inode, nr) \
vfs_dq_alloc_block_nodirty(inode, nr)
#define DQUOT_ALLOC_BLOCK(inode, nr) vfs_dq_alloc_block(inode, nr)
-#define DQUOT_CLAIM_BLOCK(inode, nr) vfs_dq_claim_block(inode, nr)
-#define DQUOT_RELEASE_RSV_BLOCK(inode, nr) vfs_dq_release_reservation(inode, nr)
#define DQUOT_ALLOC_INODE(inode) vfs_dq_alloc_inode(inode)
#define DQUOT_FREE_SPACE_NODIRTY(inode, nr) \
vfs_dq_free_space_nodirty(inode, nr)