[PATCH 14/20] Btrfs: introduce option to rebalance only metadata
Experimental patch to be able to compact only the metadata after excessive block groups are created. I guess it should be implemented as a balance option rather than a separate ioctl, but this was good enough for me to try it. Signed-off-by: Alexandre Oliva ol...@lsd.ic.unicamp.br --- fs/btrfs/ioctl.c |2 ++ fs/btrfs/ioctl.h |3 +++ fs/btrfs/volumes.c | 33 - fs/btrfs/volumes.h |1 + 4 files changed, 34 insertions(+), 5 deletions(-) diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index a90e749..6f53983 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c @@ -3077,6 +3077,8 @@ long btrfs_ioctl(struct file *file, unsigned int return btrfs_ioctl_dev_info(root, argp); case BTRFS_IOC_BALANCE: return btrfs_balance(root-fs_info-dev_root); + case BTRFS_IOC_BALANCE_METADATA: + return btrfs_balance_metadata(root-fs_info-dev_root); case BTRFS_IOC_CLONE: return btrfs_ioctl_clone(file, arg, 0, 0, 0); case BTRFS_IOC_CLONE_RANGE: diff --git a/fs/btrfs/ioctl.h b/fs/btrfs/ioctl.h index 252ae99..46bc428 100644 --- a/fs/btrfs/ioctl.h +++ b/fs/btrfs/ioctl.h @@ -277,4 +277,7 @@ struct btrfs_ioctl_logical_ino_args { #define BTRFS_IOC_LOGICAL_INO _IOWR(BTRFS_IOCTL_MAGIC, 36, \ struct btrfs_ioctl_ino_path_args) +#define BTRFS_IOC_BALANCE_METADATA _IOW(BTRFS_IOCTL_MAGIC, 37, \ + struct btrfs_ioctl_vol_args) + #endif diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c index 7b348c2..db4397d 100644 --- a/fs/btrfs/volumes.c +++ b/fs/btrfs/volumes.c @@ -2084,7 +2084,7 @@ static u64 div_factor(u64 num, int factor) return num; } -int btrfs_balance(struct btrfs_root *dev_root) +static int btrfs_balance_skip(struct btrfs_root *dev_root, u64 skip_type) { int ret; struct list_head *devices = dev_root-fs_info-fs_devices-devices; @@ -2096,6 +2096,9 @@ int btrfs_balance(struct btrfs_root *dev_root) struct btrfs_root *chunk_root = dev_root-fs_info-chunk_root; struct btrfs_trans_handle *trans; struct btrfs_key found_key; + struct btrfs_chunk *chunk; + u64 chunk_type; + bool skip; if (dev_root-fs_info-sb-s_flags MS_RDONLY) return -EROFS; @@ -2165,11 +2168,21 @@ int btrfs_balance(struct btrfs_root *dev_root) if (found_key.offset == 0) break; + if (skip_type) { + chunk = btrfs_item_ptr(path-nodes[0], path-slots[0], + struct btrfs_chunk); + chunk_type = btrfs_chunk_type(path-nodes[0], chunk); + skip = (chunk_type skip_type); + } else + skip = false; + btrfs_release_path(path); - ret = btrfs_relocate_chunk(chunk_root, - chunk_root-root_key.objectid, - found_key.objectid, - found_key.offset); + + ret = (skip ? 0 : + btrfs_relocate_chunk(chunk_root, + chunk_root-root_key.objectid, + found_key.objectid, + found_key.offset)); if (ret ret != -ENOSPC) goto error; key.offset = found_key.offset - 1; @@ -2181,6 +2194,16 @@ error: return ret; } +int btrfs_balance(struct btrfs_root *dev_root) +{ + return btrfs_balance_skip(dev_root, 0); +} + +int btrfs_balance_metadata(struct btrfs_root *dev_root) +{ + return btrfs_balance_skip(dev_root, BTRFS_BLOCK_GROUP_DATA); +} + /* * shrinking a device means finding all of the device extents past * the new size, and then following the back refs to the chunks. diff --git a/fs/btrfs/volumes.h b/fs/btrfs/volumes.h index 78f2d4d..6844010 100644 --- a/fs/btrfs/volumes.h +++ b/fs/btrfs/volumes.h @@ -229,6 +229,7 @@ struct btrfs_device *btrfs_find_device(struct btrfs_root *root, u64 devid, int btrfs_shrink_device(struct btrfs_device *device, u64 new_size); int btrfs_init_new_device(struct btrfs_root *root, char *path); int btrfs_balance(struct btrfs_root *dev_root); +int btrfs_balance_metadata(struct btrfs_root *dev_root); int btrfs_chunk_readonly(struct btrfs_root *root, u64 chunk_offset); int find_free_dev_extent(struct btrfs_trans_handle *trans, struct btrfs_device *device, u64 num_bytes, -- 1.7.4.4 -- To unsubscribe from this list: send the line unsubscribe linux-btrfs in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: Introduce option to rebalance only metadata
On Thu, Nov 10, 2011 at 07:43:07PM +, Hugo Mills wrote: On Thu, Nov 10, 2011 at 05:40:56PM -0200, Alexandre Oliva wrote: Experimental patch to be able to compact only the metadata after clustered allocation allocated lots of unnecessary metadata block groups. It's also useful to measure performance differences between -o cluster and -o nocluster. I guess it should be implemented as a balance option rather than a separate ioctl, but this was good enough for me to try it. This should be covered by the restriper work. (And was also covered by my balance-management patches, which were superseded by restriper). Hugo is right, this is covered by restriper (both kernel and userspace sides). The exact command would be btrfs fi restripe start -mconvert=PROFILE mount point Thanks, Ilya -- To unsubscribe from this list: send the line unsubscribe linux-btrfs in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: Introduce option to rebalance only metadata
On Tue, Nov 15, 2011 at 11:40:04AM +0200, Ilya Dryomov wrote: On Thu, Nov 10, 2011 at 07:43:07PM +, Hugo Mills wrote: On Thu, Nov 10, 2011 at 05:40:56PM -0200, Alexandre Oliva wrote: Experimental patch to be able to compact only the metadata after clustered allocation allocated lots of unnecessary metadata block groups. It's also useful to measure performance differences between -o cluster and -o nocluster. I guess it should be implemented as a balance option rather than a separate ioctl, but this was good enough for me to try it. This should be covered by the restriper work. (And was also covered by my balance-management patches, which were superseded by restriper). Hugo is right, this is covered by restriper (both kernel and userspace sides). The exact command would be btrfs fi restripe start -mconvert=PROFILE mount point And the exact command to mimic your patch is btrfs fi restripe start -m mount point It simply balances metadata, whereas the one in the previous mail would convert it to a specified profile. Thanks, Ilya -- To unsubscribe from this list: send the line unsubscribe linux-btrfs in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: Introduce option to rebalance only metadata
On Nov 15, 2011, Ilya Dryomov idryo...@gmail.com wrote: And the exact command to mimic your patch is btrfs fi restripe start -m mount point Thanks. I wasn't aware of the restripe patch when I wrote this Quick Hack (TM). -- Alexandre Oliva, freedom fighterhttp://FSFLA.org/~lxoliva/ You must be the change you wish to see in the world. -- Gandhi Be Free! -- http://FSFLA.org/ FSF Latin America board member Free Software Evangelist Red Hat Brazil Compiler Engineer -- To unsubscribe from this list: send the line unsubscribe linux-btrfs in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Introduce option to rebalance only metadata
Experimental patch to be able to compact only the metadata after clustered allocation allocated lots of unnecessary metadata block groups. It's also useful to measure performance differences between -o cluster and -o nocluster. I guess it should be implemented as a balance option rather than a separate ioctl, but this was good enough for me to try it. Signed-off-by: Alexandre Oliva ol...@lsd.ic.unicamp.br --- fs/btrfs/ioctl.c |2 ++ fs/btrfs/ioctl.h |3 +++ fs/btrfs/volumes.c | 33 - fs/btrfs/volumes.h |1 + 4 files changed, 34 insertions(+), 5 deletions(-) diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index 4a34c47..69bf6f2 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c @@ -3074,6 +3074,8 @@ long btrfs_ioctl(struct file *file, unsigned int return btrfs_ioctl_dev_info(root, argp); case BTRFS_IOC_BALANCE: return btrfs_balance(root-fs_info-dev_root); + case BTRFS_IOC_BALANCE_METADATA: + return btrfs_balance_metadata(root-fs_info-dev_root); case BTRFS_IOC_CLONE: return btrfs_ioctl_clone(file, arg, 0, 0, 0); case BTRFS_IOC_CLONE_RANGE: diff --git a/fs/btrfs/ioctl.h b/fs/btrfs/ioctl.h index 252ae99..46bc428 100644 --- a/fs/btrfs/ioctl.h +++ b/fs/btrfs/ioctl.h @@ -277,4 +277,7 @@ struct btrfs_ioctl_logical_ino_args { #define BTRFS_IOC_LOGICAL_INO _IOWR(BTRFS_IOCTL_MAGIC, 36, \ struct btrfs_ioctl_ino_path_args) +#define BTRFS_IOC_BALANCE_METADATA _IOW(BTRFS_IOCTL_MAGIC, 37, \ + struct btrfs_ioctl_vol_args) + #endif diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c index f8e29431..4d5b29f 100644 --- a/fs/btrfs/volumes.c +++ b/fs/btrfs/volumes.c @@ -2077,7 +2077,7 @@ static u64 div_factor(u64 num, int factor) return num; } -int btrfs_balance(struct btrfs_root *dev_root) +static int btrfs_balance_skip(struct btrfs_root *dev_root, u64 skip_type) { int ret; struct list_head *devices = dev_root-fs_info-fs_devices-devices; @@ -2089,6 +2089,9 @@ int btrfs_balance(struct btrfs_root *dev_root) struct btrfs_root *chunk_root = dev_root-fs_info-chunk_root; struct btrfs_trans_handle *trans; struct btrfs_key found_key; + struct btrfs_chunk *chunk; + u64 chunk_type; + bool skip; if (dev_root-fs_info-sb-s_flags MS_RDONLY) return -EROFS; @@ -2158,11 +2161,21 @@ int btrfs_balance(struct btrfs_root *dev_root) if (found_key.offset == 0) break; + if (skip_type) { + chunk = btrfs_item_ptr(path-nodes[0], path-slots[0], + struct btrfs_chunk); + chunk_type = btrfs_chunk_type(path-nodes[0], chunk); + skip = (chunk_type skip_type); + } else + skip = false; + btrfs_release_path(path); - ret = btrfs_relocate_chunk(chunk_root, - chunk_root-root_key.objectid, - found_key.objectid, - found_key.offset); + + ret = (skip ? 0 : + btrfs_relocate_chunk(chunk_root, + chunk_root-root_key.objectid, + found_key.objectid, + found_key.offset)); if (ret ret != -ENOSPC) goto error; key.offset = found_key.offset - 1; @@ -2174,6 +2187,16 @@ error: return ret; } +int btrfs_balance(struct btrfs_root *dev_root) +{ + return btrfs_balance_skip(dev_root, 0); +} + +int btrfs_balance_metadata(struct btrfs_root *dev_root) +{ + return btrfs_balance_skip(dev_root, BTRFS_BLOCK_GROUP_DATA); +} + /* * shrinking a device means finding all of the device extents past * the new size, and then following the back refs to the chunks. diff --git a/fs/btrfs/volumes.h b/fs/btrfs/volumes.h index ab5b1c4..c467499 100644 --- a/fs/btrfs/volumes.h +++ b/fs/btrfs/volumes.h @@ -223,6 +223,7 @@ struct btrfs_device *btrfs_find_device(struct btrfs_root *root, u64 devid, int btrfs_shrink_device(struct btrfs_device *device, u64 new_size); int btrfs_init_new_device(struct btrfs_root *root, char *path); int btrfs_balance(struct btrfs_root *dev_root); +int btrfs_balance_metadata(struct btrfs_root *dev_root); int btrfs_chunk_readonly(struct btrfs_root *root, u64 chunk_offset); int find_free_dev_extent(struct btrfs_trans_handle *trans, struct btrfs_device *device, u64 num_bytes, -- 1.7.4.4 -- Alexandre Oliva, freedom fighterhttp://FSFLA.org/~lxoliva/ You must be the change you wish to see in the world. -- Gandhi Be Free! --
Re: Introduce option to rebalance only metadata
On Thu, Nov 10, 2011 at 05:40:56PM -0200, Alexandre Oliva wrote: Experimental patch to be able to compact only the metadata after clustered allocation allocated lots of unnecessary metadata block groups. It's also useful to measure performance differences between -o cluster and -o nocluster. I guess it should be implemented as a balance option rather than a separate ioctl, but this was good enough for me to try it. This should be covered by the restriper work. (And was also covered by my balance-management patches, which were superseded by restriper). Hugo. Signed-off-by: Alexandre Oliva ol...@lsd.ic.unicamp.br --- fs/btrfs/ioctl.c |2 ++ fs/btrfs/ioctl.h |3 +++ fs/btrfs/volumes.c | 33 - fs/btrfs/volumes.h |1 + 4 files changed, 34 insertions(+), 5 deletions(-) diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index 4a34c47..69bf6f2 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c @@ -3074,6 +3074,8 @@ long btrfs_ioctl(struct file *file, unsigned int return btrfs_ioctl_dev_info(root, argp); case BTRFS_IOC_BALANCE: return btrfs_balance(root-fs_info-dev_root); + case BTRFS_IOC_BALANCE_METADATA: + return btrfs_balance_metadata(root-fs_info-dev_root); case BTRFS_IOC_CLONE: return btrfs_ioctl_clone(file, arg, 0, 0, 0); case BTRFS_IOC_CLONE_RANGE: diff --git a/fs/btrfs/ioctl.h b/fs/btrfs/ioctl.h index 252ae99..46bc428 100644 --- a/fs/btrfs/ioctl.h +++ b/fs/btrfs/ioctl.h @@ -277,4 +277,7 @@ struct btrfs_ioctl_logical_ino_args { #define BTRFS_IOC_LOGICAL_INO _IOWR(BTRFS_IOCTL_MAGIC, 36, \ struct btrfs_ioctl_ino_path_args) +#define BTRFS_IOC_BALANCE_METADATA _IOW(BTRFS_IOCTL_MAGIC, 37, \ + struct btrfs_ioctl_vol_args) + #endif diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c index f8e29431..4d5b29f 100644 --- a/fs/btrfs/volumes.c +++ b/fs/btrfs/volumes.c @@ -2077,7 +2077,7 @@ static u64 div_factor(u64 num, int factor) return num; } -int btrfs_balance(struct btrfs_root *dev_root) +static int btrfs_balance_skip(struct btrfs_root *dev_root, u64 skip_type) { int ret; struct list_head *devices = dev_root-fs_info-fs_devices-devices; @@ -2089,6 +2089,9 @@ int btrfs_balance(struct btrfs_root *dev_root) struct btrfs_root *chunk_root = dev_root-fs_info-chunk_root; struct btrfs_trans_handle *trans; struct btrfs_key found_key; + struct btrfs_chunk *chunk; + u64 chunk_type; + bool skip; if (dev_root-fs_info-sb-s_flags MS_RDONLY) return -EROFS; @@ -2158,11 +2161,21 @@ int btrfs_balance(struct btrfs_root *dev_root) if (found_key.offset == 0) break; + if (skip_type) { + chunk = btrfs_item_ptr(path-nodes[0], path-slots[0], +struct btrfs_chunk); + chunk_type = btrfs_chunk_type(path-nodes[0], chunk); + skip = (chunk_type skip_type); + } else + skip = false; + btrfs_release_path(path); - ret = btrfs_relocate_chunk(chunk_root, -chunk_root-root_key.objectid, -found_key.objectid, -found_key.offset); + + ret = (skip ? 0 : +btrfs_relocate_chunk(chunk_root, + chunk_root-root_key.objectid, + found_key.objectid, + found_key.offset)); if (ret ret != -ENOSPC) goto error; key.offset = found_key.offset - 1; @@ -2174,6 +2187,16 @@ error: return ret; } +int btrfs_balance(struct btrfs_root *dev_root) +{ + return btrfs_balance_skip(dev_root, 0); +} + +int btrfs_balance_metadata(struct btrfs_root *dev_root) +{ + return btrfs_balance_skip(dev_root, BTRFS_BLOCK_GROUP_DATA); +} + /* * shrinking a device means finding all of the device extents past * the new size, and then following the back refs to the chunks. diff --git a/fs/btrfs/volumes.h b/fs/btrfs/volumes.h index ab5b1c4..c467499 100644 --- a/fs/btrfs/volumes.h +++ b/fs/btrfs/volumes.h @@ -223,6 +223,7 @@ struct btrfs_device *btrfs_find_device(struct btrfs_root *root, u64 devid, int btrfs_shrink_device(struct btrfs_device *device, u64 new_size); int btrfs_init_new_device(struct btrfs_root *root, char *path); int btrfs_balance(struct btrfs_root *dev_root); +int btrfs_balance_metadata(struct btrfs_root *dev_root); int btrfs_chunk_readonly(struct btrfs_root *root, u64 chunk_offset); int find_free_dev_extent(struct btrfs_trans_handle
Re: Introduce option to rebalance only metadata
On Nov 10, 2011, Alexandre Oliva ol...@lsd.ic.unicamp.br wrote: Experimental patch to be able to compact only the metadata after clustered allocation allocated lots of unnecessary metadata block groups. It's also useful to measure performance differences between -o cluster and -o nocluster. I guess it should be implemented as a balance option rather than a separate ioctl, but this was good enough for me to try it. And here's a corresponding patch for the btrfs program, on a (probably very old) btrfs-progs tree. From 8765d64f95966eec28cad83bd870fc2270afaebd Mon Sep 17 00:00:00 2001 From: Alexandre Oliva lxol...@fsfla.org Date: Thu, 10 Nov 2011 17:35:29 -0200 Subject: [PATCH] Introduce balance-md to balance metadata only. Patch for btrfs to use a separate experimental IOCTL to rebalance only metadata block groups. Signed-off-by: Alexandre Oliva ol...@lsd.ic.unicamp.br --- btrfs.c |4 btrfs_cmds.c | 25 + btrfs_cmds.h |1 + ioctl.h |3 +++ 4 files changed, 33 insertions(+), 0 deletions(-) diff --git a/btrfs.c b/btrfs.c index 46314cf..9edaebe 100644 --- a/btrfs.c +++ b/btrfs.c @@ -95,6 +95,10 @@ static struct Command commands[] = { filesystem balance, path\n Balance the chunks across the device. }, + { do_balance_md, 1, + filesystem balance-md, path\n + Balance the chunks across the device. + }, { do_scan, 999, device scan, [device [device..]\n Scan all device for or the passed device for a btrfs\n diff --git a/btrfs_cmds.c b/btrfs_cmds.c index 8031c58..b8f4c05 100644 --- a/btrfs_cmds.c +++ b/btrfs_cmds.c @@ -776,6 +776,31 @@ int do_balance(int argc, char **argv) } return 0; } + +int do_balance_md(int argc, char **argv) +{ + + int fdmnt, ret=0; + struct btrfs_ioctl_vol_args args; + char *path = argv[1]; + + fdmnt = open_file_or_dir(path); + if (fdmnt 0) { + fprintf(stderr, ERROR: can't access to '%s'\n, path); + return 12; + } + + memset(args, 0, sizeof(args)); + ret = ioctl(fdmnt, BTRFS_IOC_BALANCE_METADATA, args); + close(fdmnt); + if(ret0){ + fprintf(stderr, ERROR: balancing '%s'\n, path); + + return 19; + } + return 0; +} + int do_remove_volume(int nargs, char **args) { diff --git a/btrfs_cmds.h b/btrfs_cmds.h index 7bde191..96cab6d 100644 --- a/btrfs_cmds.h +++ b/btrfs_cmds.h @@ -23,6 +23,7 @@ int do_defrag(int argc, char **argv); int do_show_filesystem(int nargs, char **argv); int do_add_volume(int nargs, char **args); int do_balance(int nargs, char **argv); +int do_balance_md(int nargs, char **argv); int do_remove_volume(int nargs, char **args); int do_scan(int nargs, char **argv); int do_resize(int nargs, char **argv); diff --git a/ioctl.h b/ioctl.h index 776d7a9..5210c0b 100644 --- a/ioctl.h +++ b/ioctl.h @@ -169,4 +169,7 @@ struct btrfs_ioctl_space_args { #define BTRFS_IOC_DEFAULT_SUBVOL _IOW(BTRFS_IOCTL_MAGIC, 19, u64) #define BTRFS_IOC_SPACE_INFO _IOWR(BTRFS_IOCTL_MAGIC, 20, \ struct btrfs_ioctl_space_args) + +#define BTRFS_IOC_BALANCE_METADATA _IOW(BTRFS_IOCTL_MAGIC, 37, \ + struct btrfs_ioctl_vol_args) #endif -- 1.7.4.4 -- Alexandre Oliva, freedom fighterhttp://FSFLA.org/~lxoliva/ You must be the change you wish to see in the world. -- Gandhi Be Free! -- http://FSFLA.org/ FSF Latin America board member Free Software Evangelist Red Hat Brazil Compiler Engineer