quota: Do not acquire dqio_sem for dquot overwrites in v2 format
authorJan Kara <jack@suse.cz>
Thu, 8 Jun 2017 14:09:46 +0000 (16:09 +0200)
committerJan Kara <jack@suse.cz>
Thu, 17 Aug 2017 17:03:16 +0000 (19:03 +0200)
When dquot has space already allocated in a quota file, we just
overwrite that place when writing dquot. So we don't need any protection
against other modifications of quota file as these keep dquot in place.

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

index 482733abe4ac9ca2cd4adc7ec38dc042eb2dd3bf..7a05b80f3b8ceb7c620f52f99a8b24fe2cf1c12d 100644 (file)
@@ -300,12 +300,23 @@ static int v2_write_dquot(struct dquot *dquot)
 {
        struct quota_info *dqopt = sb_dqopt(dquot->dq_sb);
        int ret;
 {
        struct quota_info *dqopt = sb_dqopt(dquot->dq_sb);
        int ret;
-
-       down_write(&dqopt->dqio_sem);
+       bool alloc = false;
+
+       /*
+        * If space for dquot is already allocated, we don't need any
+        * protection as we'll only overwrite the place of dquot. We are
+        * still protected by concurrent writes of the same dquot by
+        * dquot->dq_lock.
+        */
+       if (!dquot->dq_off) {
+               alloc = true;
+               down_write(&dqopt->dqio_sem);
+       }
        ret = qtree_write_dquot(
                        sb_dqinfo(dquot->dq_sb, dquot->dq_id.type)->dqi_priv,
                        dquot);
        ret = qtree_write_dquot(
                        sb_dqinfo(dquot->dq_sb, dquot->dq_id.type)->dqi_priv,
                        dquot);
-       up_write(&dqopt->dqio_sem);
+       if (alloc)
+               up_write(&dqopt->dqio_sem);
        return ret;
 }
 
        return ret;
 }