[PATCH 14/20] Btrfs: introduce option to rebalance only metadata

2011-11-28 Thread Alexandre Oliva
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

2011-11-15 Thread Ilya Dryomov
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

2011-11-15 Thread Ilya Dryomov
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

2011-11-15 Thread Alexandre Oliva
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

2011-11-10 Thread Alexandre Oliva
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

2011-11-10 Thread Hugo Mills
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

2011-11-10 Thread Alexandre Oliva
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