{
int ret = 1;
+ if (!test_bit(DQ_ACTIVE_B, &dquot->dq_flags))
+ return 0;
+
/* If quota is dirty already, we don't have to acquire dq_list_lock */
if (test_bit(DQ_MOD_B, &dquot->dq_flags))
return 1;
void mark_info_dirty(struct super_block *sb, int type)
{
- set_bit(DQF_INFO_DIRTY_B, &sb_dqopt(sb)->info[type].dqi_flags);
+ spin_lock(&dq_data_lock);
+ sb_dqopt(sb)->info[type].dqi_flags |= DQF_INFO_DIRTY;
+ spin_unlock(&dq_data_lock);
}
EXPORT_SYMBOL(mark_info_dirty);
set_bit(DQ_READ_B, &dquot->dq_flags);
/* Instantiate dquot if needed */
if (!test_bit(DQ_ACTIVE_B, &dquot->dq_flags) && !dquot->dq_off) {
- down_write(&dqopt->dqio_sem);
ret = dqopt->ops[dquot->dq_id.type]->commit_dqblk(dquot);
/* Write the info if needed */
if (info_dirty(&dqopt->info[dquot->dq_id.type])) {
ret2 = dqopt->ops[dquot->dq_id.type]->write_file_info(
dquot->dq_sb, dquot->dq_id.type);
}
- up_write(&dqopt->dqio_sem);
if (ret < 0)
goto out_iolock;
if (ret2 < 0) {
spin_unlock(&dq_list_lock);
/* Inactive dquot can be only if there was error during read/init
* => we have better not writing it */
- if (test_bit(DQ_ACTIVE_B, &dquot->dq_flags)) {
- down_write(&dqopt->dqio_sem);
+ if (test_bit(DQ_ACTIVE_B, &dquot->dq_flags))
ret = dqopt->ops[dquot->dq_id.type]->commit_dqblk(dquot);
- up_write(&dqopt->dqio_sem);
- } else {
+ else
ret = -EIO;
- }
out_lock:
mutex_unlock(&dquot->dq_lock);
return ret;
/* Check whether we are not racing with some other dqget() */
if (atomic_read(&dquot->dq_count) > 1)
goto out_dqlock;
- down_write(&dqopt->dqio_sem);
if (dqopt->ops[dquot->dq_id.type]->release_dqblk) {
ret = dqopt->ops[dquot->dq_id.type]->release_dqblk(dquot);
/* Write the info */
ret = ret2;
}
clear_bit(DQ_ACTIVE_B, &dquot->dq_flags);
- up_write(&dqopt->dqio_sem);
out_dqlock:
mutex_unlock(&dquot->dq_lock);
return ret;
while (!list_empty(dirty)) {
dquot = list_first_entry(dirty, struct dquot,
dq_dirty);
- /* Dirty and inactive can be only bad dquot... */
- if (!test_bit(DQ_ACTIVE_B, &dquot->dq_flags)) {
- clear_dquot_dirty(dquot);
- continue;
- }
+
+ WARN_ON(!test_bit(DQ_ACTIVE_B, &dquot->dq_flags));
+
/* Now we have active dquot from which someone is
* holding reference so we can safely just increase
* use count */
return;
}
/* Need to release dquot? */
- if (test_bit(DQ_ACTIVE_B, &dquot->dq_flags) && dquot_dirty(dquot)) {
+ if (dquot_dirty(dquot)) {
spin_unlock(&dq_list_lock);
/* Commit dquot before releasing */
ret = dquot->dq_sb->dq_op->write_dquot(dquot);
}
goto we_slept;
}
- /* Clear flag in case dquot was inactive (something bad happened) */
- clear_dquot_dirty(dquot);
if (test_bit(DQ_ACTIVE_B, &dquot->dq_flags)) {
spin_unlock(&dq_list_lock);
dquot->dq_sb->dq_op->release_dquot(dquot);
*/
int dquot_commit_info(struct super_block *sb, int type)
{
- int ret;
struct quota_info *dqopt = sb_dqopt(sb);
- down_write(&dqopt->dqio_sem);
- ret = dqopt->ops[type]->write_file_info(sb, type);
- up_write(&dqopt->dqio_sem);
- return ret;
+ return dqopt->ops[type]->write_file_info(sb, type);
}
EXPORT_SYMBOL(dquot_commit_info);
int dquot_get_next_id(struct super_block *sb, struct kqid *qid)
{
struct quota_info *dqopt = sb_dqopt(sb);
- int err;
if (!sb_has_quota_active(sb, qid->type))
return -ESRCH;
if (!dqopt->ops[qid->type]->get_next_id)
return -ENOSYS;
- down_read(&dqopt->dqio_sem);
- err = dqopt->ops[qid->type]->get_next_id(sb, qid);
- up_read(&dqopt->dqio_sem);
- return err;
+ return dqopt->ops[qid->type]->get_next_id(sb, qid);
}
EXPORT_SYMBOL(dquot_get_next_id);
dqopt->info[type].dqi_format = fmt;
dqopt->info[type].dqi_fmt_id = format_id;
INIT_LIST_HEAD(&dqopt->info[type].dqi_dirty_list);
- down_read(&dqopt->dqio_sem);
error = dqopt->ops[type]->read_file_info(sb, type);
- if (error < 0) {
- up_read(&dqopt->dqio_sem);
+ if (error < 0)
goto out_file_init;
- }
- if (dqopt->flags & DQUOT_QUOTA_SYS_FILE)
+ if (dqopt->flags & DQUOT_QUOTA_SYS_FILE) {
+ spin_lock(&dq_data_lock);
dqopt->info[type].dqi_flags |= DQF_SYS_FILE;
- up_read(&dqopt->dqio_sem);
+ spin_unlock(&dq_data_lock);
+ }
spin_lock(&dq_state_lock);
dqopt->flags |= dquot_state_flag(flags, type);
spin_unlock(&dq_state_lock);