Re: [PATCH V3 1/2] Btrfs: cleanup duplicated division functions

2012-09-27 Thread Miao Xie
Sorry to reply late.

On Mon, 24 Sep 2012 18:47:42 +0200, David Sterba wrote:
 This is the most straightforward transformation I can think of.  It
 doesn't result in an unnecessary BUG_ON, keeps churn to a minimum and

 agree with you.

 doesn't change the style of the balance ioctl.  (If I were to check
 every filter argument that way, btrfs_balance_ioctl() would be very long
 and complicated.)

 I think the check in btrfs_balance_ioctl() is necessary, the reason is above.
 
 btrfs_balance_ioctl does not seem as the right place, it does the
 processing related to the state of balance (resume/cancel etc). Look at
 btrfs_balance() itself, it does lot more sanity checks of the parameters

I think we should not put the check in btrfs_balance(), because the arguments
are valid forever if they pass the check when they are input, if we put the
check in btrfs_balance(), the check will be done every time we resume the 
balance.
it is unnecessary.

 We can put the extra checks into helpers (and not only this
 one) if clarity and readability of the function becomes a concern.

Agree. I will put this check into a helper in the next version of this patch.
And I will make a separate patch to move the current check in btrfs_balance
from btrfs_balance to the above helper after this patch is received.

Thanks
Miao
--
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: [PATCH V3 1/2] Btrfs: cleanup duplicated division functions

2012-09-25 Thread Miao Xie
On  mon, 24 Sep 2012 21:42:42 +0300, Ilya Dryomov wrote:
 On Mon, Sep 24, 2012 at 06:47:42PM +0200, David Sterba wrote:
 On Mon, Sep 24, 2012 at 10:05:02AM +0800, Miao Xie wrote:
 Generally, we should check the value when it is input. If not, we might
 run our program with the wrong value, and it is possible to cause unknown
 problems. So I think the above chunk is necessary.

 The difference is that giving an invalid value will exit early (your
 version), while Ilya's version will clamp the 'usage' to the allowed
 range during processing. From usability POV, I'd prefer to let the
 command fail early with a verbose error eg. that the range is invalid.
 
 I think that's the job for progs, and that's where this and a few other
 checks are currently implemented.
 
 There is no possibility for unknown problems, that's exactly how it's
 been implemented before the cleanup.  The purpose of balance filters
 (and the usage filter in particular) is to lower the number of chunks we
 have to relocate.  If someone decides to use raw ioctls, and supplies us
 with the invalid value, we just cut it down to a 100 and proceed.
 usage=100 is the equivalent of not using the usage filter at all, so the
 raw ioctl user will get what he deserves.
 
 This is very similar to what we currently do with other filters.  For
 example, soft can only be used with convert, and this is checked by
 progs.  But, if somebody were to set a soft flag without setting
 convert we would simply ignore that soft.  Same goes for drange
 and devid, invalid ranges, invalid devids, etc.  Pulling all these
 checks into the kernel is questionable at best, and, if enough people
 insist on it, should be discussed separately.

I think the usage is a special case that doesn't cause critical problem and
are not used everywhere. But if there is a variant which is referenced at
several places and the kernel would crash if it is invalid, in this case,
we would add the check everywhere and make the code more complex and ugly
if we don't check it when it is passed in. Besides that if we have done
lots of work before the check, we must roll back when we find the variant
is invalid, it wastes time. So I think doing the check and returning the
error number as early as possible is a rule we should follow.

Thanks
Miao
--
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: [PATCH V3 1/2] Btrfs: cleanup duplicated division functions

