struct btrfs_fs_info *fs_info = root->fs_info;
enum btrfs_reserve_flush_enum flush = BTRFS_RESERVE_FLUSH_DATA;
+ /* Relocation's prealloc clusters must not wait on the stripe_alloc gate. */
+ if (btrfs_is_data_reloc_root(root))
+ flush = BTRFS_RESERVE_FLUSH_DATA_RELOC;
+
/* Make sure bytes are sectorsize aligned */
bytes = ALIGN(bytes, fs_info->sectorsize);
switch (flush) {
case BTRFS_RESERVE_FLUSH_DATA:
+ case BTRFS_RESERVE_FLUSH_DATA_RELOC:
case BTRFS_RESERVE_FLUSH_ALL:
case BTRFS_RESERVE_FLUSH_ALL_STEAL:
wait_reserve_ticket(space_info, ticket);
*/
static inline bool can_ticket(enum btrfs_reserve_flush_enum flush)
{
+ /*
+ * Relocation never waits for space: at the fill edge the stripes it
+ * would wait for are the ones only it can free (stripe_alloc).
+ */
return (flush != BTRFS_RESERVE_NO_FLUSH &&
- flush != BTRFS_RESERVE_FLUSH_EMERGENCY);
+ flush != BTRFS_RESERVE_FLUSH_EMERGENCY &&
+ flush != BTRFS_RESERVE_FLUSH_DATA_RELOC);
}
/*
ASSERT(flush != BTRFS_RESERVE_FLUSH_EVICT);
}
- if (flush == BTRFS_RESERVE_FLUSH_DATA)
+ if (flush == BTRFS_RESERVE_FLUSH_DATA ||
+ flush == BTRFS_RESERVE_FLUSH_DATA_RELOC)
async_work = &fs_info->async_data_reclaim_work;
else
async_work = &fs_info->async_reclaim_work;
int ret;
ASSERT(flush == BTRFS_RESERVE_FLUSH_DATA ||
+ flush == BTRFS_RESERVE_FLUSH_DATA_RELOC ||
flush == BTRFS_RESERVE_FLUSH_FREE_SPACE_INODE ||
flush == BTRFS_RESERVE_NO_FLUSH);
- ASSERT(!current->journal_info || flush != BTRFS_RESERVE_FLUSH_DATA);
+ ASSERT(!current->journal_info ||
+ (flush != BTRFS_RESERVE_FLUSH_DATA &&
+ flush != BTRFS_RESERVE_FLUSH_DATA_RELOC));
ret = __reserve_bytes(fs_info, space_info, bytes, flush);
if (ret == -ENOSPC) {
* Can be interrupted by a fatal signal.
*/
BTRFS_RESERVE_FLUSH_DATA,
+
+ /*
+ * Data reservation for relocation: flushes like FLUSH_DATA but
+ * never waits on a ticket when the stripe_alloc whole-stripe gate
+ * refuses it -- relocation is what frees whole stripes, so it must
+ * not wait for them; it fails at once and is retried later.
+ */
+ BTRFS_RESERVE_FLUSH_DATA_RELOC,
BTRFS_RESERVE_FLUSH_FREE_SPACE_INODE,
BTRFS_RESERVE_FLUSH_ALL,