quota: Push dqio_sem down to ->write_dqblk()
authorJan Kara <jack@suse.cz>
Thu, 8 Jun 2017 13:48:16 +0000 (15:48 +0200)
committerJan Kara <jack@suse.cz>
Thu, 17 Aug 2017 17:03:09 +0000 (19:03 +0200)
Push down acquisition of dqio_sem into ->write_dqblk() callback. It will
allow quota formats to decide whether they need it or not.

Reviewed-by: Andreas Dilger <adilger@dilger.ca>
Signed-off-by: Jan Kara <jack@suse.cz>
fs/quota/dquot.c
fs/quota/quota_v1.c
fs/quota/quota_v2.c

index 46046523abf0fc55216ae958a9cfb254dccb1b05..562f5978488ff1d944affa6d381799eddf5ba578 100644 (file)
@@ -412,14 +412,14 @@ int dquot_acquire(struct dquot *dquot)
        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])) {
+                       down_write(&dqopt->dqio_sem);
                        ret2 = dqopt->ops[dquot->dq_id.type]->write_file_info(
                                        dquot->dq_sb, dquot->dq_id.type);
+                       up_write(&dqopt->dqio_sem);
                }
-               up_write(&dqopt->dqio_sem);
                if (ret < 0)
                        goto out_iolock;
                if (ret2 < 0) {
@@ -456,13 +456,10 @@ int dquot_commit(struct dquot *dquot)
        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;
index 12d69cda57cca9f25a998e88b9be38e534aa0e11..94cceb76b9a3cf5b9ca66203450eb9564e493bdd 100644 (file)
@@ -83,7 +83,9 @@ static int v1_commit_dqblk(struct dquot *dquot)
        short type = dquot->dq_id.type;
        ssize_t ret;
        struct v1_disk_dqblk dqblk;
+       struct quota_info *dqopt = sb_dqopt(dquot->dq_sb);
 
+       down_write(&dqopt->dqio_sem);
        v1_mem2disk_dqblk(&dqblk, &dquot->dq_dqb);
        if (((type == USRQUOTA) && uid_eq(dquot->dq_id.uid, GLOBAL_ROOT_UID)) ||
            ((type == GRPQUOTA) && gid_eq(dquot->dq_id.gid, GLOBAL_ROOT_GID))) {
@@ -97,6 +99,7 @@ static int v1_commit_dqblk(struct dquot *dquot)
                ret = dquot->dq_sb->s_op->quota_write(dquot->dq_sb, type,
                        (char *)&dqblk, sizeof(struct v1_disk_dqblk),
                        v1_dqoff(from_kqid(&init_user_ns, dquot->dq_id)));
+       up_write(&dqopt->dqio_sem);
        if (ret != sizeof(struct v1_disk_dqblk)) {
                quota_error(dquot->dq_sb, "dquota write failed");
                if (ret >= 0)
index b2cd34f6b3da8bb17a6fdfe1d10018250b5f162b..482733abe4ac9ca2cd4adc7ec38dc042eb2dd3bf 100644 (file)
@@ -298,7 +298,15 @@ static int v2_read_dquot(struct dquot *dquot)
 
 static int v2_write_dquot(struct dquot *dquot)
 {
-       return qtree_write_dquot(sb_dqinfo(dquot->dq_sb, dquot->dq_id.type)->dqi_priv, dquot);
+       struct quota_info *dqopt = sb_dqopt(dquot->dq_sb);
+       int ret;
+
+       down_write(&dqopt->dqio_sem);
+       ret = qtree_write_dquot(
+                       sb_dqinfo(dquot->dq_sb, dquot->dq_id.type)->dqi_priv,
+                       dquot);
+       up_write(&dqopt->dqio_sem);
+       return ret;
 }
 
 static int v2_release_dquot(struct dquot *dquot)