dect
/
linux-2.6
Archived
13
0
Fork 0

ocfs2: Remove ocfs2_dquot_initialize() and ocfs2_dquot_drop()

Since ->acquire_dquot and ->release_dquot callbacks aren't called under
dqptr_sem anymore, we don't have to start a transaction and obtain locks
so early. So we can just remove all this complicated stuff.

Signed-off-by: Jan Kara <jack@suse.cz>
Acked-by: Mark Fasheh <mfasheh@suse.de>
This commit is contained in:
Jan Kara 2009-01-12 17:44:34 +01:00
parent cc33412fb1
commit c475146d8f
1 changed files with 2 additions and 167 deletions

View File

@ -810,171 +810,6 @@ out:
return status;
}
/* This is difficult. We have to lock quota inode and start transaction
* in this function but we don't want to take the penalty of exlusive
* quota file lock when we are just going to use cached structures. So
* we just take read lock check whether we have dquot cached and if so,
* we don't have to take the write lock... */
static int ocfs2_dquot_initialize(struct inode *inode, int type)
{
handle_t *handle = NULL;
int status = 0;
struct super_block *sb = inode->i_sb;
struct ocfs2_mem_dqinfo *oinfo;
int exclusive = 0;
int cnt;
qid_t id;
mlog_entry_void();
for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
if (type != -1 && cnt != type)
continue;
if (!sb_has_quota_active(sb, cnt))
continue;
oinfo = sb_dqinfo(sb, cnt)->dqi_priv;
status = ocfs2_lock_global_qf(oinfo, 0);
if (status < 0)
goto out;
/* This is just a performance optimization not a reliable test.
* Since we hold an inode lock, noone can actually release
* the structure until we are finished with initialization. */
if (inode->i_dquot[cnt] != NODQUOT) {
ocfs2_unlock_global_qf(oinfo, 0);
continue;
}
/* When we have inode lock, we know that no dquot_release() can
* run and thus we can safely check whether we need to
* read+modify global file to get quota information or whether
* our node already has it. */
if (cnt == USRQUOTA)
id = inode->i_uid;
else if (cnt == GRPQUOTA)
id = inode->i_gid;
else
BUG();
/* Obtain exclusion from quota off... */
down_write(&sb_dqopt(sb)->dqptr_sem);
exclusive = !dquot_is_cached(sb, id, cnt);
up_write(&sb_dqopt(sb)->dqptr_sem);
if (exclusive) {
status = ocfs2_lock_global_qf(oinfo, 1);
if (status < 0) {
exclusive = 0;
mlog_errno(status);
goto out_ilock;
}
handle = ocfs2_start_trans(OCFS2_SB(sb),
ocfs2_calc_qinit_credits(sb, cnt));
if (IS_ERR(handle)) {
status = PTR_ERR(handle);
mlog_errno(status);
goto out_ilock;
}
}
dquot_initialize(inode, cnt);
if (exclusive) {
ocfs2_commit_trans(OCFS2_SB(sb), handle);
ocfs2_unlock_global_qf(oinfo, 1);
}
ocfs2_unlock_global_qf(oinfo, 0);
}
mlog_exit(0);
return 0;
out_ilock:
if (exclusive)
ocfs2_unlock_global_qf(oinfo, 1);
ocfs2_unlock_global_qf(oinfo, 0);
out:
mlog_exit(status);
return status;
}
static int ocfs2_dquot_drop_slow(struct inode *inode)
{
int status = 0;
int cnt;
int got_lock[MAXQUOTAS] = {0, 0};
handle_t *handle;
struct super_block *sb = inode->i_sb;
struct ocfs2_mem_dqinfo *oinfo;
for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
if (!sb_has_quota_active(sb, cnt))
continue;
oinfo = sb_dqinfo(sb, cnt)->dqi_priv;
status = ocfs2_lock_global_qf(oinfo, 1);
if (status < 0)
goto out;
got_lock[cnt] = 1;
}
handle = ocfs2_start_trans(OCFS2_SB(sb),
ocfs2_calc_qinit_credits(sb, USRQUOTA) +
ocfs2_calc_qinit_credits(sb, GRPQUOTA));
if (IS_ERR(handle)) {
status = PTR_ERR(handle);
mlog_errno(status);
goto out;
}
dquot_drop(inode);
ocfs2_commit_trans(OCFS2_SB(sb), handle);
out:
for (cnt = 0; cnt < MAXQUOTAS; cnt++)
if (got_lock[cnt]) {
oinfo = sb_dqinfo(sb, cnt)->dqi_priv;
ocfs2_unlock_global_qf(oinfo, 1);
}
return status;
}
/* See the comment before ocfs2_dquot_initialize. */
static int ocfs2_dquot_drop(struct inode *inode)
{
int status = 0;
struct super_block *sb = inode->i_sb;
struct ocfs2_mem_dqinfo *oinfo;
int exclusive = 0;
int cnt;
int got_lock[MAXQUOTAS] = {0, 0};
mlog_entry_void();
for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
if (!sb_has_quota_active(sb, cnt))
continue;
oinfo = sb_dqinfo(sb, cnt)->dqi_priv;
status = ocfs2_lock_global_qf(oinfo, 0);
if (status < 0)
goto out;
got_lock[cnt] = 1;
}
/* Lock against anyone releasing references so that when when we check
* we know we are not going to be last ones to release dquot */
down_write(&sb_dqopt(sb)->dqptr_sem);
/* Urgh, this is a terrible hack :( */
for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
if (inode->i_dquot[cnt] != NODQUOT &&
atomic_read(&inode->i_dquot[cnt]->dq_count) > 1) {
exclusive = 1;
break;
}
}
if (!exclusive)
dquot_drop_locked(inode);
up_write(&sb_dqopt(sb)->dqptr_sem);
out:
for (cnt = 0; cnt < MAXQUOTAS; cnt++)
if (got_lock[cnt]) {
oinfo = sb_dqinfo(sb, cnt)->dqi_priv;
ocfs2_unlock_global_qf(oinfo, 0);
}
/* In case we bailed out because we had to do expensive locking
* do it now... */
if (exclusive)
status = ocfs2_dquot_drop_slow(inode);
mlog_exit(status);
return status;
}
static struct dquot *ocfs2_alloc_dquot(struct super_block *sb, int type)
{
struct ocfs2_dquot *dquot =
@ -991,8 +826,8 @@ static void ocfs2_destroy_dquot(struct dquot *dquot)
}
struct dquot_operations ocfs2_quota_operations = {
.initialize = ocfs2_dquot_initialize,
.drop = ocfs2_dquot_drop,
.initialize = dquot_initialize,
.drop = dquot_drop,
.alloc_space = dquot_alloc_space,
.alloc_inode = dquot_alloc_inode,
.free_space = dquot_free_space,