return test_bit(DQ_ACTIVE_B, &dquot->dq_flags);
}
+static struct dquot *__dqgrab(struct dquot *dquot)
+{
+ lockdep_assert_held(&dq_list_lock);
+ if (!atomic_read(&dquot->dq_count))
+ remove_free_dquot(dquot);
+ atomic_inc(&dquot->dq_count);
+ return dquot;
+}
+
+/*
+ * Get reference to dquot when we got pointer to it by some other means. The
+ * dquot has to be active and the caller has to make sure it cannot get
+ * deactivated under our hands.
+ */
+struct dquot *dqgrab(struct dquot *dquot)
+{
+ spin_lock(&dq_list_lock);
+ WARN_ON_ONCE(!dquot_active(dquot));
+ dquot = __dqgrab(dquot);
+ spin_unlock(&dq_list_lock);
+
+ return dquot;
+}
+EXPORT_SYMBOL_GPL(dqgrab);
+
static inline int dquot_dirty(struct dquot *dquot)
{
return test_bit(DQ_MOD_B, &dquot->dq_flags);
continue;
if (dquot->dq_sb != sb)
continue;
- /* Now we have active dquot so we can just increase use count */
- atomic_inc(&dquot->dq_count);
+ __dqgrab(dquot);
spin_unlock(&dq_list_lock);
dqput(old_dquot);
old_dquot = dquot;
/*
* ->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.
+ * protects us from dquot_release() proceeding so just wait for
+ * any outstanding call and recheck the DQ_ACTIVE_B after that.
*/
wait_on_dquot(dquot);
if (dquot_active(dquot)) {
/* Now we have active dquot from which someone is
* holding reference so we can safely just increase
* use count */
- dqgrab(dquot);
+ __dqgrab(dquot);
spin_unlock(&dq_list_lock);
err = dquot_write_dquot(dquot);
if (err && !ret)
spin_unlock(&dq_list_lock);
dqstats_inc(DQST_LOOKUPS);
} else {
- if (!atomic_read(&dquot->dq_count))
- remove_free_dquot(dquot);
- atomic_inc(&dquot->dq_count);
+ __dqgrab(dquot);
spin_unlock(&dq_list_lock);
dqstats_inc(DQST_CACHE_HITS);
dqstats_inc(DQST_LOOKUPS);
bool dquot_initialize_needed(struct inode *inode);
void dquot_drop(struct inode *inode);
struct dquot *dqget(struct super_block *sb, struct kqid qid);
-static inline struct dquot *dqgrab(struct dquot *dquot)
-{
- /* Make sure someone else has active reference to dquot */
- WARN_ON_ONCE(!atomic_read(&dquot->dq_count));
- WARN_ON_ONCE(!test_bit(DQ_ACTIVE_B, &dquot->dq_flags));
- atomic_inc(&dquot->dq_count);
- return dquot;
-}
+struct dquot *dqgrab(struct dquot *dquot);
static inline bool dquot_is_busy(struct dquot *dquot)
{