Commit 8bbd4223 authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds

[PATCH] dquot: fix i_blocks accounting and locking

From: Jan Kara <jack@ucw.cz>

A patch which fixes a problem that i_blocks are not updated for quota files
(when quota turned on) in 2.6.1.  The patch also fixes possible unlock of
not locked spin_lock.
parent 60f99f6a
...@@ -889,11 +889,9 @@ int dquot_alloc_space(struct inode *inode, qsize_t number, int warn) ...@@ -889,11 +889,9 @@ int dquot_alloc_space(struct inode *inode, qsize_t number, int warn)
warntype[cnt] = NOWARN; warntype[cnt] = NOWARN;
down_read(&sb_dqopt(inode->i_sb)->dqptr_sem); down_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
if (IS_NOQUOTA(inode)) {
up_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
return QUOTA_OK;
}
spin_lock(&dq_data_lock); spin_lock(&dq_data_lock);
if (IS_NOQUOTA(inode))
goto add_bytes;
for (cnt = 0; cnt < MAXQUOTAS; cnt++) { for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
if (inode->i_dquot[cnt] == NODQUOT) if (inode->i_dquot[cnt] == NODQUOT)
continue; continue;
...@@ -905,6 +903,7 @@ int dquot_alloc_space(struct inode *inode, qsize_t number, int warn) ...@@ -905,6 +903,7 @@ int dquot_alloc_space(struct inode *inode, qsize_t number, int warn)
continue; continue;
dquot_incr_space(inode->i_dquot[cnt], number); dquot_incr_space(inode->i_dquot[cnt], number);
} }
add_bytes:
inode_add_bytes(inode, number); inode_add_bytes(inode, number);
ret = QUOTA_OK; ret = QUOTA_OK;
warn_put_all: warn_put_all:
...@@ -958,16 +957,15 @@ void dquot_free_space(struct inode *inode, qsize_t number) ...@@ -958,16 +957,15 @@ void dquot_free_space(struct inode *inode, qsize_t number)
unsigned int cnt; unsigned int cnt;
down_read(&sb_dqopt(inode->i_sb)->dqptr_sem); down_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
if (IS_NOQUOTA(inode)) {
up_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
return;
}
spin_lock(&dq_data_lock); spin_lock(&dq_data_lock);
if (IS_NOQUOTA(inode))
goto sub_bytes;
for (cnt = 0; cnt < MAXQUOTAS; cnt++) { for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
if (inode->i_dquot[cnt] == NODQUOT) if (inode->i_dquot[cnt] == NODQUOT)
continue; continue;
dquot_decr_space(inode->i_dquot[cnt], number); dquot_decr_space(inode->i_dquot[cnt], number);
} }
sub_bytes:
inode_sub_bytes(inode, number); inode_sub_bytes(inode, number);
spin_unlock(&dq_data_lock); spin_unlock(&dq_data_lock);
up_read(&sb_dqopt(inode->i_sb)->dqptr_sem); up_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
...@@ -1015,8 +1013,10 @@ int dquot_transfer(struct inode *inode, struct iattr *iattr) ...@@ -1015,8 +1013,10 @@ int dquot_transfer(struct inode *inode, struct iattr *iattr)
warntype[cnt] = NOWARN; warntype[cnt] = NOWARN;
} }
down_write(&sb_dqopt(inode->i_sb)->dqptr_sem); down_write(&sb_dqopt(inode->i_sb)->dqptr_sem);
if (IS_NOQUOTA(inode)) /* File without quota accounting? */ if (IS_NOQUOTA(inode)) { /* File without quota accounting? */
goto warn_put_all; up_write(&sb_dqopt(inode->i_sb)->dqptr_sem);
return QUOTA_OK;
}
/* First build the transfer_to list - here we can block on reading of dquots... */ /* First build the transfer_to list - here we can block on reading of dquots... */
for (cnt = 0; cnt < MAXQUOTAS; cnt++) { for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
switch (cnt) { switch (cnt) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment