* the bytes already admitted would no longer be placeable:
* otherwise their writebacks fail and the data is dropped.
*/
- if (!ret && READ_ONCE(cache->stripe_unusable_ready) &&
- sinfo->bytes_may_use + sinfo->bytes_stripe_margin >
- sinfo->bytes_stripe_claimable - cache->stripe_claimable)
- ret = -ENOSPC;
+ if (!ret && READ_ONCE(cache->stripe_unusable_ready)) {
+ /*
+ * stripe_claimable_mod() updates the group's value
+ * under the free-space tree lock and only then the
+ * aggregate under sinfo->lock, so a reader here can see
+ * the group ahead of the total: saturate, or the
+ * difference wraps and waves the transition through.
+ */
+ const u64 supply = sinfo->bytes_stripe_claimable;
+ const u64 mine = min(supply,
+ READ_ONCE(cache->stripe_claimable));
+
+ if (sinfo->bytes_may_use + sinfo->bytes_stripe_margin >
+ supply - mine)
+ ret = -ENOSPC;
+ }
} else {
/*
* We overcommit metadata, so we need to do the