diff options
author | Miao Xie <miaox@cn.fujitsu.com> | 2013-02-28 05:04:33 -0500 |
---|---|---|
committer | Josef Bacik <jbacik@fusionio.com> | 2013-02-28 13:33:54 -0500 |
commit | d5c1207017cd8387b4d3224dd7ab6cf5cd7f1c9a (patch) | |
tree | 7208d1c89aa625fa6eb349fdafa2e49a00bbe078 /fs/btrfs/extent-tree.c | |
parent | e9662f701c85ebc99f532bf8bb53208c0648846a (diff) |
Btrfs: fix wrong reserved space in qgroup during snap/subv creation
There are two problems in the space reservation of the snapshot/
subvolume creation.
- don't reserve the space for the root item insertion
- the space which is reserved in the qgroup is different with
the free space reservation. we need reserve free space for
7 items, but in qgroup reservation, we need reserve space only
for 3 items.
So we implement new metadata reservation functions for the
snapshot/subvolume creation.
Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
Signed-off-by: Josef Bacik <jbacik@fusionio.com>
Diffstat (limited to 'fs/btrfs/extent-tree.c')
-rw-r--r-- | fs/btrfs/extent-tree.c | 65 |
1 files changed, 53 insertions, 12 deletions
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index 5681a91ed400..7cb9d734f6e5 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c | |||
@@ -4560,19 +4560,60 @@ void btrfs_orphan_release_metadata(struct inode *inode) | |||
4560 | btrfs_block_rsv_release(root, root->orphan_block_rsv, num_bytes); | 4560 | btrfs_block_rsv_release(root, root->orphan_block_rsv, num_bytes); |
4561 | } | 4561 | } |
4562 | 4562 | ||
4563 | int btrfs_snap_reserve_metadata(struct btrfs_trans_handle *trans, | 4563 | /* |
4564 | struct btrfs_pending_snapshot *pending) | 4564 | * btrfs_subvolume_reserve_metadata() - reserve space for subvolume operation |
4565 | * root: the root of the parent directory | ||
4566 | * rsv: block reservation | ||
4567 | * items: the number of items that we need do reservation | ||
4568 | * qgroup_reserved: used to return the reserved size in qgroup | ||
4569 | * | ||
4570 | * This function is used to reserve the space for snapshot/subvolume | ||
4571 | * creation and deletion. Those operations are different with the | ||
4572 | * common file/directory operations, they change two fs/file trees | ||
4573 | * and root tree, the number of items that the qgroup reserves is | ||
4574 | * different with the free space reservation. So we can not use | ||
4575 | * the space reseravtion mechanism in start_transaction(). | ||
4576 | */ | ||
4577 | int btrfs_subvolume_reserve_metadata(struct btrfs_root *root, | ||
4578 | struct btrfs_block_rsv *rsv, | ||
4579 | int items, | ||
4580 | u64 *qgroup_reserved) | ||
4565 | { | 4581 | { |
4566 | struct btrfs_root *root = pending->root; | 4582 | u64 num_bytes; |
4567 | struct btrfs_block_rsv *src_rsv = get_block_rsv(trans, root); | 4583 | int ret; |
4568 | struct btrfs_block_rsv *dst_rsv = &pending->block_rsv; | 4584 | |
4569 | /* | 4585 | if (root->fs_info->quota_enabled) { |
4570 | * two for root back/forward refs, two for directory entries, | 4586 | /* One for parent inode, two for dir entries */ |
4571 | * one for root of the snapshot and one for parent inode. | 4587 | num_bytes = 3 * root->leafsize; |
4572 | */ | 4588 | ret = btrfs_qgroup_reserve(root, num_bytes); |
4573 | u64 num_bytes = btrfs_calc_trans_metadata_size(root, 6); | 4589 | if (ret) |
4574 | dst_rsv->space_info = src_rsv->space_info; | 4590 | return ret; |
4575 | return block_rsv_migrate_bytes(src_rsv, dst_rsv, num_bytes); | 4591 | } else { |
4592 | num_bytes = 0; | ||
4593 | } | ||
4594 | |||
4595 | *qgroup_reserved = num_bytes; | ||
4596 | |||
4597 | num_bytes = btrfs_calc_trans_metadata_size(root, items); | ||
4598 | rsv->space_info = __find_space_info(root->fs_info, | ||
4599 | BTRFS_BLOCK_GROUP_METADATA); | ||
4600 | ret = btrfs_block_rsv_add(root, rsv, num_bytes, | ||
4601 | BTRFS_RESERVE_FLUSH_ALL); | ||
4602 | if (ret) { | ||
4603 | if (*qgroup_reserved) | ||
4604 | btrfs_qgroup_free(root, *qgroup_reserved); | ||
4605 | } | ||
4606 | |||
4607 | return ret; | ||
4608 | } | ||
4609 | |||
4610 | void btrfs_subvolume_release_metadata(struct btrfs_root *root, | ||
4611 | struct btrfs_block_rsv *rsv, | ||
4612 | u64 qgroup_reserved) | ||
4613 | { | ||
4614 | btrfs_block_rsv_release(root, rsv, (u64)-1); | ||
4615 | if (qgroup_reserved) | ||
4616 | btrfs_qgroup_free(root, qgroup_reserved); | ||
4576 | } | 4617 | } |
4577 | 4618 | ||
4578 | /** | 4619 | /** |