2012-09-24 Thread David Sterba
On Sun, Sep 23, 2012 at 05:54:18PM +0800, Miao Xie wrote:
  @@ -2347,7 +2335,8 @@ static int chunk_usage_filter(struct btrfs_fs_info 
  *fs_info, u64 chunk_offset,
 cache = btrfs_lookup_block_group(fs_info, chunk_offset);
 chunk_used = btrfs_block_group_used(cache-item);
   
  -  user_thresh = div_factor_fine(cache-key.offset, bargs-usage);
  +  BUG_ON(bargs-usage  0 || bargs-usage  100);
  
  otherwise it reliably crashes here
 
 Sorry, I don't know why it will crash here if we input 0. I tried to input 0,
 and it worked well.

My oversight, sorry.

 I think the only case we must take into account is the users might input the 
 wrong value (100 or 0)
 on the old kernel, and it can be stored into the filesystem. If we mount this 
 filesystem
 on the new kernel, some problems may happen.

So better avoid a BUG_ON.
--
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: [PATCH V3 1/2] Btrfs: cleanup duplicated division functions

2012-09-24 Thread David Sterba
On Mon, Sep 24, 2012 at 10:05:02AM +0800, Miao Xie wrote:
 Generally, we should check the value when it is input. If not, we might
 run our program with the wrong value, and it is possible to cause unknown
 problems. So I think the above chunk is necessary.

The difference is that giving an invalid value will exit early (your
version), while Ilya's version will clamp the 'usage' to the allowed
range during processing. From usability POV, I'd prefer to let the
command fail early with a verbose error eg. that the range is invalid.

  (diff is on top of the patch in question)
  
  This is the most straightforward transformation I can think of.  It
  doesn't result in an unnecessary BUG_ON, keeps churn to a minimum and
 
 agree with you.
 
  doesn't change the style of the balance ioctl.  (If I were to check
  every filter argument that way, btrfs_balance_ioctl() would be very long
  and complicated.)
 
 I think the check in btrfs_balance_ioctl() is necessary, the reason is above.

btrfs_balance_ioctl does not seem as the right place, it does the
processing related to the state of balance (resume/cancel etc). Look at
btrfs_balance() itself, it does lot more sanity checks of the
parameters. We can put the extra checks into helpers (and not only this
one) if clarity and readability of the function becomes a concern.


david
--
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: [PATCH V3 1/2] Btrfs: cleanup duplicated division functions

2012-09-24 Thread Ilya Dryomov
On Mon, Sep 24, 2012 at 06:47:42PM +0200, David Sterba wrote:
 On Mon, Sep 24, 2012 at 10:05:02AM +0800, Miao Xie wrote:
  Generally, we should check the value when it is input. If not, we might
  run our program with the wrong value, and it is possible to cause unknown
  problems. So I think the above chunk is necessary.
 
 The difference is that giving an invalid value will exit early (your
 version), while Ilya's version will clamp the 'usage' to the allowed
 range during processing. From usability POV, I'd prefer to let the
 command fail early with a verbose error eg. that the range is invalid.

I think that's the job for progs, and that's where this and a few other
checks are currently implemented.

There is no possibility for unknown problems, that's exactly how it's
been implemented before the cleanup.  The purpose of balance filters
(and the usage filter in particular) is to lower the number of chunks we
have to relocate.  If someone decides to use raw ioctls, and supplies us
with the invalid value, we just cut it down to a 100 and proceed.
usage=100 is the equivalent of not using the usage filter at all, so the
raw ioctl user will get what he deserves.

This is very similar to what we currently do with other filters.  For
example, soft can only be used with convert, and this is checked by
progs.  But, if somebody were to set a soft flag without setting
convert we would simply ignore that soft.  Same goes for drange
and devid, invalid ranges, invalid devids, etc.  Pulling all these
checks into the kernel is questionable at best, and, if enough people
insist on it, should be discussed separately.

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: [PATCH V3 1/2] Btrfs: cleanup duplicated division functions

2012-09-23 Thread Miao Xie
On Fri, 21 Sep 2012 17:24:44 +0200, David Sterba wrote:
 On Fri, Sep 21, 2012 at 05:07:46PM +0800, Miao Xie wrote:
 --- a/fs/btrfs/ioctl.c
 +++ b/fs/btrfs/ioctl.c
 @@ -3335,6 +3335,24 @@ static long btrfs_ioctl_balance(struct file *file, 
 void __user *arg)
  
  goto do_balance;
  }
 +
 +if ((bargs-data.flags  BTRFS_BALANCE_ARGS_USAGE) 
 +(bargs-data.usage  0 || bargs-data.usage  100)) {
 
 the 0 checks belong here
 
 +ret = -EINVAL;
 +goto out_bargs;
 +}
 +
 +if ((bargs-meta.flags  BTRFS_BALANCE_ARGS_USAGE) 
 +(bargs-meta.usage  0 || bargs-meta.usage  100)) {
 +ret = -EINVAL;
 +goto out_bargs;
 +}
 +
 +if ((bargs-sys.flags  BTRFS_BALANCE_ARGS_USAGE) 
 +(bargs-sys.usage  0 || bargs-sys.usage  100)) {
 +ret = -EINVAL;
 +goto out_bargs;
 +}
  } else {
  bargs = NULL;
  }
 @@ -2347,7 +2335,8 @@ static int chunk_usage_filter(struct btrfs_fs_info 
 *fs_info, u64 chunk_offset,
  cache = btrfs_lookup_block_group(fs_info, chunk_offset);
  chunk_used = btrfs_block_group_used(cache-item);
  
 -user_thresh = div_factor_fine(cache-key.offset, bargs-usage);
 +BUG_ON(bargs-usage  0 || bargs-usage  100);
 
 otherwise it reliably crashes here

Sorry, I don't know why it will crash here if we input 0. I tried to input 0,
and it worked well.

I think the only case we must take into account is the users might input the 
wrong value (100 or 0)
on the old kernel, and it can be stored into the filesystem. If we mount this 
filesystem
on the new kernel, some problems may happen.

Thanks
Miao
--
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: [PATCH V3 1/2] Btrfs: cleanup duplicated division functions

2012-09-23 Thread Ilya Dryomov
On Fri, Sep 21, 2012 at 05:07:46PM +0800, Miao Xie wrote:
 div_factor{_fine} has been implemented for two times, and these two functions
 are very similar, so cleanup the reduplicate implement and drop the original
 div_factor(), and then rename div_factor_fine() to div_factor(). So the 
 divisor
 of the new div_factor() is 100, not 10.
 
 And I move div_factor into a independent file named math.h because it is a
 common math function, may be used by every composition of btrfs.
 
 Because these functions are mostly used on the hot path, and we are sure
 the parameters are right in the most cases, we don't add complex checks
 for the parameters. But in the other place, we must check and make sure
 the parameters are right. So besides the code cleanup, this patch also
 add a check for the usage of the space balance, it is the only place that
 we need add check to make sure the parameters of div_factor are right till 
 now.
 
 Signed-off-by: Miao Xie mi...@cn.fujitsu.com
 ---
 Changelog v2 - v3:
 - drop the original div_factor and rename div_factor_fine to div_factor
 - drop the check of the factor
 
 Changelog v1 - v2:
 - add missing check
 ---
  fs/btrfs/extent-tree.c |   29 ++---
  fs/btrfs/ioctl.c   |   18 ++
  fs/btrfs/math.h|   33 +
  fs/btrfs/relocation.c  |2 +-
  fs/btrfs/transaction.c |2 +-
  fs/btrfs/volumes.c |   30 +-
  6 files changed, 64 insertions(+), 50 deletions(-)
  create mode 100644 fs/btrfs/math.h
 
 diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
 index a010234..bcb9ced 100644
 --- a/fs/btrfs/extent-tree.c
 +++ b/fs/btrfs/extent-tree.c
 @@ -33,6 +33,7 @@
  #include volumes.h
  #include locking.h
  #include free-space-cache.h
 +#include math.h
  
  #undef SCRAMBLE_DELAYED_REFS
  
 @@ -648,24 +649,6 @@ void btrfs_clear_space_info_full(struct btrfs_fs_info 
 *info)
   rcu_read_unlock();
  }
  
 -static u64 div_factor(u64 num, int factor)
 -{
 - if (factor == 10)
 - return num;
 - num *= factor;
 - do_div(num, 10);
 - return num;
 -}
 -
 -static u64 div_factor_fine(u64 num, int factor)
 -{
 - if (factor == 100)
 - return num;
 - num *= factor;
 - do_div(num, 100);
 - return num;
 -}
 -
  u64 btrfs_find_block_group(struct btrfs_root *root,
  u64 search_start, u64 search_hint, int owner)
  {
 @@ -674,7 +657,7 @@ u64 btrfs_find_block_group(struct btrfs_root *root,
   u64 last = max(search_hint, search_start);
   u64 group_start = 0;
   int full_search = 0;
 - int factor = 9;
 + int factor = 90;
   int wrapped = 0;
  again:
   while (1) {
 @@ -708,7 +691,7 @@ again:
   if (!full_search  factor  10) {
   last = search_start;
   full_search = 1;
 - factor = 10;
 + factor = 100;
   goto again;
   }
  found:
 @@ -3513,7 +3496,7 @@ static int should_alloc_chunk(struct btrfs_root *root,
   if (force == CHUNK_ALLOC_LIMITED) {
   thresh = btrfs_super_total_bytes(root-fs_info-super_copy);
   thresh = max_t(u64, 64 * 1024 * 1024,
 -div_factor_fine(thresh, 1));
 +div_factor(thresh, 1));
  
   if (num_bytes - num_allocated  thresh)
   return 1;
 @@ -3521,12 +3504,12 @@ static int should_alloc_chunk(struct btrfs_root *root,
   thresh = btrfs_super_total_bytes(root-fs_info-super_copy);
  
   /* 256MB or 2% of the FS */
 - thresh = max_t(u64, 256 * 1024 * 1024, div_factor_fine(thresh, 2));
 + thresh = max_t(u64, 256 * 1024 * 1024, div_factor(thresh, 2));
   /* system chunks need a much small threshold */
   if (sinfo-flags  BTRFS_BLOCK_GROUP_SYSTEM)
   thresh = 32 * 1024 * 1024;
  
 - if (num_bytes  thresh  sinfo-bytes_used  div_factor(num_bytes, 8))
 + if (num_bytes  thresh  sinfo-bytes_used  div_factor(num_bytes, 80))
   return 0;
   return 1;
  }
 diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
 index 9384a2a..d8d53f7 100644
 --- a/fs/btrfs/ioctl.c
 +++ b/fs/btrfs/ioctl.c
 @@ -3335,6 +3335,24 @@ static long btrfs_ioctl_balance(struct file *file, 
 void __user *arg)
  
   goto do_balance;
   }
 +
 + if ((bargs-data.flags  BTRFS_BALANCE_ARGS_USAGE) 
 + (bargs-data.usage  0 || bargs-data.usage  100)) {
 + ret = -EINVAL;
 + goto out_bargs;
 + }
 +
 + if ((bargs-meta.flags  BTRFS_BALANCE_ARGS_USAGE) 
 + (bargs-meta.usage  0 || bargs-meta.usage  100)) {
 + ret = -EINVAL;
 + goto out_bargs;
 + }
 +
 + if ((bargs-sys.flags  BTRFS_BALANCE_ARGS_USAGE) 
 + (bargs-sys.usage  0 || bargs-sys.usage  100)) {
 +

Re: [PATCH V3 1/2] Btrfs: cleanup duplicated division functions

2012-09-23 Thread Miao Xie
On Sun, 23 Sep 2012 14:49:24 +0300, Ilya Dryomov wrote:
 diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
 index 9384a2a..d8d53f7 100644
 --- a/fs/btrfs/ioctl.c
 +++ b/fs/btrfs/ioctl.c
 @@ -3335,6 +3335,24 @@ static long btrfs_ioctl_balance(struct file *file, 
 void __user *arg)
  
  goto do_balance;
  }
 +
 +if ((bargs-data.flags  BTRFS_BALANCE_ARGS_USAGE) 
 +(bargs-data.usage  0 || bargs-data.usage  100)) {
 +ret = -EINVAL;
 +goto out_bargs;
 +}
 +
 +if ((bargs-meta.flags  BTRFS_BALANCE_ARGS_USAGE) 
 +(bargs-meta.usage  0 || bargs-meta.usage  100)) {
 +ret = -EINVAL;
 +goto out_bargs;
 +}
 +
 +if ((bargs-sys.flags  BTRFS_BALANCE_ARGS_USAGE) 
 +(bargs-sys.usage  0 || bargs-sys.usage  100)) {
 +ret = -EINVAL;
 +goto out_bargs;
 +}
  } else {
  bargs = NULL;
  }
 
 Why not drop this hunk ...

Generally, we should check the value when it is input. If not, we might
run our program with the wrong value, and it is possible to cause unknown
problems. So I think the above chunk is necessary.

 diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
 index 6019fb2..ff86f91 100644
 --- a/fs/btrfs/volumes.c
 +++ b/fs/btrfs/volumes.c
 @@ -2334,8 +2334,13 @@ static int chunk_usage_filter(struct btrfs_fs_info 
 *fs_info, u64 chunk_offset,
   cache = btrfs_lookup_block_group(fs_info, chunk_offset);
   chunk_used = btrfs_block_group_used(cache-item);
  
 - BUG_ON(bargs-usage  0 || bargs-usage  100);
 - user_thresh = div_factor(cache-key.offset, bargs-usage);
 + if (bargs-usage == 0)
 + user_thresh = 0;
 + else if (bargs-usage = 100)
 + user_thresh = cache-key.offset;
 + else
 + user_thresh = div_factor(cache-key.offset, bargs-usage);
 +
   if (chunk_used  user_thresh)
   ret = 0;
 
 (diff is on top of the patch in question)
 
 This is the most straightforward transformation I can think of.  It
 doesn't result in an unnecessary BUG_ON, keeps churn to a minimum and

agree with you.

 doesn't change the style of the balance ioctl.  (If I were to check
 every filter argument that way, btrfs_balance_ioctl() would be very long
 and complicated.)


I think the check in btrfs_balance_ioctl() is necessary, the reason is above.

Thanks
Miao
--
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: [PATCH V3 1/2] Btrfs: cleanup duplicated division functions

2012-09-21 Thread David Sterba
On Fri, Sep 21, 2012 at 05:07:46PM +0800, Miao Xie wrote:
 --- a/fs/btrfs/ioctl.c
 +++ b/fs/btrfs/ioctl.c
 @@ -3335,6 +3335,24 @@ static long btrfs_ioctl_balance(struct file *file, 
 void __user *arg)
  
   goto do_balance;
   }
 +
 + if ((bargs-data.flags  BTRFS_BALANCE_ARGS_USAGE) 
 + (bargs-data.usage  0 || bargs-data.usage  100)) {

the 0 checks belong here

 + ret = -EINVAL;
 + goto out_bargs;
 + }
 +
 + if ((bargs-meta.flags  BTRFS_BALANCE_ARGS_USAGE) 
 + (bargs-meta.usage  0 || bargs-meta.usage  100)) {
 + ret = -EINVAL;
 + goto out_bargs;
 + }
 +
 + if ((bargs-sys.flags  BTRFS_BALANCE_ARGS_USAGE) 
 + (bargs-sys.usage  0 || bargs-sys.usage  100)) {
 + ret = -EINVAL;
 + goto out_bargs;
 + }
   } else {
   bargs = NULL;
   }
 @@ -2347,7 +2335,8 @@ static int chunk_usage_filter(struct btrfs_fs_info 
 *fs_info, u64 chunk_offset,
   cache = btrfs_lookup_block_group(fs_info, chunk_offset);
   chunk_used = btrfs_block_group_used(cache-item);
  
 - user_thresh = div_factor_fine(cache-key.offset, bargs-usage);
 + BUG_ON(bargs-usage  0 || bargs-usage  100);

otherwise it reliably crashes here

 + user_thresh = div_factor(cache-key.offset, bargs-usage);
   if (chunk_used  user_thresh)
   ret = 0;
  

other than that, patch looks good tome,

thanks,
david
--
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