}
/*
- * Does @logical lie within an open stripe run? Used by the raid56 layer to
- * decide whether a partial write to this stripe may be parked to collect
- * into a full-stripe write: an open run guarantees the rest of the stripe
- * is either filled before the run closes or never.
+ * Does @logical lie within a stripe run (open or draining)? Used by the
+ * raid56 layer to decide whether a partial write to this stripe may be
+ * parked to collect into a full-stripe write: an open run guarantees the
+ * rest of the stripe is either filled before the run closes or never, and
+ * a draining run's frozen frontier makes "never" decidable -- everything
+ * allocated below it is inflight IO the commit drain already waits for,
+ * and everything above it is dead space the pad fills.
*/
bool btrfs_stripe_in_open_run(struct btrfs_fs_info *fs_info, u64 logical)
{
return false;
spin_lock_irqsave(&bg->stripe_run_lock, flags);
list_for_each_entry(run, &bg->open_stripe_runs, list) {
- if (run->open && logical >= run->start && logical < run->end) {
+ /*
+ * A closed run's end has been shrunk to its frontier, so a
+ * write into it (necessarily below the frontier) still
+ * matches; its arrival is what the run's drain is waiting
+ * for. Excluding draining runs here made every run's tail
+ * writes unparkable -- the run closes on exhaustion in the
+ * gap between allocation and write arrival -- and those
+ * writes were the bulk of stripe_alloc's read-modify-writes.
+ */
+ if (logical >= run->start && logical < run->end) {
if (class)
*class = run->class;
ret = true;