diff options
Diffstat (limited to 'fs/btrfs/extent-tree.c')
-rw-r--r-- | fs/btrfs/extent-tree.c | 25 |
1 files changed, 25 insertions, 0 deletions
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index 4ec8305fe078..e14f8bd4b310 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c | |||
@@ -4297,6 +4297,31 @@ static void block_rsv_add_bytes(struct btrfs_block_rsv *block_rsv, | |||
4297 | spin_unlock(&block_rsv->lock); | 4297 | spin_unlock(&block_rsv->lock); |
4298 | } | 4298 | } |
4299 | 4299 | ||
4300 | int btrfs_cond_migrate_bytes(struct btrfs_fs_info *fs_info, | ||
4301 | struct btrfs_block_rsv *dest, u64 num_bytes, | ||
4302 | int min_factor) | ||
4303 | { | ||
4304 | struct btrfs_block_rsv *global_rsv = &fs_info->global_block_rsv; | ||
4305 | u64 min_bytes; | ||
4306 | |||
4307 | if (global_rsv->space_info != dest->space_info) | ||
4308 | return -ENOSPC; | ||
4309 | |||
4310 | spin_lock(&global_rsv->lock); | ||
4311 | min_bytes = div_factor(global_rsv->size, min_factor); | ||
4312 | if (global_rsv->reserved < min_bytes + num_bytes) { | ||
4313 | spin_unlock(&global_rsv->lock); | ||
4314 | return -ENOSPC; | ||
4315 | } | ||
4316 | global_rsv->reserved -= num_bytes; | ||
4317 | if (global_rsv->reserved < global_rsv->size) | ||
4318 | global_rsv->full = 0; | ||
4319 | spin_unlock(&global_rsv->lock); | ||
4320 | |||
4321 | block_rsv_add_bytes(dest, num_bytes, 1); | ||
4322 | return 0; | ||
4323 | } | ||
4324 | |||
4300 | static void block_rsv_release_bytes(struct btrfs_fs_info *fs_info, | 4325 | static void block_rsv_release_bytes(struct btrfs_fs_info *fs_info, |
4301 | struct btrfs_block_rsv *block_rsv, | 4326 | struct btrfs_block_rsv *block_rsv, |
4302 | struct btrfs_block_rsv *dest, u64 num_bytes) | 4327 | struct btrfs_block_rsv *dest, u64 num_bytes) |