diff options
author | Chris Mason <chris.mason@oracle.com> | 2007-08-07 16:15:09 -0400 |
---|---|---|
committer | David Woodhouse <dwmw2@hera.kernel.org> | 2007-08-07 16:15:09 -0400 |
commit | 6702ed490ca0bb44e17131818a5a18b773957c5a (patch) | |
tree | f6bc4b77e58506a68f1ab539ca6c96854f39f92d /fs/btrfs/inode.c | |
parent | 3c69faecb8d83cb2ef085a98b196a3fecea67725 (diff) |
Btrfs: Add run time btree defrag, and an ioctl to force btree defrag
This adds two types of btree defrag, a run time form that tries to
defrag recently allocated blocks in the btree when they are still in ram,
and an ioctl that forces defrag of all btree blocks.
File data blocks are not defragged yet, but this can make a huge difference
in sequential btree reads.
Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs/inode.c')
-rw-r--r-- | fs/btrfs/inode.c | 33 |
1 files changed, 30 insertions, 3 deletions
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 3889032fc449..12aa043b9f6f 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c | |||
@@ -554,7 +554,7 @@ static int btrfs_truncate_page(struct address_space *mapping, loff_t from) | |||
554 | &alloc_hint); | 554 | &alloc_hint); |
555 | if (ret) | 555 | if (ret) |
556 | goto out; | 556 | goto out; |
557 | ret = btrfs_alloc_extent(trans, root, inode->i_ino, 1, | 557 | ret = btrfs_alloc_extent(trans, root, inode->i_ino, 1, 0, |
558 | alloc_hint, (u64)-1, &ins, 1); | 558 | alloc_hint, (u64)-1, &ins, 1); |
559 | if (ret) | 559 | if (ret) |
560 | goto out; | 560 | goto out; |
@@ -1360,7 +1360,7 @@ not_found: | |||
1360 | if (create & BTRFS_GET_BLOCK_CREATE) { | 1360 | if (create & BTRFS_GET_BLOCK_CREATE) { |
1361 | struct btrfs_key ins; | 1361 | struct btrfs_key ins; |
1362 | ret = btrfs_alloc_extent(trans, root, inode->i_ino, | 1362 | ret = btrfs_alloc_extent(trans, root, inode->i_ino, |
1363 | 1, alloc_hint, (u64)-1, | 1363 | 1, 0, alloc_hint, (u64)-1, |
1364 | &ins, 1); | 1364 | &ins, 1); |
1365 | if (ret) { | 1365 | if (ret) { |
1366 | err = ret; | 1366 | err = ret; |
@@ -1998,7 +1998,7 @@ static int create_subvol(struct btrfs_root *root, char *name, int namelen) | |||
1998 | trans = btrfs_start_transaction(root, 1); | 1998 | trans = btrfs_start_transaction(root, 1); |
1999 | BUG_ON(!trans); | 1999 | BUG_ON(!trans); |
2000 | 2000 | ||
2001 | subvol = btrfs_alloc_free_block(trans, root, 0); | 2001 | subvol = btrfs_alloc_free_block(trans, root, 0, 0); |
2002 | if (IS_ERR(subvol)) | 2002 | if (IS_ERR(subvol)) |
2003 | return PTR_ERR(subvol); | 2003 | return PTR_ERR(subvol); |
2004 | leaf = btrfs_buffer_leaf(subvol); | 2004 | leaf = btrfs_buffer_leaf(subvol); |
@@ -2159,7 +2159,9 @@ int btrfs_ioctl(struct inode *inode, struct file *filp, unsigned int | |||
2159 | { | 2159 | { |
2160 | struct btrfs_root *root = BTRFS_I(inode)->root; | 2160 | struct btrfs_root *root = BTRFS_I(inode)->root; |
2161 | struct btrfs_ioctl_vol_args vol_args; | 2161 | struct btrfs_ioctl_vol_args vol_args; |
2162 | struct btrfs_trans_handle *trans; | ||
2162 | int ret = 0; | 2163 | int ret = 0; |
2164 | int err; | ||
2163 | struct btrfs_dir_item *di; | 2165 | struct btrfs_dir_item *di; |
2164 | int namelen; | 2166 | int namelen; |
2165 | struct btrfs_path *path; | 2167 | struct btrfs_path *path; |
@@ -2196,6 +2198,31 @@ int btrfs_ioctl(struct inode *inode, struct file *filp, unsigned int | |||
2196 | else | 2198 | else |
2197 | ret = create_snapshot(root, vol_args.name, namelen); | 2199 | ret = create_snapshot(root, vol_args.name, namelen); |
2198 | break; | 2200 | break; |
2201 | |||
2202 | case BTRFS_IOC_DEFRAG: | ||
2203 | mutex_lock(&root->fs_info->fs_mutex); | ||
2204 | trans = btrfs_start_transaction(root, 1); | ||
2205 | memset(&root->defrag_progress, 0, | ||
2206 | sizeof(root->defrag_progress)); | ||
2207 | while (1) { | ||
2208 | root->defrag_running = 1; | ||
2209 | err = btrfs_defrag_leaves(trans, root, 0); | ||
2210 | |||
2211 | btrfs_end_transaction(trans, root); | ||
2212 | mutex_unlock(&root->fs_info->fs_mutex); | ||
2213 | |||
2214 | btrfs_btree_balance_dirty(root); | ||
2215 | |||
2216 | mutex_lock(&root->fs_info->fs_mutex); | ||
2217 | trans = btrfs_start_transaction(root, 1); | ||
2218 | if (err != -EAGAIN) | ||
2219 | break; | ||
2220 | } | ||
2221 | root->defrag_running = 0; | ||
2222 | btrfs_end_transaction(trans, root); | ||
2223 | mutex_unlock(&root->fs_info->fs_mutex); | ||
2224 | ret = 0; | ||
2225 | break; | ||
2199 | default: | 2226 | default: |
2200 | return -ENOTTY; | 2227 | return -ENOTTY; |
2201 | } | 2228 | } |