|
@@ -581,9 +581,17 @@ int dquot_scan_active(struct super_block *sb,
|
|
dqstats_inc(DQST_LOOKUPS);
|
|
dqstats_inc(DQST_LOOKUPS);
|
|
dqput(old_dquot);
|
|
dqput(old_dquot);
|
|
old_dquot = dquot;
|
|
old_dquot = dquot;
|
|
- ret = fn(dquot, priv);
|
|
|
|
- if (ret < 0)
|
|
|
|
- goto out;
|
|
|
|
|
|
+ /*
|
|
|
|
+ * ->release_dquot() can be racing with us. Our reference
|
|
|
|
+ * protects us from new calls to it so just wait for any
|
|
|
|
+ * outstanding call and recheck the DQ_ACTIVE_B after that.
|
|
|
|
+ */
|
|
|
|
+ wait_on_dquot(dquot);
|
|
|
|
+ if (test_bit(DQ_ACTIVE_B, &dquot->dq_flags)) {
|
|
|
|
+ ret = fn(dquot, priv);
|
|
|
|
+ if (ret < 0)
|
|
|
|
+ goto out;
|
|
|
|
+ }
|
|
spin_lock(&dq_list_lock);
|
|
spin_lock(&dq_list_lock);
|
|
/* We are safe to continue now because our dquot could not
|
|
/* We are safe to continue now because our dquot could not
|
|
* be moved out of the inuse list while we hold the reference */
|
|
* be moved out of the inuse list while we hold the reference */
|