struct btrfs_fs_info *fs_info = rbio->bioc->fs_info;
struct btrfs_stripe_hash_table *table = fs_info->stripe_hash_table;
unsigned int timeout_ms = BTRFS_RBIO_PARK_TIMEOUT_MS;
+ enum btrfs_stripe_run_class class;
- if (!btrfs_stripe_in_open_run(fs_info, rbio->bioc->full_stripe_logical))
+ if (!btrfs_stripe_open_run_class(fs_info,
+ rbio->bioc->full_stripe_logical,
+ &class))
return false;
spin_lock(&rbio->bio_list_lock);
timeout_ms = BTRFS_RBIO_PARK_SYNC_TIMEOUT_MS;
spin_unlock(&rbio->bio_list_lock);
+ /*
+ * A sync write into a nodatacow inode's private run has a waiter
+ * behind it and nothing worth waiting to merge with: in-place
+ * overwrites arrive one fsync at a time, and the plain (unparked)
+ * write path is what stock nodatacow latency looks like. Park only
+ * async writeback there.
+ */
+ if (class == BTRFS_STRIPE_RUN_NOCOW &&
+ timeout_ms == BTRFS_RBIO_PARK_SYNC_TIMEOUT_MS)
+ return false;
+
spin_lock(&table->parked_lock);
set_bit(RBIO_PARKED_BIT, &rbio->flags);
rbio->park_deadline = jiffies + msecs_to_jiffies(timeout_ms);