*/
#define RBIO_PADDED_BIT 5
+/*
+ * Set when an unplug callback finished merging this rbio's submission
+ * batch: the submitter has no more bios coming. A sync rbio past this
+ * point gains nothing from parking (its own batch is fully merged and a
+ * waiter is behind it), so it skips straight to the write.
+ */
+#define RBIO_BATCH_DONE_BIT 6
+
/* Set at park time and never cleared: this rbio once parked (stats). */
#define RBIO_WAS_PARKED_BIT 7
timeout_ms == BTRFS_RBIO_PARK_SYNC_TIMEOUT_MS)
return false;
+ /*
+ * A sync rbio whose submission batch was already merged by its
+ * unplug callback has nothing more coming from its submitter; the
+ * only thing parking can add is its deadline. (Unplugged sync
+ * submissions -- the fsync flush -- still park: their sibling bios
+ * arrive one by one and merge into the parked rbio, and the fsync
+ * path kicks it as soon as they have all been submitted.)
+ */
+ if (test_bit(RBIO_BATCH_DONE_BIT, &rbio->flags) &&
+ timeout_ms == BTRFS_RBIO_PARK_SYNC_TIMEOUT_MS)
+ return false;
+
spin_lock(&table->parked_lock);
set_bit(RBIO_PARKED_BIT, &rbio->flags);
set_bit(RBIO_WAS_PARKED_BIT, &rbio->flags);
free_raid_bio(cur);
continue;
}
+ set_bit(RBIO_BATCH_DONE_BIT, &last->flags);
start_async_work(last, rmw_rbio_work);
}
last = cur;
}
- if (last)
+ if (last) {
+ set_bit(RBIO_BATCH_DONE_BIT, &last->flags);
start_async_work(last, rmw_rbio_work);
+ }
kfree(plug);
}