[PATCH 2/2] btrfs-progs: qgroup limit: add a check for invalid input of 'T/G/M/K'

2015-06-03 Thread Dongsheng Yang
Add a check to error out in the following case:

 # ./btrfs qgroup limit  T /mnt/
Invalid size argument given

Without this patch, btrfs-progs would parse the input as 0
and continue.

Signed-off-by: Dongsheng Yang yangds.f...@cn.fujitsu.com
---
 cmds-qgroup.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/cmds-qgroup.c b/cmds-qgroup.c
index 5ea4021..9545a20 100644
--- a/cmds-qgroup.c
+++ b/cmds-qgroup.c
@@ -121,6 +121,9 @@ static int parse_limit(const char *p, unsigned long long *s)
return 0;
 
size = strtoull(p, endptr, 10);
+   if (p == endptr)
+   return 0;
+
switch (*endptr) {
case 'T':
case 't':
-- 
1.8.4.2

--
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


[PATCH 1/2] btrfs-progs: qgroup: show 'none' when we did not limit it on this qgroup

2015-06-03 Thread Dongsheng Yang
There are two understanding of the '0' value in btrfs qgroup show.
(1) is no-limitation on this qgroup. (2) is the max-limitation is 0.

This patch make it showing in different way.

(1). max-limitation for 0 is still showing '0'.
(2). no-limitation will show 'none'.

qgroupid rfer excl max_rfer max_excl parent
     --
0/5   2.19GiB  2.19GiB none none ---
0/257   100.02MiB100.02MiB none none ---

Signed-off-by: Dongsheng Yang yangds.f...@cn.fujitsu.com
---
 qgroup.c | 10 --
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/qgroup.c b/qgroup.c
index 53815b5..dc04b03 100644
--- a/qgroup.c
+++ b/qgroup.c
@@ -237,10 +237,16 @@ static void print_qgroup_column(struct btrfs_qgroup 
*qgroup,
print_qgroup_column_add_blank(BTRFS_QGROUP_PARENT, len);
break;
case BTRFS_QGROUP_MAX_RFER:
-   len = printf(%*s, max_len, pretty_size_mode(qgroup-max_rfer, 
unit_mode));
+   if (qgroup-flags  BTRFS_QGROUP_LIMIT_MAX_RFER)
+   len = printf(%*s, max_len, 
pretty_size_mode(qgroup-max_rfer, unit_mode));
+   else
+   len = printf(%*s, max_len, none);
break;
case BTRFS_QGROUP_MAX_EXCL:
-   len = printf(%*s, max_len, pretty_size_mode(qgroup-max_excl, 
unit_mode));
+   if (qgroup-flags  BTRFS_QGROUP_LIMIT_MAX_EXCL)
+   len = printf(%*s, max_len, 
pretty_size_mode(qgroup-max_excl, unit_mode));
+   else
+   len = printf(%*s, max_len, none);
break;
case BTRFS_QGROUP_CHILD:
len = print_child_column(qgroup);
-- 
1.8.4.2

--
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


[PATCH 2/2] btrfs-progs: qgroup: allow user to clear some limitation on qgroup.

2015-06-03 Thread Dongsheng Yang
Currently, we can not clear a limitation on a qgroup. Although
there is a 'none' choice provided to user to do it, it does not
work well.

It does not set the flag which user want to clear, then kernel
will never know what the user want to do at all.

*Without this commit*
 # ./btrfs qgroup show -re /mnt
qgroupid rfer excl max_rfer max_excl
    
0/5   2.19GiB  2.19GiB  5.00GiB none
0/257   100.02MiB100.02MiB none none
 # ./btrfs qgroup limit none /mnt
 # ./btrfs qgroup show -re /mnt
qgroupid rfer excl max_rfer max_excl
    
0/5   2.19GiB  2.19GiB  5.00GiB none
0/257   100.02MiB100.02MiB none none

This patch will set the flag user want to clear and pass a
size=-1 to kernel. Then kernel will clear it correctly.

*With this commit*
 # ./btrfs qgroup show -re /mnt
qgroupid rfer excl max_rfer max_excl
    
0/5   2.19GiB  2.19GiB  5.00GiB none
0/257   100.02MiB100.02MiB none none
 # ./btrfs qgroup limit none /mnt
 # ./btrfs qgroup show -re /mnt
qgroupid rfer excl max_rfer max_excl
    
0/5   2.19GiB  2.19GiB none none
0/257   100.02MiB100.02MiB none none

Reported-by: Tsutomu Itoh t-i...@jp.fujitsu.com
Signed-off-by: Dongsheng Yang yangds.f...@cn.fujitsu.com
---
 cmds-qgroup.c | 23 +++
 1 file changed, 11 insertions(+), 12 deletions(-)

diff --git a/cmds-qgroup.c b/cmds-qgroup.c
index b073250..00cc089 100644
--- a/cmds-qgroup.c
+++ b/cmds-qgroup.c
@@ -110,9 +110,10 @@ static int parse_limit(const char *p, unsigned long long 
*s)
 {
char *endptr;
unsigned long long size;
+   unsigned long long CLEAR_VALUE = -1;
 
if (strcasecmp(p, none) == 0) {
-   *s = 0;
+   *s = CLEAR_VALUE;
return 1;
}
size = strtoull(p, endptr, 10);
@@ -406,17 +407,15 @@ static int cmd_qgroup_limit(int argc, char **argv)
}
 
memset(args, 0, sizeof(args));
-   if (size) {
-   if (compressed)
-   args.lim.flags |= BTRFS_QGROUP_LIMIT_RFER_CMPR |
- BTRFS_QGROUP_LIMIT_EXCL_CMPR;
-   if (exclusive) {
-   args.lim.flags |= BTRFS_QGROUP_LIMIT_MAX_EXCL;
-   args.lim.max_exclusive = size;
-   } else {
-   args.lim.flags |= BTRFS_QGROUP_LIMIT_MAX_RFER;
-   args.lim.max_referenced = size;
-   }
+   if (compressed)
+   args.lim.flags |= BTRFS_QGROUP_LIMIT_RFER_CMPR |
+ BTRFS_QGROUP_LIMIT_EXCL_CMPR;
+   if (exclusive) {
+   args.lim.flags |= BTRFS_QGROUP_LIMIT_MAX_EXCL;
+   args.lim.max_exclusive = size;
+   } else {
+   args.lim.flags |= BTRFS_QGROUP_LIMIT_MAX_RFER;
+   args.lim.max_referenced = size;
}
 
if (argc - optind == 2) {
-- 
1.8.4.2

--
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


[PATCH] btrfs: qgroup: allow user to clear the limitation on qgroup

2015-06-03 Thread Dongsheng Yang
Currently, we can only set a limitation on a qgroup, but we
can not clear it.

This patch provide a choice to user to clear a limitation on
qgroup by passing a value of CLEAR_VALUE(-1) to kernel.

Reported-by: Tsutomu Itoh t-i...@jp.fujitsu.com
Signed-off-by: Dongsheng Yang yangds.f...@cn.fujitsu.com
---
 fs/btrfs/qgroup.c | 49 +
 1 file changed, 41 insertions(+), 8 deletions(-)

diff --git a/fs/btrfs/qgroup.c b/fs/btrfs/qgroup.c
index 3d65465..0412d5b 100644
--- a/fs/btrfs/qgroup.c
+++ b/fs/btrfs/qgroup.c
@@ -1317,6 +1317,11 @@ int btrfs_limit_qgroup(struct btrfs_trans_handle *trans,
struct btrfs_root *quota_root;
struct btrfs_qgroup *qgroup;
int ret = 0;
+   /* Sometimes we would want to clear the limit on this qgroup.
+* To meet this requirement, we treat the -1 as a special value
+* which tell kernel to clear the limit on this qgroup.
+*/
+   const u64 CLEAR_VALUE = -1;
 
mutex_lock(fs_info-qgroup_ioctl_lock);
quota_root = fs_info-quota_root;
@@ -1332,14 +1337,42 @@ int btrfs_limit_qgroup(struct btrfs_trans_handle *trans,
}
 
spin_lock(fs_info-qgroup_lock);
-   if (limit-flags  BTRFS_QGROUP_LIMIT_MAX_RFER)
-   qgroup-max_rfer = limit-max_rfer;
-   if (limit-flags  BTRFS_QGROUP_LIMIT_MAX_EXCL)
-   qgroup-max_excl = limit-max_excl;
-   if (limit-flags  BTRFS_QGROUP_LIMIT_RSV_RFER)
-   qgroup-rsv_rfer = limit-rsv_rfer;
-   if (limit-flags  BTRFS_QGROUP_LIMIT_RSV_EXCL)
-   qgroup-rsv_excl = limit-rsv_excl;
+   if (limit-flags  BTRFS_QGROUP_LIMIT_MAX_RFER) {
+   if (limit-max_rfer == CLEAR_VALUE) {
+   qgroup-lim_flags = ~BTRFS_QGROUP_LIMIT_MAX_RFER;
+   limit-flags = ~BTRFS_QGROUP_LIMIT_MAX_RFER;
+   qgroup-max_rfer = 0;
+   } else {
+   qgroup-max_rfer = limit-max_rfer;
+   }
+   }
+   if (limit-flags  BTRFS_QGROUP_LIMIT_MAX_EXCL) {
+   if (limit-max_excl == CLEAR_VALUE) {
+   qgroup-lim_flags = ~BTRFS_QGROUP_LIMIT_MAX_EXCL;
+   limit-flags = ~BTRFS_QGROUP_LIMIT_MAX_EXCL;
+   qgroup-max_excl = 0;
+   } else {
+   qgroup-max_excl = limit-max_excl;
+   }
+   }
+   if (limit-flags  BTRFS_QGROUP_LIMIT_RSV_RFER) {
+   if (limit-rsv_rfer == CLEAR_VALUE) {
+   qgroup-lim_flags = ~BTRFS_QGROUP_LIMIT_RSV_RFER;
+   limit-flags = ~BTRFS_QGROUP_LIMIT_RSV_RFER;
+   qgroup-rsv_rfer = 0;
+   } else {
+   qgroup-rsv_rfer = limit-rsv_rfer;
+   }
+   }
+   if (limit-flags  BTRFS_QGROUP_LIMIT_RSV_EXCL) {
+   if (limit-rsv_excl == CLEAR_VALUE) {
+   qgroup-lim_flags = ~BTRFS_QGROUP_LIMIT_RSV_EXCL;
+   limit-flags = ~BTRFS_QGROUP_LIMIT_RSV_EXCL;
+   qgroup-rsv_excl = 0;
+   } else {
+   qgroup-rsv_excl = limit-rsv_excl;
+   }
+   }
qgroup-lim_flags |= limit-flags;
 
spin_unlock(fs_info-qgroup_lock);
-- 
1.8.4.2

--
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


[PATCH 1/2] btrfs-progs: qgroup limit: error out if input value is negative

2015-06-03 Thread Dongsheng Yang
If we pass a negative value to command qgroup limit, btrfs-progs
would convert it to unsigned long long silently. That's a little
confusing to user, why I can limit my quota to a negative value.

This patch add a check in parse_limit, if the input value is negative,
error out to user.

Reported-by: Tsutomu Itoh t-i...@jp.fujitsu.com
Signed-off-by: Dongsheng Yang yangds.f...@cn.fujitsu.com
---
 cmds-qgroup.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/cmds-qgroup.c b/cmds-qgroup.c
index 00cc089..5ea4021 100644
--- a/cmds-qgroup.c
+++ b/cmds-qgroup.c
@@ -116,6 +116,10 @@ static int parse_limit(const char *p, unsigned long long 
*s)
*s = CLEAR_VALUE;
return 1;
}
+
+   if (p[0] == '-')
+   return 0;
+
size = strtoull(p, endptr, 10);
switch (*endptr) {
case 'T':
-- 
1.8.4.2

--
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


[PATCH] xfstests: btrfs: 022: add a quota rescan -w to wait rescan finished.

2015-06-03 Thread Dongsheng Yang
When we enable quota, btrfs will rescan quota numbers. We need
to wait the rescan finished before any more operations on btrfs
qgroups. Otherwith, the new btrfs-progs would WARN out:

WARNING: Rescan is running, qgroup data may be incorrect.

It would make btrfs/022 failed.

Signed-off-by: Dongsheng Yang yangds.f...@cn.fujitsu.com
---
 tests/btrfs/022 | 1 +
 1 file changed, 1 insertion(+)

diff --git a/tests/btrfs/022 b/tests/btrfs/022
index 5c1a82d..56d4f3d 100755
--- a/tests/btrfs/022
+++ b/tests/btrfs/022
@@ -51,6 +51,7 @@ _basic_test()
 {
_run_btrfs_util_prog subvolume create $SCRATCH_MNT/a
_run_btrfs_util_prog quota enable $SCRATCH_MNT/a
+   _run_btrfs_util_prog quota rescan -w $SCRATCH_MNT
subvolid=$(_btrfs_get_subvolid $SCRATCH_MNT a)
$BTRFS_UTIL_PROG qgroup show $units $SCRATCH_MNT | grep $subvolid  \
$seqres.full 21
-- 
1.8.4.2

--
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] xfstests: btrfs: 022: add a quota rescan -w to wait rescan finished.

2015-06-03 Thread Dongsheng Yang

Hi Filip,

Qu is off duty this week, would you please try this patch here?

Thanx
Yang

On 06/03/2015 03:10 PM, Dongsheng Yang wrote:

When we enable quota, btrfs will rescan quota numbers. We need
to wait the rescan finished before any more operations on btrfs
qgroups. Otherwith, the new btrfs-progs would WARN out:

WARNING: Rescan is running, qgroup data may be incorrect.

It would make btrfs/022 failed.

Signed-off-by: Dongsheng Yang yangds.f...@cn.fujitsu.com
---
  tests/btrfs/022 | 1 +
  1 file changed, 1 insertion(+)

diff --git a/tests/btrfs/022 b/tests/btrfs/022
index 5c1a82d..56d4f3d 100755
--- a/tests/btrfs/022
+++ b/tests/btrfs/022
@@ -51,6 +51,7 @@ _basic_test()
  {
_run_btrfs_util_prog subvolume create $SCRATCH_MNT/a
_run_btrfs_util_prog quota enable $SCRATCH_MNT/a
+   _run_btrfs_util_prog quota rescan -w $SCRATCH_MNT
subvolid=$(_btrfs_get_subvolid $SCRATCH_MNT a)
$BTRFS_UTIL_PROG qgroup show $units $SCRATCH_MNT | grep $subvolid  \
$seqres.full 21



--
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 2/2] btrfs-progs: qgroup: allow user to clear some limitation on qgroup.

2015-06-03 Thread Dongsheng Yang
On 06/03/2015 04:40 PM, Tsutomu Itoh wrote:
 On 2015/06/03 15:57, Dongsheng Yang wrote:
 Currently, we can not clear a limitation on a qgroup. Although
 there is a 'none' choice provided to user to do it, it does not
 work well.

 It does not set the flag which user want to clear, then kernel
 will never know what the user want to do at all.

 *Without this commit*
# ./btrfs qgroup show -re /mnt
 qgroupid rfer excl max_rfer max_excl
     
 0/5   2.19GiB  2.19GiB  5.00GiB none
 0/257   100.02MiB100.02MiB none none
# ./btrfs qgroup limit none /mnt
# ./btrfs qgroup show -re /mnt
 qgroupid rfer excl max_rfer max_excl
     
 0/5   2.19GiB  2.19GiB  5.00GiB none
 0/257   100.02MiB100.02MiB none none

 This patch will set the flag user want to clear and pass a
 size=-1 to kernel. Then kernel will clear it correctly.

 *With this commit*
# ./btrfs qgroup show -re /mnt
 qgroupid rfer excl max_rfer max_excl
     
 0/5   2.19GiB  2.19GiB  5.00GiB none
 0/257   100.02MiB100.02MiB none none
# ./btrfs qgroup limit none /mnt
# ./btrfs qgroup show -re /mnt
 qgroupid rfer excl max_rfer max_excl
     
 0/5   2.19GiB  2.19GiB none none
 0/257   100.02MiB100.02MiB none none

 Reported-by: Tsutomu Itoh t-i...@jp.fujitsu.com
 Signed-off-by: Dongsheng Yang yangds.f...@cn.fujitsu.com
 ---
cmds-qgroup.c | 23 +++
1 file changed, 11 insertions(+), 12 deletions(-)

 diff --git a/cmds-qgroup.c b/cmds-qgroup.c
 index b073250..00cc089 100644
 --- a/cmds-qgroup.c
 +++ b/cmds-qgroup.c
 @@ -110,9 +110,10 @@ static int parse_limit(const char *p, unsigned long 
 long *s)
{
  char *endptr;
  unsigned long long size;
 +unsigned long long CLEAR_VALUE = -1;
 
 Even if a negative value is specified, it doesn't become an error...
 So, it doesn't make an error of the following command.
 
 # btrfs qg lim -- -1 sub1
 # btrfs qg show -prce /test1
 qgroupid rfer excl max_rfer max_excl parent  child
      --  -
 0/5  16.00KiB 16.00KiB none none --- ---
 0/259 8.86GiB  7.88GiB none none --- ---
 # btrfs qg lim -- -2 sub1
 # btrfs qg show -prce /test1
 qgroupid rfer excl max_rfer max_excl parent  child
      --  -
 0/5  16.00KiB 16.00KiB none none --- ---
 0/259 8.86GiB  7.88GiB 16.00EiB none --- ---

Agreed, I understand your point here.

If we pass a negative value to limit command, we should Error out. But
currently, btrfs-progs are treating it as a unsigned value in parsing
it. Yes, that's a bit of confusing.

We need to cover it in parsing steps with another patch I think.
 
 Otherwise OK,
 
 Tested-by: Tsutomu Itoh t-i...@jp.fujitsu.com

Thanx


Yang
 
 

  if (strcasecmp(p, none) == 0) {
 -*s = 0;
 +*s = CLEAR_VALUE;
  return 1;
  }
  size = strtoull(p, endptr, 10);
 @@ -406,17 +407,15 @@ static int cmd_qgroup_limit(int argc, char **argv)
  }

  memset(args, 0, sizeof(args));
 -if (size) {
 -if (compressed)
 -args.lim.flags |= BTRFS_QGROUP_LIMIT_RFER_CMPR |
 -  BTRFS_QGROUP_LIMIT_EXCL_CMPR;
 -if (exclusive) {
 -args.lim.flags |= BTRFS_QGROUP_LIMIT_MAX_EXCL;
 -args.lim.max_exclusive = size;
 -} else {
 -args.lim.flags |= BTRFS_QGROUP_LIMIT_MAX_RFER;
 -args.lim.max_referenced = size;
 -}
 +if (compressed)
 +args.lim.flags |= BTRFS_QGROUP_LIMIT_RFER_CMPR |
 +  BTRFS_QGROUP_LIMIT_EXCL_CMPR;
 +if (exclusive) {
 +args.lim.flags |= BTRFS_QGROUP_LIMIT_MAX_EXCL;
 +args.lim.max_exclusive = size;
 +} else {
 +args.lim.flags |= BTRFS_QGROUP_LIMIT_MAX_RFER;
 +args.lim.max_referenced = size;
  }

  if (argc - optind == 2) {

 
 
 .
 

--
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


[PATCH] Btrfs: fill -last_trans for delayed inode in btrfs_fill_inode.

2015-04-08 Thread Dongsheng Yang
We need to fill inode when we found a node for it in delayed_nodes_tree.
But we did not fill the -last_trans currently, it will cause the test
of xfstest/generic/311 fail. Scenario of the 311 is shown as below:

Problem:
(1). test_fd = open(fname, O_RDWR|O_DIRECT)
(2). pwrite(test_fd, buf, 4096, 0)
(3). close(test_fd)
(4). drop_all_caches()   echo 3  /proc/sys/vm/drop_caches
(5). test_fd = open(fname, O_RDWR|O_DIRECT)
(6). fsync(test_fd);
 we did not get the correct log entry 
for the file
Reason:
When we re-open this file in (5), we would find a node
in delayed_nodes_tree and fill the inode we are lookup with the
information. But the -last_trans is not filled, then the fsync()
will check the -last_trans and found it's 0 then say this inode
is already in our tree which is commited, not recording the extents
for it.

Fix:
This patch fill the -last_trans properly and set the
runtime_flags if needed in this situation. Then we can get the
log entries we expected after (6) and generic/311 passed.

Signed-off-by: Dongsheng Yang yangds.f...@cn.fujitsu.com
---
 fs/btrfs/delayed-inode.c |  2 ++
 fs/btrfs/inode.c | 21 -
 2 files changed, 14 insertions(+), 9 deletions(-)

diff --git a/fs/btrfs/delayed-inode.c b/fs/btrfs/delayed-inode.c
index 82f0c7c..9e8b435 100644
--- a/fs/btrfs/delayed-inode.c
+++ b/fs/btrfs/delayed-inode.c
@@ -1801,6 +1801,8 @@ int btrfs_fill_inode(struct inode *inode, u32 *rdev)
set_nlink(inode, btrfs_stack_inode_nlink(inode_item));
inode_set_bytes(inode, btrfs_stack_inode_nbytes(inode_item));
BTRFS_I(inode)-generation = btrfs_stack_inode_generation(inode_item);
+BTRFS_I(inode)-last_trans = btrfs_stack_inode_transid(inode_item);
+
inode-i_version = btrfs_stack_inode_sequence(inode_item);
inode-i_rdev = 0;
*rdev = btrfs_stack_inode_rdev(inode_item);
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index d2e732d..b132936 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -3628,25 +3628,28 @@ static void btrfs_read_locked_inode(struct inode *inode)
BTRFS_I(inode)-generation = btrfs_inode_generation(leaf, inode_item);
BTRFS_I(inode)-last_trans = btrfs_inode_transid(leaf, inode_item);
 
+   inode-i_version = btrfs_inode_sequence(leaf, inode_item);
+   inode-i_generation = BTRFS_I(inode)-generation;
+   inode-i_rdev = 0;
+   rdev = btrfs_inode_rdev(leaf, inode_item);
+
+   BTRFS_I(inode)-index_cnt = (u64)-1;
+   BTRFS_I(inode)-flags = btrfs_inode_flags(leaf, inode_item);
+
+cache_index:
/*
 * If we were modified in the current generation and evicted from memory
 * and then re-read we need to do a full sync since we don't have any
 * idea about which extents were modified before we were evicted from
 * cache.
+*
+* This is required for both inode re-read from disk and delayed inode
+* in delayed_nodes_tree.
 */
if (BTRFS_I(inode)-last_trans == root-fs_info-generation)
set_bit(BTRFS_INODE_NEEDS_FULL_SYNC,
BTRFS_I(inode)-runtime_flags);
 
-   inode-i_version = btrfs_inode_sequence(leaf, inode_item);
-   inode-i_generation = BTRFS_I(inode)-generation;
-   inode-i_rdev = 0;
-   rdev = btrfs_inode_rdev(leaf, inode_item);
-
-   BTRFS_I(inode)-index_cnt = (u64)-1;
-   BTRFS_I(inode)-flags = btrfs_inode_flags(leaf, inode_item);
-
-cache_index:
path-slots[0]++;
if (inode-i_nlink != 1 ||
path-slots[0] = btrfs_header_nritems(leaf))
-- 
1.8.4.2

--
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


[PATCH 4/4] Btrfs-progs: qgroup: show specified quota data.

2015-03-19 Thread Dongsheng Yang
This patch allow user to choose the information type
in command of qgroup show.

Signed-off-by: Dongsheng Yang yangds.f...@cn.fujitsu.com
---
 cmds-qgroup.c | 24 +++-
 qgroup.c  | 44 +++-
 qgroup.h  |  7 ++-
 3 files changed, 64 insertions(+), 11 deletions(-)

diff --git a/cmds-qgroup.c b/cmds-qgroup.c
index 1c42fc8..86b6d2d 100644
--- a/cmds-qgroup.c
+++ b/cmds-qgroup.c
@@ -204,6 +204,21 @@ static int cmd_qgroup_destroy(int argc, char **argv)
return ret;
 }
 
+static int parse_show_type(u8 *qgroup_type, char *arg)
+{
+   if (strcmp(arg, data) == 0)
+   *qgroup_type = BTRFS_QGROUP_SHOW_TYPE_DATA;
+   else if (strcmp(arg, metadata) == 0)
+   *qgroup_type = BTRFS_QGROUP_SHOW_TYPE_METADATA;
+   else if (strcmp(arg, mixed) == 0) {
+   *qgroup_type = BTRFS_QGROUP_SHOW_TYPE_MIXED;
+   } else {
+   fprintf(stderr, ERROR: Invalid qgroup type arguments given\n);
+   return -EINVAL;
+   }
+   return 0;
+}
+
 static const char * const cmd_qgroup_show_usage[] = {
btrfs qgroup show -pcreFf 
[--sort=qgroupid,rfer,excl,max_rfer,max_excl] path,
@@ -238,6 +253,7 @@ static int cmd_qgroup_show(int argc, char **argv)
int ret = 0;
int fd;
int e;
+   u8 type = BTRFS_QGROUP_SHOW_TYPE_MIXED;
DIR *dirstream = NULL;
u64 qgroupid;
int filter_flag = 0;
@@ -253,6 +269,7 @@ static int cmd_qgroup_show(int argc, char **argv)
int c;
int option_index = 0;
static const struct option long_options[] = {
+   {type, required_argument, NULL, 't'},
{sort, 1, NULL, 'S'},
{raw, no_argument, NULL, GETOPT_VAL_RAW},
{kbytes, no_argument, NULL, GETOPT_VAL_KBYTES},
@@ -299,6 +316,11 @@ static int cmd_qgroup_show(int argc, char **argv)
if (ret)
usage(cmd_qgroup_show_usage);
break;
+   case 't':
+   ret = parse_show_type(type, optarg);
+   if (ret)
+   usage(cmd_qgroup_show_usage);
+   break;
case GETOPT_VAL_RAW:
unit_mode = UNITS_RAW;
break;
@@ -350,7 +372,7 @@ static int cmd_qgroup_show(int argc, char **argv)
BTRFS_QGROUP_FILTER_PARENT,
qgroupid);
}
-   ret = btrfs_show_qgroups(fd, filter_set, comparer_set);
+   ret = btrfs_show_qgroups(fd, filter_set, comparer_set, type);
e = errno;
close_file_or_dir(fd, dirstream);
if (ret  0)
diff --git a/qgroup.c b/qgroup.c
index 91e25ea..0e32284 100644
--- a/qgroup.c
+++ b/qgroup.c
@@ -226,14 +226,36 @@ static void print_qgroup_column_add_blank(enum 
btrfs_qgroup_column_enum column,
 }
 
 static void print_qgroup_column(struct btrfs_qgroup *qgroup,
-   enum btrfs_qgroup_column_enum column)
+   enum btrfs_qgroup_column_enum column,
+   u8 type)
 {
BUG_ON(column = BTRFS_QGROUP_ALL || column  0);
int len;
int unit_mode = btrfs_qgroup_columns[column].unit_mode;
int max_len = btrfs_qgroup_columns[column].max_len;
-   struct btrfs_qgroup_info *info = qgroup-data_info;
-   struct btrfs_qgroup_limits *limits = qgroup-mixed_limits;
+   struct btrfs_qgroup_limits *limits = NULL;
+   struct btrfs_qgroup_info *info = NULL;
+   int need_free = 0;
+
+
+   if (type == BTRFS_QGROUP_SHOW_TYPE_DATA) {
+   info = qgroup-data_info;
+   limits = qgroup-data_limits;
+   } else if (type == BTRFS_QGROUP_SHOW_TYPE_METADATA) {
+   info = qgroup-metadata_info;
+   limits = qgroup-metadata_limits;
+   } else {
+   /*
+* For mixed type show.
+*/ 
+   info = malloc(sizeof(*info));
+   info-rfer = qgroup-data_info.rfer +
+   qgroup-metadata_info.rfer;
+   info-excl = qgroup-data_info.excl +
+   qgroup-metadata_info.excl;
+   limits = qgroup-mixed_limits;
+   need_free = 1;
+   }
 
switch (column) {
 
@@ -265,16 +287,19 @@ static void print_qgroup_column(struct btrfs_qgroup 
*qgroup,
default:
break;
}
+
+   if (need_free)
+   free(info);
 }
 
-static void print_single_qgroup_table(struct btrfs_qgroup *qgroup)
+static void print_single_qgroup_table(struct btrfs_qgroup *qgroup, u8 type)
 {
int i;
 
for (i = 0; i  BTRFS_QGROUP_ALL; i++) {
if (!btrfs_qgroup_columns[i].need_print

[PATCH 3/7] Btrfs: qgroup: record and account ref for qgroup in different type.

2015-03-19 Thread Dongsheng Yang
This patch make the qgroup account the information of data or metadata
by different infos.

Signed-off-by: Dongsheng Yang yangds.f...@cn.fujitsu.com
---
 fs/btrfs/extent-tree.c|  48 +
 fs/btrfs/qgroup.c | 239 ++
 fs/btrfs/qgroup.h |  25 -
 fs/btrfs/tests/qgroup-tests.c |  15 ++-
 fs/btrfs/transaction.c|  11 +-
 5 files changed, 217 insertions(+), 121 deletions(-)

diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index 3f49316..cb27da6 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -83,7 +83,7 @@ static int __btrfs_free_extent(struct btrfs_trans_handle 
*trans,
u64 root_objectid, u64 owner_objectid,
u64 owner_offset, int refs_to_drop,
struct btrfs_delayed_extent_op *extra_op,
-   int no_quota);
+   int no_quota, unsigned int quota_type);
 static void __run_delayed_extent_op(struct btrfs_delayed_extent_op *extent_op,
struct extent_buffer *leaf,
struct btrfs_extent_item *ei);
@@ -1971,7 +1971,8 @@ static int __btrfs_inc_extent_ref(struct 
btrfs_trans_handle *trans,
  u64 parent, u64 root_objectid,
  u64 owner, u64 offset, int refs_to_add,
  int no_quota,
- struct btrfs_delayed_extent_op *extent_op)
+ struct btrfs_delayed_extent_op *extent_op,
+ unsigned int quota_type)
 {
struct btrfs_fs_info *fs_info = root-fs_info;
struct btrfs_path *path;
@@ -2013,7 +2014,8 @@ static int __btrfs_inc_extent_ref(struct 
btrfs_trans_handle *trans,
btrfs_release_path(path);
 
ret = btrfs_qgroup_record_ref(trans, fs_info, root_objectid,
- bytenr, num_bytes, type, 0);
+ bytenr, num_bytes, type,
+ quota_type, 0);
goto out;
}
 
@@ -2037,7 +2039,8 @@ static int __btrfs_inc_extent_ref(struct 
btrfs_trans_handle *trans,
 
if (!no_quota) {
ret = btrfs_qgroup_record_ref(trans, fs_info, root_objectid,
- bytenr, num_bytes, type, 0);
+ bytenr, num_bytes, type,
+ quota_type, 0);
if (ret)
goto out;
}
@@ -2091,13 +2094,15 @@ static int run_delayed_data_ref(struct 
btrfs_trans_handle *trans,
 node-num_bytes, parent,
 ref_root, ref-objectid,
 ref-offset, node-ref_mod,
-node-no_quota, extent_op);
+node-no_quota, extent_op,
+BTRFS_QGROUP_REF_TYPE_DATA);
} else if (node-action == BTRFS_DROP_DELAYED_REF) {
ret = __btrfs_free_extent(trans, root, node-bytenr,
  node-num_bytes, parent,
  ref_root, ref-objectid,
  ref-offset, node-ref_mod,
- extent_op, node-no_quota);
+ extent_op, node-no_quota,
+ BTRFS_QGROUP_REF_TYPE_DATA);
} else {
BUG();
}
@@ -2258,12 +2263,12 @@ static int run_delayed_tree_ref(struct 
btrfs_trans_handle *trans,
ret = __btrfs_inc_extent_ref(trans, root, node-bytenr,
 node-num_bytes, parent, ref_root,
 ref-level, 0, 1, node-no_quota,
-extent_op);
+extent_op, 
BTRFS_QGROUP_REF_TYPE_METADATA);
} else if (node-action == BTRFS_DROP_DELAYED_REF) {
ret = __btrfs_free_extent(trans, root, node-bytenr,
  node-num_bytes, parent, ref_root,
  ref-level, 0, 1, extent_op,
- node-no_quota);
+ node-no_quota, 
BTRFS_QGROUP_REF_TYPE_METADATA);
} else {
BUG();
}
@@ -3694,7 +3699,7 @@ commit_trans:
  data_sinfo-flags, bytes, 1);
return -ENOSPC;
}
-   ret = btrfs_qgroup_reserve(root, write_bytes

[PATCH 5/7] Btrfs: qgroup: update quota numbers in btrfs_qgroup_inherit.

2015-03-19 Thread Dongsheng Yang
Original, the all quota numbers are stored in data_info, but
now, we store them separately in data_info and metadata_info.
Then, when we create a snapshot and update the quota number,
we need to update both of the data_info and metadata_info.

Signed-off-by: Dongsheng Yang yangds.f...@cn.fujitsu.com
---
 fs/btrfs/qgroup.c | 57 ++-
 1 file changed, 40 insertions(+), 17 deletions(-)

diff --git a/fs/btrfs/qgroup.c b/fs/btrfs/qgroup.c
index 5df8527..9363fd0 100644
--- a/fs/btrfs/qgroup.c
+++ b/fs/btrfs/qgroup.c
@@ -2525,34 +2525,57 @@ int btrfs_qgroup_inherit(struct btrfs_trans_handle 
*trans,
srcgroup = find_qgroup_rb(fs_info, srcid);
if (!srcgroup)
goto unlock;
-   /*
-* FIXME: use the data_info to store all information currently.
-* will seperate the information into data and metadata later.
-**/
dstinfo = dstgroup-data_info;
srcinfo = srcgroup-data_info;
 
-   /*
-* We call inherit after we clone the root in order to make sure
-* our counts don't go crazy, so at this point the only
-* difference between the two roots should be the root node.
-*/
-   dstinfo-rfer = srcinfo-rfer;
-   dstinfo-rfer_cmpr = srcinfo-rfer_cmpr;
-   dstinfo-excl = level_size;
-   dstinfo-excl_cmpr = level_size;
-   srcinfo-excl = level_size;
-   srcinfo-excl_cmpr = level_size;
+   if (!btrfs_fs_incompat(fs_info, QGROUP_TYPE)) {
+   /*
+* We call inherit after we clone the root in order to 
make sure
+* our counts don't go crazy, so at this point the only
+* difference between the two roots should be the root 
node.
+*/
+   dstinfo-rfer = srcinfo-rfer;
+   dstinfo-rfer_cmpr = srcinfo-rfer_cmpr;
+   dstinfo-excl = level_size;
+   dstinfo-excl_cmpr = level_size;
+   srcinfo-excl = level_size;
+   srcinfo-excl_cmpr = level_size;
+   } else {
+   dstinfo-rfer = srcinfo-rfer;
+   dstinfo-rfer_cmpr = srcinfo-rfer_cmpr;
+   /*
+* add the metadata for dstqgroup.
+*/
+   dstinfo = dstgroup-metadata_info;
+   dstinfo-rfer = level_size;
+   dstinfo-rfer_cmpr = level_size;
+   dstinfo-excl = level_size;
+   dstinfo-excl_cmpr = level_size;
+   srcinfo-excl = 0;
+   srcinfo-excl_cmpr = 0;
+   }
 
-   dstlimits = dstgroup-mixed_limits;
-   srclimits = srcgroup-mixed_limits;
+   if (!btrfs_fs_incompat(fs_info, QGROUP_TYPE)) {
+   dstlimits = dstgroup-mixed_limits;
+   srclimits = srcgroup-mixed_limits;
+   } else {
+   dstlimits = dstgroup-data_limits;
+   srclimits = srcgroup-data_limits;
+   }
/* inherit the limit info */
+again:
dstlimits-lim_flags = srclimits-lim_flags;
dstlimits-max_rfer = srclimits-max_rfer;
dstlimits-max_excl = srclimits-max_excl;
dstlimits-rsv_rfer = srclimits-rsv_rfer;
dstlimits-rsv_excl = srclimits-rsv_excl;
 
+   if (dstlimits != dstgroup-mixed_limits) {
+   dstlimits++;
+   srclimits++;
+   goto again;
+   }
+
qgroup_dirty(fs_info, dstgroup);
qgroup_dirty(fs_info, srcgroup);
}
-- 
1.8.4.2

--
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


[PATCH 1/7] Btrfs: qgroup: split information and limits in qgroup to other structures.

2015-03-19 Thread Dongsheng Yang
Restruct the btrfs_qgroup structure:

btrfs_qgroup: |-|
- |rfer |
|data_info  |---btrfs_qgroup_info|rfer_cmpr|
|metadata_info  | |excl |
|   | |excl_cmpr|
|data_limits| ---
|metadata_limits|
|mixed_limits   |---btrfs_qgroup_limits|-
|-- |   |lim_flags  |
|max_rfer   |
|max_excl   |
|rsv_rfer   |
|rsv_excl   |


Then we can account data and metadata separately. And we can limit them
separately. mixed_limits is provided to limit the sum of data and metadata.

Signed-off-by: Dongsheng Yang yangds.f...@cn.fujitsu.com
---
 fs/btrfs/qgroup.c | 308 +-
 1 file changed, 214 insertions(+), 94 deletions(-)

diff --git a/fs/btrfs/qgroup.c b/fs/btrfs/qgroup.c
index 28b0aa5..dd99908 100644
--- a/fs/btrfs/qgroup.c
+++ b/fs/btrfs/qgroup.c
@@ -46,33 +46,44 @@
  *  - check all ioctl parameters
  */
 
-/*
- * one struct for each qgroup, organized in fs_info-qgroup_tree.
- */
-struct btrfs_qgroup {
-   u64 qgroupid;
-
-   /*
-* state
-*/
+struct btrfs_qgroup_info {
u64 rfer;   /* referenced */
u64 rfer_cmpr;  /* referenced compressed */
u64 excl;   /* exclusive */
u64 excl_cmpr;  /* exclusive compressed */
 
/*
-* limits
+* reservation tracking
 */
+   u64 reserved;
+};
+
+struct btrfs_qgroup_limits {
u64 lim_flags;  /* which limits are set */
u64 max_rfer;
u64 max_excl;
u64 rsv_rfer;
u64 rsv_excl;
+};
+
+/*
+ * one struct for each qgroup, organized in fs_info-qgroup_tree.
+ */
+struct btrfs_qgroup {
+   u64 qgroupid;
 
/*
-* reservation tracking
+* infos
 */
-   u64 reserved;
+   struct btrfs_qgroup_infodata_info;
+   struct btrfs_qgroup_infometadata_info;
+
+   /*
+* limits
+*/
+   struct btrfs_qgroup_limits  data_limits;
+   struct btrfs_qgroup_limits  metadata_limits;
+   struct btrfs_qgroup_limits  mixed_limits;
 
/*
 * lists
@@ -251,11 +262,13 @@ int btrfs_verify_qgroup_counts(struct btrfs_fs_info 
*fs_info, u64 qgroupid,
   u64 rfer, u64 excl)
 {
struct btrfs_qgroup *qgroup;
+   struct btrfs_qgroup_info *info;
 
qgroup = find_qgroup_rb(fs_info, qgroupid);
if (!qgroup)
return -EINVAL;
-   if (qgroup-rfer != rfer || qgroup-excl != excl)
+   info = qgroup-data_info;
+   if (info-rfer != rfer || info-excl != excl)
return -EINVAL;
return 0;
 }
@@ -357,26 +370,30 @@ int btrfs_read_qgroup_config(struct btrfs_fs_info 
*fs_info)
switch (found_key.type) {
case BTRFS_QGROUP_INFO_KEY: {
struct btrfs_qgroup_info_item *ptr;
+   struct btrfs_qgroup_info *info;
 
+   info = qgroup-data_info;
ptr = btrfs_item_ptr(l, slot,
 struct btrfs_qgroup_info_item);
-   qgroup-rfer = btrfs_qgroup_info_rfer(l, ptr);
-   qgroup-rfer_cmpr = btrfs_qgroup_info_rfer_cmpr(l, ptr);
-   qgroup-excl = btrfs_qgroup_info_excl(l, ptr);
-   qgroup-excl_cmpr = btrfs_qgroup_info_excl_cmpr(l, ptr);
+   info-rfer = btrfs_qgroup_info_rfer(l, ptr);
+   info-rfer_cmpr = btrfs_qgroup_info_rfer_cmpr(l, ptr);
+   info-excl = btrfs_qgroup_info_excl(l, ptr);
+   info-excl_cmpr = btrfs_qgroup_info_excl_cmpr(l, ptr);
/* generation currently unused */
break;
}
case BTRFS_QGROUP_LIMIT_KEY: {
struct btrfs_qgroup_limit_item *ptr;
+   struct btrfs_qgroup_limits *limits;
 
+   limits = qgroup-mixed_limits;
ptr = btrfs_item_ptr(l, slot,
 struct btrfs_qgroup_limit_item);
-   qgroup-lim_flags = btrfs_qgroup_limit_flags(l, ptr);
-   qgroup-max_rfer = btrfs_qgroup_limit_max_rfer(l, ptr);
-   qgroup-max_excl = btrfs_qgroup_limit_max_excl(l, ptr);
-   qgroup-rsv_rfer

[PATCH 4/7] Btrfs: qgroup: update all infos and limits to disk.

2015-03-19 Thread Dongsheng Yang
There are not only one info for a qgroup, then we need
to store the all infos and limits to disk.

Signed-off-by: Dongsheng Yang yangds.f...@cn.fujitsu.com
---
 fs/btrfs/qgroup.c | 52 
 1 file changed, 40 insertions(+), 12 deletions(-)

diff --git a/fs/btrfs/qgroup.c b/fs/btrfs/qgroup.c
index 9dd2627..5df8527 100644
--- a/fs/btrfs/qgroup.c
+++ b/fs/btrfs/qgroup.c
@@ -624,6 +624,8 @@ info_again:
 
if (btrfs_fs_incompat(quota_root-fs_info, QGROUP_TYPE))
key.objectid = BTRFS_QGROUP_DATA_LIMIT_OBJECTID;
+   else
+   key.objectid = 0;
 
key.type = BTRFS_QGROUP_LIMIT_KEY;
 
@@ -700,6 +702,8 @@ info_again:
 
if (btrfs_fs_incompat(quota_root-fs_info, QGROUP_TYPE))
key.objectid = BTRFS_QGROUP_DATA_LIMIT_OBJECTID;
+   else
+   key.objectid = 0;
 
key.type = BTRFS_QGROUP_LIMIT_KEY;
 
@@ -739,14 +743,21 @@ static int update_qgroup_limit_item(struct 
btrfs_trans_handle *trans,
int ret;
int slot;
 
-   key.objectid = 0;
+   if (!btrfs_fs_incompat(root-fs_info, QGROUP_TYPE)) {
+   key.objectid = 0;
+   limits = qgroup-mixed_limits;
+   } else {
+   key.objectid = BTRFS_QGROUP_DATA_LIMIT_OBJECTID;
+   limits = qgroup-data_limits;
+   }
+
key.type = BTRFS_QGROUP_LIMIT_KEY;
key.offset = qgroup-qgroupid;
 
path = btrfs_alloc_path();
if (!path)
return -ENOMEM;
-
+again:
ret = btrfs_search_slot(trans, root, key, path, 0, 1);
if (ret  0)
ret = -ENOENT;
@@ -754,8 +765,6 @@ static int update_qgroup_limit_item(struct 
btrfs_trans_handle *trans,
if (ret)
goto out;
 
-   limits = qgroup-mixed_limits;
-
l = path-nodes[0];
slot = path-slots[0];
qgroup_limit = btrfs_item_ptr(l, slot, struct btrfs_qgroup_limit_item);
@@ -766,6 +775,14 @@ static int update_qgroup_limit_item(struct 
btrfs_trans_handle *trans,
btrfs_set_qgroup_limit_rsv_excl(l, qgroup_limit, limits-rsv_excl);
 
btrfs_mark_buffer_dirty(l);
+   btrfs_release_path(path);
+
+   if (btrfs_fs_incompat(root-fs_info, QGROUP_TYPE) 
+   key.objectid != BTRFS_QGROUP_MIXED_LIMIT_OBJECTID) {
+   key.objectid++;
+   limits++;
+   goto again;
+   }
 
 out:
btrfs_free_path(path);
@@ -780,14 +797,18 @@ static int update_qgroup_info_item(struct 
btrfs_trans_handle *trans,
struct btrfs_key key;
struct extent_buffer *l;
struct btrfs_qgroup_info_item *qgroup_info;
-   struct btrfs_qgroup_info *data_info;
+   struct btrfs_qgroup_info *info;
int ret;
int slot;
 
if (btrfs_test_is_dummy_root(root))
return 0;
 
-   key.objectid = 0;
+   if (!btrfs_fs_incompat(root-fs_info, QGROUP_TYPE))
+   key.objectid = 0;
+   else
+   key.objectid = BTRFS_QGROUP_DATA_INFO_OBJECTID;
+
key.type = BTRFS_QGROUP_INFO_KEY;
key.offset = qgroup-qgroupid;
 
@@ -795,6 +816,8 @@ static int update_qgroup_info_item(struct 
btrfs_trans_handle *trans,
if (!path)
return -ENOMEM;
 
+   info = qgroup-data_info;
+again:
ret = btrfs_search_slot(trans, root, key, path, 0, 1);
if (ret  0)
ret = -ENOENT;
@@ -802,19 +825,24 @@ static int update_qgroup_info_item(struct 
btrfs_trans_handle *trans,
if (ret)
goto out;
 
-   data_info = qgroup-data_info;
-
l = path-nodes[0];
slot = path-slots[0];
qgroup_info = btrfs_item_ptr(l, slot, struct btrfs_qgroup_info_item);
btrfs_set_qgroup_info_generation(l, qgroup_info, trans-transid);
-   btrfs_set_qgroup_info_rfer(l, qgroup_info, data_info-rfer);
-   btrfs_set_qgroup_info_rfer_cmpr(l, qgroup_info, data_info-rfer_cmpr);
-   btrfs_set_qgroup_info_excl(l, qgroup_info, data_info-excl);
-   btrfs_set_qgroup_info_excl_cmpr(l, qgroup_info, data_info-excl_cmpr);
+   btrfs_set_qgroup_info_rfer(l, qgroup_info, info-rfer);
+   btrfs_set_qgroup_info_rfer_cmpr(l, qgroup_info, info-rfer_cmpr);
+   btrfs_set_qgroup_info_excl(l, qgroup_info, info-excl);
+   btrfs_set_qgroup_info_excl_cmpr(l, qgroup_info, info-excl_cmpr);
 
btrfs_mark_buffer_dirty(l);
+   btrfs_release_path(path);
 
+   if (btrfs_fs_incompat(root-fs_info, QGROUP_TYPE) 
+   key.objectid != BTRFS_QGROUP_METADATA_INFO_OBJECTID) {
+   key.objectid++;
+   info++;
+   goto again;
+   }
 out:
btrfs_free_path(path);
return ret;
-- 
1.8.4.2

--
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


[PATCH 7/7] Btrfs: qgroup: allow user to limit qgroup in different type.

2015-03-19 Thread Dongsheng Yang
until now, we can account the quota number for data and metadata
separately, but we can not limit only one of them. This patch
add the support to only limit one of the data or metadata.

Also you can limit them at the same time.

Even you can limit data quota, metadata quota and mixed quota
at the same time.

Signed-off-by: Dongsheng Yang yangds.f...@cn.fujitsu.com
---
 fs/btrfs/qgroup.c | 10 +++---
 fs/btrfs/qgroup.h | 26 ++
 2 files changed, 33 insertions(+), 3 deletions(-)

diff --git a/fs/btrfs/qgroup.c b/fs/btrfs/qgroup.c
index bb98bdd..793c7bb 100644
--- a/fs/btrfs/qgroup.c
+++ b/fs/btrfs/qgroup.c
@@ -1322,6 +1322,7 @@ int btrfs_limit_qgroup(struct btrfs_trans_handle *trans,
struct btrfs_root *quota_root;
struct btrfs_qgroup *qgroup;
struct btrfs_qgroup_limits *limits;
+   u8 limits_type = get_limit_type(limit-flags);
int ret = 0;
 
mutex_lock(fs_info-qgroup_ioctl_lock);
@@ -1337,9 +1338,12 @@ int btrfs_limit_qgroup(struct btrfs_trans_handle *trans,
goto out;
}
 
-   /* To the compatibility, treat the mixed limits as the
-* default limits now. will change it later. */
-   limits = qgroup-mixed_limits;
+   if (limits_type == BTRFS_QGROUP_LIMIT_DATA)
+   limits = qgroup-data_limits;
+   else if (limits_type == BTRFS_QGROUP_LIMIT_METADATA)
+   limits = qgroup-metadata_limits;
+   else
+   limits = qgroup-mixed_limits;
 
spin_lock(fs_info-qgroup_lock);
if (limit-flags  BTRFS_QGROUP_LIMIT_MAX_RFER)
diff --git a/fs/btrfs/qgroup.h b/fs/btrfs/qgroup.h
index 11b73f3..6e4565f 100644
--- a/fs/btrfs/qgroup.h
+++ b/fs/btrfs/qgroup.h
@@ -36,6 +36,32 @@
 #define BTRFS_QGROUP_REF_TYPE_DEFAULT  BTRFS_QGROUP_REF_TYPE_DATA
 
 /*
+ * As we can account and limit data and metadata in
+ * a qgroup separately. We use the first 8 bits in
+ * btrfs_qgroup_limit-flags to specify the type we
+ * want to limit. Currently, there are three choice:
+ * DATA, METADATA, MIXED.
+ */
+#define BTRFS_QGROUP_LIMIT_TYPE_SHIFT   56
+
+#define BTRFS_QGROUP_LIMIT_DATA 1
+#define BTRFS_QGROUP_LIMIT_METADATA 2
+#define BTRFS_QGROUP_LIMIT_MIXED4
+
+static inline u8 get_limit_type(u64 flag)
+{
+u8 type = (flag  BTRFS_QGROUP_LIMIT_TYPE_SHIFT);
+   /*
+* If user did not set the type for limit, default
+* for mixed_limits;
+*/
+   if (!type)
+   type = BTRFS_QGROUP_LIMIT_MIXED;
+   return type;
+}
+
+
+/*
  * A description of the operations, all of these operations only happen when we
  * are adding the 1st reference for that subvolume in the case of adding space
  * or on the last reference delete in the case of subtraction.  The only
-- 
1.8.4.2

--
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


[PATCH 0/7 V2] Btrfs: qgroup: part-4: Add type to btrfs qgroup.

2015-03-19 Thread Dongsheng Yang
0 10485760 --- 
---  --DATA info and limits
qgroupid rfer excl max_rfer max_excl parent  
child 
     --  
- 
0/5 163841638400 --- 
---  
0/257   163841638400 --- 
---  --METADATA info and limits
qgroupid rfer excl max_rfer max_excl parent  
child 
     --  
- 
0/5 163841638400 --- 
---  
0/25710502144 1050214400 --- 
---  --MIXED info and limits

After all, you can use btrfs-debug-tree tool to show the details for each items.

Any comment or test are welcome !!!

Thanx
Yang

Dongsheng Yang (7):
  Btrfs: qgroup: split information and limits in qgroup to other
structures.
  Btrfs: qgroup: add incompatability feature for QGROUP_TYPE.
  Btrfs: qgroup: record and account ref for qgroup in different type.
  Btrfs: qgroup: update all infos and limits to disk.
  Btrfs: qgroup: update quota numbers in btrfs_qgroup_inherit.
  Btrfs: qgroup: account data and metadata separately in rescan.
  Btrfs: qgroup: allow user to limit qgroup in different type.

 fs/btrfs/ctree.h  |  20 +-
 fs/btrfs/extent-tree.c|  48 ++--
 fs/btrfs/qgroup.c | 536 +-
 fs/btrfs/qgroup.h |  52 +++-
 fs/btrfs/tests/qgroup-tests.c |  15 +-
 fs/btrfs/transaction.c|  11 +-
 6 files changed, 534 insertions(+), 148 deletions(-)

-- 
1.8.4.2

--
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


[PATCH 6/7] Btrfs: qgroup: account data and metadata separately in rescan.

2015-03-19 Thread Dongsheng Yang
So far, we can account quota number for data and metadata separately,
but in quota resan, we have not implemented this feature. This patch
make the rescan smart to distingush data and metadata and account them
separately.

Signed-off-by: Dongsheng Yang yangds.f...@cn.fujitsu.com
---
 fs/btrfs/qgroup.c | 21 ++---
 1 file changed, 18 insertions(+), 3 deletions(-)

diff --git a/fs/btrfs/qgroup.c b/fs/btrfs/qgroup.c
index 9363fd0..bb98bdd 100644
--- a/fs/btrfs/qgroup.c
+++ b/fs/btrfs/qgroup.c
@@ -2872,6 +2872,8 @@ qgroup_rescan_leaf(struct btrfs_fs_info *fs_info, struct 
btrfs_path *path,
int new_roots;
int slot;
int ret;
+   bool skinny_metadata = btrfs_fs_incompat(fs_info,
+SKINNY_METADATA);
 
path-leave_spinning = 1;
mutex_lock(fs_info-qgroup_rescan_lock);
@@ -2910,14 +2912,27 @@ qgroup_rescan_leaf(struct btrfs_fs_info *fs_info, 
struct btrfs_path *path,
mutex_unlock(fs_info-qgroup_rescan_lock);
 
for (; slot  btrfs_header_nritems(scratch_leaf); ++slot) {
+   u8 quota_type = BTRFS_QGROUP_REF_TYPE_DATA;
+   struct btrfs_extent_item *ei;
+   u64 flags;
+
+   ei = btrfs_item_ptr(scratch_leaf, slot, struct 
btrfs_extent_item);
+   flags = btrfs_extent_flags(scratch_leaf, ei);
+
btrfs_item_key_to_cpu(scratch_leaf, found, slot);
if (found.type != BTRFS_EXTENT_ITEM_KEY 
found.type != BTRFS_METADATA_ITEM_KEY)
continue;
-   if (found.type == BTRFS_METADATA_ITEM_KEY)
+   if (found.type == BTRFS_METADATA_ITEM_KEY) {
num_bytes = fs_info-extent_root-nodesize;
-   else
+   if (btrfs_fs_incompat(fs_info, QGROUP_TYPE))
+   quota_type = BTRFS_QGROUP_REF_TYPE_METADATA;
+   } else {
num_bytes = found.offset;
+   if (!skinny_metadata  (flags  
BTRFS_EXTENT_FLAG_TREE_BLOCK) 
+   btrfs_fs_incompat(fs_info, QGROUP_TYPE))
+   quota_type = BTRFS_QGROUP_REF_TYPE_METADATA;
+   }
 
ulist_reinit(qgroups);
ret = btrfs_find_all_roots(NULL, fs_info, found.objectid, 0,
@@ -2937,7 +2952,7 @@ qgroup_rescan_leaf(struct btrfs_fs_info *fs_info, struct 
btrfs_path *path,
goto out;
}
 
-   ret = qgroup_adjust_counters(fs_info, 0, num_bytes, 0, qgroups,
+   ret = qgroup_adjust_counters(fs_info, 0, num_bytes, quota_type, 
qgroups,
 seq, 0, new_roots, 1);
if (ret  0) {
spin_unlock(fs_info-qgroup_lock);
-- 
1.8.4.2

--
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


[PATCH 2/7] Btrfs: qgroup: add incompatability feature for QGROUP_TYPE.

2015-03-19 Thread Dongsheng Yang
As we need to change the structure in disk for qgroup, we have
to introduce a incompatability feature for it.

  

|0 |BTRFS_QGROUP_INFO_KEY |qgroupid| |TYPE_OBJECTID 
|BTRFS_QGROUP_INFO_KEY |qgroupid|
  


similar for the limits.

Signed-off-by: Dongsheng Yang yangds.f...@cn.fujitsu.com
---
 fs/btrfs/ctree.h  | 20 ++-
 fs/btrfs/qgroup.c | 77 +++
 2 files changed, 91 insertions(+), 6 deletions(-)

diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
index f00eacd..d029119 100644
--- a/fs/btrfs/ctree.h
+++ b/fs/btrfs/ctree.h
@@ -150,6 +150,22 @@ struct btrfs_ordered_sum;
 #define BTRFS_DEV_REPLACE_DEVID 0ULL
 
 /*
+ * the items for qgroup info.
+ */
+#define BTRFS_QGROUP_DATA_INFO_OBJECTID 1ULL
+
+#define BTRFS_QGROUP_METADATA_INFO_OBJECTID 2ULL
+
+/*
+ * the items for qgroup limits.
+ */
+#define BTRFS_QGROUP_DATA_LIMIT_OBJECTID 1ULL
+
+#define BTRFS_QGROUP_METADATA_LIMIT_OBJECTID 2ULL
+
+#define BTRFS_QGROUP_MIXED_LIMIT_OBJECTID 3ULL
+
+/*
  * the max metadata block size.  This limit is somewhat artificial,
  * but the memmove costs go through the roof for larger blocks.
  */
@@ -522,6 +538,7 @@ struct btrfs_super_block {
 #define BTRFS_FEATURE_INCOMPAT_RAID56  (1ULL  7)
 #define BTRFS_FEATURE_INCOMPAT_SKINNY_METADATA (1ULL  8)
 #define BTRFS_FEATURE_INCOMPAT_NO_HOLES(1ULL  9)
+#define BTRFS_FEATURE_INCOMPAT_QGROUP_TYPE (1ULL  10)
 
 #define BTRFS_FEATURE_COMPAT_SUPP  0ULL
 #define BTRFS_FEATURE_COMPAT_SAFE_SET  0ULL
@@ -539,7 +556,8 @@ struct btrfs_super_block {
 BTRFS_FEATURE_INCOMPAT_RAID56 |\
 BTRFS_FEATURE_INCOMPAT_EXTENDED_IREF | \
 BTRFS_FEATURE_INCOMPAT_SKINNY_METADATA |   \
-BTRFS_FEATURE_INCOMPAT_NO_HOLES)
+BTRFS_FEATURE_INCOMPAT_NO_HOLES |  \
+BTRFS_FEATURE_INCOMPAT_QGROUP_TYPE)
 
 #define BTRFS_FEATURE_INCOMPAT_SAFE_SET\
(BTRFS_FEATURE_INCOMPAT_EXTENDED_IREF)
diff --git a/fs/btrfs/qgroup.c b/fs/btrfs/qgroup.c
index dd99908..34eb4f5 100644
--- a/fs/btrfs/qgroup.c
+++ b/fs/btrfs/qgroup.c
@@ -372,7 +372,19 @@ int btrfs_read_qgroup_config(struct btrfs_fs_info *fs_info)
struct btrfs_qgroup_info_item *ptr;
struct btrfs_qgroup_info *info;
 
-   info = qgroup-data_info;
+   /*
+* In newer qgroup, we store the quota data in
+* different info_items.
+*/
+   if (!btrfs_fs_incompat(fs_info, QGROUP_TYPE)) {
+   info = qgroup-data_info;
+   } else {
+   if (found_key.objectid == 
BTRFS_QGROUP_DATA_INFO_OBJECTID)
+   info = qgroup-data_info;
+   else
+   info = qgroup-metadata_info;
+   }
+
ptr = btrfs_item_ptr(l, slot,
 struct btrfs_qgroup_info_item);
info-rfer = btrfs_qgroup_info_rfer(l, ptr);
@@ -386,7 +398,17 @@ int btrfs_read_qgroup_config(struct btrfs_fs_info *fs_info)
struct btrfs_qgroup_limit_item *ptr;
struct btrfs_qgroup_limits *limits;
 
-   limits = qgroup-mixed_limits;
+   if (!btrfs_fs_incompat(fs_info, QGROUP_TYPE)) {
+   limits = qgroup-mixed_limits;
+   } else {
+   if (found_key.objectid == 
BTRFS_QGROUP_DATA_LIMIT_OBJECTID)
+   limits = qgroup-data_limits;
+   else if (found_key.objectid == 
BTRFS_QGROUP_METADATA_LIMIT_OBJECTID)
+   limits = qgroup-metadata_limits;
+   else
+   limits = qgroup-mixed_limits;
+   }
+
ptr = btrfs_item_ptr(l, slot,
 struct btrfs_qgroup_limit_item);
limits-lim_flags = btrfs_qgroup_limit_flags(l, ptr);
@@ -563,7 +585,10 @@ static int add_qgroup_item(struct btrfs_trans_handle 
*trans,
if (!path)
return -ENOMEM;
 
-   key.objectid = 0;
+   if (!btrfs_fs_incompat(quota_root-fs_info, QGROUP_TYPE))
+   key.objectid = 0;
+   else
+   key.objectid = BTRFS_QGROUP_DATA_INFO_OBJECTID;
key.type = BTRFS_QGROUP_INFO_KEY;
key.offset = qgroupid;
 
@@ -573,6 +598,7 @@ static int

[PATCH 2/4] Btrfs-progs: qgroup: print info and limits type in btrfs-debug-tree.

2015-03-19 Thread Dongsheng Yang
We have restructured the btrfs_qgroup, and we are using
objectid for btrfs_qgroup_info_item now. Then we need to
print the objectid in btrfs-debug-tree.

Signed-off-by: Dongsheng Yang yangds.f...@cn.fujitsu.com
---
 print-tree.c | 16 
 1 file changed, 16 insertions(+)

diff --git a/print-tree.c b/print-tree.c
index 3a7c13c..7cb9563 100644
--- a/print-tree.c
+++ b/print-tree.c
@@ -644,6 +644,22 @@ static void print_objectid(u64 objectid, u8 type)
printf(%llu/%llu, objectid  48,
objectid  ((1ll  48) - 1));
return;
+   case BTRFS_QGROUP_INFO_KEY:
+   if (objectid == 0)
+   printf(MIXED);
+   else if (objectid == BTRFS_QGROUP_DATA_INFO_OBJECTID)
+   printf(DATA);
+   else
+   printf(METADATA);
+   return;
+   case BTRFS_QGROUP_LIMIT_KEY:
+   if (objectid == BTRFS_QGROUP_DATA_LIMIT_OBJECTID)
+   printf(DATA);
+   else if (objectid == BTRFS_QGROUP_METADATA_LIMIT_OBJECTID)
+   printf(METADATA);
+   else
+   printf(MIXED);
+   return;
case BTRFS_UUID_KEY_SUBVOL:
case BTRFS_UUID_KEY_RECEIVED_SUBVOL:
printf(0x%016llx, (unsigned long long)objectid);
-- 
1.8.4.2

--
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


[PATCH 3/4] Btrfs-progs: qgroup: add a opt for type of qgroup limit.

2015-03-19 Thread Dongsheng Yang
This patch add a support for user to limit the data, metadata,
or mixed of a qgroup. Even you can set these three limits at
one time for a qgroup.

Signed-off-by: Dongsheng Yang yangds.f...@cn.fujitsu.com
---
 cmds-qgroup.c | 48 +++-
 ioctl.h   | 13 +
 2 files changed, 60 insertions(+), 1 deletion(-)

diff --git a/cmds-qgroup.c b/cmds-qgroup.c
index c5082f7..1c42fc8 100644
--- a/cmds-qgroup.c
+++ b/cmds-qgroup.c
@@ -367,14 +367,46 @@ static const char * const cmd_qgroup_limit_usage[] = {
-c   limit amount of data after compression. This is the default,,
 it is currently not possible to turn off this option.,
-e   limit space exclusively assigned to this qgroup,
+   -t   limit space for data, metadata or mixed,
NULL
 };
 
+inline u8 get_limit_type(u64 flag)
+{
+   return (flag  BTRFS_QGROUP_LIMIT_TYPE_SHIFT);
+}
+
+inline u64 set_limit_type(u64 flag, u8 type)
+{
+   u64 temp = (flag  BTRFS_QGROUP_LIMIT_TYPE_SHIFT);
+
+   temp |= type;
+   flag |= (temp  BTRFS_QGROUP_LIMIT_TYPE_SHIFT);
+
+   return flag;
+}
+
+static int parse_limit_type(u8 *qgroup_type, char *arg)
+{
+   if (strcmp(arg, data) == 0)
+   *qgroup_type = BTRFS_QGROUP_LIMIT_DATA;
+   else if (strcmp(arg, metadata) == 0)
+   *qgroup_type = BTRFS_QGROUP_LIMIT_METADATA;
+   else if (strcmp(arg, mixed) == 0) {
+   *qgroup_type = BTRFS_QGROUP_LIMIT_MIXED;
+   } else {
+   fprintf(stderr, ERROR: Invalid qgroup type arguments given\n);
+   return -EINVAL;
+   }
+   return 0;
+}
+
 static int cmd_qgroup_limit(int argc, char **argv)
 {
int ret = 0;
int fd;
int e;
+   u8 type = BTRFS_QGROUP_LIMIT_MIXED;
char *path = NULL;
struct btrfs_ioctl_qgroup_limit_args args;
unsigned long long size;
@@ -384,7 +416,14 @@ static int cmd_qgroup_limit(int argc, char **argv)
 
optind = 1;
while (1) {
-   int c = getopt(argc, argv, ce);
+   int c;
+   static const struct option long_options[] = {
+   {type, required_argument, NULL, 't'},
+   {NULL, 0, NULL, 0}
+   };
+
+   c = getopt_long(argc, argv, ce,
+   long_options, NULL);
if (c  0)
break;
switch (c) {
@@ -394,6 +433,11 @@ static int cmd_qgroup_limit(int argc, char **argv)
case 'e':
exclusive = 1;
break;
+   case 't':
+   ret = parse_limit_type(type, optarg);
+   if (ret)
+   return -EINVAL;
+   break;
default:
usage(cmd_qgroup_limit_usage);
}
@@ -419,6 +463,8 @@ static int cmd_qgroup_limit(int argc, char **argv)
args.lim.flags |= BTRFS_QGROUP_LIMIT_MAX_RFER;
args.lim.max_referenced = size;
}
+
+   args.lim.flags = set_limit_type(args.lim.flags, type);
}
 
if (argc - optind == 2) {
diff --git a/ioctl.h b/ioctl.h
index d550ca6..a1ebbb5 100644
--- a/ioctl.h
+++ b/ioctl.h
@@ -45,6 +45,19 @@ struct btrfs_ioctl_vol_args {
 
 #define BTRFS_QGROUP_INHERIT_SET_LIMITS(1ULL  0)
 
+/*
+ * As we can account and limit data and metadata in
+ * a qgroup separately. We use the first 8 bits in
+ * btrfs_qgroup_limit-flags to specify the type we
+ * want to limit. Currently, there are three choice:
+ * DATA, METADATA, MIXED.
+ */
+#define BTRFS_QGROUP_LIMIT_TYPE_SHIFT  56
+
+#define BTRFS_QGROUP_LIMIT_DATA1
+#define BTRFS_QGROUP_LIMIT_METADATA2
+#define BTRFS_QGROUP_LIMIT_MIXED   4
+
 struct btrfs_qgroup_limit {
__u64   flags;
__u64   max_referenced;
-- 
1.8.4.2

--
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


[PATCH 1/4] Btrfs-progs: qgroup: add incompatability feature for QGROUP_TYPE.

2015-03-19 Thread Dongsheng Yang
This patch splits info and limits from qgroup.

btrfs_qgroup: |-|
- |rfer |
|data_info  |---btrfs_qgroup_info|rfer_cmpr|
|metadata_info  | |excl |
|   | |excl_cmpr|
|data_limits| ---
|metadata_limits|
|mixed_limits   |---btrfs_qgroup_limits|-
|-- |   |lim_flags  |
|max_rfer   |
|max_excl   |
|rsv_rfer   |
|rsv_excl   |


And the objectid for each items are changed:
  

|0 |BTRFS_QGROUP_INFO_KEY |qgroupid| |TYPE_OBJECTID 
|BTRFS_QGROUP_INFO_KEY |qgroupid|
  


Signed-off-by: Dongsheng Yang yangds.f...@cn.fujitsu.com
---
 ctree.h  |  20 ++-
 mkfs.c   |   2 +
 qgroup.c | 184 +++
 3 files changed, 147 insertions(+), 59 deletions(-)

diff --git a/ctree.h b/ctree.h
index 2d2988b..85d4992 100644
--- a/ctree.h
+++ b/ctree.h
@@ -125,6 +125,22 @@ struct btrfs_free_space_ctl;
 #define BTRFS_DEV_ITEMS_OBJECTID 1ULL
 
 /*
+ *  * the items for qgroup info.
+ *   */
+#define BTRFS_QGROUP_DATA_INFO_OBJECTID 1ULL
+
+#define BTRFS_QGROUP_METADATA_INFO_OBJECTID 2ULL
+
+/*
+ *  * the items for qgroup limits.
+ *   */
+#define BTRFS_QGROUP_DATA_LIMIT_OBJECTID 1ULL
+
+#define BTRFS_QGROUP_METADATA_LIMIT_OBJECTID 2ULL
+
+#define BTRFS_QGROUP_MIXED_LIMIT_OBJECTID 3ULL
+
+/*
  * the max metadata block size.  This limit is somewhat artificial,
  * but the memmove costs go through the roof for larger blocks.
  */
@@ -473,6 +489,7 @@ struct btrfs_super_block {
 #define BTRFS_FEATURE_INCOMPAT_RAID56  (1ULL  7)
 #define BTRFS_FEATURE_INCOMPAT_SKINNY_METADATA (1ULL  8)
 #define BTRFS_FEATURE_INCOMPAT_NO_HOLES(1ULL  9)
+#define BTRFS_FEATURE_INCOMPAT_QGROUP_TYPE (1ULL  10)
 
 
 #define BTRFS_FEATURE_COMPAT_SUPP  0ULL
@@ -486,7 +503,8 @@ struct btrfs_super_block {
 BTRFS_FEATURE_INCOMPAT_RAID56 |\
 BTRFS_FEATURE_INCOMPAT_MIXED_GROUPS |  \
 BTRFS_FEATURE_INCOMPAT_SKINNY_METADATA |   \
-BTRFS_FEATURE_INCOMPAT_NO_HOLES)
+BTRFS_FEATURE_INCOMPAT_NO_HOLES |  \
+BTRFS_FEATURE_INCOMPAT_QGROUP_TYPE)
 
 /*
  * A leaf is full of items. offset and size tell us where to find
diff --git a/mkfs.c b/mkfs.c
index f83554d..de7612b 100644
--- a/mkfs.c
+++ b/mkfs.c
@@ -1143,6 +1143,8 @@ static const struct btrfs_fs_feature {
reduced-size metadata extent refs },
{ no-holes, BTRFS_FEATURE_INCOMPAT_NO_HOLES,
no explicit hole extents for files },
+   { qgroup-type, BTRFS_FEATURE_INCOMPAT_QGROUP_TYPE,
+   account data and metadata separately },
/* Keep this one last */
{ list-all, BTRFS_FEATURE_LIST_ALL, NULL }
 };
diff --git a/qgroup.c b/qgroup.c
index 5a4e393..91e25ea 100644
--- a/qgroup.c
+++ b/qgroup.c
@@ -30,6 +30,26 @@ struct qgroup_lookup {
struct rb_root root;
 };
 
+struct btrfs_qgroup_info {
+u64 rfer;   /* referenced */
+u64 rfer_cmpr;  /* referenced compressed */
+u64 excl;   /* exclusive */
+u64 excl_cmpr;  /* exclusive compressed */
+
+/*
+* reservation tracking
+*/
+u64 reserved;
+};
+
+struct btrfs_qgroup_limits {
+u64 flags;  /* which limits are set */
+u64 max_rfer;
+u64 max_excl;
+u64 rsv_rfer;
+u64 rsv_excl;
+};
+
 struct btrfs_qgroup {
struct rb_node rb_node;
struct rb_node sort_node;
@@ -40,23 +60,20 @@ struct btrfs_qgroup {
struct rb_node all_parent_node;
u64 qgroupid;
 
+   u64 generation;
+
/*
 * info_item
 */
-   u64 generation;
-   u64 rfer;   /*referenced*/
-   u64 rfer_cmpr;  /*referenced compressed*/
-   u64 excl;   /*exclusive*/
-   u64 excl_cmpr;  /*exclusive compressed*/
+   struct btrfs_qgroup_infodata_info;
+   struct btrfs_qgroup_infometadata_info;
 
/*
 *limit_item
 */
-   u64 flags;  /*which limits are set*/
-   u64 max_rfer;
-   u64 max_excl;
-   u64 rsv_rfer;
-   u64 rsv_excl;
+   struct btrfs_qgroup_limits  data_limits

Re: [PATCH 3/3] btrfs: qgroup: fix a wrong parameter of no_quota.

2015-03-17 Thread Dongsheng Yang
Okey, I found a patch from Mark 35 weeks ago which was not merged into xfstest:

[PATCH] xfstests/btrfs: add test for quota groups and drop snapshot

It looks can answer my question here.

Thanx
Yang

On Mon, Mar 16, 2015 at 12:59 PM, Dongsheng Yang
yangds.f...@cn.fujitsu.com wrote:
 On 03/04/2015 04:20 AM, Mark Fasheh wrote:

 On Tue, Mar 03, 2015 at 09:00:36AM -0500, Josef Bacik wrote:

 On 03/03/2015 06:18 AM, Dongsheng Yang wrote:

 On 02/26/2015 02:05 PM, Dongsheng Yang wrote:

 Wait a minute, this patch seems not working well in accounting quota
 number when
 deleting data shared by different subvolumes.

 I will investigate more about it and send a V2 out.

 I have sent a fstest
[PATCH] fstest: btrfs: add a test for quota number when deleting a
 subvol.
 for this problem I was trying to solve in this patch.

 Please consider reverting the two commits introduced the problem:

 e339a6b0 (Btrfs: __btrfs_mod_ref should always use no_quota)
 1152651a (btrfs: qgroup: account shared subtrees during snapshot delete)

 We aren't reverting these two commits, what we had was worse before than
 it
 is now.  We need to figure out why this is resulting in problems and fix
 that rather than throwing out a whole bunch of work.  Thanks,

 Agreed, reverting these would re-introduce far more problems than it would
 solve.


 Hi Josef and Mark,

 Sorry for the late.

 Thanx for your reply and sorry I am not clear about the far more problems.

 From the result below, I saw there are some diff reports in V4.0-rc1 and
 when I
 revert these two commits. It's consistent now.

 But I think there must be something I am missing.  I am glad to investigate
 more
 about it and solve it. But at first I need to know what's the problem
 SUBTREE is
 trying to solve.

 Example:
 mkfs.btrfs  /dev/sdc -f
 mount /dev/sdc /mnt
 btrfs quota enable /mnt
 btrfs sub create /mnt/sub
 dd if=/dev/zero of=/mnt/sub/data bs=1024 count=1000
 btrfs sub snapshot /mnt/sub /mnt/snap
 btrfs qgroup create 1/1 /mnt
 btrfs qgroup assign 0/257 1/1 /mnt
 btrfs quota rescan -w /mnt
 sync
 btrfs sub delete /mnt/sub
 ---  -wait for cleaner_kthread.
 btrfs qgroup show /mnt
 umount /mnt
 btrfs check --qgroup-report /dev/sdc |grep diff

 Result:
 (1). V4.0-rc1
 # btrfs qgroup show /mnt
 qgroupid rfer excl
   
 0/5  16.00KiB 16.00KiB
 0/257  1000.00KiB0.00B
 0/258  1016.00KiB   1016.00KiB
 1/11000.00KiB0.00B
 # btrfs check --qgroup-report /dev/sdc |grep diff
 Counts for qgroup id: 257 are different
 diff:referenced -1024000 referenced compressed -1024000
 Counts for qgroup id: 281474976710657 are different
 diff:referenced -1024000 referenced compressed -1024000

 (2). V4.0-rc1 with reverts of 96c92f and c04cad
 # btrfs qgroup show /mnt
 qgroupid rfer excl
   
 0/5  16.00KiB 16.00KiB
 0/257   0.00B0.00B
 0/258  1016.00KiB   1016.00KiB
 1/1 0.00B0.00B
 # btrfs check --qgroup-report /dev/sdc |grep diff
 #
 *No diff in btrfs check --qgroup-report*


 Thanx

 --Mark

 --
 Mark Fasheh
 .


 --
 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
--
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: [RFC PATCH 0/7] Btrfs: qgroup: part-4: Add type to btrfs qgroup.

2015-03-17 Thread Dongsheng Yang

Hi all,
I am cooking a V2 for this patchset, it will make user to limit 
data, metadata or mixed of a qgroup.
Even, you can limit all of the three quota number at one time. I believe 
it's much better.


Thanx.

On 02/10/2015 06:24 PM, Dongsheng Yang wrote:

Hi all,
This patchset is based on [Btrfs: qgroup: part-3: bug fixes.]

I am introducing a type to qgroup, then we can get the numbers what we
only care about.

Easy way to get the code for testing:
btrfs: https://yangdongsh...@github.com/yangdongsheng/linux.git 
qgroup_type
   btrfs-progs: https://yangdongsh...@github.com/yangdongsheng/btrfs-progs.git 
qgroup_type
with the patches applied in this series, both in btrfs and btrfs-progs:

[root@atest-guest linux_btrfs]# mkfs.btrfs -O qgroup-type /dev/sdc -f
Btrfs v3.18-76-ga900a61
See http://btrfs.wiki.kernel.org for more information.

Turning ON incompat feature 'extref': increased hardlink limit per file to 65536
Turning ON incompat feature 'skinny-metadata': reduced-size metadata extent refs
Turning ON incompat feature 'qgroup-type': create qgroup in different type
fs created label (null) on /dev/sdc
nodesize 16384 leafsize 16384 sectorsize 4096 size 10.00GiB
[root@atest-guest linux_btrfs]# mount /dev/sdc  /mnt/
[root@atest-guest linux_btrfs]# btrfs quota enable /mnt
[root@atest-guest linux_btrfs]# btrfs qgroup show -prce /mnt
qgroupid rfer excl max_rfer max_excl parent  child type
     --  - 
0/5  16.00KiB 16.00KiB0.00B0.00B --- ---   
metadata,data
[root@atest-guest linux_btrfs]# btrfs qgroup show -prce /mnt
qgroupid rfer excl max_rfer max_excl parent  child type
     --  - 
0/5  16.00KiB 16.00KiB0.00B0.00B --- ---   
metadata,data
0/25716.00KiB 16.00KiB0.00B0.00B --- ---   
metadata,data --- default type is mixed.
[root@atest-guest linux_btrfs]# btrfs sub create --qgroup-type data /mnt/sub1
Create subvolume '/mnt/sub1'
Set qgroup arguments:
qgroup type: data
[root@atest-guest linux_btrfs]# btrfs qgroup show -prce /mnt
qgroupid rfer excl max_rfer max_excl parent  child type
     --  - 
0/5  16.00KiB 16.00KiB0.00B0.00B --- ---   
metadata,data
0/25716.00KiB 16.00KiB0.00B0.00B --- ---   
metadata,data
0/258   0.00B0.00B0.00B0.00B --- ---   data
  --- create a data qgroup
[root@atest-guest linux_btrfs]# btrfs qgroup limit -e 5M 0/258 /mnt
[root@atest-guest linux_btrfs]# btrfs qgroup show -prce /mnt
qgroupid rfer excl max_rfer max_excl parent  child type
     --  - 
0/5  16.00KiB 16.00KiB0.00B0.00B --- ---   
metadata,data
0/25716.00KiB 16.00KiB0.00B0.00B --- ---   
metadata,data
0/258   0.00B0.00B0.00B  5.00MiB --- ---   data
[root@atest-guest linux_btrfs]# dd if=/dev/zero of=/mnt/sub1/data bs=1024
dd: error writing \u2018/mnt/sub1/data\u2019: Disk quota exceeded
5121+0 records in
5120+0 records out
5242880 bytes (5.2 MB) copied, 0.0218646 s, 240 MB/s
[root@atest-guest linux_btrfs]# sync
[root@atest-guest linux_btrfs]# ll /mnt/sub1/data
-rw-r--r--. 1 root root 5242880 Feb 10 16:17 /mnt/sub1/data
[root@atest-guest linux_btrfs]# btrfs qgroup show -prce --raw /mnt
qgroupid rfer excl max_rfer max_excl parent  child type
     --  - 
0/5 163841638400 --- ---   
metadata,data
0/257   163841638400 --- ---   
metadata,data
0/258 5242880  52428800  5242880 --- ---   data
 --- excl == max_excl == data_size == 5M == 5242880

Dongsheng Yang (7):
   Btrfs: qgroup: Add type to btrfs_qgroup.
   btrfs: qgroup: apply type to the recording and accounting.
   btrfs: qgroup: Apply type to btrfs_qgroup_inherit().
   btrfs: qgroup: Apply qgroup type to qgroup creating.
   btrfs: qgroup: Apply qgroup type to subvol creating.
   btrfs: qgroup: apply type to quota rescan.
   btrfs: qgroup: fix a bug when type of parent is different with
 child's.

  fs/btrfs/ctree.h  |  10 ++-
  fs/btrfs/extent-tree.c|  48 ++-
  fs/btrfs/ioctl.c  |  49 ---
  fs/btrfs/qgroup.c | 186 --
  fs/btrfs/qgroup.h |  29 ++-
  fs/btrfs/tests/qgroup-tests.c |  19 +++--
  fs/btrfs/transaction.c|  13 +--
  include/uapi

[PATCH v2] fstest: btrfs: add a test for quota number when deleting a subvol.

2015-03-16 Thread Dongsheng Yang
This regression is introduced by two commits:

e339a6b0 (Btrfs: __btrfs_mod_ref should always use no_quota)
1152651a (btrfs: qgroup: account shared subtrees during snapshot delete)

Signed-off-by: Dongsheng Yang yangds.f...@cn.fujitsu.com
---
changlog:
v1:
1. Fix lots of coding style problems pointed by Eryu.
2. Add more description for the regression.

 tests/btrfs/083 | 118 
 tests/btrfs/083.out |   3 ++
 tests/btrfs/group   |   1 +
 3 files changed, 122 insertions(+)
 create mode 100755 tests/btrfs/083
 create mode 100644 tests/btrfs/083.out

diff --git a/tests/btrfs/083 b/tests/btrfs/083
new file mode 100755
index 000..a5e85e3
--- /dev/null
+++ b/tests/btrfs/083
@@ -0,0 +1,118 @@
+#! /bin/bash
+# FS QA Test No. 083
+#
+# This is a case for the regression introduced by
+#
+# e339a6b0 (Btrfs: __btrfs_mod_ref should always use no_quota)
+# 1152651a (btrfs: qgroup: account shared subtrees during snapshot delete)
+#
+# The problem is shown as below:
+#  $ btrfs sub create /mnt/sub
+#  Create subvolume '/mnt/sub'
+#  $ fallocate -l 1M /mnt/sub/data
+#  $ btrfs quota enable /mnt
+#  $ sync
+#  $ btrfs qgroup show --raw /mnt
+#  qgroupid rfer excl
+#    
+#  0/5 1638416384
+#  0/257 1064960  1064960
+#  $ btrfs sub dele /mnt/sub
+#  Delete subvolume (no-commit): '/mnt/sub'
+#
+#  ... ... Wait for the 
cleaner_kthread, about 30s.
+#  $ btrfs qgroup show --raw /mnt
+#  qgroupid rfer excl
+#    
+#  0/5 1638416384
+#  0/257 1048576  1048576  ---sub 0/257 is 
deleted, but the quota numbers are not 0.
+#
+#
+# What we are expecting is:
+#  $ btrfs qgroup show --raw /mnt
+#  $ qgroupid rfer excl
+#    
+#  0/5 1638416384
+#  0/257   00
+#
+# Currently, just revert these two commits mentioned above, we
+# can get the expected result. But there are some more things
+# we need to consider.
+#
+#---
+# Copyright (c) 2015 Fujitsu.  All Rights Reserved.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it would be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write the Free Software Foundation,
+# Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+#---
+#
+
+seq=`basename $0`
+seqres=$RESULT_DIR/$seq
+echo QA output created by $seq
+
+here=`pwd`
+tmp=/tmp/$$
+status=1   # failure is the default!
+trap _cleanup; exit \$status 0 1 2 3 15
+
+_cleanup()
+{
+   cd /
+   rm -f $tmp.*
+}
+
+# get standard environment, filters and checks
+. ./common/rc
+. ./common/filter
+
+# real QA test starts here
+_need_to_be_root
+_supported_fs btrfs
+_supported_os Linux
+_require_scratch
+
+rm -f $seqres.full
+
+_scratch_mkfs $seqres.full 21
+_scratch_mount
+
+$XFS_IO_PROG -f -d -c pwrite 0 8K $SCRATCH_MNT/foo 21  /dev/null
+
+_run_btrfs_util_prog subvolume snapshot $SCRATCH_MNT $SCRATCH_MNT/snap
+
+_run_btrfs_util_prog quota enable $SCRATCH_MNT
+_run_btrfs_util_prog quota rescan -w $SCRATCH_MNT
+
+units=`_btrfs_qgroup_units`
+orig_result=`$BTRFS_UTIL_PROG qgroup show $units $SCRATCH_MNT | $AWK_PROG 
'NR==NF {print $3}'`
+
+_run_btrfs_util_prog subvolume delete $SCRATCH_MNT/snap
+
+_run_btrfs_util_prog filesystem sync $SCRATCH_MNT
+
+timeout=100
+# There is a background thread doing the clean work
+for ((i=0; i$timeout; i++)); do
+   result=`$BTRFS_UTIL_PROG qgroup show $units $SCRATCH_MNT | $AWK_PROG 
'NR==NF {print $3}'`
+   if (($orig_result != $result)); then
+   break
+   fi
+   sleep 1
+done
+
+$BTRFS_UTIL_PROG qgroup show $units $SCRATCH_MNT | $AWK_PROG '/[0-9]/ {print 
$2 $3}'
+
+# success, all done
+status=0
+exit
diff --git a/tests/btrfs/083.out b/tests/btrfs/083.out
new file mode 100644
index 000..e73797e
--- /dev/null
+++ b/tests/btrfs/083.out
@@ -0,0 +1,3 @@
+QA output created by 083
+24576 24576
+0 0
diff --git a/tests/btrfs/group b/tests/btrfs/group
index fd2fa76..e98a154 100644
--- a/tests/btrfs/group
+++ b/tests/btrfs/group
@@ -85,3 +85,4 @@
 080 auto snapshot
 081 auto quick clone
 082 auto quick remount
+083 auto qgroup
-- 
1.8.4.2

Re: [PATCH 3/3] btrfs: qgroup: fix a wrong parameter of no_quota.

2015-03-15 Thread Dongsheng Yang

On 03/04/2015 04:20 AM, Mark Fasheh wrote:

On Tue, Mar 03, 2015 at 09:00:36AM -0500, Josef Bacik wrote:

On 03/03/2015 06:18 AM, Dongsheng Yang wrote:

On 02/26/2015 02:05 PM, Dongsheng Yang wrote:

Wait a minute, this patch seems not working well in accounting quota
number when
deleting data shared by different subvolumes.

I will investigate more about it and send a V2 out.

I have sent a fstest
   [PATCH] fstest: btrfs: add a test for quota number when deleting a
subvol.
for this problem I was trying to solve in this patch.

Please consider reverting the two commits introduced the problem:

e339a6b0 (Btrfs: __btrfs_mod_ref should always use no_quota)
1152651a (btrfs: qgroup: account shared subtrees during snapshot delete)


We aren't reverting these two commits, what we had was worse before than it
is now.  We need to figure out why this is resulting in problems and fix
that rather than throwing out a whole bunch of work.  Thanks,

Agreed, reverting these would re-introduce far more problems than it would
solve.


Hi Josef and Mark,

Sorry for the late.

Thanx for your reply and sorry I am not clear about the far more 
problems.


From the result below, I saw there are some diff reports in V4.0-rc1 
and when I

revert these two commits. It's consistent now.

But I think there must be something I am missing.  I am glad to 
investigate more
about it and solve it. But at first I need to know what's the problem 
SUBTREE is

trying to solve.

Example:
mkfs.btrfs  /dev/sdc -f
mount /dev/sdc /mnt
btrfs quota enable /mnt
btrfs sub create /mnt/sub
dd if=/dev/zero of=/mnt/sub/data bs=1024 count=1000
btrfs sub snapshot /mnt/sub /mnt/snap
btrfs qgroup create 1/1 /mnt
btrfs qgroup assign 0/257 1/1 /mnt
btrfs quota rescan -w /mnt
sync
btrfs sub delete /mnt/sub
---  -wait for cleaner_kthread.
btrfs qgroup show /mnt
umount /mnt
btrfs check --qgroup-report /dev/sdc |grep diff

Result:
(1). V4.0-rc1
# btrfs qgroup show /mnt
qgroupid rfer excl
  
0/5  16.00KiB 16.00KiB
0/257  1000.00KiB0.00B
0/258  1016.00KiB   1016.00KiB
1/11000.00KiB0.00B
# btrfs check --qgroup-report /dev/sdc |grep diff
Counts for qgroup id: 257 are different
diff:referenced -1024000 referenced compressed -1024000
Counts for qgroup id: 281474976710657 are different
diff:referenced -1024000 referenced compressed -1024000

(2). V4.0-rc1 with reverts of 96c92f and c04cad
# btrfs qgroup show /mnt
qgroupid rfer excl
  
0/5  16.00KiB 16.00KiB
0/257   0.00B0.00B
0/258  1016.00KiB   1016.00KiB
1/1 0.00B0.00B
# btrfs check --qgroup-report /dev/sdc |grep diff
#
*No diff in btrfs check --qgroup-report*


Thanx

--Mark

--
Mark Fasheh
.



--
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] fstest: btrfs: add a test for quota number when deleting a subvol.

2015-03-15 Thread Dongsheng Yang

Hi Guan,  sorry for the late.

On 03/06/2015 01:06 PM, Eryu Guan wrote:

On Tue, Mar 03, 2015 at 07:13:30PM +0800, Dongsheng Yang wrote:

This regression is introduced by two commits:

e339a6b0 (Btrfs: __btrfs_mod_ref should always use no_quota)
1152651a (btrfs: qgroup: account shared subtrees during snapshot delete)

I think you should add more description about the issue you're going to
test. I see only failures like

[root@dhcp-66-86-11 xfstests]# diff -u tests/btrfs/084.out 
/root/xfstests/results//btrfs/084.out.bad
--- tests/btrfs/084.out 2015-03-06 12:47:02.31900 +0800
+++ /root/xfstests/results//btrfs/084.out.bad   2015-03-06
12:48:03.70700 +0800
@@ -1,3 +1,3 @@
  QA output created by 084
  24576 24576
-0 0
+8192 0

but from the test I don't know why 8192 0 is expected result not 0 0


Sure, I will add more description in V2 to explain why we are expecting 
0 0 here.



Signed-off-by: Dongsheng Yang yangds.f...@cn.fujitsu.com
---
  tests/btrfs/084 | 84 +
  tests/btrfs/084.out |  3 ++
  tests/btrfs/group   |  1 +
  3 files changed, 88 insertions(+)
  create mode 100755 tests/btrfs/084
  create mode 100644 tests/btrfs/084.out

diff --git a/tests/btrfs/084 b/tests/btrfs/084
new file mode 100755
index 000..7b7c7ac
--- /dev/null
+++ b/tests/btrfs/084
@@ -0,0 +1,84 @@
+#! /bin/bash
+# FS QA Test No. 084
+#
+# This is a case for the regression introduced by
+#
+# e339a6b0 (Btrfs: __btrfs_mod_ref should always use no_quota)
+# 1152651a (btrfs: qgroup: account shared subtrees during snapshot delete)
+#
+#---
+# Copyright (c) 2015 Fujitsu.  All Rights Reserved.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it would be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write the Free Software Foundation,
+# Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+#---
+#
+
+seq=`basename $0`
+seqres=$RESULT_DIR/$seq
+echo QA output created by $seq
+
+here=`pwd`
+tmp=/tmp/$$
+status=1   # failure is the default!
+trap _cleanup; exit \$status 0 1 2 3 15
+
+_cleanup()
+{
+cd /
+rm -f $tmp.*

Better to use a tab not 4 spaces, maybe new should be updated too (in
another patch)


Thanx, will send another patch for ./new.



+}
+
+# get standard environment, filters and checks
+. ./common/rc
+. ./common/filter
+
+# real QA test starts here
+_need_to_be_root
+_supported_fs btrfs
+_supported_os Linux
+_require_scratch
+
+_scratch_mount

_scratch_mkfs first before you mount it.

And you need to remove $seqres.full before test, since you called
_run_btrfs_util_prog and it will dump commands and outputs to
$seqres.full, the file will keep growing over runs if you don't remove
it first.

rm -f $seqres.full


Great! thanx for your review.



+
+$XFS_IO_PROG -f -d -c pwrite 0 8K $SCRATCH_MNT/foo 21  /dev/null
+
+_run_btrfs_util_prog subvolume snapshot $SCRATCH_MNT $SCRATCH_MNT/snap
+
+_run_btrfs_util_prog quota enable $SCRATCH_MNT
+_run_btrfs_util_prog quota rescan -w $SCRATCH_MNT
+
+units=`_btrfs_qgroup_units`
+orig_result=`$BTRFS_UTIL_PROG qgroup show $units $SCRATCH_MNT | $AWK_PROG 
'NR==NF {print $3}'`
+
+_run_btrfs_util_prog subvolume delete $SCRATCH_MNT/snap
+
+_run_btrfs_util_prog filesystem sync $SCRATCH_MNT
+
+timeout=100
+# There is a background thread doing the clean work
+for ((i=0; i$timeout; i++))
+do
+   result=`$BTRFS_UTIL_PROG qgroup show $units $SCRATCH_MNT | $AWK_PROG 
'NR==NF {print $3}'`
+   if (($orig_result != $result))
+   then
+   break
+   fi
+   sleep 1

I'm not sure if we need 100 iterations and sleeping 1 sec after each
iteration, that means we need 100s for a PASS run.


The 100sec is the limit for the loop, it means if the clean work is done 
in 100sec, we will

break immediately. We don't have to wait for 100s in each test.



+done

Please follow this code style, as Dave pointed before

for ; do
# code
done

if ; then
# code
fi


Great,

+
+$BTRFS_UTIL_PROG qgroup show $units $SCRATCH_MNT | $AWK_PROG '/[0-9]/ {print $2 
$3}'
+
+# success, all done
+status=0
+exit
diff --git a/tests/btrfs/084.out b/tests/btrfs/084.out
new file mode 100644
index 000..7bf6dbf
--- /dev/null
+++ b/tests/btrfs/084.out
@@ -0,0 +1,3 @@
+QA output created by 084
+24576 24576
+0 0
diff --git a/tests/btrfs/group b/tests/btrfs/group
index fe82a9c..1be7392 100644
--- a/tests/btrfs/group
+++ b/tests/btrfs/group
@@ -86,3 +86,4

Re: [PATCH] fstest: btrfs: add a test for quota number when deleting a subvol.

2015-03-15 Thread Dongsheng Yang

On 03/16/2015 01:33 PM, Eryu Guan wrote:

On Mon, Mar 16, 2015 at 01:06:52PM +0800, Dongsheng Yang wrote:

Hi Guan,  sorry for the late.

On 03/06/2015 01:06 PM, Eryu Guan wrote:

On Tue, Mar 03, 2015 at 07:13:30PM +0800, Dongsheng Yang wrote:

This regression is introduced by two commits:

e339a6b0 (Btrfs: __btrfs_mod_ref should always use no_quota)
1152651a (btrfs: qgroup: account shared subtrees during snapshot delete)

[snip]


+_cleanup()
+{
+cd /
+rm -f $tmp.*

Better to use a tab not 4 spaces, maybe new should be updated too (in
another patch)

Thanx, will send another patch for ./new.

Just FYI, I've already sent out the fix, please see

http://www.spinics.net/lists/fstests/msg01073.html
Great!! Thanx for your information. But I found some other 4 spaces in 
new, I am not sure

whether we also need to replace them with tab or not as shown below.

Thanx

commit 931340c0c5599ae2c6714df16c796ea24240a5a7
Author: Dongsheng Yang yangds.f...@cn.fujitsu.com
Date:   Mon Mar 16 01:15:53 2015 -0400

new: replace 4 spaces with a tab.

Sugguested-by: Eryu Guan eg...@redhat.com
Signed-off-by: Dongsheng Yang yangds.f...@cn.fujitsu.com

diff --git a/new b/new
index 86f9075..f94daed 100755
--- a/new
+++ b/new
@@ -29,15 +29,15 @@ trap rm -f /tmp/$$.; exit 0 1 2 3 15

 _cleanup()
 {
-:
+   :
 }

 SRC_GROUPS=`find tests -not -path tests -type d -printf %f `
 usage()
 {
-echo Usage $0 test_dir
-echo Available dirs are: $SRC_GROUPS
-exit
+   echo Usage $0 test_dir
+   echo Available dirs are: $SRC_GROUPS
+   exit
 }

 [ $# -eq 0 ]  usage
@@ -46,8 +46,8 @@ shift

 if [ ! -f $tdir/group ]
 then
-echo Creating the $tdir/group index ...
-cat 'End-of-File' $tdir/group
+   echo Creating the $tdir/group index ...
+   cat 'End-of-File' $tdir/group
 # QA groups control
 #
 # define groups and default group owners
@@ -65,15 +65,15 @@ fi

 if [ ! -w $tdir/group ]
 then
-chmod u+w $tdir/group
-echo Warning: making the index file \$tdir/group\ writeable
+   chmod u+w $tdir/group
+   echo Warning: making the index file \$tdir/group\ writeable
 fi

 if make
 then
-:
+   :
 else
-echo Warning: make failed -- some tests may be missing
+   echo Warning: make failed -- some tests may be missing
 fi

 i=0
@@ -83,16 +83,16 @@ eof=1

 for found in `cat $tdir/group | $AWK_PROG '{ print $1 }'`
 do
-line=$((line+1))
-if [ -z $found ] || [ $found == # ];then
+   line=$((line+1))
+   if [ -z $found ] || [ $found == # ];then
continue
-fi
-i=$((i+1))
-id=`printf %03d $i`
-if [ $id != $found ];then
+   fi
+   i=$((i+1))
+   id=`printf %03d $i`
+   if [ $id != $found ];then
eof=0
break
-fi
+   fi
 done
 if [ $eof -eq 1 ]; then
line=$((line+1))
@@ -104,9 +104,9 @@ echo Next test is $id

 if [ -f $tdir/$id ]
 then
-echo Error: test $id already exists!
-_cleanup
-exit 1
+   echo Error: test $id already exists!
+   _cleanup
+   exit 1
 fi

 echo -n Creating skeletal script for you to edit ...
@@ -148,8 +148,8 @@ trap _cleanup; exit \\\$status 0 1 2 3 15

 _cleanup()
 {
-cd /
-rm -f \$tmp.*
+   cd /
+   rm -f \$tmp.*
 }

 # get standard environment, filters and checks
@@ -184,39 +184,39 @@ ${EDITOR-vi} $tdir/$id
 if [ $# -eq 0 ]
 then

-while true
-do
+   while true
+   do
echo -n Add to group(s) [other] (? for list): 
read ans
[ -z $ans ]  ans=other
if [ X$ans = X? ]
then
-   for d in $SRC_GROUPS; do
+   for d in $SRC_GROUPS; do
l=$(sed -n  tests/$d/group \
-   -e 's/#.*//' \
-   -e 's/$/ /' \
-   -e 's;\(^[0-9][0-9][0-9]\)\(.*$\);\2;p')
+   -e 's/#.*//' \
+   -e 's/$/ /' \
+   -e 's;\(^[0-9][0-9][0-9]\)\(.*$\);\2;p')
grpl=$grpl $l
-   done
-   lst=`for word in $grpl; do echo $word; done | sort| uniq `
-   echo $lst
+   done
+   lst=`for word in $grpl; do echo $word; done | sort| uniq `
+   echo $lst
else
-   break
+   break
fi
-done
+   done
 else
-# expert mode, groups are on the command line
-#
-for g in $*
-do
+   # expert mode, groups are on the command line
+   #
+   for g in $*
+   do
if grep ^$g[   ] $tdir/group /dev/null
then
-   :
+   :
else
-   echo Warning: group \$g\ not defined in $tdir/group
+   echo Warning: group \$g\ not defined in $tdir/group
fi
-done
-ans=$*
+   done
+   ans=$*
 fi



Thanks,
Eryu Guan
.



--
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

Re: Quota limit question

2015-03-10 Thread Dongsheng Yang

Sorry about the late reply!!

On 03/10/2015 04:41 PM, Qu Wenruo wrote:



 Original Message  
Subject: Re: Quota limit question
From: Christian Robottom Reis k...@canonical.com
To: Duncan 1i5t5.dun...@cox.net
Date: 2015年03月07日 05:44


Just as a follow-up, I upgraded btrfs-tools and the kernel again. I
currently have a filesystem which reports 1G exclusive use:

root@riff# btrfs qg show -r -e /var -p -c
qgroupid rfer excl max_rfer max_excl parent 
child
     -- 
-

0/261 1.52GiB  1.01GiB0.00B100.00GiB --- ---
It's recommended to sync the btrfs before 'qg show' command, since 
quota tree is not updated until commit transaction.


Yes, sync is required be fore qg show now. There is no ioctl to get 
qgroup info from kernel space,
so we have to read the data from disk then we have to do a sync before 
we getting the correct information.


This filesystem reports over quota, and removing the quota fixes that:

root@riff# touch x
touch: cannot touch ‘x’: Disk quota exceeded
root@riff# btrfs qg limit -e
none 261 /var
root@riff# touch x
root@riff#

So at the moment quotas are pretty much unusable in kernel 3.18.6/tools
3.18.2, at least for my use case, and that's a bit surprising since
there isn't anything very interesting about it (other than it contains a
bunch of lxc-cloned rootfs).
Yes, Btrfs really has some problems, from yours to other annoying 
incorrect values.


[Some guess]
For your case, I'm afraid your reserved space in your qgroup takes too 
much space, and it's definitely a bug. Maybe some 
btrfs_qgroup_reserve() leaking?


Agreed, there must be a reserve leaking in your use case. And I have posted
some patches about qgroup.reserved. some of them is about reserved leaking.

Could you try the tree :

btrfs:https://yangdongsh...@github.com/yangdongsheng/linux.git  
qgroup_type
  btrfs-progs:https://yangdongsh...@github.com/yangdongsheng/btrfs-progs.git  
qgroup_type

It could be working better but I can not guarantee your problem here 
will be solved by it.




[Reproducer]
Would you please describe your workload? Or some easy-to-reproduce 
scripts?


[Image dump/debug tree]
Another one which may help is your btrfs-debug-tree output on your 
quota tree.

You can dump it by btrfs-debug-tree -t 8 DEVICE.
Or full disk metadata dump by btrfs-image -c9 DEVICE


A reproducer is great for investigation. btrfs-debug-tree is important 
to us.


Thanx
Yang


Thanks,
Qu


I've proactively added Yang who has submitted a few patches on quota
checking recently just to let me know if he thinks that this should be
fixed with a trunk kernel, or if he'd like to investigate or consider
this further. Thanks!

On Wed, Dec 24, 2014 at 03:52:41AM +, Duncan wrote:

Christian Robottom Reis posted on Tue, 23 Dec 2014 18:36:02 -0200 as
excerpted:

On Tue, Dec 16, 2014 at 11:15:37PM -0200, Christian Robottom Reis 
wrote:
 # btrfs qgroup limit 2000m 0/261 .  touch x touch: cannot 
touch

 ‘x’: Disk quota exceeded

The strange thing is that it doesn't seem to be actually out of 
space:


 # btrfs qgroup show -p -r -e /var | grep 261
 0/261810048  391114752   2097152000 0  ---


Replying to myself as I had not yet been subscribed in time to 
receive a

reply; I just upgraded to 3.18.1 and am seeing the same issue on the
same subvolume (and on no others).


Looking at the thread here on gmane.org (list2news and list2web 
gateway),
it appears my reply was the only reply in any case, and it was 
general as

I don't run quotas myself.

Basically I suggested upgrading, as the quota code as some rather huge
bugs in it (quotas could go seriously negative!) with the old versions
you were running.  But you've upgraded at least the kernel now 
(userspace

you didn't say).

Here's a link to the thread on the gmane web interface for 
completeness,

but the above about covers my reply, as I said the only one until your
thread bump and my reply here, so there's not much new there unless
someone posts further followups to this thread...


http://comments.gmane.org/gmane.comp.file-systems.btrfs/41491


--
Duncan - List replies preferred.   No HTML msgs.
Every nonfree program has a lord, a master --
and if you use the program, he is your master.  Richard Stallman

--
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

.



--
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


[PATCH v4 1/3] Btrfs: get more accurate output in df command.

2015-03-05 Thread Dongsheng Yang
When function btrfs_statfs() calculate the tatol size of fs, it is calculating
the total size of disks and then dividing it by a factor. But in some usecase,
the result is not good to user.
Example:
# mkfs.btrfs -f /dev/vdf1 /dev/vdf2 -d raid1
# mount /dev/vdf1 /mnt
# dd if=/dev/zero of=/mnt/zero bs=1M count=1000
# df -h /mnt
Filesystem  Size  Used Avail Use% Mounted on
/dev/vdf1   3.0G 1018M  1.3G  45% /mnt
# btrfs fi show /dev/vdf1
Label: none  uuid: f85d93dc-81f4-445d-91e5-6a5cd9563294
Total devices 2 FS bytes used 1001.53MiB
devid1 size 2.00GiB used 1.85GiB path /dev/vdf1
devid2 size 4.00GiB used 1.83GiB path /dev/vdf2
a. df -h should report Size as 2GiB rather than as 3GiB.
Because this is 2 device raid1, the limiting factor is devid 1 @2GiB.

b. df -h should report Avail as 0.97GiB or less, rather than as 1.3GiB.
1.85   (the capacity of the allocated chunk)
   -1.018  (the file stored)
   +(2-1.85=0.15)  (the residual capacity of the disks
considering a raid1 fs)
   ---
=   0.97

This patch drops the factor at all and calculate the size observable to
user without considering which raid level the data is in and what's the
size exactly in disk.
After this patch applied:
# mkfs.btrfs -f /dev/vdf1 /dev/vdf2 -d raid1
# mount /dev/vdf1 /mnt
# dd if=/dev/zero of=/mnt/zero bs=1M count=1000
# df -h /mnt
Filesystem  Size  Used Avail Use% Mounted on
/dev/vdf1   2.0G  1.3G  713M  66% /mnt
# df /mnt
Filesystem 1K-blocksUsed Available Use% Mounted on
/dev/vdf12097152 1359424729536  66% /mnt
# btrfs fi show /dev/vdf1
Label: none  uuid: e98c1321-645f-4457-b20d-4f41dc1cf2f4
Total devices 2 FS bytes used 1001.55MiB
devid1 size 2.00GiB used 1.85GiB path /dev/vdf1
devid2 size 4.00GiB used 1.83GiB path /dev/vdf2
a). The @Size is 2G as we expected.
b). @Available is 700M = 1.85G - 1.3G + (2G - 1.85G).
c). @Used is changed to 1.3G rather than 1018M as above. Because
this patch do not treat the free space in metadata chunk
and system chunk as available to user. It's true, user can
not use these space to store data, then it should not be
thought as available. At the same time, it will make the
@Used + @Available == @Size as possible to user.

Signed-off-by: Dongsheng Yang yangds.f...@cn.fujitsu.com
---
v3-v4:
Fix a trailing whitespace error found by checkpatch.
 fs/btrfs/ctree.h   |  1 -
 fs/btrfs/extent-tree.c | 41 
 fs/btrfs/super.c   | 72 --
 3 files changed, 41 insertions(+), 73 deletions(-)

diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
index 84c3b00..d1ae425 100644
--- a/fs/btrfs/ctree.h
+++ b/fs/btrfs/ctree.h
@@ -3460,7 +3460,6 @@ int btrfs_set_block_group_ro(struct btrfs_root *root,
 void btrfs_set_block_group_rw(struct btrfs_root *root,
  struct btrfs_block_group_cache *cache);
 void btrfs_put_block_group_cache(struct btrfs_fs_info *info);
-u64 btrfs_account_ro_block_groups_free_space(struct btrfs_space_info *sinfo);
 int btrfs_error_unpin_extent_range(struct btrfs_root *root,
   u64 start, u64 end);
 int btrfs_discard_extent(struct btrfs_root *root, u64 bytenr,
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index 571f402..857eb0e3 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -8515,47 +8515,6 @@ int btrfs_force_chunk_alloc(struct btrfs_trans_handle 
*trans,
  CHUNK_ALLOC_FORCE);
 }
 
-/*
- * helper to account the unused space of all the readonly block group in the
- * space_info. takes mirrors into account.
- */
-u64 btrfs_account_ro_block_groups_free_space(struct btrfs_space_info *sinfo)
-{
-   struct btrfs_block_group_cache *block_group;
-   u64 free_bytes = 0;
-   int factor;
-
-   /* It's df, we don't care if it's racey */
-   if (list_empty(sinfo-ro_bgs))
-   return 0;
-
-   spin_lock(sinfo-lock);
-   list_for_each_entry(block_group, sinfo-ro_bgs, ro_list) {
-   spin_lock(block_group-lock);
-
-   if (!block_group-ro) {
-   spin_unlock(block_group-lock);
-   continue;
-   }
-
-   if (block_group-flags  (BTRFS_BLOCK_GROUP_RAID1 |
- BTRFS_BLOCK_GROUP_RAID10 |
- BTRFS_BLOCK_GROUP_DUP))
-   factor = 2;
-   else
-   factor = 1;
-
-   free_bytes += (block_group-key.offset -
-  btrfs_block_group_used(block_group-item)) *
-  factor;
-
-   spin_unlock(block_group-lock);
-   }
-   spin_unlock

[PATCH v3 1/3] Btrfs: get more accurate output in df command.

2015-03-04 Thread Dongsheng Yang
When function btrfs_statfs() calculate the tatol size of fs, it is calculating
the total size of disks and then dividing it by a factor. But in some usecase,
the result is not good to user.
Example:
# mkfs.btrfs -f /dev/vdf1 /dev/vdf2 -d raid1
# mount /dev/vdf1 /mnt
# dd if=/dev/zero of=/mnt/zero bs=1M count=1000
# df -h /mnt
Filesystem  Size  Used Avail Use% Mounted on
/dev/vdf1   3.0G 1018M  1.3G  45% /mnt
# btrfs fi show /dev/vdf1
Label: none  uuid: f85d93dc-81f4-445d-91e5-6a5cd9563294
Total devices 2 FS bytes used 1001.53MiB
devid1 size 2.00GiB used 1.85GiB path /dev/vdf1
devid2 size 4.00GiB used 1.83GiB path /dev/vdf2
a. df -h should report Size as 2GiB rather than as 3GiB.
Because this is 2 device raid1, the limiting factor is devid 1 @2GiB.

b. df -h should report Avail as 0.97GiB or less, rather than as 1.3GiB.
1.85   (the capacity of the allocated chunk)
   -1.018  (the file stored)
   +(2-1.85=0.15)  (the residual capacity of the disks
considering a raid1 fs)
   ---
=   0.97

This patch drops the factor at all and calculate the size observable to
user without considering which raid level the data is in and what's the
size exactly in disk.
After this patch applied:
# mkfs.btrfs -f /dev/vdf1 /dev/vdf2 -d raid1
# mount /dev/vdf1 /mnt
# dd if=/dev/zero of=/mnt/zero bs=1M count=1000
# df -h /mnt
Filesystem  Size  Used Avail Use% Mounted on
/dev/vdf1   2.0G  1.3G  713M  66% /mnt
# df /mnt
Filesystem 1K-blocksUsed Available Use% Mounted on
/dev/vdf12097152 1359424729536  66% /mnt
# btrfs fi show /dev/vdf1
Label: none  uuid: e98c1321-645f-4457-b20d-4f41dc1cf2f4
Total devices 2 FS bytes used 1001.55MiB
devid1 size 2.00GiB used 1.85GiB path /dev/vdf1
devid2 size 4.00GiB used 1.83GiB path /dev/vdf2
a). The @Size is 2G as we expected.
b). @Available is 700M = 1.85G - 1.3G + (2G - 1.85G).
c). @Used is changed to 1.3G rather than 1018M as above. Because
this patch do not treat the free space in metadata chunk
and system chunk as available to user. It's true, user can
not use these space to store data, then it should not be
thought as available. At the same time, it will make the
@Used + @Available == @Size as possible to user.

Signed-off-by: Dongsheng Yang yangds.f...@cn.fujitsu.com
---
 fs/btrfs/ctree.h   |  1 -
 fs/btrfs/extent-tree.c | 41 
 fs/btrfs/super.c   | 74 --
 3 files changed, 42 insertions(+), 74 deletions(-)

diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
index 84c3b00..d1ae425 100644
--- a/fs/btrfs/ctree.h
+++ b/fs/btrfs/ctree.h
@@ -3460,7 +3460,6 @@ int btrfs_set_block_group_ro(struct btrfs_root *root,
 void btrfs_set_block_group_rw(struct btrfs_root *root,
  struct btrfs_block_group_cache *cache);
 void btrfs_put_block_group_cache(struct btrfs_fs_info *info);
-u64 btrfs_account_ro_block_groups_free_space(struct btrfs_space_info *sinfo);
 int btrfs_error_unpin_extent_range(struct btrfs_root *root,
   u64 start, u64 end);
 int btrfs_discard_extent(struct btrfs_root *root, u64 bytenr,
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index 571f402..857eb0e3 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -8515,47 +8515,6 @@ int btrfs_force_chunk_alloc(struct btrfs_trans_handle 
*trans,
  CHUNK_ALLOC_FORCE);
 }
 
-/*
- * helper to account the unused space of all the readonly block group in the
- * space_info. takes mirrors into account.
- */
-u64 btrfs_account_ro_block_groups_free_space(struct btrfs_space_info *sinfo)
-{
-   struct btrfs_block_group_cache *block_group;
-   u64 free_bytes = 0;
-   int factor;
-
-   /* It's df, we don't care if it's racey */
-   if (list_empty(sinfo-ro_bgs))
-   return 0;
-
-   spin_lock(sinfo-lock);
-   list_for_each_entry(block_group, sinfo-ro_bgs, ro_list) {
-   spin_lock(block_group-lock);
-
-   if (!block_group-ro) {
-   spin_unlock(block_group-lock);
-   continue;
-   }
-
-   if (block_group-flags  (BTRFS_BLOCK_GROUP_RAID1 |
- BTRFS_BLOCK_GROUP_RAID10 |
- BTRFS_BLOCK_GROUP_DUP))
-   factor = 2;
-   else
-   factor = 1;
-
-   free_bytes += (block_group-key.offset -
-  btrfs_block_group_used(block_group-item)) *
-  factor;
-
-   spin_unlock(block_group-lock);
-   }
-   spin_unlock(sinfo-lock);
-
-   return free_bytes;
-}
-
 void btrfs_set_block_group_rw(struct

[PATCH v3 2/3] Btrfs: raid56: simplify the parameter of nr_parity_stripes().

2015-03-04 Thread Dongsheng Yang
We just need the type of a chunk to calculate the number of parity stripes,
but we have to pass a structure of lookup_map to it. This will prevent some
callers to use it where there is no a convenient lookup_map to be passed.

This patch replace the parameter of struct map_lookup * with a profile type.
Then we can use it more easily.

Signed-off-by: Dongsheng Yang yangds.f...@cn.fujitsu.com
Reviewed-by: Satoru Takeuchi takeuchi_sat...@jp.fujitsu.com
---
 fs/btrfs/raid56.h  | 8 
 fs/btrfs/volumes.c | 2 +-
 2 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/fs/btrfs/raid56.h b/fs/btrfs/raid56.h
index 2b5d797..751fcd5 100644
--- a/fs/btrfs/raid56.h
+++ b/fs/btrfs/raid56.h
@@ -19,11 +19,11 @@
 
 #ifndef __BTRFS_RAID56__
 #define __BTRFS_RAID56__
-static inline int nr_parity_stripes(struct map_lookup *map)
+static inline int nr_parity_stripes(u64 type)
 {
-   if (map-type  BTRFS_BLOCK_GROUP_RAID5)
+   if (type  BTRFS_BLOCK_GROUP_RAID5)
return 1;
-   else if (map-type  BTRFS_BLOCK_GROUP_RAID6)
+   else if (type  BTRFS_BLOCK_GROUP_RAID6)
return 2;
else
return 0;
@@ -31,7 +31,7 @@ static inline int nr_parity_stripes(struct map_lookup *map)
 
 static inline int nr_data_stripes(struct map_lookup *map)
 {
-   return map-num_stripes - nr_parity_stripes(map);
+   return map-num_stripes - nr_parity_stripes(map-type);
 }
 #define RAID5_P_STRIPE ((u64)-2)
 #define RAID6_Q_STRIPE ((u64)-1)
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
index cd4d131..35043c9 100644
--- a/fs/btrfs/volumes.c
+++ b/fs/btrfs/volumes.c
@@ -5196,7 +5196,7 @@ static int __btrfs_map_block(struct btrfs_fs_info 
*fs_info, int rw,
 
/* RAID[56] write or recovery. Return all stripes */
num_stripes = map-num_stripes;
-   max_errors = nr_parity_stripes(map);
+   max_errors = nr_parity_stripes(map-type);
 
*length = map-stripe_len;
stripe_index = 0;
-- 
1.8.4.2

--
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


[PATCH v3 0/3] Enhancement for df command.

2015-03-04 Thread Dongsheng Yang
Hi all,

This is V3, just rebase it against 4.0-rc1.

Any comment is welcome!!

Thanx

Dongsheng Yang (3):
  Btrfs: get more accurate output in df command.
  Btrfs: raid56: simplify the parameter of nr_parity_stripes().
  Btrfs: adapt df command to RAID5/6.

 fs/btrfs/ctree.h   |  1 -
 fs/btrfs/extent-tree.c | 41 
 fs/btrfs/raid56.h  |  8 ++---
 fs/btrfs/super.c   | 86 +++---
 fs/btrfs/volumes.c |  2 +-
 5 files changed, 59 insertions(+), 79 deletions(-)

-- 
1.8.4.2

--
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


[PATCH v3 3/3] Btrfs: adapt df command to RAID5/6.

2015-03-04 Thread Dongsheng Yang
When we use btrfs with raid5/6, the output of df is unexpected as below.
Example:
# mkfs.btrfs -f /dev/vdf1 /dev/vdf2 -d raid5
# mount /dev/vdf1 /mnt
# dd if=/dev/zero of=/mnt/zero bs=1M count=1000
# df -h /mnt
Filesystem  Size  Used Avail Use% Mounted on
/dev/vdf1   4.2G  1.3G  2.9G  32% /mnt
[root@atest-guest linux_btrfs]# btrfs fi show /mnt
Label: none  uuid: f7fac7f2-3898-482e-9cf2-fbcd7fdd7084
Total devices 2 FS bytes used 1001.53MiB
devid1 size 2.00GiB used 1.85GiB path /dev/vdf1
devid2 size 4.00GiB used 1.83GiB path /dev/vdf2
The @size should be 2G rather than 4.2G.

This patch makes the btrfs_calc_avail_data_space() consider raid5/6,
then we can get the correct result of it.

Example:
# mkfs.btrfs -f /dev/vdf1 /dev/vdf2 -d raid5
# mount /dev/vdf1 /mnt
# dd if=/dev/zero of=/mnt/zero bs=1M count=1000
# df -h /mnt
Filesystem  Size  Used Avail Use% Mounted on
/dev/vdf1   2.0G  1.3G  713M  66% /mnt
[root@atest-guest linux_btrfs]# btrfs fi show /mnt
Label: none  uuid: ea3a6e6e-fbe1-47aa-b4b5-bc37b98565d9
Total devices 2 FS bytes used 1001.53MiB
devid1 size 2.00GiB used 1.85GiB path /dev/vdf1
devid2 size 4.00GiB used 1.83GiB path /dev/vdf2

Signed-off-by: Dongsheng Yang yangds.f...@cn.fujitsu.com
---
 fs/btrfs/super.c | 16 ++--
 1 file changed, 14 insertions(+), 2 deletions(-)

diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c
index 25b0f79..7cac6b4 100644
--- a/fs/btrfs/super.c
+++ b/fs/btrfs/super.c
@@ -52,6 +52,7 @@
 #include props.h
 #include xattr.h
 #include volumes.h
+#include raid56.h
 #include export.h
 #include compression.h
 #include rcu-string.h
@@ -1698,6 +1699,14 @@ static int btrfs_calc_avail_data_space(struct btrfs_root 
*root, u64 *free_bytes)
min_stripes = 4;
num_stripes = 4;
data_stripes = 2;
+   } else if (type  BTRFS_BLOCK_GROUP_RAID5) {
+   min_stripes = 2;
+   num_stripes = nr_devices;
+   data_stripes = num_stripes - nr_parity_stripes(type);
+   } else if (type  BTRFS_BLOCK_GROUP_RAID6) {
+   min_stripes = 3;
+   num_stripes = nr_devices;
+   data_stripes = num_stripes - nr_parity_stripes(type);
}
 
if (type  BTRFS_BLOCK_GROUP_DUP)
@@ -1787,8 +1796,11 @@ static int btrfs_calc_avail_data_space(struct btrfs_root 
*root, u64 *free_bytes)
while (nr_devices = min_stripes) {
if (num_stripes  nr_devices) {
num_stripes = nr_devices;
-   if (type  BTRFS_BLOCK_GROUP_RAID0)
-   data_stripes = num_stripes;
+   /* Only RAID0, RAID5 and RAID6 will get here.
+* And we can use the following calculation
+* for all the three cases.
+**/
+   data_stripes = num_stripes - nr_parity_stripes(type);
}
 
if (devices_info[i].max_avail = min_stripe_size) {
-- 
1.8.4.2

--
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


[PATCH] fstest: btrfs: add a test for quota number when deleting a subvol.

2015-03-03 Thread Dongsheng Yang
This regression is introduced by two commits:

e339a6b0 (Btrfs: __btrfs_mod_ref should always use no_quota)
1152651a (btrfs: qgroup: account shared subtrees during snapshot delete)

Signed-off-by: Dongsheng Yang yangds.f...@cn.fujitsu.com
---
 tests/btrfs/084 | 84 +
 tests/btrfs/084.out |  3 ++
 tests/btrfs/group   |  1 +
 3 files changed, 88 insertions(+)
 create mode 100755 tests/btrfs/084
 create mode 100644 tests/btrfs/084.out

diff --git a/tests/btrfs/084 b/tests/btrfs/084
new file mode 100755
index 000..7b7c7ac
--- /dev/null
+++ b/tests/btrfs/084
@@ -0,0 +1,84 @@
+#! /bin/bash
+# FS QA Test No. 084
+#
+# This is a case for the regression introduced by
+#
+# e339a6b0 (Btrfs: __btrfs_mod_ref should always use no_quota)
+# 1152651a (btrfs: qgroup: account shared subtrees during snapshot delete)
+#
+#---
+# Copyright (c) 2015 Fujitsu.  All Rights Reserved.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it would be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write the Free Software Foundation,
+# Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+#---
+#
+
+seq=`basename $0`
+seqres=$RESULT_DIR/$seq
+echo QA output created by $seq
+
+here=`pwd`
+tmp=/tmp/$$
+status=1   # failure is the default!
+trap _cleanup; exit \$status 0 1 2 3 15
+
+_cleanup()
+{
+cd /
+rm -f $tmp.*
+}
+
+# get standard environment, filters and checks
+. ./common/rc
+. ./common/filter
+
+# real QA test starts here
+_need_to_be_root
+_supported_fs btrfs
+_supported_os Linux
+_require_scratch
+
+_scratch_mount
+
+$XFS_IO_PROG -f -d -c pwrite 0 8K $SCRATCH_MNT/foo 21  /dev/null
+
+_run_btrfs_util_prog subvolume snapshot $SCRATCH_MNT $SCRATCH_MNT/snap
+
+_run_btrfs_util_prog quota enable $SCRATCH_MNT
+_run_btrfs_util_prog quota rescan -w $SCRATCH_MNT
+
+units=`_btrfs_qgroup_units`
+orig_result=`$BTRFS_UTIL_PROG qgroup show $units $SCRATCH_MNT | $AWK_PROG 
'NR==NF {print $3}'`
+
+_run_btrfs_util_prog subvolume delete $SCRATCH_MNT/snap
+
+_run_btrfs_util_prog filesystem sync $SCRATCH_MNT
+
+timeout=100
+# There is a background thread doing the clean work
+for ((i=0; i$timeout; i++))
+do
+   result=`$BTRFS_UTIL_PROG qgroup show $units $SCRATCH_MNT | $AWK_PROG 
'NR==NF {print $3}'`
+   if (($orig_result != $result))
+   then
+   break
+   fi
+   sleep 1
+done
+
+$BTRFS_UTIL_PROG qgroup show $units $SCRATCH_MNT | $AWK_PROG '/[0-9]/ {print 
$2 $3}'
+
+# success, all done
+status=0
+exit
diff --git a/tests/btrfs/084.out b/tests/btrfs/084.out
new file mode 100644
index 000..7bf6dbf
--- /dev/null
+++ b/tests/btrfs/084.out
@@ -0,0 +1,3 @@
+QA output created by 084
+24576 24576
+0 0
diff --git a/tests/btrfs/group b/tests/btrfs/group
index fe82a9c..1be7392 100644
--- a/tests/btrfs/group
+++ b/tests/btrfs/group
@@ -86,3 +86,4 @@
 081 auto quick clone
 082 auto quick remount
 083 auto quick send
+084 qgroup
-- 
1.8.4.2

--
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 0/4] Btrfs: qgroup: part-2: bug fixes for qgroup reservation.

2015-03-03 Thread Dongsheng Yang

On 02/10/2015 06:23 PM, Dongsheng Yang wrote:

Hi all,
This is part2 for qgroup. It is based on
[PATCH 0/9] Btrfs: qgroup: part-1: bug fixes.

[1/4] is reviewed-by Josef.

[2/4] - [4/4] are trying to solve a problem in qgroup reservation.
It would be weired I introduce a may_use in 2/4 and delete it in 4/4.

Yes, I am glad to rebase and squash them, here I am keeping this history
of the problem for reviewing. I have explained the problem and sent the
[2/4] out. Josef give me a looks good at that time. But in the later, I
found another problem and solved it with [4/4]. So they are trying to
solve different problems at different timing. When the all patches are
reviewed by you guys, I am okey to squash them if you request.


Hi, any comment on this patchset?

Thanx


Thanx.

Dongsheng Yang (4):
   Btrfs: qgroup: free reserved in exceeding quota.
   Btrfs: qgroup: Introduce a may_use to account
 space_info-bytes_may_use.
   Btrfs: qgroup, Account data space in more proper timings.
   btrfs: qgroup: do a reservation in a higher level.

  fs/btrfs/ctree.h   |  2 +-
  fs/btrfs/extent-tree.c | 25 +++--
  fs/btrfs/file.c| 13 ++---
  fs/btrfs/inode.c   |  3 ++-
  fs/btrfs/qgroup.c  | 10 --
  fs/btrfs/relocation.c  |  2 +-
  6 files changed, 21 insertions(+), 34 deletions(-)



--
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: [RFC PATCH 0/7] Btrfs: qgroup: part-4: Add type to btrfs qgroup.

2015-03-03 Thread Dongsheng Yang

On 02/10/2015 06:24 PM, Dongsheng Yang wrote:

Hi all,
This patchset is based on [Btrfs: qgroup: part-3: bug fixes.]

I am introducing a type to qgroup, then we can get the numbers what we
only care about.

Easy way to get the code for testing:
btrfs: https://yangdongsh...@github.com/yangdongsheng/linux.git 
qgroup_type
   btrfs-progs: https://yangdongsh...@github.com/yangdongsheng/btrfs-progs.git 
qgroup_type
with the patches applied in this series, both in btrfs and btrfs-progs:


Any comment on this patchset?
I think it's a good enhancement for qgroup.

Thanx


[root@atest-guest linux_btrfs]# mkfs.btrfs -O qgroup-type /dev/sdc -f
Btrfs v3.18-76-ga900a61
See http://btrfs.wiki.kernel.org for more information.

Turning ON incompat feature 'extref': increased hardlink limit per file to 65536
Turning ON incompat feature 'skinny-metadata': reduced-size metadata extent refs
Turning ON incompat feature 'qgroup-type': create qgroup in different type
fs created label (null) on /dev/sdc
nodesize 16384 leafsize 16384 sectorsize 4096 size 10.00GiB
[root@atest-guest linux_btrfs]# mount /dev/sdc  /mnt/
[root@atest-guest linux_btrfs]# btrfs quota enable /mnt
[root@atest-guest linux_btrfs]# btrfs qgroup show -prce /mnt
qgroupid rfer excl max_rfer max_excl parent  child type
     --  - 
0/5  16.00KiB 16.00KiB0.00B0.00B --- ---   
metadata,data
[root@atest-guest linux_btrfs]# btrfs qgroup show -prce /mnt
qgroupid rfer excl max_rfer max_excl parent  child type
     --  - 
0/5  16.00KiB 16.00KiB0.00B0.00B --- ---   
metadata,data
0/25716.00KiB 16.00KiB0.00B0.00B --- ---   
metadata,data --- default type is mixed.
[root@atest-guest linux_btrfs]# btrfs sub create --qgroup-type data /mnt/sub1
Create subvolume '/mnt/sub1'
Set qgroup arguments:
qgroup type: data
[root@atest-guest linux_btrfs]# btrfs qgroup show -prce /mnt
qgroupid rfer excl max_rfer max_excl parent  child type
     --  - 
0/5  16.00KiB 16.00KiB0.00B0.00B --- ---   
metadata,data
0/25716.00KiB 16.00KiB0.00B0.00B --- ---   
metadata,data
0/258   0.00B0.00B0.00B0.00B --- ---   data
  --- create a data qgroup
[root@atest-guest linux_btrfs]# btrfs qgroup limit -e 5M 0/258 /mnt
[root@atest-guest linux_btrfs]# btrfs qgroup show -prce /mnt
qgroupid rfer excl max_rfer max_excl parent  child type
     --  - 
0/5  16.00KiB 16.00KiB0.00B0.00B --- ---   
metadata,data
0/25716.00KiB 16.00KiB0.00B0.00B --- ---   
metadata,data
0/258   0.00B0.00B0.00B  5.00MiB --- ---   data
[root@atest-guest linux_btrfs]# dd if=/dev/zero of=/mnt/sub1/data bs=1024
dd: error writing \u2018/mnt/sub1/data\u2019: Disk quota exceeded
5121+0 records in
5120+0 records out
5242880 bytes (5.2 MB) copied, 0.0218646 s, 240 MB/s
[root@atest-guest linux_btrfs]# sync
[root@atest-guest linux_btrfs]# ll /mnt/sub1/data
-rw-r--r--. 1 root root 5242880 Feb 10 16:17 /mnt/sub1/data
[root@atest-guest linux_btrfs]# btrfs qgroup show -prce --raw /mnt
qgroupid rfer excl max_rfer max_excl parent  child type
     --  - 
0/5 163841638400 --- ---   
metadata,data
0/257   163841638400 --- ---   
metadata,data
0/258 5242880  52428800  5242880 --- ---   data
 --- excl == max_excl == data_size == 5M == 5242880

Dongsheng Yang (7):
   Btrfs: qgroup: Add type to btrfs_qgroup.
   btrfs: qgroup: apply type to the recording and accounting.
   btrfs: qgroup: Apply type to btrfs_qgroup_inherit().
   btrfs: qgroup: Apply qgroup type to qgroup creating.
   btrfs: qgroup: Apply qgroup type to subvol creating.
   btrfs: qgroup: apply type to quota rescan.
   btrfs: qgroup: fix a bug when type of parent is different with
 child's.

  fs/btrfs/ctree.h  |  10 ++-
  fs/btrfs/extent-tree.c|  48 ++-
  fs/btrfs/ioctl.c  |  49 ---
  fs/btrfs/qgroup.c | 186 --
  fs/btrfs/qgroup.h |  29 ++-
  fs/btrfs/tests/qgroup-tests.c |  19 +++--
  fs/btrfs/transaction.c|  13 +--
  include/uapi/linux/btrfs.h|   1 +
  8 files changed, 246 insertions(+), 109 deletions(-)



--
To unsubscribe from this list: send the line

Re: [PATCH 3/3] btrfs: qgroup: fix a wrong parameter of no_quota.

2015-03-03 Thread Dongsheng Yang

On 02/26/2015 02:05 PM, Dongsheng Yang wrote:
Wait a minute, this patch seems not working well in accounting quota 
number when

deleting data shared by different subvolumes.

I will investigate more about it and send a V2 out.

I have sent a fstest
 [PATCH] fstest: btrfs: add a test for quota number when deleting a subvol.
for this problem I was trying to solve in this patch.

Please consider reverting the two commits introduced the problem:

e339a6b0 (Btrfs: __btrfs_mod_ref should always use no_quota)
1152651a (btrfs: qgroup: account shared subtrees during snapshot delete)

as what I attached.

Thanx


Thanx
Yang

On 02/13/2015 05:38 PM, Dongsheng Yang wrote:hen

Hi Josef and Mark,

I saw the commit message of 1152651a:

[btrfs: qgroup: account shared subtrees during snapshot delete]

that SUBTREE operation was introduced to account the quota number
in subvolume deleting.

But, I found it does not work well currently:

Create subvolume '/mnt/sub'
+ btrfs qgroup show -prce /mnt
qgroupid rfer excl max_rfer max_excl parent child
     -- -
0/5 16.00KiB 16.00KiB 0.00B 0.00B --- ---
0/257 16.00KiB 16.00KiB 0.00B 0.00B --- ---
+ dd if=/dev/zero of=/mnt/sub/data bs=1024 count=100
100+0 records in
100+0 records out
102400 bytes (102 kB) copied, 0.000876526 s, 117 MB/s
+ sync
+ btrfs qgroup show -prce --raw /mnt
qgroupid rfer excl max_rfer max_excl parent child
     -- -
0/5 16384 16384 0 0 --- ---
0/257 118784 118784 0 0 --- ---
+ btrfs sub snap /mnt/sub /mnt/snap
Create a snapshot of '/mnt/sub' in '/mnt/snap'
+ sync
+ btrfs qgroup show -prce --raw /mnt
qgroupid rfer excl max_rfer max_excl parent child
     -- -
0/5 16384 16384 0 0 --- ---
0/257 118784 16384 0 0 --- ---
0/258 118784 16384 0 0 --- ---
+ btrfs sub delete /mnt/sub
Delete subvolume (no-commit): '/mnt/sub'
+ sync
+ btrfs qgroup show -prce --raw /mnt
qgroupid rfer excl max_rfer max_excl parent child
     -- -
0/5 16384 16384 0 0 --- ---
0/257 118784 16384 0 0 --- ---
0/258 118784 16384 0 0 --- ---

--- 
--- WAIT for cleaner

[root@atest-guest linux_btrfs]# btrfs qgroup show -prce /mnt
qgroupid rfer excl max_rfer max_excl parent child
     -- -
0/5 16.00KiB 16.00KiB 0.00B 0.00B --- ---
0/257 100.00KiB 0.00B 0.00B 0.00B --- --- --- the data size was 
not cleaned from qgroup.
0/258 116.00KiB 116.00KiB 0.00B 0.00B --- --- --- but the excl 
in the snapshot qgroup is increased to 116KB by SUBTREE operation


My question is:
(1), SUBTREE is not working well.
(2), why we need a rule-breaker in qgroup operations SUBTREE to do 
this work?
We can do it via the delayed-ref routine like the other qgroup 
operations.


with my patch here applied and 1152651a reverted, I got the result:
qgroupid rfer excl max_rfer max_excl parent child
     -- -
0/5 16.00KiB 16.00KiB 0.00B 0.00B --- ---
0/257 0.00B 0.00B 0.00B 0.00B --- --- --- data and tree 
block both are cleaned
0/258 116.00KiB 116.00KiB 0.00B 0.00B --- --- -- quota numbers 
in snapshot qgroup is correct.


(1), quota is working well now in subvolume deleting.
(2), all operations are inserted by delayed-ref.

So, the conclusion seems like that:
(1), commit 1152651a was introducing a SUBTREE operation to account 
the number in subvolume deleted.

(2). SUBTREE is not working well.
(3). we can solve the same problem in a better way without 
introducing a new operation of SUBTREE.


To be honest, I am suspecting myself *very much*. I trust you guys 
and believe there must be something I am missing.


Then I send this mail to ask your help.

Thanx in advance.
Yang


On 02/10/2015 06:24 PM, Dongsheng Yang wrote:

In function of __btrfs_mod_ref(), we are passing the no_quota=1
to process_func() anyway. It will make the numbers in qgroup be
wrong when deleting a subvolume. The data size in a deleted subvolume
will never be decressed from all related qgroups.

Signed-off-by: Dongsheng Yang yangds.f...@cn.fujitsu.com
---
  fs/btrfs/extent-tree.c | 8 ++--
  1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index 652be74..f59809c 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -3056,6 +3056,7 @@ static int __btrfs_mod_ref(struct 
btrfs_trans_handle *trans,

  int i;
  int level;
  int ret = 0;
+int no_quota = 0;
  int (*process_func)(struct btrfs_trans_handle *, struct 
btrfs_root *,

  u64, u64, u64, u64, u64, u64, int);
  @@ -3080,6 +3081,9 @@ static int __btrfs_mod_ref(struct 
btrfs_trans_handle *trans,

  else
  parent = 0;
  +if (!root-fs_info-quota_enabled || !is_fstree(ref_root))
+no_quota = 1;
+
  for (i = 0; i  nritems; i

Re: [PATCH 3/3] btrfs: qgroup: fix a wrong parameter of no_quota.

2015-02-25 Thread Dongsheng Yang
Wait a minute, this patch seems not working well in accounting quota 
number when

deleting data shared by different subvolumes.

I will investigate more about it and send a V2 out.

Thanx
Yang

On 02/13/2015 05:38 PM, Dongsheng Yang wrote:hen

Hi Josef and Mark,

I saw the commit message of 1152651a:

[btrfs: qgroup: account shared subtrees during snapshot delete]

that SUBTREE operation was introduced to account the quota number
in subvolume deleting.

But, I found it does not work well currently:

Create subvolume '/mnt/sub'
+ btrfs qgroup show -prce /mnt
qgroupid rfer excl max_rfer max_excl parent child
     -- -
0/5 16.00KiB 16.00KiB 0.00B 0.00B --- ---
0/257 16.00KiB 16.00KiB 0.00B 0.00B --- ---
+ dd if=/dev/zero of=/mnt/sub/data bs=1024 count=100
100+0 records in
100+0 records out
102400 bytes (102 kB) copied, 0.000876526 s, 117 MB/s
+ sync
+ btrfs qgroup show -prce --raw /mnt
qgroupid rfer excl max_rfer max_excl parent child
     -- -
0/5 16384 16384 0 0 --- ---
0/257 118784 118784 0 0 --- ---
+ btrfs sub snap /mnt/sub /mnt/snap
Create a snapshot of '/mnt/sub' in '/mnt/snap'
+ sync
+ btrfs qgroup show -prce --raw /mnt
qgroupid rfer excl max_rfer max_excl parent child
     -- -
0/5 16384 16384 0 0 --- ---
0/257 118784 16384 0 0 --- ---
0/258 118784 16384 0 0 --- ---
+ btrfs sub delete /mnt/sub
Delete subvolume (no-commit): '/mnt/sub'
+ sync
+ btrfs qgroup show -prce --raw /mnt
qgroupid rfer excl max_rfer max_excl parent child
     -- -
0/5 16384 16384 0 0 --- ---
0/257 118784 16384 0 0 --- ---
0/258 118784 16384 0 0 --- ---

--- 
--- WAIT for cleaner

[root@atest-guest linux_btrfs]# btrfs qgroup show -prce /mnt
qgroupid rfer excl max_rfer max_excl parent child
     -- -
0/5 16.00KiB 16.00KiB 0.00B 0.00B --- ---
0/257 100.00KiB 0.00B 0.00B 0.00B --- --- --- the data size was 
not cleaned from qgroup.
0/258 116.00KiB 116.00KiB 0.00B 0.00B --- --- --- but the excl in 
the snapshot qgroup is increased to 116KB by SUBTREE operation


My question is:
(1), SUBTREE is not working well.
(2), why we need a rule-breaker in qgroup operations SUBTREE to do 
this work?
We can do it via the delayed-ref routine like the other qgroup 
operations.


with my patch here applied and 1152651a reverted, I got the result:
qgroupid rfer excl max_rfer max_excl parent child
     -- -
0/5 16.00KiB 16.00KiB 0.00B 0.00B --- ---
0/257 0.00B 0.00B 0.00B 0.00B --- --- --- data and tree block 
both are cleaned
0/258 116.00KiB 116.00KiB 0.00B 0.00B --- --- -- quota numbers in 
snapshot qgroup is correct.


(1), quota is working well now in subvolume deleting.
(2), all operations are inserted by delayed-ref.

So, the conclusion seems like that:
(1), commit 1152651a was introducing a SUBTREE operation to account 
the number in subvolume deleted.

(2). SUBTREE is not working well.
(3). we can solve the same problem in a better way without introducing 
a new operation of SUBTREE.


To be honest, I am suspecting myself *very much*. I trust you guys and 
believe there must be something I am missing.


Then I send this mail to ask your help.

Thanx in advance.
Yang


On 02/10/2015 06:24 PM, Dongsheng Yang wrote:

In function of __btrfs_mod_ref(), we are passing the no_quota=1
to process_func() anyway. It will make the numbers in qgroup be
wrong when deleting a subvolume. The data size in a deleted subvolume
will never be decressed from all related qgroups.

Signed-off-by: Dongsheng Yang yangds.f...@cn.fujitsu.com
---
  fs/btrfs/extent-tree.c | 8 ++--
  1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index 652be74..f59809c 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -3056,6 +3056,7 @@ static int __btrfs_mod_ref(struct 
btrfs_trans_handle *trans,

  int i;
  int level;
  int ret = 0;
+int no_quota = 0;
  int (*process_func)(struct btrfs_trans_handle *, struct 
btrfs_root *,

  u64, u64, u64, u64, u64, u64, int);
  @@ -3080,6 +3081,9 @@ static int __btrfs_mod_ref(struct 
btrfs_trans_handle *trans,

  else
  parent = 0;
  +if (!root-fs_info-quota_enabled || !is_fstree(ref_root))
+no_quota = 1;
+
  for (i = 0; i  nritems; i++) {
  if (level == 0) {
  btrfs_item_key_to_cpu(buf, key, i);
@@ -3098,7 +3102,7 @@ static int __btrfs_mod_ref(struct 
btrfs_trans_handle *trans,

  key.offset -= btrfs_file_extent_offset(buf, fi);
  ret = process_func(trans, root, bytenr, num_bytes,
 parent, ref_root, key.objectid,
-   key.offset, 1);
+   key.offset, no_quota

Re: [PATCH 3/3] btrfs: qgroup: fix a wrong parameter of no_quota.

2015-02-13 Thread Dongsheng Yang

Hi Josef and Mark,

I saw the commit message of 1152651a:

[btrfs: qgroup: account shared subtrees during snapshot delete]

that SUBTREE operation was introduced to account the quota number
in subvolume deleting.

But, I found it does not work well currently:

Create subvolume '/mnt/sub'
+ btrfs qgroup show -prce /mnt
qgroupid rfer excl max_rfer max_excl parent child
     -- -
0/5 16.00KiB 16.00KiB 0.00B 0.00B --- ---
0/257 16.00KiB 16.00KiB 0.00B 0.00B --- ---
+ dd if=/dev/zero of=/mnt/sub/data bs=1024 count=100
100+0 records in
100+0 records out
102400 bytes (102 kB) copied, 0.000876526 s, 117 MB/s
+ sync
+ btrfs qgroup show -prce --raw /mnt
qgroupid rfer excl max_rfer max_excl parent child
     -- -
0/5 16384 16384 0 0 --- ---
0/257 118784 118784 0 0 --- ---
+ btrfs sub snap /mnt/sub /mnt/snap
Create a snapshot of '/mnt/sub' in '/mnt/snap'
+ sync
+ btrfs qgroup show -prce --raw /mnt
qgroupid rfer excl max_rfer max_excl parent child
     -- -
0/5 16384 16384 0 0 --- ---
0/257 118784 16384 0 0 --- ---
0/258 118784 16384 0 0 --- ---
+ btrfs sub delete /mnt/sub
Delete subvolume (no-commit): '/mnt/sub'
+ sync
+ btrfs qgroup show -prce --raw /mnt
qgroupid rfer excl max_rfer max_excl parent child
     -- -
0/5 16384 16384 0 0 --- ---
0/257 118784 16384 0 0 --- ---
0/258 118784 16384 0 0 --- ---

--- 
--- WAIT for cleaner

[root@atest-guest linux_btrfs]# btrfs qgroup show -prce /mnt
qgroupid rfer excl max_rfer max_excl parent child
     -- -
0/5 16.00KiB 16.00KiB 0.00B 0.00B --- ---
0/257 100.00KiB 0.00B 0.00B 0.00B --- --- --- the data size was not 
cleaned from qgroup.
0/258 116.00KiB 116.00KiB 0.00B 0.00B --- --- --- but the excl in 
the snapshot qgroup is increased to 116KB by SUBTREE operation


My question is:
(1), SUBTREE is not working well.
(2), why we need a rule-breaker in qgroup operations SUBTREE to do this 
work?

We can do it via the delayed-ref routine like the other qgroup operations.

with my patch here applied and 1152651a reverted, I got the result:
qgroupid rfer excl max_rfer max_excl parent child
     -- -
0/5 16.00KiB 16.00KiB 0.00B 0.00B --- ---
0/257 0.00B 0.00B 0.00B 0.00B --- --- --- data and tree block 
both are cleaned
0/258 116.00KiB 116.00KiB 0.00B 0.00B --- --- -- quota numbers in 
snapshot qgroup is correct.


(1), quota is working well now in subvolume deleting.
(2), all operations are inserted by delayed-ref.

So, the conclusion seems like that:
(1), commit 1152651a was introducing a SUBTREE operation to account the 
number in subvolume deleted.

(2). SUBTREE is not working well.
(3). we can solve the same problem in a better way without introducing a 
new operation of SUBTREE.


To be honest, I am suspecting myself *very much*. I trust you guys and 
believe there must be something I am missing.


Then I send this mail to ask your help.

Thanx in advance.
Yang


On 02/10/2015 06:24 PM, Dongsheng Yang wrote:

In function of __btrfs_mod_ref(), we are passing the no_quota=1
to process_func() anyway. It will make the numbers in qgroup be
wrong when deleting a subvolume. The data size in a deleted subvolume
will never be decressed from all related qgroups.

Signed-off-by: Dongsheng Yang yangds.f...@cn.fujitsu.com
---
  fs/btrfs/extent-tree.c | 8 ++--
  1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index 652be74..f59809c 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -3056,6 +3056,7 @@ static int __btrfs_mod_ref(struct btrfs_trans_handle 
*trans,
int i;
int level;
int ret = 0;
+   int no_quota = 0;
int (*process_func)(struct btrfs_trans_handle *, struct btrfs_root *,
u64, u64, u64, u64, u64, u64, int);
  
@@ -3080,6 +3081,9 @@ static int __btrfs_mod_ref(struct btrfs_trans_handle *trans,

else
parent = 0;
  
+	if (!root-fs_info-quota_enabled || !is_fstree(ref_root))

+   no_quota = 1;
+
for (i = 0; i  nritems; i++) {
if (level == 0) {
btrfs_item_key_to_cpu(buf, key, i);
@@ -3098,7 +3102,7 @@ static int __btrfs_mod_ref(struct btrfs_trans_handle 
*trans,
key.offset -= btrfs_file_extent_offset(buf, fi);
ret = process_func(trans, root, bytenr, num_bytes,
   parent, ref_root, key.objectid,
-  key.offset, 1);
+  key.offset, no_quota);
if (ret)
goto fail;
} else {
@@ -3106,7 +3110,7

Re: [PATCH 3/3] btrfs: qgroup: fix a wrong parameter of no_quota.

2015-02-10 Thread Dongsheng Yang

On 02/10/2015 07:24 PM, Filipe David Manana wrote:

On Tue, Feb 10, 2015 at 10:24 AM, Dongsheng Yang
yangds.f...@cn.fujitsu.com wrote:

In function of __btrfs_mod_ref(), we are passing the no_quota=1
to process_func() anyway. It will make the numbers in qgroup be
wrong when deleting a subvolume. The data size in a deleted subvolume
will never be decressed from all related qgroups.

How about getting a test case for xfstests for this?


Good idea!!

Will do it.

Thanx


thanks


Signed-off-by: Dongsheng Yang yangds.f...@cn.fujitsu.com
---
  fs/btrfs/extent-tree.c | 8 ++--
  1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index 652be74..f59809c 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -3056,6 +3056,7 @@ static int __btrfs_mod_ref(struct btrfs_trans_handle 
*trans,
 int i;
 int level;
 int ret = 0;
+   int no_quota = 0;
 int (*process_func)(struct btrfs_trans_handle *, struct btrfs_root *,
 u64, u64, u64, u64, u64, u64, int);

@@ -3080,6 +3081,9 @@ static int __btrfs_mod_ref(struct btrfs_trans_handle 
*trans,
 else
 parent = 0;

+   if (!root-fs_info-quota_enabled || !is_fstree(ref_root))
+   no_quota = 1;
+
 for (i = 0; i  nritems; i++) {
 if (level == 0) {
 btrfs_item_key_to_cpu(buf, key, i);
@@ -3098,7 +3102,7 @@ static int __btrfs_mod_ref(struct btrfs_trans_handle 
*trans,
 key.offset -= btrfs_file_extent_offset(buf, fi);
 ret = process_func(trans, root, bytenr, num_bytes,
parent, ref_root, key.objectid,
-  key.offset, 1);
+  key.offset, no_quota);
 if (ret)
 goto fail;
 } else {
@@ -3106,7 +3110,7 @@ static int __btrfs_mod_ref(struct btrfs_trans_handle 
*trans,
 num_bytes = root-nodesize;
 ret = process_func(trans, root, bytenr, num_bytes,
parent, ref_root, level - 1, 0,
-  1);
+  no_quota);
 if (ret)
 goto fail;
 }
--
1.8.4.2

--
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





--
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


[PATCH 0/9] Btrfs: qgroup: part-1: bug fixes for qgroup inherit.

2015-02-10 Thread Dongsheng Yang
Hi all,

[1/9] is a RESEND with a reviewed-by.

[2/9]-[6/9] are bug fixes about qgroup_inherit(), these patch make
user can set the limits when creating a subvolume with the related
patch in userspace applied.

[7/9]-[8/9] are a cleanup for qgroup.

[9/9] provides a way for btrfs-progs to get the quota status by ioctl(),
then btrfs-progs can warn user when they are using qgroup with quota_disabled.

With this series patch applied, both btrfs and btrfs-progs:

[root@atest-guest linux_btrfs]# btrfs quota enable /mnt
[root@atest-guest linux_btrfs]# btrfs qgroup show -prce /mnt
qgroupid rfer excl max_rfer max_excl parent  child 
     --  - 
0/5  16.00KiB 16.00KiB0.00B0.00B --- ---  
[root@atest-guest linux_btrfs]# btrfs sub create /mnt/sub1
Create subvolume '/mnt/sub1'
[root@atest-guest linux_btrfs]# btrfs qgroup show -prce /mnt
qgroupid rfer excl max_rfer max_excl parent  child 
     --  - 
0/5  16.00KiB 16.00KiB0.00B0.00B --- ---  
0/25716.00KiB 16.00KiB0.00B0.00B --- ---  
[root@atest-guest linux_btrfs]# btrfs sub create /mnt/sub2 -r 10M -e 5M
Create subvolume '/mnt/sub2'
Set qgroup arguments:
max reference: 10485760
max exclusive: 5242880
[root@atest-guest linux_btrfs]# btrfs qgroup show -prce /mnt
qgroupid rfer excl max_rfer max_excl parent  child 
     --  - 
0/5  16.00KiB 16.00KiB0.00B0.00B --- ---  
0/25716.00KiB 16.00KiB0.00B0.00B --- ---  
0/25816.00KiB 16.00KiB 10.00MiB  5.00MiB --- --- 

Dongsheng Yang (8):
  btrfs: qgroup: move WARN_ON() to the correct location.
  btrfs: qgroup: inherit limit info from srcgroup in creating snapshot.
  btrfs: qgroup: update qgroup in memory at the same time when we update
it in btree.
  btrfs: qgroup: consolidate the parameter of fucntion
update_qgroup_limit_item().
  btrfs: qgroup: update limit info in function btrfs_run_qgroups().
  btrfs: qgroup: fix limit args override whole limit struct
  Btrfs: qgroup: make the btree for qgroup increase from left to right.
  Btrfs: qgroup: cleanup, remove an unsued parameter in
btrfs_create_qgroup().

Fan Chengniang (1):
  btrfs: qgroup: obtain quota status

 fs/btrfs/ioctl.c  |   9 +++-
 fs/btrfs/qgroup.c | 109 +++---
 fs/btrfs/qgroup.h |   6 ++-
 fs/btrfs/tests/qgroup-tests.c |   4 +-
 include/uapi/linux/btrfs.h|   3 ++
 5 files changed, 87 insertions(+), 44 deletions(-)

-- 
1.8.4.2

--
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


[PATCH 9/9] btrfs: qgroup: obtain quota status

2015-02-10 Thread Dongsheng Yang
From: Fan Chengniang fancn.f...@cn.fujitsu.com

add a function to obtain quota status. Now it can only get
whether quota is enabled. We can extend the function to get
more quota status

Signed-off-by: Fan Chengniang fancn.f...@cn.fujitsu.com
---
 fs/btrfs/ioctl.c   |  6 ++
 fs/btrfs/qgroup.c  | 14 ++
 fs/btrfs/qgroup.h  |  3 +++
 include/uapi/linux/btrfs.h |  3 +++
 4 files changed, 26 insertions(+)

diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
index 658d83d..f6e730b 100644
--- a/fs/btrfs/ioctl.c
+++ b/fs/btrfs/ioctl.c
@@ -4572,6 +4572,12 @@ static long btrfs_ioctl_quota_ctl(struct file *file, 
void __user *arg)
case BTRFS_QUOTA_CTL_DISABLE:
ret = btrfs_quota_disable(trans, root-fs_info);
break;
+   case BTRFS_QUOTA_CTL_STATUS:
+   ret = btrfs_quota_status(trans, root-fs_info, sa);
+   if (!ret)
+   if (copy_to_user(arg, sa, sizeof(*sa)))
+   ret = -EFAULT;
+   break;
default:
ret = -EINVAL;
break;
diff --git a/fs/btrfs/qgroup.c b/fs/btrfs/qgroup.c
index 24c5bb1..b57fe45 100644
--- a/fs/btrfs/qgroup.c
+++ b/fs/btrfs/qgroup.c
@@ -993,6 +993,20 @@ out:
return ret;
 }
 
+int btrfs_quota_status(struct btrfs_trans_handle *trans,
+   struct btrfs_fs_info *fs_info,
+   struct btrfs_ioctl_quota_ctl_args *sa)
+{
+   int ret = 0;
+
+   if (fs_info-quota_enabled)
+   sa-status |= BTRFS_QUOTA_STATUS_QUOTA_ENABLED;
+   else
+   sa-status = ~BTRFS_QUOTA_STATUS_QUOTA_ENABLED;
+
+   return ret;
+}
+
 static void qgroup_dirty(struct btrfs_fs_info *fs_info,
 struct btrfs_qgroup *qgroup)
 {
diff --git a/fs/btrfs/qgroup.h b/fs/btrfs/qgroup.h
index c5242aa..52d8b19 100644
--- a/fs/btrfs/qgroup.h
+++ b/fs/btrfs/qgroup.h
@@ -62,6 +62,9 @@ int btrfs_quota_enable(struct btrfs_trans_handle *trans,
   struct btrfs_fs_info *fs_info);
 int btrfs_quota_disable(struct btrfs_trans_handle *trans,
struct btrfs_fs_info *fs_info);
+int btrfs_quota_status(struct btrfs_trans_handle *trans,
+   struct btrfs_fs_info *fs_info,
+   struct btrfs_ioctl_quota_ctl_args *sa);
 int btrfs_qgroup_rescan(struct btrfs_fs_info *fs_info);
 void btrfs_qgroup_rescan_resume(struct btrfs_fs_info *fs_info);
 int btrfs_qgroup_wait_for_completion(struct btrfs_fs_info *fs_info);
diff --git a/include/uapi/linux/btrfs.h b/include/uapi/linux/btrfs.h
index 611e1c5..d4014e6 100644
--- a/include/uapi/linux/btrfs.h
+++ b/include/uapi/linux/btrfs.h
@@ -423,6 +423,9 @@ struct btrfs_ioctl_get_dev_stats {
 #define BTRFS_QUOTA_CTL_ENABLE 1
 #define BTRFS_QUOTA_CTL_DISABLE2
 #define BTRFS_QUOTA_CTL_RESCAN__NOTUSED3
+#define BTRFS_QUOTA_CTL_STATUS  4
+
+#define BTRFS_QUOTA_STATUS_QUOTA_ENABLED 1
 struct btrfs_ioctl_quota_ctl_args {
__u64 cmd;
__u64 status;
-- 
1.8.4.2

--
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


[PATCH 5/9] btrfs: qgroup: update limit info in function btrfs_run_qgroups().

2015-02-10 Thread Dongsheng Yang
When we commit_transaction(), qgroups in btree should be updated.
But, limit info is not considered currently. It will cause a problem
when a qgroup of a snapshot inherit the limit info from srcqgroup,
then there is an inconsistency.

Signed-off-by: Dongsheng Yang yangds.f...@cn.fujitsu.com
---
 fs/btrfs/qgroup.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/fs/btrfs/qgroup.c b/fs/btrfs/qgroup.c
index a7ffebb..953befd 100644
--- a/fs/btrfs/qgroup.c
+++ b/fs/btrfs/qgroup.c
@@ -2154,6 +2154,10 @@ int btrfs_run_qgroups(struct btrfs_trans_handle *trans,
if (ret)
fs_info-qgroup_flags |=
BTRFS_QGROUP_STATUS_FLAG_INCONSISTENT;
+   ret = update_qgroup_limit_item(trans, quota_root, qgroup);
+   if (ret)
+   fs_info-qgroup_flags |=
+   BTRFS_QGROUP_STATUS_FLAG_INCONSISTENT;
spin_lock(fs_info-qgroup_lock);
}
if (fs_info-quota_enabled)
-- 
1.8.4.2

--
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


[PATCH 4/4] btrfs: qgroup: do a reservation in a higher level.

2015-02-10 Thread Dongsheng Yang
There are two problems in qgroup:

a). The PAGE_CACHE is 4K, even when we are writing a data of 1K,
qgroup will reserve a 4K size. It will cause the last 3K in a qgroup
is not available to user.

b). When user is writing a inline data, qgroup will not reserve it,
it means this is a window we can exceed the limit of a qgroup.

The main idea of this patch is reserving the data size of write_bytes
rather than the reserve_bytes. It means qgroup will not care about
the data size btrfs will reserve for user, but only care about the
data size user is going to write. Then reserve it when user want to
write and release it in transaction committed.

In this way, qgroup can be released from the complex procedure in
btrfs and only do the reserve when user want to write and account
when the data is written in commit_transaction().

Signed-off-by: Dongsheng Yang yangds.f...@cn.fujitsu.com
---
 fs/btrfs/ctree.h   |  2 +-
 fs/btrfs/extent-tree.c | 38 +--
 fs/btrfs/file.c|  4 +--
 fs/btrfs/inode.c   | 15 ---
 fs/btrfs/qgroup.c  | 70 +++---
 fs/btrfs/qgroup.h  |  4 ---
 fs/btrfs/relocation.c  |  2 +-
 7 files changed, 14 insertions(+), 121 deletions(-)

diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
index 7e60741..1d17e7a 100644
--- a/fs/btrfs/ctree.h
+++ b/fs/btrfs/ctree.h
@@ -3433,7 +3433,7 @@ enum btrfs_reserve_flush_enum {
BTRFS_RESERVE_FLUSH_ALL,
 };
 
-int btrfs_check_data_free_space(struct inode *inode, u64 bytes);
+int btrfs_check_data_free_space(struct inode *inode, u64 bytes, u64 
write_bytes);
 void btrfs_free_reserved_data_space(struct inode *inode, u64 bytes);
 void btrfs_trans_release_metadata(struct btrfs_trans_handle *trans,
struct btrfs_root *root);
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index 67c2e28..652be74 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -3286,7 +3286,7 @@ again:
num_pages *= 16;
num_pages *= PAGE_CACHE_SIZE;
 
-   ret = btrfs_check_data_free_space(inode, num_pages);
+   ret = btrfs_check_data_free_space(inode, num_pages, num_pages);
if (ret)
goto out_put;
 
@@ -3673,7 +3673,7 @@ u64 btrfs_get_alloc_profile(struct btrfs_root *root, int 
data)
  * This will check the space that the inode allocates from to make sure we have
  * enough space for bytes.
  */
-int btrfs_check_data_free_space(struct inode *inode, u64 bytes)
+int btrfs_check_data_free_space(struct inode *inode, u64 bytes, u64 
write_bytes)
 {
struct btrfs_space_info *data_sinfo;
struct btrfs_root *root = BTRFS_I(inode)-root;
@@ -3774,7 +3774,7 @@ commit_trans:
  data_sinfo-flags, bytes, 1);
return -ENOSPC;
}
-   ret = btrfs_qgroup_reserve(root, bytes);
+   ret = btrfs_qgroup_reserve(root, write_bytes);
if (ret)
goto out;
data_sinfo-bytes_may_use += bytes;
@@ -3800,7 +3800,6 @@ void btrfs_free_reserved_data_space(struct inode *inode, 
u64 bytes)
data_sinfo = root-fs_info-data_sinfo;
spin_lock(data_sinfo-lock);
WARN_ON(data_sinfo-bytes_may_use  bytes);
-   btrfs_qgroup_free(root, bytes);
data_sinfo-bytes_may_use -= bytes;
trace_btrfs_space_reservation(root-fs_info, space_info,
  data_sinfo-flags, bytes, 0);
@@ -5041,8 +5040,6 @@ void btrfs_subvolume_release_metadata(struct btrfs_root 
*root,
  u64 qgroup_reserved)
 {
btrfs_block_rsv_release(root, rsv, (u64)-1);
-   if (qgroup_reserved)
-   btrfs_qgroup_free(root, qgroup_reserved);
 }
 
 /**
@@ -5278,11 +5275,8 @@ out_fail:
to_free = 0;
}
spin_unlock(BTRFS_I(inode)-lock);
-   if (dropped) {
-   if (root-fs_info-quota_enabled)
-   btrfs_qgroup_free(root, dropped * root-nodesize);
+   if (dropped)
to_free += btrfs_calc_trans_metadata_size(root, dropped);
-   }
 
if (to_free) {
btrfs_block_rsv_release(root, block_rsv, to_free);
@@ -5321,9 +5315,6 @@ void btrfs_delalloc_release_metadata(struct inode *inode, 
u64 num_bytes)
 
trace_btrfs_space_reservation(root-fs_info, delalloc,
  btrfs_ino(inode), to_free, 0);
-   if (root-fs_info-quota_enabled) {
-   btrfs_qgroup_free(root, dropped * root-nodesize);
-   }
 
btrfs_block_rsv_release(root, root-fs_info-delalloc_block_rsv,
to_free);
@@ -5348,7 +5339,7 @@ int btrfs_delalloc_reserve_space(struct inode *inode, u64 
num_bytes)
 {
int ret;
 
-   ret = btrfs_check_data_free_space(inode, num_bytes);
+   ret = btrfs_check_data_free_space(inode, num_bytes, num_bytes);
if (ret)
return ret

[PATCH 4/9] btrfs: qgroup: consolidate the parameter of fucntion update_qgroup_limit_item().

2015-02-10 Thread Dongsheng Yang
Cleanup: Change the parameter of update_qgroup_limit_item() to the family of
update_qgroup_xxx_item().

Signed-off-by: Dongsheng Yang yangds.f...@cn.fujitsu.com
---
 fs/btrfs/qgroup.c | 51 ---
 1 file changed, 24 insertions(+), 27 deletions(-)

diff --git a/fs/btrfs/qgroup.c b/fs/btrfs/qgroup.c
index 1aae0c3..a7ffebb 100644
--- a/fs/btrfs/qgroup.c
+++ b/fs/btrfs/qgroup.c
@@ -644,9 +644,8 @@ out:
 }
 
 static int update_qgroup_limit_item(struct btrfs_trans_handle *trans,
-   struct btrfs_root *root, u64 qgroupid,
-   u64 flags, u64 max_rfer, u64 max_excl,
-   u64 rsv_rfer, u64 rsv_excl)
+   struct btrfs_root *root,
+   struct btrfs_qgroup *qgroup)
 {
struct btrfs_path *path;
struct btrfs_key key;
@@ -657,7 +656,7 @@ static int update_qgroup_limit_item(struct 
btrfs_trans_handle *trans,
 
key.objectid = 0;
key.type = BTRFS_QGROUP_LIMIT_KEY;
-   key.offset = qgroupid;
+   key.offset = qgroup-qgroupid;
 
path = btrfs_alloc_path();
if (!path)
@@ -673,11 +672,11 @@ static int update_qgroup_limit_item(struct 
btrfs_trans_handle *trans,
l = path-nodes[0];
slot = path-slots[0];
qgroup_limit = btrfs_item_ptr(l, slot, struct btrfs_qgroup_limit_item);
-   btrfs_set_qgroup_limit_flags(l, qgroup_limit, flags);
-   btrfs_set_qgroup_limit_max_rfer(l, qgroup_limit, max_rfer);
-   btrfs_set_qgroup_limit_max_excl(l, qgroup_limit, max_excl);
-   btrfs_set_qgroup_limit_rsv_rfer(l, qgroup_limit, rsv_rfer);
-   btrfs_set_qgroup_limit_rsv_excl(l, qgroup_limit, rsv_excl);
+   btrfs_set_qgroup_limit_flags(l, qgroup_limit, qgroup-lim_flags);
+   btrfs_set_qgroup_limit_max_rfer(l, qgroup_limit, qgroup-max_rfer);
+   btrfs_set_qgroup_limit_max_excl(l, qgroup_limit, qgroup-max_excl);
+   btrfs_set_qgroup_limit_rsv_rfer(l, qgroup_limit, qgroup-rsv_rfer);
+   btrfs_set_qgroup_limit_rsv_excl(l, qgroup_limit, qgroup-rsv_excl);
 
btrfs_mark_buffer_dirty(l);
 
@@ -1184,15 +1183,6 @@ int btrfs_limit_qgroup(struct btrfs_trans_handle *trans,
ret = -ENOENT;
goto out;
}
-   ret = update_qgroup_limit_item(trans, quota_root, qgroupid,
-  limit-flags, limit-max_rfer,
-  limit-max_excl, limit-rsv_rfer,
-  limit-rsv_excl);
-   if (ret) {
-   fs_info-qgroup_flags |= BTRFS_QGROUP_STATUS_FLAG_INCONSISTENT;
-   btrfs_info(fs_info, unable to update quota limit for %llu,
-  qgroupid);
-   }
 
spin_lock(fs_info-qgroup_lock);
qgroup-lim_flags = limit-flags;
@@ -1201,6 +1191,14 @@ int btrfs_limit_qgroup(struct btrfs_trans_handle *trans,
qgroup-rsv_rfer = limit-rsv_rfer;
qgroup-rsv_excl = limit-rsv_excl;
spin_unlock(fs_info-qgroup_lock);
+
+   ret = update_qgroup_limit_item(trans, quota_root, qgroup);
+   if (ret) {
+   fs_info-qgroup_flags |= BTRFS_QGROUP_STATUS_FLAG_INCONSISTENT;
+   btrfs_info(fs_info, unable to update quota limit for %llu,
+  qgroupid);
+   }
+
 out:
mutex_unlock(fs_info-qgroup_ioctl_lock);
return ret;
@@ -2276,20 +2274,19 @@ int btrfs_qgroup_inherit(struct btrfs_trans_handle 
*trans,
}
 
if (inherit  inherit-flags  BTRFS_QGROUP_INHERIT_SET_LIMITS) {
-   ret = update_qgroup_limit_item(trans, quota_root, objectid,
-  inherit-lim.flags,
-  inherit-lim.max_rfer,
-  inherit-lim.max_excl,
-  inherit-lim.rsv_rfer,
-  inherit-lim.rsv_excl);
-   if (ret)
-   goto unlock;
-
dstgroup-lim_flags = inherit-lim.flags;
dstgroup-max_rfer = inherit-lim.max_rfer;
dstgroup-max_excl = inherit-lim.max_excl;
dstgroup-rsv_rfer = inherit-lim.rsv_rfer;
dstgroup-rsv_excl = inherit-lim.rsv_excl;
+
+   ret = update_qgroup_limit_item(trans, quota_root, dstgroup);
+   if (ret) {
+   fs_info-qgroup_flags |= 
BTRFS_QGROUP_STATUS_FLAG_INCONSISTENT;
+   btrfs_info(fs_info, unable to update quota limit for 
%llu,
+  dstgroup-qgroupid);
+   goto unlock;
+   }
}
 
if (srcid) {
-- 
1.8.4.2

--
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

[PATCH 1/2] btrfs-progs:correct the return value

2015-02-10 Thread Dongsheng Yang
From: Fan Chengniang fancn.f...@cn.fujitsu.com

the return values 12 and 13 are not used spectially except as
return value. No description and definition about them. so I
change them to generic errno

Signed-off-by: Fan Chengniang fancn.f...@cn.fujitsu.com
---
 qgroup.c | 7 ---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/qgroup.c b/qgroup.c
index d59f4bb..5a4e393 100644
--- a/qgroup.c
+++ b/qgroup.c
@@ -21,6 +21,7 @@
 #include ctree.h
 #include ioctl.h
 #include utils.h
+#include errno.h
 
 #define BTRFS_QGROUP_NFILTERS_INCREASE (2 * BTRFS_QGROUP_FILTER_MAX)
 #define BTRFS_QGROUP_NCOMPS_INCREASE (2 * BTRFS_QGROUP_COMP_MAX)
@@ -1294,7 +1295,7 @@ qgroup_inherit_realloc(struct btrfs_qgroup_inherit 
**inherit, int n, int pos)
out = calloc(sizeof(*out) + sizeof(out-qgroups[0]) * (nitems + n), 1);
if (out == NULL) {
fprintf(stderr, ERROR: Not enough memory\n);
-   return 13;
+   return -ENOMEM;
}
 
if (*inherit) {
@@ -1322,7 +1323,7 @@ int qgroup_inherit_add_group(struct btrfs_qgroup_inherit 
**inherit, char *arg)
 
if (qgroupid == 0) {
fprintf(stderr, ERROR: bad qgroup specification\n);
-   return 12;
+   return -EINVAL;
}
 
if (*inherit)
@@ -1349,7 +1350,7 @@ int qgroup_inherit_add_copy(struct btrfs_qgroup_inherit 
**inherit, char *arg,
if (!p) {
 bad:
fprintf(stderr, ERROR: bad copy specification\n);
-   return 12;
+   return -EINVAL;
}
*p = 0;
qgroup_src = parse_qgroupid(arg);
-- 
1.8.4.2

--
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


[PATCH 1/3] btrfs: qgroup: return EINVAL if level of parent is not higher than child's.

2015-02-10 Thread Dongsheng Yang
When we create a subvol inheriting a qgroup, we need to check the level
of them. Otherwise, there is a chance a qgroup can inherit another qgroup
at the same level.

Signed-off-by: Dongsheng Yang yangds.f...@cn.fujitsu.com
---
 fs/btrfs/qgroup.c | 5 +
 1 file changed, 5 insertions(+)

diff --git a/fs/btrfs/qgroup.c b/fs/btrfs/qgroup.c
index 5a1463d..d519055 100644
--- a/fs/btrfs/qgroup.c
+++ b/fs/btrfs/qgroup.c
@@ -2244,6 +2244,11 @@ int btrfs_qgroup_inherit(struct btrfs_trans_handle 
*trans,
ret = -EINVAL;
goto out;
}
+
+   if ((srcgroup-qgroupid  48) = (objectid  48)) {
+   ret = -EINVAL;
+   goto out;
+   }
++i_qgroups;
}
}
-- 
1.8.4.2

--
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


[PATCH 3/3] btrfs: qgroup: fix a wrong parameter of no_quota.

2015-02-10 Thread Dongsheng Yang
In function of __btrfs_mod_ref(), we are passing the no_quota=1
to process_func() anyway. It will make the numbers in qgroup be
wrong when deleting a subvolume. The data size in a deleted subvolume
will never be decressed from all related qgroups.

Signed-off-by: Dongsheng Yang yangds.f...@cn.fujitsu.com
---
 fs/btrfs/extent-tree.c | 8 ++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index 652be74..f59809c 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -3056,6 +3056,7 @@ static int __btrfs_mod_ref(struct btrfs_trans_handle 
*trans,
int i;
int level;
int ret = 0;
+   int no_quota = 0;
int (*process_func)(struct btrfs_trans_handle *, struct btrfs_root *,
u64, u64, u64, u64, u64, u64, int);
 
@@ -3080,6 +3081,9 @@ static int __btrfs_mod_ref(struct btrfs_trans_handle 
*trans,
else
parent = 0;
 
+   if (!root-fs_info-quota_enabled || !is_fstree(ref_root))
+   no_quota = 1;
+
for (i = 0; i  nritems; i++) {
if (level == 0) {
btrfs_item_key_to_cpu(buf, key, i);
@@ -3098,7 +3102,7 @@ static int __btrfs_mod_ref(struct btrfs_trans_handle 
*trans,
key.offset -= btrfs_file_extent_offset(buf, fi);
ret = process_func(trans, root, bytenr, num_bytes,
   parent, ref_root, key.objectid,
-  key.offset, 1);
+  key.offset, no_quota);
if (ret)
goto fail;
} else {
@@ -3106,7 +3110,7 @@ static int __btrfs_mod_ref(struct btrfs_trans_handle 
*trans,
num_bytes = root-nodesize;
ret = process_func(trans, root, bytenr, num_bytes,
   parent, ref_root, level - 1, 0,
-  1);
+  no_quota);
if (ret)
goto fail;
}
-- 
1.8.4.2

--
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


[PATCH 2/2] btrfs-progs:set max_rfer and max_excl on creating new subvolume

2015-02-10 Thread Dongsheng Yang
From: Fan Chengniang fancn.f...@cn.fujitsu.com

add -r and -e options to enable setting max reference size
and max exclusive on creating new subvolumes.

Signed-off-by: Fan Chengniang fancn.f...@cn.fujitsu.com
---
 Documentation/btrfs-subvolume.txt |  8 +++-
 cmds-qgroup.c | 42 --
 cmds-subvolume.c  | 57 +++-
 ioctl.h   |  3 ++
 qgroup.c  | 92 +++
 qgroup.h  |  3 ++
 6 files changed, 160 insertions(+), 45 deletions(-)

diff --git a/Documentation/btrfs-subvolume.txt 
b/Documentation/btrfs-subvolume.txt
index b0ae030..fe13943 100644
--- a/Documentation/btrfs-subvolume.txt
+++ b/Documentation/btrfs-subvolume.txt
@@ -43,7 +43,7 @@ from normal directories.
 
 SUBCOMMAND
 ---
-*create* [-i qgroupid] [dest]name::
+*create* [-i qgroupid] [-r max_rfer] [-e max_excl] [dest]name::
 Create a subvolume name in dest.
 +
 If dest is not given, subvolume name will be created in the currently
@@ -54,6 +54,12 @@ directory.
 -i qgroupid
 Add the newly created subvolume to a qgroup. This option can be given multiple
 times.
++
+-r max_rfer
+set the newly created subvolume's max reference size
++
+-e max_excl
+set the newly created subvolume's max exclusive size
 
 *delete* [options] subvolume [subvolume...]::
 Delete the subvolume(s) from the filesystem.
diff --git a/cmds-qgroup.c b/cmds-qgroup.c
index 2172944..30f0851 100644
--- a/cmds-qgroup.c
+++ b/cmds-qgroup.c
@@ -106,48 +106,6 @@ static int qgroup_create(int create, int argc, char **argv)
return 0;
 }
 
-static int parse_limit(const char *p, unsigned long long *s)
-{
-   char *endptr;
-   unsigned long long size;
-
-   if (strcasecmp(p, none) == 0) {
-   *s = 0;
-   return 1;
-   }
-   size = strtoull(p, endptr, 10);
-   switch (*endptr) {
-   case 'T':
-   case 't':
-   size *= 1024;
-   /* fallthrough */
-   case 'G':
-   case 'g':
-   size *= 1024;
-   /* fallthrough */
-   case 'M':
-   case 'm':
-   size *= 1024;
-   /* fallthrough */
-   case 'K':
-   case 'k':
-   size *= 1024;
-   ++endptr;
-   break;
-   case 0:
-   break;
-   default:
-   return 0;
-   }
-
-   if (*endptr)
-   return 0;
-
-   *s = size;
-
-   return 1;
-}
-
 static const char * const cmd_qgroup_assign_usage[] = {
btrfs qgroup assign src dst path,
Enable subvolume qgroup support for a filesystem.,
diff --git a/cmds-subvolume.c b/cmds-subvolume.c
index a31cb1b..f0e22ac 100644
--- a/cmds-subvolume.c
+++ b/cmds-subvolume.c
@@ -42,13 +42,15 @@ static const char * const subvolume_cmd_group_usage[] = {
 };
 
 static const char * const cmd_subvol_create_usage[] = {
-   btrfs subvolume create [-i qgroupid] [dest/]name,
+   btrfs subvolume create [-i qgroupid] [-r max_rfer] [-e max_excl] 
[dest/]name,
Create a subvolume,
Create a subvolume name in dest.  If dest is not given,
subvolume name will be created in the current directory.,
,
-i qgroupid  add the newly created subvolume to a qgroup. This,
   option can be given multiple times.,
+   -r max_rfer  set the newly created subvolume's max reference size,
+   -e max_excl  set the newly created subvolume's max exclusive size,
NULL
 };
 
@@ -66,7 +68,7 @@ static int cmd_subvol_create(int argc, char **argv)
 
optind = 1;
while (1) {
-   int c = getopt(argc, argv, c:i:v);
+   int c = getopt(argc, argv, c:i:r:e:v);
if (c  0)
break;
 
@@ -85,6 +87,20 @@ static int cmd_subvol_create(int argc, char **argv)
goto out;
}
break;
+   case 'r':
+   res = qgroup_inherit_set_maxrfer(inherit, optarg);
+   if (res) {
+   retval = res;
+   goto out;
+   }
+   break;
+   case 'e':
+   res = qgroup_inherit_set_maxexcl(inherit, optarg);
+   if (res) {
+   retval = res;
+   goto out;
+   }
+   break;
default:
usage(cmd_subvol_create_usage);
}
@@ -129,6 +145,43 @@ static int cmd_subvol_create(int argc, char **argv)
printf(Create subvolume '%s/%s'\n, dstdir, newname);
if (inherit) {
struct btrfs_ioctl_vol_args_v2  args;
+   struct btrfs_ioctl_quota_ctl_args sa;
+
+   

[PATCH 0/4] Btrfs: qgroup: part-2: bug fixes for qgroup reservation.

2015-02-10 Thread Dongsheng Yang
Hi all,
This is part2 for qgroup. It is based on 
[PATCH 0/9] Btrfs: qgroup: part-1: bug fixes.

[1/4] is reviewed-by Josef.

[2/4] - [4/4] are trying to solve a problem in qgroup reservation.
It would be weired I introduce a may_use in 2/4 and delete it in 4/4.

Yes, I am glad to rebase and squash them, here I am keeping this history
of the problem for reviewing. I have explained the problem and sent the
[2/4] out. Josef give me a looks good at that time. But in the later, I
found another problem and solved it with [4/4]. So they are trying to
solve different problems at different timing. When the all patches are
reviewed by you guys, I am okey to squash them if you request.

Thanx.

Dongsheng Yang (4):
  Btrfs: qgroup: free reserved in exceeding quota.
  Btrfs: qgroup: Introduce a may_use to account
space_info-bytes_may_use.
  Btrfs: qgroup, Account data space in more proper timings.
  btrfs: qgroup: do a reservation in a higher level.

 fs/btrfs/ctree.h   |  2 +-
 fs/btrfs/extent-tree.c | 25 +++--
 fs/btrfs/file.c| 13 ++---
 fs/btrfs/inode.c   |  3 ++-
 fs/btrfs/qgroup.c  | 10 --
 fs/btrfs/relocation.c  |  2 +-
 6 files changed, 21 insertions(+), 34 deletions(-)

-- 
1.8.4.2

--
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


[PATCH 3/9] btrfs: qgroup: update qgroup in memory at the same time when we update it in btree.

2015-02-10 Thread Dongsheng Yang
When we call btrfs_qgroup_inherit() with BTRFS_QGROUP_INHERIT_SET_LIMITS,
btrfs will update the limit info of qgroup in btree but forget to update
the qgroup in rbtree at the same time. It obviousely will cause an 
inconsistency.

This patch fix it by updating the rbtree at the same time.

Signed-off-by: Dongsheng Yang yangds.f...@cn.fujitsu.com
---
 fs/btrfs/qgroup.c | 28 +---
 1 file changed, 17 insertions(+), 11 deletions(-)

diff --git a/fs/btrfs/qgroup.c b/fs/btrfs/qgroup.c
index b2cee33..1aae0c3 100644
--- a/fs/btrfs/qgroup.c
+++ b/fs/btrfs/qgroup.c
@@ -2230,17 +2230,6 @@ int btrfs_qgroup_inherit(struct btrfs_trans_handle 
*trans,
if (ret)
goto out;
 
-   if (inherit  inherit-flags  BTRFS_QGROUP_INHERIT_SET_LIMITS) {
-   ret = update_qgroup_limit_item(trans, quota_root, objectid,
-  inherit-lim.flags,
-  inherit-lim.max_rfer,
-  inherit-lim.max_excl,
-  inherit-lim.rsv_rfer,
-  inherit-lim.rsv_excl);
-   if (ret)
-   goto out;
-   }
-
if (srcid) {
struct btrfs_root *srcroot;
struct btrfs_key srckey;
@@ -2286,6 +2275,23 @@ int btrfs_qgroup_inherit(struct btrfs_trans_handle 
*trans,
goto unlock;
}
 
+   if (inherit  inherit-flags  BTRFS_QGROUP_INHERIT_SET_LIMITS) {
+   ret = update_qgroup_limit_item(trans, quota_root, objectid,
+  inherit-lim.flags,
+  inherit-lim.max_rfer,
+  inherit-lim.max_excl,
+  inherit-lim.rsv_rfer,
+  inherit-lim.rsv_excl);
+   if (ret)
+   goto unlock;
+
+   dstgroup-lim_flags = inherit-lim.flags;
+   dstgroup-max_rfer = inherit-lim.max_rfer;
+   dstgroup-max_excl = inherit-lim.max_excl;
+   dstgroup-rsv_rfer = inherit-lim.rsv_rfer;
+   dstgroup-rsv_excl = inherit-lim.rsv_excl;
+   }
+
if (srcid) {
srcgroup = find_qgroup_rb(fs_info, srcid);
if (!srcgroup)
-- 
1.8.4.2

--
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


[PATCH 8/9] Btrfs: qgroup: cleanup, remove an unsued parameter in btrfs_create_qgroup().

2015-02-10 Thread Dongsheng Yang
Signed-off-by: Dongsheng Yang yangds.f...@cn.fujitsu.com
---
 fs/btrfs/ioctl.c  | 3 +--
 fs/btrfs/qgroup.c | 2 +-
 fs/btrfs/qgroup.h | 3 +--
 fs/btrfs/tests/qgroup-tests.c | 4 ++--
 4 files changed, 5 insertions(+), 7 deletions(-)

diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
index d49fe8a..658d83d 100644
--- a/fs/btrfs/ioctl.c
+++ b/fs/btrfs/ioctl.c
@@ -4669,8 +4669,7 @@ static long btrfs_ioctl_qgroup_create(struct file *file, 
void __user *arg)
 
/* FIXME: check if the IDs really exist */
if (sa-create) {
-   ret = btrfs_create_qgroup(trans, root-fs_info, sa-qgroupid,
- NULL);
+   ret = btrfs_create_qgroup(trans, root-fs_info, sa-qgroupid);
} else {
ret = btrfs_remove_qgroup(trans, root-fs_info, sa-qgroupid);
}
diff --git a/fs/btrfs/qgroup.c b/fs/btrfs/qgroup.c
index d3c261b..24c5bb1 100644
--- a/fs/btrfs/qgroup.c
+++ b/fs/btrfs/qgroup.c
@@ -1094,7 +1094,7 @@ out:
 }
 
 int btrfs_create_qgroup(struct btrfs_trans_handle *trans,
-   struct btrfs_fs_info *fs_info, u64 qgroupid, char *name)
+   struct btrfs_fs_info *fs_info, u64 qgroupid)
 {
struct btrfs_root *quota_root;
struct btrfs_qgroup *qgroup;
diff --git a/fs/btrfs/qgroup.h b/fs/btrfs/qgroup.h
index 18cc68c..c5242aa 100644
--- a/fs/btrfs/qgroup.h
+++ b/fs/btrfs/qgroup.h
@@ -70,8 +70,7 @@ int btrfs_add_qgroup_relation(struct btrfs_trans_handle 
*trans,
 int btrfs_del_qgroup_relation(struct btrfs_trans_handle *trans,
  struct btrfs_fs_info *fs_info, u64 src, u64 dst);
 int btrfs_create_qgroup(struct btrfs_trans_handle *trans,
-   struct btrfs_fs_info *fs_info, u64 qgroupid,
-   char *name);
+   struct btrfs_fs_info *fs_info, u64 qgroupid);
 int btrfs_remove_qgroup(struct btrfs_trans_handle *trans,
  struct btrfs_fs_info *fs_info, u64 qgroupid);
 int btrfs_limit_qgroup(struct btrfs_trans_handle *trans,
diff --git a/fs/btrfs/tests/qgroup-tests.c b/fs/btrfs/tests/qgroup-tests.c
index ec3dcb2..bcc1c7a 100644
--- a/fs/btrfs/tests/qgroup-tests.c
+++ b/fs/btrfs/tests/qgroup-tests.c
@@ -232,7 +232,7 @@ static int test_no_shared_qgroup(struct btrfs_root *root)
init_dummy_trans(trans);
 
test_msg(Qgroup basic add\n);
-   ret = btrfs_create_qgroup(NULL, fs_info, 5, NULL);
+   ret = btrfs_create_qgroup(NULL, fs_info, 5);
if (ret) {
test_msg(Couldn't create a qgroup %d\n, ret);
return ret;
@@ -301,7 +301,7 @@ static int test_multiple_refs(struct btrfs_root *root)
test_msg(Qgroup multiple refs test\n);
 
/* We have 5 created already from the previous test */
-   ret = btrfs_create_qgroup(NULL, fs_info, 256, NULL);
+   ret = btrfs_create_qgroup(NULL, fs_info, 256);
if (ret) {
test_msg(Couldn't create a qgroup %d\n, ret);
return ret;
-- 
1.8.4.2

--
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


[PATCH 0/3] Btrfs: qgroup: part-3: bug fixes for deleting subvolume.

2015-02-10 Thread Dongsheng Yang
Hi all,
This is a part3 for qgroup, it is based on
Btrfs: qgroup: part-2: bug fixes.

Dongsheng Yang (3):
  btrfs: qgroup: return EINVAL if level of parent is not higher than
child's.
  btrfs: qgroup: allow to remove qgroup which has parent but no child.
  btrfs: qgroup: fix a wrong parameter of no_quota.

 fs/btrfs/extent-tree.c |  8 ++--
 fs/btrfs/qgroup.c  | 35 ++-
 2 files changed, 36 insertions(+), 7 deletions(-)

-- 
1.8.4.2

--
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


[PATCH 2/9] btrfs: qgroup: inherit limit info from srcgroup in creating snapshot.

2015-02-10 Thread Dongsheng Yang
Currently, when we snapshot a subvol, snapshot will not copy the limits
from srcqgroup.

This patch make the qgroup in snapshot inherit the limit info when create
a snapshot.

Signed-off-by: Dongsheng Yang yangds.f...@cn.fujitsu.com
---
 fs/btrfs/qgroup.c | 8 
 1 file changed, 8 insertions(+)

diff --git a/fs/btrfs/qgroup.c b/fs/btrfs/qgroup.c
index 97159a8..b2cee33 100644
--- a/fs/btrfs/qgroup.c
+++ b/fs/btrfs/qgroup.c
@@ -2302,6 +2302,14 @@ int btrfs_qgroup_inherit(struct btrfs_trans_handle 
*trans,
dstgroup-excl_cmpr = level_size;
srcgroup-excl = level_size;
srcgroup-excl_cmpr = level_size;
+
+   /* inherit the limit info */
+   dstgroup-lim_flags = srcgroup-lim_flags;
+   dstgroup-max_rfer = srcgroup-max_rfer;
+   dstgroup-max_excl = srcgroup-max_excl;
+   dstgroup-rsv_rfer = srcgroup-rsv_rfer;
+   dstgroup-rsv_excl = srcgroup-rsv_excl;
+
qgroup_dirty(fs_info, dstgroup);
qgroup_dirty(fs_info, srcgroup);
}
-- 
1.8.4.2

--
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


[PATCH 1/9] btrfs: qgroup: move WARN_ON() to the correct location.

2015-02-10 Thread Dongsheng Yang
In function qgroup_excl_accounting(), we need to WARN when
qg-excl is less than what we want to free, same to child
and parents. But currently, for parent qgroup, the WARN_ON()
is located after freeing qg-excl. It will WARN out even we
free it normally.

This patch move this WARN_ON() before freeing qg-excl.

Signed-off-by: Dongsheng Yang yangds.f...@cn.fujitsu.com
Reviewed-by: Satoru Takeuchi takeuchi_sat...@jp.fujitsu.com
---
 fs/btrfs/qgroup.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/fs/btrfs/qgroup.c b/fs/btrfs/qgroup.c
index 48b60db..97159a8 100644
--- a/fs/btrfs/qgroup.c
+++ b/fs/btrfs/qgroup.c
@@ -1431,9 +1431,8 @@ static int qgroup_excl_accounting(struct btrfs_fs_info 
*fs_info,
qgroup = u64_to_ptr(unode-aux);
qgroup-rfer += sign * oper-num_bytes;
qgroup-rfer_cmpr += sign * oper-num_bytes;
+   WARN_ON(sign  0  qgroup-excl  oper-num_bytes);
qgroup-excl += sign * oper-num_bytes;
-   if (sign  0)
-   WARN_ON(qgroup-excl  oper-num_bytes);
qgroup-excl_cmpr += sign * oper-num_bytes;
qgroup_dirty(fs_info, qgroup);
 
-- 
1.8.4.2

--
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


[PATCH 7/9] Btrfs: qgroup: make the btree for qgroup increase from left to right.

2015-02-10 Thread Dongsheng Yang
It's not a big deal, but I would rather make the btree follow the
convention to increase from left to right.

Signed-off-by: Dongsheng Yang yangds.f...@cn.fujitsu.com
---
 fs/btrfs/qgroup.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/fs/btrfs/qgroup.c b/fs/btrfs/qgroup.c
index 34717ed..d3c261b 100644
--- a/fs/btrfs/qgroup.c
+++ b/fs/btrfs/qgroup.c
@@ -117,9 +117,9 @@ static struct btrfs_qgroup *find_qgroup_rb(struct 
btrfs_fs_info *fs_info,
while (n) {
qgroup = rb_entry(n, struct btrfs_qgroup, node);
if (qgroup-qgroupid  qgroupid)
-   n = n-rb_left;
-   else if (qgroup-qgroupid  qgroupid)
n = n-rb_right;
+   else if (qgroup-qgroupid  qgroupid)
+   n = n-rb_left;
else
return qgroup;
}
@@ -139,9 +139,9 @@ static struct btrfs_qgroup *add_qgroup_rb(struct 
btrfs_fs_info *fs_info,
qgroup = rb_entry(parent, struct btrfs_qgroup, node);
 
if (qgroup-qgroupid  qgroupid)
-   p = (*p)-rb_left;
-   else if (qgroup-qgroupid  qgroupid)
p = (*p)-rb_right;
+   else if (qgroup-qgroupid  qgroupid)
+   p = (*p)-rb_left;
else
return qgroup;
}
-- 
1.8.4.2

--
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


[PATCH 6/9] btrfs: qgroup: fix limit args override whole limit struct

2015-02-10 Thread Dongsheng Yang
btrfs_limit_group use arg limit to override the old qgroup_limit of
corresponding qgroup. However, we should override part of old qgroup_limit
according to the bit which has been set in arg limit.

Signed-off-by: Fan Chengniang fancn.f...@cn.fujitsu.com
Signed-off-by: Dongsheng Yang yangds.f...@cn.fujitsu.com
---
 fs/btrfs/qgroup.c | 15 ++-
 1 file changed, 10 insertions(+), 5 deletions(-)

diff --git a/fs/btrfs/qgroup.c b/fs/btrfs/qgroup.c
index 953befd..34717ed 100644
--- a/fs/btrfs/qgroup.c
+++ b/fs/btrfs/qgroup.c
@@ -1185,11 +1185,16 @@ int btrfs_limit_qgroup(struct btrfs_trans_handle *trans,
}
 
spin_lock(fs_info-qgroup_lock);
-   qgroup-lim_flags = limit-flags;
-   qgroup-max_rfer = limit-max_rfer;
-   qgroup-max_excl = limit-max_excl;
-   qgroup-rsv_rfer = limit-rsv_rfer;
-   qgroup-rsv_excl = limit-rsv_excl;
+   if (limit-flags  BTRFS_QGROUP_LIMIT_MAX_RFER)
+   qgroup-max_rfer = limit-max_rfer;
+   if (limit-flags  BTRFS_QGROUP_LIMIT_MAX_EXCL)
+   qgroup-max_excl = limit-max_excl;
+   if (limit-flags  BTRFS_QGROUP_LIMIT_RSV_RFER)
+   qgroup-rsv_rfer = limit-rsv_rfer;
+   if (limit-flags  BTRFS_QGROUP_LIMIT_RSV_EXCL)
+   qgroup-rsv_excl = limit-rsv_excl;
+   qgroup-lim_flags |= limit-flags;
+
spin_unlock(fs_info-qgroup_lock);
 
ret = update_qgroup_limit_item(trans, quota_root, qgroup);
-- 
1.8.4.2

--
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


[PATCH 5/7] btrfs: qgroup: Apply qgroup type to subvol creating.

2015-02-10 Thread Dongsheng Yang
Although we have a type in each qgroup, the all qgroups
are created in a default mode. This patch provide a
method to user to specify the type of qgroup for a sub volume.

It uses an unused byte in btrfs_ioctl_vol_args_v2 to pass
a qgroup type from userspace to kernel. Then kernel can
create a qgroup with requested type to the subvolume.

Signed-off-by: Dongsheng Yang yangds.f...@cn.fujitsu.com
---
 fs/btrfs/ioctl.c   | 38 --
 fs/btrfs/qgroup.c  |  9 ++---
 fs/btrfs/qgroup.h  |  2 +-
 fs/btrfs/transaction.c |  2 +-
 include/uapi/linux/btrfs.h |  1 +
 5 files changed, 37 insertions(+), 15 deletions(-)

diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
index b1f46e8..a6d83c4 100644
--- a/fs/btrfs/ioctl.c
+++ b/fs/btrfs/ioctl.c
@@ -432,7 +432,8 @@ static noinline int create_subvol(struct inode *dir,
  struct dentry *dentry,
  char *name, int namelen,
  u64 *async_transid,
- struct btrfs_qgroup_inherit *inherit)
+ struct btrfs_qgroup_inherit *inherit,
+ u8 qgroup_type)
 {
struct btrfs_trans_handle *trans;
struct btrfs_key key;
@@ -476,7 +477,7 @@ static noinline int create_subvol(struct inode *dir,
trans-block_rsv = block_rsv;
trans-bytes_reserved = block_rsv.size;
 
-   ret = btrfs_qgroup_inherit(trans, root-fs_info, 0, objectid, inherit);
+   ret = btrfs_qgroup_inherit(trans, root-fs_info, 0, objectid, inherit, 
qgroup_type);
if (ret)
goto fail;
 
@@ -808,7 +809,8 @@ static noinline int btrfs_mksubvol(struct path *parent,
   char *name, int namelen,
   struct btrfs_root *snap_src,
   u64 *async_transid, bool readonly,
-  struct btrfs_qgroup_inherit *inherit)
+  struct btrfs_qgroup_inherit *inherit,
+  u8 qgroup_type)
 {
struct inode *dir  = parent-dentry-d_inode;
struct dentry *dentry;
@@ -851,7 +853,7 @@ static noinline int btrfs_mksubvol(struct path *parent,
async_transid, readonly, inherit);
} else {
error = create_subvol(dir, dentry, name, namelen,
- async_transid, inherit);
+ async_transid, inherit, qgroup_type);
}
if (!error)
fsnotify_mkdir(dir, dentry);
@@ -1594,7 +1596,8 @@ out:
 static noinline int btrfs_ioctl_snap_create_transid(struct file *file,
char *name, unsigned long fd, int subvol,
u64 *transid, bool readonly,
-   struct btrfs_qgroup_inherit *inherit)
+   struct btrfs_qgroup_inherit *inherit,
+   u8 qgroup_type)
 {
int namelen;
int ret = 0;
@@ -1617,7 +1620,8 @@ static noinline int 
btrfs_ioctl_snap_create_transid(struct file *file,
 
if (subvol) {
ret = btrfs_mksubvol(file-f_path, name, namelen,
-NULL, transid, readonly, inherit);
+NULL, transid, readonly, inherit,
+qgroup_type);
} else {
struct fd src = fdget(fd);
struct inode *src_inode;
@@ -1640,7 +1644,8 @@ static noinline int 
btrfs_ioctl_snap_create_transid(struct file *file,
} else {
ret = btrfs_mksubvol(file-f_path, name, namelen,
 BTRFS_I(src_inode)-root,
-transid, readonly, inherit);
+transid, readonly, inherit,
+qgroup_type);
}
fdput(src);
}
@@ -1663,7 +1668,8 @@ static noinline int btrfs_ioctl_snap_create(struct file 
*file,
 
ret = btrfs_ioctl_snap_create_transid(file, vol_args-name,
  vol_args-fd, subvol,
- NULL, false, NULL);
+ NULL, false, NULL,
+ BTRFS_QGROUP_TYPE_DEFAULT);
 
kfree(vol_args);
return ret;
@@ -1673,11 +1679,13 @@ static noinline int btrfs_ioctl_snap_create_v2(struct 
file *file,
   void __user *arg, int subvol)
 {
struct btrfs_ioctl_vol_args_v2 *vol_args;
+   struct btrfs_root *root = BTRFS_I(file_inode(file))-root;
int ret;
u64 transid = 0;
u64 *ptr = NULL

[PATCH 3/4] Btrfs: qgroup, Account data space in more proper timings.

2015-02-10 Thread Dongsheng Yang
Currenly, in data writing, -reserved is accounted in
fill_delalloc(), but -may_use is released in clear_bit_hook()
which is called by btrfs_finish_ordered_io(). That's too late,
that said, between fill_delalloc() and btrfs_finish_ordered_io(),
the data is doublely accounted by qgroup. It will cause some
unexpected -EDQUOT.

Example:
# btrfs quota enable /root/btrfs-auto-test/
# btrfs subvolume create /root/btrfs-auto-test//sub
Create subvolume '/root/btrfs-auto-test/sub'
# btrfs qgroup limit 1G /root/btrfs-auto-test//sub
dd if=/dev/zero of=/root/btrfs-auto-test//sub/file bs=1024 count=150
dd: error writing '/root/btrfs-auto-test//sub/file': Disk quota exceeded
681353+0 records in
681352+0 records out
697704448 bytes (698 MB) copied, 8.15563 s, 85.5 MB/s
It's (698 MB) when we got an -EDQUOT, but we limit it by 1G.

This patch move the btrfs_qgroup_reserve/free() for data from
btrfs_delalloc_reserve/release_metadata() to btrfs_check_data_free_space()
and btrfs_free_reserved_data_space(). Then the accounter in qgroup
will be updated at the same time with the accounter in space_info updated.
In this way, the unexpected -EDQUOT will be killed.

Reported-by: Satoru Takeuchi takeuchi_sat...@jp.fujitsu.com
Signed-off-by: Dongsheng Yang yangds.f...@cn.fujitsu.com
---
 fs/btrfs/extent-tree.c | 16 +---
 fs/btrfs/file.c|  9 -
 2 files changed, 9 insertions(+), 16 deletions(-)

diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index d1a7ce0..67c2e28 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -3774,12 +3774,16 @@ commit_trans:
  data_sinfo-flags, bytes, 1);
return -ENOSPC;
}
+   ret = btrfs_qgroup_reserve(root, bytes);
+   if (ret)
+   goto out;
data_sinfo-bytes_may_use += bytes;
trace_btrfs_space_reservation(root-fs_info, space_info,
  data_sinfo-flags, bytes, 1);
+out:
spin_unlock(data_sinfo-lock);
 
-   return 0;
+   return ret;
 }
 
 /*
@@ -3796,6 +3800,7 @@ void btrfs_free_reserved_data_space(struct inode *inode, 
u64 bytes)
data_sinfo = root-fs_info-data_sinfo;
spin_lock(data_sinfo-lock);
WARN_ON(data_sinfo-bytes_may_use  bytes);
+   btrfs_qgroup_free(root, bytes);
data_sinfo-bytes_may_use -= bytes;
trace_btrfs_space_reservation(root-fs_info, space_info,
  data_sinfo-flags, bytes, 0);
@@ -5191,8 +5196,7 @@ int btrfs_delalloc_reserve_metadata(struct inode *inode, 
u64 num_bytes)
spin_unlock(BTRFS_I(inode)-lock);
 
if (root-fs_info-quota_enabled) {
-   ret = btrfs_qgroup_reserve(root, num_bytes +
-  nr_extents * root-nodesize);
+   ret = btrfs_qgroup_reserve(root, nr_extents * root-nodesize);
if (ret)
goto out_fail;
}
@@ -5200,8 +5204,7 @@ int btrfs_delalloc_reserve_metadata(struct inode *inode, 
u64 num_bytes)
ret = reserve_metadata_bytes(root, block_rsv, to_reserve, flush);
if (unlikely(ret)) {
if (root-fs_info-quota_enabled)
-   btrfs_qgroup_free(root, num_bytes +
-   nr_extents * root-nodesize);
+   btrfs_qgroup_free(root, nr_extents * root-nodesize);
goto out_fail;
}
 
@@ -5319,8 +5322,7 @@ void btrfs_delalloc_release_metadata(struct inode *inode, 
u64 num_bytes)
trace_btrfs_space_reservation(root-fs_info, delalloc,
  btrfs_ino(inode), to_free, 0);
if (root-fs_info-quota_enabled) {
-   btrfs_qgroup_free(root, num_bytes +
-   dropped * root-nodesize);
+   btrfs_qgroup_free(root, dropped * root-nodesize);
}
 
btrfs_block_rsv_release(root, root-fs_info-delalloc_block_rsv,
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c
index e409025..0ab1333 100644
--- a/fs/btrfs/file.c
+++ b/fs/btrfs/file.c
@@ -2527,7 +2527,6 @@ static long btrfs_fallocate(struct file *file, int mode,
 {
struct inode *inode = file_inode(file);
struct extent_state *cached_state = NULL;
-   struct btrfs_root *root = BTRFS_I(inode)-root;
u64 cur_offset;
u64 last_byte;
u64 alloc_start;
@@ -2555,11 +2554,6 @@ static long btrfs_fallocate(struct file *file, int mode,
ret = btrfs_check_data_free_space(inode, alloc_end - alloc_start);
if (ret)
return ret;
-   if (root-fs_info-quota_enabled) {
-   ret = btrfs_qgroup_reserve(root, alloc_end - alloc_start);
-   if (ret)
-   goto out_reserve_fail;
-   }
 
mutex_lock(inode-i_mutex);
ret = inode_newsize_ok(inode

[PATCH 2/4] Btrfs: qgroup: Introduce a may_use to account space_info-bytes_may_use.

2015-02-10 Thread Dongsheng Yang
Currently, for pre_alloc or delay_alloc, the bytes will be accounted
in space_info by the three guys.
space_info-bytes_may_use --- space_info-reserved --- space_info-used.
But on the other hand, in qgroup, there are only two counters to account the
bytes, qgroup-reserved and qgroup-excl. And qg-reserved accounts
bytes in space_info-bytes_may_use and qg-excl accounts bytes in
space_info-used. So the bytes in space_info-reserved is not accounted
in qgroup. If so, there is a window we can exceed the quota limit when
bytes is in space_info-reserved.

Example:
# btrfs quota enable /mnt
# btrfs qgroup limit -e 10M /mnt
# for((i=0;i20;i++));do fallocate -l 1M /mnt/data$i; done
# sync
# btrfs qgroup show -pcre /mnt
qgroupid rfer excl max_rfer max_excl parent  child
     --  -
0/5  20987904 20987904 010485760 --- ---

qg-excl is 20987904 larger than max_excl 10485760.

This patch introduce a new counter named may_use to qgroup, then
there are three counters in qgroup to account bytes in space_info
as below.
space_info-bytes_may_use --- space_info-reserved --- space_info-used.
qgroup-may_use   --- qgroup-reserved --- qgroup-excl

With this patch applied:
# btrfs quota enable /mnt
# btrfs qgroup limit -e 10M /mnt
# for((i=0;i20;i++));do fallocate -l 1M /mnt/data$i; done
fallocate: /mnt/data9: fallocate failed: Disk quota exceeded
fallocate: /mnt/data10: fallocate failed: Disk quota exceeded
fallocate: /mnt/data11: fallocate failed: Disk quota exceeded
fallocate: /mnt/data12: fallocate failed: Disk quota exceeded
fallocate: /mnt/data13: fallocate failed: Disk quota exceeded
fallocate: /mnt/data14: fallocate failed: Disk quota exceeded
fallocate: /mnt/data15: fallocate failed: Disk quota exceeded
fallocate: /mnt/data16: fallocate failed: Disk quota exceeded
fallocate: /mnt/data17: fallocate failed: Disk quota exceeded
fallocate: /mnt/data18: fallocate failed: Disk quota exceeded
fallocate: /mnt/data19: fallocate failed: Disk quota exceeded
# sync
# btrfs qgroup show -pcre /mnt
qgroupid rferexclmax_rfer max_excl parent  child
   --  -
0/5  9453568 9453568 010485760 --- ---

Reported-by: Cyril SCETBON cyril.scet...@free.fr
Signed-off-by: Dongsheng Yang yangds.f...@cn.fujitsu.com
---
 fs/btrfs/extent-tree.c | 20 ++-
 fs/btrfs/inode.c   | 18 -
 fs/btrfs/qgroup.c  | 68 +++---
 fs/btrfs/qgroup.h  |  4 +++
 4 files changed, 104 insertions(+), 6 deletions(-)

diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index 88b4e32..d1a7ce0 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -5512,8 +5512,12 @@ static int pin_down_extent(struct btrfs_root *root,
 
set_extent_dirty(root-fs_info-pinned_extents, bytenr,
 bytenr + num_bytes - 1, GFP_NOFS | __GFP_NOFAIL);
-   if (reserved)
+   if (reserved) {
+   btrfs_qgroup_update_reserved_bytes(root-fs_info,
+  root-root_key.objectid,
+  num_bytes, -1);
trace_btrfs_reserved_extent_free(root, bytenr, num_bytes);
+   }
return 0;
 }
 
@@ -6244,6 +6248,9 @@ void btrfs_free_tree_block(struct btrfs_trans_handle 
*trans,
btrfs_update_reserved_bytes(cache, buf-len, RESERVE_FREE, 0);
trace_btrfs_reserved_extent_free(root, buf-start, buf-len);
pin = 0;
+   btrfs_qgroup_update_reserved_bytes(root-fs_info,
+  root-root_key.objectid,
+  buf-len, -1);
}
 out:
if (pin)
@@ -6978,7 +6985,11 @@ static int __btrfs_free_reserved_extent(struct 
btrfs_root *root,
else {
btrfs_add_free_space(cache, start, len);
btrfs_update_reserved_bytes(cache, len, RESERVE_FREE, delalloc);
+   btrfs_qgroup_update_reserved_bytes(root-fs_info,
+  root-root_key.objectid,
+  len, -1);
}
+
btrfs_put_block_group(cache);
 
trace_btrfs_reserved_extent_free(root, start, len);
@@ -7214,6 +7225,9 @@ int btrfs_alloc_logged_file_extent(struct 
btrfs_trans_handle *trans,
BUG_ON(ret); /* logic error */
ret = alloc_reserved_file_extent(trans, root, 0, root_objectid,
 0, owner, offset, ins, 1);
+   btrfs_qgroup_update_reserved_bytes(root-fs_info,
+  root-root_key.objectid,
+  ins-offset, 1);
btrfs_put_block_group(block_group);
return ret

[PATCH 4/4] btrfs-progs:show qgroup type

2015-02-10 Thread Dongsheng Yang
From: Fan Chengniang fancn.f...@cn.fujitsu.com

make 'btrfs qgroup show' command show qgroup type.

Signed-off-by: Fan Chengniang fancn.f...@cn.fujitsu.com
---
 qgroup.c | 42 +++---
 qgroup.h |  1 +
 2 files changed, 40 insertions(+), 3 deletions(-)

diff --git a/qgroup.c b/qgroup.c
index a647925..d359659 100644
--- a/qgroup.c
+++ b/qgroup.c
@@ -135,6 +135,13 @@ static struct {
.max_len= 5,
},
{
+   .name   = type,
+   .column_name= Type,
+   .need_print = 1,
+   .unit_mode  = 0,
+   .max_len= 8,
+   },
+   {
.name   = NULL,
.column_name= NULL,
.need_print = 0,
@@ -201,6 +208,20 @@ static int print_child_column(struct btrfs_qgroup *qgroup)
return len;
 }
 
+static int print_type_column(struct btrfs_qgroup *qgroup)
+{
+   __u8 type = qgroup-type;
+   int len = 0;
+
+   if (type == BTRFS_QGROUP_TYPE_DATA)
+   len = printf(data);
+   if (type == BTRFS_QGROUP_TYPE_METADATA)
+   len = printf(metadata);
+   if (type == BTRFS_QGROUP_TYPE_MIXED)
+   len = printf(metadata,data);
+   return len;
+}
+
 static void print_qgroup_column_add_blank(enum btrfs_qgroup_column_enum column,
  int len)
 {
@@ -244,6 +265,10 @@ static void print_qgroup_column(struct btrfs_qgroup 
*qgroup,
len = print_child_column(qgroup);
print_qgroup_column_add_blank(BTRFS_QGROUP_CHILD, len);
break;
+   case BTRFS_QGROUP_TYPE:
+   len = print_type_column(qgroup);
+   print_qgroup_column_add_blank(BTRFS_QGROUP_TYPE, len);
+   break;
default:
break;
}
@@ -258,7 +283,7 @@ static void print_single_qgroup_table(struct btrfs_qgroup 
*qgroup)
continue;
print_qgroup_column(qgroup, i);
 
-   if (i != BTRFS_QGROUP_CHILD)
+   if (i != BTRFS_QGROUP_ALL - 1)
printf( );
}
printf(\n);
@@ -275,7 +300,7 @@ static void print_table_head()
if (!btrfs_qgroup_columns[i].need_print)
continue;
if ((i == BTRFS_QGROUP_QGROUPID) | (i == BTRFS_QGROUP_PARENT) |
-   (i == BTRFS_QGROUP_CHILD))
+   (i == BTRFS_QGROUP_CHILD) | (i == BTRFS_QGROUP_TYPE))
printf(%-*s, max_len, btrfs_qgroup_columns[i].name);
else
printf(%*s, max_len, btrfs_qgroup_columns[i].name);
@@ -287,7 +312,7 @@ static void print_table_head()
if (!btrfs_qgroup_columns[i].need_print)
continue;
if ((i == BTRFS_QGROUP_QGROUPID) | (i == BTRFS_QGROUP_PARENT) |
-   (i == BTRFS_QGROUP_CHILD)) {
+   (i == BTRFS_QGROUP_CHILD) | (i == BTRFS_QGROUP_TYPE)) {
len = strlen(btrfs_qgroup_columns[i].name);
while (len--)
printf(-);
@@ -976,6 +1001,17 @@ static void __update_columns_max_len(struct btrfs_qgroup 
*bq,
if (btrfs_qgroup_columns[column].max_len  len)
btrfs_qgroup_columns[column].max_len = len;
break;
+   case BTRFS_QGROUP_TYPE:
+   len = 0;
+   if (bq-type == BTRFS_QGROUP_TYPE_DATA)
+   len = strlen(data);
+   if (bq-type == BTRFS_QGROUP_TYPE_METADATA)
+   len = strlen(metadata);
+   if (bq-type == BTRFS_QGROUP_TYPE_MIXED)
+   len = strlen(metadata,data);
+   if (btrfs_qgroup_columns[column].max_len  len)
+   btrfs_qgroup_columns[column].max_len = len;
+   break;
default:
break;
}
diff --git a/qgroup.h b/qgroup.h
index 8423fdf..cc61477 100644
--- a/qgroup.h
+++ b/qgroup.h
@@ -75,6 +75,7 @@ enum btrfs_qgroup_column_enum {
BTRFS_QGROUP_MAX_EXCL,
BTRFS_QGROUP_PARENT,
BTRFS_QGROUP_CHILD,
+BTRFS_QGROUP_TYPE,
BTRFS_QGROUP_ALL,
 };
 
-- 
1.8.4.2

--
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


[PATCH 3/4] btrfs-progs:specify qgroup type when creating qgroup

2015-02-10 Thread Dongsheng Yang
From: Fan Chengniang fancn.f...@cn.fujitsu.com

add --qgroup-type option to specify qgroup type. Type
can be metadata, data or mixed.

Signed-off-by: Fan Chengniang fancn.f...@cn.fujitsu.com
Signed-off-by: Dongsheng Yang yangds.f...@cn.fujitsu.com
---
 Documentation/btrfs-qgroup.txt |  5 +
 cmds-qgroup.c  | 37 ++---
 2 files changed, 39 insertions(+), 3 deletions(-)

diff --git a/Documentation/btrfs-qgroup.txt b/Documentation/btrfs-qgroup.txt
index eadfe1c..7b07e97 100644
--- a/Documentation/btrfs-qgroup.txt
+++ b/Documentation/btrfs-qgroup.txt
@@ -45,6 +45,11 @@ Create a subvolume quota group.
 +
 For the '0/subvolume id' qgroup, a qgroup can be created even before the
 subvolume created.
++
+--qgroup-type=type
+specify the type of qgroup to set qgroup limit.
++
+attr can be one of metadata, data, mixed.
 
 *destroy* qgroupid path::
 Destroy a qgroup.
diff --git a/cmds-qgroup.c b/cmds-qgroup.c
index 30f0851..23accdf 100644
--- a/cmds-qgroup.c
+++ b/cmds-qgroup.c
@@ -78,16 +78,45 @@ static int qgroup_create(int create, int argc, char **argv)
int ret = 0;
int fd;
int e;
-   char *path = argv[2];
+   char *path = argv[argc - 1];
struct btrfs_ioctl_qgroup_create_args args;
DIR *dirstream = NULL;
+   __u8 qgroup_type = 0;
+   __u64 create_type;
 
-   if (check_argc_exact(argc, 3))
+   optind = 1;
+   while (1) {
+   int c;
+   static const struct option long_options[] = {
+   {qgroup-type, required_argument, NULL, 'q'},
+   {NULL, 0, NULL, 0}
+   };
+
+   c = getopt_long(argc, argv, , long_options, NULL);
+   if (c  0)
+   break;
+
+   switch (c) {
+   case 'q':
+   ret = btrfs_qgroup_set_qgroup_type(qgroup_type, 
optarg);
+   if (ret)
+   return -1;
+   break;
+   default:
+   return -1;
+   }
+   }
+
+   if (check_argc_exact(argc - optind, 2))
return -1;
 
memset(args, 0, sizeof(args));
args.create = create;
-   args.qgroupid = parse_qgroupid(argv[1]);
+   if (create  qgroup_type) {
+   create_type = qgroup_type;
+   args.create |= (create_type  BTRFS_QGROUP_TYPE_SHIFT);
+   }
+   args.qgroupid = parse_qgroupid(argv[argc - 2]);
 
fd = open_file_or_dir(path, dirstream);
if (fd  0) {
@@ -137,6 +166,8 @@ static int cmd_qgroup_remove(int argc, char **argv)
 static const char * const cmd_qgroup_create_usage[] = {
btrfs qgroup create qgroupid path,
Create a subvolume quota group.,
+   --qgroup-type=metadata,data,mixed,
+  specify which qgroup type to set qgroup limit,
NULL
 };
 
-- 
1.8.4.2

--
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


[PATCH 3/7] btrfs: qgroup: Apply type to btrfs_qgroup_inherit().

2015-02-10 Thread Dongsheng Yang
Now, we have a type in each qgroup, then when we do a inherit(),
we need to consider the type of qgroup to decide account metadata
or not.

Signed-off-by: Dongsheng Yang yangds.f...@cn.fujitsu.com
---
 fs/btrfs/qgroup.c | 18 ++
 1 file changed, 14 insertions(+), 4 deletions(-)

diff --git a/fs/btrfs/qgroup.c b/fs/btrfs/qgroup.c
index 2fa8497..0129dae 100644
--- a/fs/btrfs/qgroup.c
+++ b/fs/btrfs/qgroup.c
@@ -2382,10 +2382,20 @@ int btrfs_qgroup_inherit(struct btrfs_trans_handle 
*trans,
dstgroup-type = srcgroup-type;
dstgroup-rfer = srcgroup-rfer;
dstgroup-rfer_cmpr = srcgroup-rfer_cmpr;
-   dstgroup-excl = level_size;
-   dstgroup-excl_cmpr = level_size;
-   srcgroup-excl = level_size;
-   srcgroup-excl_cmpr = level_size;
+   if (dstgroup-type  BTRFS_QGROUP_TYPE_METADATA) {
+   dstgroup-excl = level_size;
+   dstgroup-excl_cmpr = level_size;
+   } else {
+   dstgroup-excl = 0;
+   dstgroup-excl_cmpr = 0;
+   }
+   if (srcgroup-type  BTRFS_QGROUP_TYPE_METADATA) {
+   srcgroup-excl = level_size;
+   srcgroup-excl_cmpr = level_size;
+   } else {
+   srcgroup-excl = 0;
+   srcgroup-excl_cmpr = 0;
+   }
 
/* inherit the limit info */
dstgroup-lim_flags = srcgroup-lim_flags;
-- 
1.8.4.2

--
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


[PATCH 4/7] btrfs: qgroup: Apply qgroup type to qgroup creating.

2015-02-10 Thread Dongsheng Yang
This patch provide a method to user to create a qgroup
in a specified type.

It use a byte of the -create in btrfs_ioctl_qgroup_create_args
to pass the type of qgroup to kernel. Then there is a macro
named as BTRFS_QGROUP_TYPE_SHIFT to help kernel get the type
of qgroup user want to creat.

Signed-off-by: Dongsheng Yang yangds.f...@cn.fujitsu.com
---
 fs/btrfs/ioctl.c  | 12 ++--
 fs/btrfs/qgroup.h |  6 ++
 2 files changed, 16 insertions(+), 2 deletions(-)

diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
index a50f295..b1f46e8 100644
--- a/fs/btrfs/ioctl.c
+++ b/fs/btrfs/ioctl.c
@@ -4675,8 +4675,16 @@ static long btrfs_ioctl_qgroup_create(struct file *file, 
void __user *arg)
 
/* FIXME: check if the IDs really exist */
if (sa-create) {
-   ret = btrfs_create_qgroup(trans, root-fs_info, sa-qgroupid,
- BTRFS_QGROUP_TYPE_DEFAULT);
+   u8 type = (sa-create  BTRFS_QGROUP_TYPE_SHIFT);
+   if (type) {
+   if (!btrfs_fs_incompat(root-fs_info, QGROUP_TYPE)) {
+   ret = -EINVAL;
+   goto out;
+   }
+   } else {
+   type = BTRFS_QGROUP_TYPE_DEFAULT;
+   }
+   ret = btrfs_create_qgroup(trans, root-fs_info, sa-qgroupid, 
type);
} else {
ret = btrfs_remove_qgroup(trans, root-fs_info, sa-qgroupid);
}
diff --git a/fs/btrfs/qgroup.h b/fs/btrfs/qgroup.h
index 75d0bb6..0be0548 100644
--- a/fs/btrfs/qgroup.h
+++ b/fs/btrfs/qgroup.h
@@ -30,6 +30,12 @@
 #define BTRFS_QGROUP_TYPE_DEFAULT  BTRFS_QGROUP_TYPE_MIXED
 
 /*
+ * We are using the first byte in -create of btrfs_ioctl_qgroup_create_args
+ * to specify the type of the qgroup to be created.
+ */
+#define BTRFS_QGROUP_TYPE_SHIFT56
+
+/*
  * A description of the operations, all of these operations only happen when we
  * are adding the 1st reference for that subvolume in the case of adding space
  * or on the last reference delete in the case of subtraction.  The only
-- 
1.8.4.2

--
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


[RFC PATCH 0/7] Btrfs: qgroup: part-4: Add type to btrfs qgroup.

2015-02-10 Thread Dongsheng Yang
Hi all,
This patchset is based on [Btrfs: qgroup: part-3: bug fixes.]

I am introducing a type to qgroup, then we can get the numbers what we
only care about.

Easy way to get the code for testing:
btrfs: https://yangdongsh...@github.com/yangdongsheng/linux.git 
qgroup_type
  btrfs-progs: https://yangdongsh...@github.com/yangdongsheng/btrfs-progs.git 
qgroup_type
with the patches applied in this series, both in btrfs and btrfs-progs:

[root@atest-guest linux_btrfs]# mkfs.btrfs -O qgroup-type /dev/sdc -f
Btrfs v3.18-76-ga900a61
See http://btrfs.wiki.kernel.org for more information.

Turning ON incompat feature 'extref': increased hardlink limit per file to 65536
Turning ON incompat feature 'skinny-metadata': reduced-size metadata extent refs
Turning ON incompat feature 'qgroup-type': create qgroup in different type
fs created label (null) on /dev/sdc
nodesize 16384 leafsize 16384 sectorsize 4096 size 10.00GiB
[root@atest-guest linux_btrfs]# mount /dev/sdc  /mnt/
[root@atest-guest linux_btrfs]# btrfs quota enable /mnt
[root@atest-guest linux_btrfs]# btrfs qgroup show -prce /mnt
qgroupid rfer excl max_rfer max_excl parent  child type 
 
     --  -  
 
0/5  16.00KiB 16.00KiB0.00B0.00B --- ---   
metadata,data
[root@atest-guest linux_btrfs]# btrfs qgroup show -prce /mnt
qgroupid rfer excl max_rfer max_excl parent  child type 
 
     --  -  
 
0/5  16.00KiB 16.00KiB0.00B0.00B --- ---   
metadata,data
0/25716.00KiB 16.00KiB0.00B0.00B --- ---   
metadata,data --- default type is mixed.
[root@atest-guest linux_btrfs]# btrfs sub create --qgroup-type data /mnt/sub1
Create subvolume '/mnt/sub1'
Set qgroup arguments:
qgroup type: data
[root@atest-guest linux_btrfs]# btrfs qgroup show -prce /mnt
qgroupid rfer excl max_rfer max_excl parent  child type 
 
     --  -  
 
0/5  16.00KiB 16.00KiB0.00B0.00B --- ---   
metadata,data
0/25716.00KiB 16.00KiB0.00B0.00B --- ---   
metadata,data
0/258   0.00B0.00B0.00B0.00B --- ---   data 
 --- create a data qgroup
[root@atest-guest linux_btrfs]# btrfs qgroup limit -e 5M 0/258 /mnt
[root@atest-guest linux_btrfs]# btrfs qgroup show -prce /mnt
qgroupid rfer excl max_rfer max_excl parent  child type 
 
     --  -  
 
0/5  16.00KiB 16.00KiB0.00B0.00B --- ---   
metadata,data
0/25716.00KiB 16.00KiB0.00B0.00B --- ---   
metadata,data
0/258   0.00B0.00B0.00B  5.00MiB --- ---   data 
   
[root@atest-guest linux_btrfs]# dd if=/dev/zero of=/mnt/sub1/data bs=1024
dd: error writing \u2018/mnt/sub1/data\u2019: Disk quota exceeded
5121+0 records in
5120+0 records out
5242880 bytes (5.2 MB) copied, 0.0218646 s, 240 MB/s
[root@atest-guest linux_btrfs]# sync
[root@atest-guest linux_btrfs]# ll /mnt/sub1/data 
-rw-r--r--. 1 root root 5242880 Feb 10 16:17 /mnt/sub1/data
[root@atest-guest linux_btrfs]# btrfs qgroup show -prce --raw /mnt
qgroupid rfer excl max_rfer max_excl parent  child type 
 
     --  -  
 
0/5 163841638400 --- ---   
metadata,data
0/257   163841638400 --- ---   
metadata,data
0/258 5242880  52428800  5242880 --- ---   data 
--- excl == max_excl == data_size == 5M == 5242880

Dongsheng Yang (7):
  Btrfs: qgroup: Add type to btrfs_qgroup.
  btrfs: qgroup: apply type to the recording and accounting.
  btrfs: qgroup: Apply type to btrfs_qgroup_inherit().
  btrfs: qgroup: Apply qgroup type to qgroup creating.
  btrfs: qgroup: Apply qgroup type to subvol creating.
  btrfs: qgroup: apply type to quota rescan.
  btrfs: qgroup: fix a bug when type of parent is different with
child's.

 fs/btrfs/ctree.h  |  10 ++-
 fs/btrfs/extent-tree.c|  48 ++-
 fs/btrfs/ioctl.c  |  49 ---
 fs/btrfs/qgroup.c | 186 --
 fs/btrfs/qgroup.h |  29 ++-
 fs/btrfs/tests/qgroup-tests.c |  19 +++--
 fs/btrfs/transaction.c|  13 +--
 include/uapi/linux/btrfs.h|   1 +
 8 files changed, 246 insertions(+), 109 deletions(-)

-- 
1.8.4.2

--
To unsubscribe from this list: send the line unsubscribe linux-btrfs

[PATCH 2/4] btrfs-progs: specify qgroup type when creating subvolume

2015-02-10 Thread Dongsheng Yang
From: Fan Chengniang fancn.f...@cn.fujitsu.com

add --qgroup-type option to specify qgroup type. Type
can be metadata, data or all.

Signed-off-by: Fan Chengniang fancn.f...@cn.fujitsu.com
Signed-off-by: Dongsheng Yang yangds.f...@cn.fujitsu.com
---
 Documentation/btrfs-subvolume.txt |  4 
 cmds-subvolume.c  | 50 +--
 qgroup.c  | 15 
 qgroup.h  |  1 +
 4 files changed, 63 insertions(+), 7 deletions(-)

diff --git a/Documentation/btrfs-subvolume.txt 
b/Documentation/btrfs-subvolume.txt
index fe13943..4ac8cf5 100644
--- a/Documentation/btrfs-subvolume.txt
+++ b/Documentation/btrfs-subvolume.txt
@@ -60,6 +60,10 @@ set the newly created subvolume's max reference size
 +
 -e max_excl
 set the newly created subvolume's max exclusive size
+--qgroup-type=type
+specify the type of qgroup to set qgroup limit.
++
+attr can be one of metadata, data, mixed.
 
 *delete* [options] subvolume [subvolume...]::
 Delete the subvolume(s) from the filesystem.
diff --git a/cmds-subvolume.c b/cmds-subvolume.c
index f0e22ac..871f749 100644
--- a/cmds-subvolume.c
+++ b/cmds-subvolume.c
@@ -51,6 +51,8 @@ static const char * const cmd_subvol_create_usage[] = {
   option can be given multiple times.,
-r max_rfer  set the newly created subvolume's max reference size,
-e max_excl  set the newly created subvolume's max exclusive size,
+   --qgroup-type=metadata,data,mixed,
+  specify which qgroup type to set qgroup limit,
NULL
 };
 
@@ -65,10 +67,19 @@ static int cmd_subvol_create(int argc, char **argv)
char*dst;
struct btrfs_qgroup_inherit *inherit = NULL;
DIR *dirstream = NULL;
+   __u8qgroup_type = 0;
+   int set_qgroup_type = 0;
 
optind = 1;
while (1) {
-   int c = getopt(argc, argv, c:i:r:e:v);
+   int c;
+   static const struct option long_options[] = {
+   {qgroup-type, required_argument, NULL, 'q'},
+   {NULL, 0, NULL, 0}
+   };
+
+   c = getopt_long(argc, argv, c:i:r:e:v,
+   long_options, NULL);
if (c  0)
break;
 
@@ -101,6 +112,14 @@ static int cmd_subvol_create(int argc, char **argv)
goto out;
}
break;
+   case 'q':
+   set_qgroup_type = 1;
+   res = btrfs_qgroup_set_qgroup_type(qgroup_type, 
optarg);
+   if (res) {
+   retval = res;
+   goto out;
+   }
+   break;
default:
usage(cmd_subvol_create_usage);
}
@@ -143,11 +162,21 @@ static int cmd_subvol_create(int argc, char **argv)
}
 
printf(Create subvolume '%s/%s'\n, dstdir, newname);
-   if (inherit) {
-   struct btrfs_ioctl_vol_args_v2  args;
-   struct btrfs_ioctl_quota_ctl_args sa;
 
+   if (set_qgroup_type || inherit)
printf(Set qgroup arguments:\n);
+
+   if (set_qgroup_type) {
+   if (qgroup_type != 0) {
+   printf(\tqgroup type: );
+   if (qgroup_type  BTRFS_QGROUP_TYPE_METADATA)
+   printf(metadata );
+   if (qgroup_type  BTRFS_QGROUP_TYPE_DATA)
+   printf(data);
+   printf(\n);
+   }
+   }
+   if (inherit) {
if (inherit-num_qgroups  0) {
__u64 index;
__u64 qgroupid;
@@ -168,7 +197,11 @@ static int cmd_subvol_create(int argc, char **argv)
printf(\tmax exclusive: %llu\n,
inherit-lim.max_exclusive);
}
+   }
 
+   if (inherit || set_qgroup_type) {
+   struct btrfs_ioctl_vol_args_v2  args;
+   struct btrfs_ioctl_quota_ctl_args sa;
sa.cmd = BTRFS_QUOTA_CTL_STATUS;
res = ioctl(fddst, BTRFS_IOC_QUOTA_CTL, sa);
if (res  0) {
@@ -185,9 +218,12 @@ static int cmd_subvol_create(int argc, char **argv)
 
memset(args, 0, sizeof(args));
strncpy_null(args.name, newname);
-   args.flags |= BTRFS_SUBVOL_QGROUP_INHERIT;
-   args.size = qgroup_inherit_size(inherit);
-   args.qgroup_inherit = inherit;
+   if (inherit != NULL) {
+   args.flags |= BTRFS_SUBVOL_QGROUP_INHERIT;
+   args.size = qgroup_inherit_size(inherit);
+   args.qgroup_inherit = inherit

[PATCH 6/7] btrfs: qgroup: apply type to quota rescan.

2015-02-10 Thread Dongsheng Yang
Although we have different type for each qgroup now,
but the rescan is also working as before which is considering
data and metadata both.

This patch fix this problem.

Signed-off-by: Dongsheng Yang yangds.f...@cn.fujitsu.com
---
 fs/btrfs/qgroup.c | 19 ++-
 1 file changed, 14 insertions(+), 5 deletions(-)

diff --git a/fs/btrfs/qgroup.c b/fs/btrfs/qgroup.c
index ba1997f..d4ad565 100644
--- a/fs/btrfs/qgroup.c
+++ b/fs/btrfs/qgroup.c
@@ -1759,7 +1759,8 @@ static int qgroup_calc_new_refcnt(struct btrfs_fs_info 
*fs_info,
 static int qgroup_adjust_counters(struct btrfs_fs_info *fs_info,
  u64 root_to_skip, u64 num_bytes,
  struct ulist *qgroups, u64 seq,
- int old_roots, int new_roots, int rescan)
+ int old_roots, int new_roots, int rescan,
+ u8 qgroup_type)
 {
struct ulist_node *unode;
struct ulist_iterator uiter;
@@ -1771,6 +1772,9 @@ static int qgroup_adjust_counters(struct btrfs_fs_info 
*fs_info,
bool dirty = false;
 
qg = u64_to_ptr(unode-aux);
+
+   if (!(qg-type  qgroup_type))
+   continue;
/*
 * Wasn't referenced before but is now, add to the reference
 * counters.
@@ -2007,7 +2011,7 @@ static int qgroup_shared_accounting(struct 
btrfs_trans_handle *trans,
 * solution for this.
 */
qgroup_adjust_counters(fs_info, oper-ref_root, oper-num_bytes,
-  qgroups, seq, old_roots, new_roots, 0);
+  qgroups, seq, old_roots, new_roots, 0, 
oper-quota_type);
 out:
spin_unlock(fs_info-qgroup_lock);
ulist_free(qgroups);
@@ -2670,14 +2674,19 @@ qgroup_rescan_leaf(struct btrfs_fs_info *fs_info, 
struct btrfs_path *path,
mutex_unlock(fs_info-qgroup_rescan_lock);
 
for (; slot  btrfs_header_nritems(scratch_leaf); ++slot) {
+   u8 type;
+
btrfs_item_key_to_cpu(scratch_leaf, found, slot);
if (found.type != BTRFS_EXTENT_ITEM_KEY 
found.type != BTRFS_METADATA_ITEM_KEY)
continue;
-   if (found.type == BTRFS_METADATA_ITEM_KEY)
+   if (found.type == BTRFS_METADATA_ITEM_KEY) {
num_bytes = fs_info-extent_root-nodesize;
-   else
+   type = BTRFS_QGROUP_TYPE_METADATA;
+   } else {
num_bytes = found.offset;
+   type = BTRFS_QGROUP_TYPE_DATA;
+   }
 
ulist_reinit(qgroups);
ret = btrfs_find_all_roots(NULL, fs_info, found.objectid, 0,
@@ -2698,7 +2707,7 @@ qgroup_rescan_leaf(struct btrfs_fs_info *fs_info, struct 
btrfs_path *path,
}
 
ret = qgroup_adjust_counters(fs_info, 0, num_bytes, qgroups,
-seq, 0, new_roots, 1);
+seq, 0, new_roots, 1, type);
if (ret  0) {
spin_unlock(fs_info-qgroup_lock);
ulist_free(roots);
-- 
1.8.4.2

--
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


[PATCH 1/7] Btrfs: qgroup: Add type to btrfs_qgroup.

2015-02-10 Thread Dongsheng Yang
This patch is introducing a *type* to btrfs_qgroup.

Type could be data, metadata or both. data means this
qgroup only care about the data size, metadata means
this qgroup only care about the metadata size and both
means this qgroup will care about data and metadata like
what it was doing before this patch.

This idea comes from some complain of user that
Why I can not write one byte in the subvolume when
the qgroup does not reach the limit?. That is caused
by the qgroup was accounting the metadata also, but it
is not confusing to a user.

So this patch here allow user to only limit the data size
in a qgroup.

Signed-off-by: Dongsheng Yang yangds.f...@cn.fujitsu.com
---
 fs/btrfs/ctree.h  | 10 -
 fs/btrfs/ioctl.c  |  3 ++-
 fs/btrfs/qgroup.c | 47 +++
 fs/btrfs/qgroup.h | 12 ++-
 fs/btrfs/tests/qgroup-tests.c |  4 ++--
 5 files changed, 58 insertions(+), 18 deletions(-)

diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
index 1d17e7a..24b0d42 100644
--- a/fs/btrfs/ctree.h
+++ b/fs/btrfs/ctree.h
@@ -521,6 +521,11 @@ struct btrfs_super_block {
 #define BTRFS_FEATURE_INCOMPAT_SKINNY_METADATA (1ULL  8)
 #define BTRFS_FEATURE_INCOMPAT_NO_HOLES(1ULL  9)
 
+/*
+ * Add a type in btrfs_qgroup_info_item;
+ */
+#define BTRFS_FEATURE_INCOMPAT_QGROUP_TYPE (1ULL  10)
+
 #define BTRFS_FEATURE_COMPAT_SUPP  0ULL
 #define BTRFS_FEATURE_COMPAT_SAFE_SET  0ULL
 #define BTRFS_FEATURE_COMPAT_SAFE_CLEAR0ULL
@@ -537,7 +542,8 @@ struct btrfs_super_block {
 BTRFS_FEATURE_INCOMPAT_RAID56 |\
 BTRFS_FEATURE_INCOMPAT_EXTENDED_IREF | \
 BTRFS_FEATURE_INCOMPAT_SKINNY_METADATA |   \
-BTRFS_FEATURE_INCOMPAT_NO_HOLES)
+BTRFS_FEATURE_INCOMPAT_NO_HOLES |  \
+BTRFS_FEATURE_INCOMPAT_QGROUP_TYPE)
 
 #define BTRFS_FEATURE_INCOMPAT_SAFE_SET\
(BTRFS_FEATURE_INCOMPAT_EXTENDED_IREF)
@@ -1101,6 +1107,7 @@ struct btrfs_qgroup_info_item {
__le64 rfer_cmpr;
__le64 excl;
__le64 excl_cmpr;
+   __u8 type;
 } __attribute__ ((__packed__));
 
 /* flags definition for qgroup limits */
@@ -3214,6 +3221,7 @@ BTRFS_SETGET_FUNCS(qgroup_status_rescan, struct 
btrfs_qgroup_status_item,
 /* btrfs_qgroup_info_item */
 BTRFS_SETGET_FUNCS(qgroup_info_generation, struct btrfs_qgroup_info_item,
   generation, 64);
+BTRFS_SETGET_FUNCS(qgroup_info_type, struct btrfs_qgroup_info_item, type, 8);
 BTRFS_SETGET_FUNCS(qgroup_info_rfer, struct btrfs_qgroup_info_item, rfer, 64);
 BTRFS_SETGET_FUNCS(qgroup_info_rfer_cmpr, struct btrfs_qgroup_info_item,
   rfer_cmpr, 64);
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
index f6e730b..a50f295 100644
--- a/fs/btrfs/ioctl.c
+++ b/fs/btrfs/ioctl.c
@@ -4675,7 +4675,8 @@ static long btrfs_ioctl_qgroup_create(struct file *file, 
void __user *arg)
 
/* FIXME: check if the IDs really exist */
if (sa-create) {
-   ret = btrfs_create_qgroup(trans, root-fs_info, sa-qgroupid);
+   ret = btrfs_create_qgroup(trans, root-fs_info, sa-qgroupid,
+ BTRFS_QGROUP_TYPE_DEFAULT);
} else {
ret = btrfs_remove_qgroup(trans, root-fs_info, sa-qgroupid);
}
diff --git a/fs/btrfs/qgroup.c b/fs/btrfs/qgroup.c
index 28b0aa5..8ac785a 100644
--- a/fs/btrfs/qgroup.c
+++ b/fs/btrfs/qgroup.c
@@ -51,6 +51,7 @@
  */
 struct btrfs_qgroup {
u64 qgroupid;
+   u8 type;
 
/*
 * state
@@ -128,7 +129,7 @@ static struct btrfs_qgroup *find_qgroup_rb(struct 
btrfs_fs_info *fs_info,
 
 /* must be called with qgroup_lock held */
 static struct btrfs_qgroup *add_qgroup_rb(struct btrfs_fs_info *fs_info,
- u64 qgroupid)
+ u64 qgroupid, u8 type)
 {
struct rb_node **p = fs_info-qgroup_tree.rb_node;
struct rb_node *parent = NULL;
@@ -151,6 +152,7 @@ static struct btrfs_qgroup *add_qgroup_rb(struct 
btrfs_fs_info *fs_info,
return ERR_PTR(-ENOMEM);
 
qgroup-qgroupid = qgroupid;
+   qgroup-type = type;
INIT_LIST_HEAD(qgroup-groups);
INIT_LIST_HEAD(qgroup-members);
INIT_LIST_HEAD(qgroup-dirty);
@@ -348,7 +350,8 @@ int btrfs_read_qgroup_config(struct btrfs_fs_info *fs_info)
flags |= BTRFS_QGROUP_STATUS_FLAG_INCONSISTENT;
}
if (!qgroup) {
-   qgroup = add_qgroup_rb(fs_info, found_key.offset);
+   qgroup = add_qgroup_rb(fs_info, found_key.offset,
+  BTRFS_QGROUP_TYPE_DEFAULT);
if (IS_ERR(qgroup)) {
ret = PTR_ERR(qgroup);
goto out;
@@ -360,6 +363,8 @@ int

Re: [PATCH 3/3] btrfs: qgroup: destroy related qgroup when removing subvolume if needed.

2015-01-22 Thread Dongsheng Yang
On 01/22/2015 02:16 PM, Wang Shilong wrote:
 Hello,

 When removing a subvol, if the related qgroup has no child qgroup, we should 
 destroy
 it at the same time. Also remove the TODO entry in qgroup.c.
 My two cents here:

 Take a quick look at this, i am not sure whether this is right way to do it.

 Actually, i think we can only remove a subvolume qgroup safely when both 
 refer and excl are 0,
 because for subvolume removal case, to make qgroup accounting right, we need 
 walk tree.

 At this time, qgroup walking might have not finished, if we remove this 
 qgroup directly,
 accounting for this qgroup will be skipped.

Good point!

 Maybe we could remove such qgroup when at qgroup accounting, we find an 
 qgroup’s refer and excl
 are 0, we could remove it, or we do it at the background..

 Also, there is another risk, that is to say, if qgroup accounting not work 
 right, So
 we might need gurantee that subvolume it going to be deleted or have been 
 deleted at the same time,
 then we could remove qgroup safely etc.

Yes, you are right. This is not a good timing to remove the qgroup directly.
I need some more investigation for a better solution.

As I have some emergency to deal with in this period, maybe the V2 will
come a little late.
Sorry about it.

Thanx
Yang


 Signed-off-by: Dongsheng Yang yangds.f...@cn.fujitsu.com
 ---
 fs/btrfs/inode.c  | 4 
 fs/btrfs/qgroup.c | 1 -
 2 files changed, 4 insertions(+), 1 deletion(-)

 diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
 index e687bb0..31de211 100644
 --- a/fs/btrfs/inode.c
 +++ b/fs/btrfs/inode.c
 @@ -59,6 +59,7 @@
 #include backref.h
 #include hash.h
 #include props.h
 +#include qgroup.h

 struct btrfs_iget_args {
  struct btrfs_key *location;
 @@ -4029,6 +4030,9 @@ int btrfs_unlink_subvol(struct btrfs_trans_handle 
 *trans,
  ret = btrfs_update_inode_fallback(trans, root, dir);
  if (ret)
  btrfs_abort_transaction(trans, root, ret);
 +ret = btrfs_remove_qgroup(trans, root-fs_info, objectid);
 +if (ret == -EBUSY)
 +ret = 0;
 out:
  btrfs_free_path(path);
  return ret;
 diff --git a/fs/btrfs/qgroup.c b/fs/btrfs/qgroup.c
 index c3b1e4f..303c078 100644
 --- a/fs/btrfs/qgroup.c
 +++ b/fs/btrfs/qgroup.c
 @@ -35,7 +35,6 @@
 #include qgroup.h

 /* TODO XXX FIXME
 - *  - subvol delete - delete when ref goes to 0? delete limits also?
  *  - reorganize keys
  *  - compressed
  *  - sync
 -- 
 1.8.4.2

 --
 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
 Best Regards,
 Wang Shilong

 .


--
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


[PATCH 3/3] btrfs: qgroup: destroy related qgroup when removing subvolume if needed.

2015-01-21 Thread Dongsheng Yang
When removing a subvol, if the related qgroup has no child qgroup, we should 
destroy
it at the same time. Also remove the TODO entry in qgroup.c.

Signed-off-by: Dongsheng Yang yangds.f...@cn.fujitsu.com
---
 fs/btrfs/inode.c  | 4 
 fs/btrfs/qgroup.c | 1 -
 2 files changed, 4 insertions(+), 1 deletion(-)

diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index e687bb0..31de211 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -59,6 +59,7 @@
 #include backref.h
 #include hash.h
 #include props.h
+#include qgroup.h
 
 struct btrfs_iget_args {
struct btrfs_key *location;
@@ -4029,6 +4030,9 @@ int btrfs_unlink_subvol(struct btrfs_trans_handle *trans,
ret = btrfs_update_inode_fallback(trans, root, dir);
if (ret)
btrfs_abort_transaction(trans, root, ret);
+   ret = btrfs_remove_qgroup(trans, root-fs_info, objectid);
+   if (ret == -EBUSY)
+   ret = 0;
 out:
btrfs_free_path(path);
return ret;
diff --git a/fs/btrfs/qgroup.c b/fs/btrfs/qgroup.c
index c3b1e4f..303c078 100644
--- a/fs/btrfs/qgroup.c
+++ b/fs/btrfs/qgroup.c
@@ -35,7 +35,6 @@
 #include qgroup.h
 
 /* TODO XXX FIXME
- *  - subvol delete - delete when ref goes to 0? delete limits also?
  *  - reorganize keys
  *  - compressed
  *  - sync
-- 
1.8.4.2

--
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


[PATCH 2/3] btrfs: qgroup: allow user to remove qgroup which has parent but no child.

2015-01-21 Thread Dongsheng Yang
When a qgroup has parents but no child, it should be removable in
Theory. But currently, we can not remove it when it has
either parent or child.

Example:
# btrfs quota enable /mnt
# btrfs qgroup create 1/0 /mnt
# btrfs qgroup create 2/0 /mnt
# btrfs qgroup assign 1/0 2/0 /mnt
# btrfs qgroup show -pcre /mnt
qgroupid rfer  excl  max_rfer max_excl parent  child
       --  -
0/5  16384 16384 00--- ---
1/0  0 0 002/0 ---
2/0  0 0 00--- 1/0

At this time, there is no subvol or qgroup depending on qgroup 1/0.
Just a qgroup 2/0 is its parent, but 2/0 can work well without
1/0. So I think 1/0 should be removalbe. But:
# btrfs qgroup destroy 1/0 /mnt
ERROR: unable to destroy quota group: Device or resource busy

This patch remove the check of qgroup-parent in removing it.

Signed-off-by: Dongsheng Yang yangds.f...@cn.fujitsu.com
---
 fs/btrfs/qgroup.c | 30 +-
 1 file changed, 25 insertions(+), 5 deletions(-)

diff --git a/fs/btrfs/qgroup.c b/fs/btrfs/qgroup.c
index c2983a4..c3b1e4f 100644
--- a/fs/btrfs/qgroup.c
+++ b/fs/btrfs/qgroup.c
@@ -1048,7 +1048,7 @@ out:
return ret;
 }
 
-int btrfs_del_qgroup_relation(struct btrfs_trans_handle *trans,
+int __del_qgroup_relation(struct btrfs_trans_handle *trans,
  struct btrfs_fs_info *fs_info, u64 src, u64 dst)
 {
struct btrfs_root *quota_root;
@@ -1058,7 +1058,6 @@ int btrfs_del_qgroup_relation(struct btrfs_trans_handle 
*trans,
int ret = 0;
int err;
 
-   mutex_lock(fs_info-qgroup_ioctl_lock);
quota_root = fs_info-quota_root;
if (!quota_root) {
ret = -EINVAL;
@@ -1089,7 +1088,18 @@ exist:
del_relation_rb(fs_info, src, dst);
spin_unlock(fs_info-qgroup_lock);
 out:
+   return ret;
+}
+
+int btrfs_del_qgroup_relation(struct btrfs_trans_handle *trans,
+ struct btrfs_fs_info *fs_info, u64 src, u64 dst)
+{
+   int ret = 0;
+
+   mutex_lock(fs_info-qgroup_ioctl_lock);
+   ret = __del_qgroup_relation(trans, fs_info, src, dst);
mutex_unlock(fs_info-qgroup_ioctl_lock);
+
return ret;
 }
 
@@ -1132,6 +1142,7 @@ int btrfs_remove_qgroup(struct btrfs_trans_handle *trans,
 {
struct btrfs_root *quota_root;
struct btrfs_qgroup *qgroup;
+   struct btrfs_qgroup_list *list;
int ret = 0;
 
mutex_lock(fs_info-qgroup_ioctl_lock);
@@ -1146,15 +1157,24 @@ int btrfs_remove_qgroup(struct btrfs_trans_handle 
*trans,
ret = -ENOENT;
goto out;
} else {
-   /* check if there are no relations to this qgroup */
-   if (!list_empty(qgroup-groups) ||
-   !list_empty(qgroup-members)) {
+   /* check if there are no children of this qgroup */
+   if (!list_empty(qgroup-members)) {
ret = -EBUSY;
goto out;
}
}
ret = del_qgroup_item(trans, quota_root, qgroupid);
 
+   while (!list_empty(qgroup-groups)) {
+   list = list_first_entry(qgroup-groups,
+   struct btrfs_qgroup_list, next_group);
+   ret = __del_qgroup_relation(trans, fs_info,
+  qgroupid,
+  list-group-qgroupid);
+   if (ret)
+   goto out;
+   }
+
spin_lock(fs_info-qgroup_lock);
del_qgroup_rb(quota_root-fs_info, qgroupid);
spin_unlock(fs_info-qgroup_lock);
-- 
1.8.4.2

--
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] btrfs: get the accurate value of used_bytes in btrfs_get_block_group_info().

2015-01-07 Thread Dongsheng Yang

On 01/07/2015 05:22 PM, Qu Wenruo wrote:

Hi Satoru-san

Hi Dongsheng,

On 2015/01/05 20:19, Dongsheng Yang wrote:


Ping.

IOCTL of BTRFS_IOC_SPACE_INFO currently does not report
the data used but not synced to user.  Then btrfs fi df will
give user a wrong numbers before sync. This patch solve
this problem.

On 10/27/2014 08:38 PM, Dongsheng Yang wrote:

Reproducer:
# mkfs.btrfs -f -b 20G /dev/sdb
# mount /dev/sdb /mnt/test
# fallocate  -l 17G /mnt/test/largefile
# btrfs fi df /mnt/test
Data, single: total=17.49GiB, used=6.00GiB - only 6G, but 
actually it should be 17G.

System, DUP: total=8.00MiB, used=16.00KiB
System, single: total=4.00MiB, used=0.00B
Metadata, DUP: total=1.00GiB, used=112.00KiB
Metadata, single: total=8.00MiB, used=0.00B
GlobalReserve, single: total=16.00MiB, used=0.00B


I tried to reproduce your problem with 3.19-rc1.
However, this problem doesn't happen. Could you
also try to reproduce with the upstream kernel?
I can still reproduce it in 3.18, but it seems to be fixed in 3.19-rc1 
already by other patch,

so this patch is no longer needed.


Oops, my fault. I forgot to test it with upstream. :(

Satoru and Qu, thanx a lot.

Yang


Thanks,
Qu


* Detail

test script (named yang-test.sh here):
=== 


#!/bin/bash -x

PART1=/dev/vdb
MNT_PNT=./mnt
mkfs.btrfs -f -b 20G ${PART1}
mount ${PART1} ${MNT_PNT}
fallocate -l 17G ${MNT_PNT}/largefile
btrfs fi df ${MNT_PNT}
sync
btrfs fi df ${MNT_PNT}
umount ${MNT_PNT}
=== 



Result:
=== 


# ./yang-test.sh
+ PART1=/dev/vdb
+ MNT_PNT=./mnt
+ mkfs.btrfs -f -b 20G /dev/vdb
Btrfs v3.17
See http://btrfs.wiki.kernel.org for more information.

Turning ON incompat feature 'extref': increased hardlink limit per 
file to 65536

fs created label (null) on /dev/vdb
nodesize 16384 leafsize 16384 sectorsize 4096 size 20.00GiB
+ mount /dev/vdb ./mnt
+ fallocate -l 17G ./mnt/largefile
+ btrfs fi df ./mnt
Data, single: total=17.01GiB, used=17.00GiB   # Used 17GiB properly
System, DUP: total=8.00MiB, used=16.00KiB
System, single: total=4.00MiB, used=0.00B
Metadata, DUP: total=1.00GiB, used=112.00KiB
Metadata, single: total=8.00MiB, used=0.00B
GlobalReserve, single: total=16.00MiB, used=0.00B
+ sync
+ btrfs fi df ./mnt
Data, single: total=17.01GiB, used=17.00GiB# (of course) used 
17GiB too

System, DUP: total=8.00MiB, used=16.00KiB
System, single: total=4.00MiB, used=0.00B
Metadata, DUP: total=1.00GiB, used=112.00KiB
Metadata, single: total=8.00MiB, used=0.00B
GlobalReserve, single: total=16.00MiB, used=0.00B
+ umount ./mnt
=== 



Although I ran this test five times, the results are the same.

Thanks,
Satoru


# sync
# btrfs fi df /mnt/test
Data, single: total=17.49GiB, used=17.00GiB - After sync, it 
is expected.

System, DUP: total=8.00MiB, used=16.00KiB
System, single: total=4.00MiB, used=0.00B
Metadata, DUP: total=1.00GiB, used=112.00KiB
Metadata, single: total=8.00MiB, used=0.00B
GlobalReserve, single: total=16.00MiB, used=0.00B

The value of 6.00GiB is actually calculated in 
btrfs_get_block_group_info()
by adding the @block_group-item-used for each group together. In 
this way,

it did not consider the bytes in cache.

This patch adds the value of @pinned, @reserved and @bytes_super in
struct btrfs_block_group_cache to make sure we can get the accurate 
@used_bytes.


Reported-by: Qu Wenruo quwen...@cn.fujitsu.com
Signed-off-by: Dongsheng Yang yangds.f...@cn.fujitsu.com
---
  fs/btrfs/ioctl.c | 4 
  1 file changed, 4 insertions(+)

diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
index 33c80f5..bc2aaeb 100644
--- a/fs/btrfs/ioctl.c
+++ b/fs/btrfs/ioctl.c
@@ -3892,6 +3892,10 @@ void btrfs_get_block_group_info(struct 
list_head *groups_list,

  space-total_bytes += block_group-key.offset;
  space-used_bytes +=
btrfs_block_group_used(block_group-item);
+/* Add bytes-info in cache */
+space-used_bytes += block_group-pinned;
+space-used_bytes += block_group-reserved;
+space-used_bytes += block_group-bytes_super;
  }
  }


--
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


--
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


.



--
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 0/3] Btrfs: Enhancment for qgroup.

2015-01-07 Thread Dongsheng Yang
On 01/07/2015 08:49 AM, Satoru Takeuchi wrote:
 Hi Yang,

 On 2015/01/05 15:16, Dongsheng Yang wrote:
 Hi Josef and others,

 This patch set is about enhancing qgroup.

 [1/3]: fix a bug about qgroup leak when we exceed quota limit,
  It is reviewd by Josef.
 [2/3]: introduce a new accounter in qgroup to close a window where
  user will exceed the limit by qgroup. It looks good to Josef.
 [3/3]: a new patch to fix a bug reported by Satoru.
 I tested your the patchset v3. Although it's far better
 than the patchset v2, there is still one problem in this patchset.
 When I wrote 1.5GiB to a subvolume with 1.0 GiB limit,
 1.0GiB - 139 block (in this case, 1KiB/block) was written.

 I consider user should be able to write just 1.0GiB in this case.

Hi Satoru,

Yes, Currently, user can not write 1.0GiB in this case. Because qgroup
is accounting data and metadata togather. And I have posted an idea
in this thread that split it into three modes, data, metadata and both.

TODO issues:
c). limit and account size in 3 modes, data, metadata and both.
qgroup is accounting the size both of data and metadata
togather, but to users, the data size is the most useful to them.


But, you mentioned that the result is different in each time.
Hmmm there must be something wrong in it. I need some more
investigation to answer this question.

Thanx a lot for your test!
Yang

 * Test result

 ===
 + mkfs.btrfs -f /dev/vdb
 Btrfs v3.17
 See http://btrfs.wiki.kernel.org for more information.

 Turning ON incompat feature 'extref': increased hardlink limit per file to 
 65536
 fs created label (null) on /dev/vdb
 nodesize 16384 leafsize 16384 sectorsize 4096 size 30.00GiB
 + mount /dev/vdb /root/btrfs-auto-test/
 + ret=0
 + btrfs quota enable /root/btrfs-auto-test/
 + btrfs subvolume create /root/btrfs-auto-test//sub
 Create subvolume '/root/btrfs-auto-test/sub'
 + btrfs qgroup limit 1G /root/btrfs-auto-test//sub
 + dd if=/dev/zero of=/root/btrfs-auto-test//sub/file bs=1024 count=150
 dd: error writing '/root/btrfs-auto-test//sub/file': Disk quota exceeded
 1048438+0 records in# Tried to write 1GiB - 138 KiB
 1048437+0 records out   # Succeeded to write 1GiB - 139 KiB
 1073599488 bytes (1.1 GB) copied, 19.0247 s, 56.4 MB/s
 ===

 * note

 I tried to run the reproducer five times and the result is
 a bit different for each time.

 =
 # Written
 -
 1 1GiB - 139 KiB
 2 1GiB - 139 KiB
 3 1GiB - 145 KiB
 4 1GiB - 135 KiB
 5 1GiB - 135 KiB
 ==

 So I consider it's a problem comes from timing.

 If I changed the block size from 1KiB to 1 MiB,
 the difference in bytes got larger.

 
 # Written
 
 1 1GiB - 1 MiB
 2 1GiB - 1 MiB
 3 1GiB - 1 MiB
 4 1GiB - 1 MiB
 5 1GiB - 1 MiB
 

 Thanks,
 Satoru

 BTW, I have some other plan about qgroup in my TODO list:

 Kernel:
 a). adjust the accounters in parent qgroup when we move
 the child qgroup.
  Currently, when we move a qgroup, the parent qgroup
 will not updated at the same time. This will cause some wrong
 numbers in qgroup.

 b). add a ioctl to show the qgroup info.
  Command btrfs qgroup show is showing the qgroup info
 read from qgroup tree. But there is some information in memory
 which is not synced into device. Then it will show some outdate
 number.

 c). limit and account size in 3 modes, data, metadata and both.
  qgroup is accounting the size both of data and metadata
 togather, but to a user, the data size is the most useful to them.

 d). remove a subvolume related qgroup when subvolume is deleted and
 there is no other reference to it.

 user-tool:
 a). Add the unit of B/K/M/G to btrfs qgroup show.
 b). get the information via ioctl rather than reading it from
 btree. Will keep the old way as a fallback for compatiblity.

 Any comment and sugguestion is welcome. :)

 Yang

 Dongsheng Yang (3):
Btrfs: qgroup: free reserved in exceeding quota.
Btrfs: qgroup: Introduce a may_use to account
  space_info-bytes_may_use.
Btrfs: qgroup, Account data space in more proper timings.

   fs/btrfs/extent-tree.c | 41 +++---
   fs/btrfs/file.c|  9 ---
   fs/btrfs/inode.c   | 18 -
   fs/btrfs/qgroup.c  | 68 
 +++---
   fs/btrfs/qgroup.h  |  4 +++
   5 files changed, 117 insertions(+), 23 deletions(-)

 .


--
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


[PATCH] btrfs: qgroup: move WARN_ON() to the correct location.

2015-01-06 Thread Dongsheng Yang
In function qgroup_excl_accounting(), we need to WARN when
qg-excl is less than what we want to free, same to child
and parents. But currently, for parent qgroup, the WARN_ON()
is located after freeing qg-excl. It will WARN out even we
free it normally.

This patch move this WARN_ON() before freeing qg-excl.

Signed-off-by: Dongsheng Yang yangds.f...@cn.fujitsu.com
---
 fs/btrfs/qgroup.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/fs/btrfs/qgroup.c b/fs/btrfs/qgroup.c
index 48b60db..97159a8 100644
--- a/fs/btrfs/qgroup.c
+++ b/fs/btrfs/qgroup.c
@@ -1431,9 +1431,8 @@ static int qgroup_excl_accounting(struct btrfs_fs_info 
*fs_info,
qgroup = u64_to_ptr(unode-aux);
qgroup-rfer += sign * oper-num_bytes;
qgroup-rfer_cmpr += sign * oper-num_bytes;
+   WARN_ON(sign  0  qgroup-excl  oper-num_bytes);
qgroup-excl += sign * oper-num_bytes;
-   if (sign  0)
-   WARN_ON(qgroup-excl  oper-num_bytes);
qgroup-excl_cmpr += sign * oper-num_bytes;
qgroup_dirty(fs_info, qgroup);
 
-- 
1.8.4.2

--
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: Standards Problems [Was: [PATCH v2 1/3] Btrfs: get more accurate output in df command.]

2015-01-05 Thread Dongsheng Yang

On 12/31/2014 08:15 AM, Zygo Blaxell wrote:

On Wed, Dec 17, 2014 at 08:07:27PM -0800, Robert White wrote:

[...]

There are a number of pathological examples in here, but I think there
are justifiable correct answers for each of them that emerge from a
single interpretation of the meanings of f_bavail, f_blocks, and f_bfree.

One gotcha is that some of the numbers required may be difficult to
calculate precisely before all space is allocated to chunks; however,
some error is tolerable as long as free space is not overestimated.
In other words:  when in doubt, guess low.

statvfs(2) gives us six numbers, three of which are block counts.
Very few users or programs ever bother to look at the inode counts
(f_files, f_ffree, f_favail), but they could be overloaded for metadata
block counts.

The f_blocks parameter is mostly irrelevant to application behavior,
except to the extent that the ratio between f_bavail and f_blocks is
used by applications to calculate a percentage of occupied or free space.
f_blocks must always be greater than or equal to f_bavail and f_blocks,
and preferably f_blocks would be scaled to use the same effective unit
size as f_bavail and f_blocks within a percent or two.

Nobody cares about f_bfree since traditionally only root could use the
difference between f_bfree and f_bavail.  f_bfree is effectively space
conditionally available (e.g. if the process euid is root or the process
egid matches a configured group id), while f_bavail is space available
without conditions (e.g. processes without privilege can use it).

The most important number is f_bavail.  It's what a bunch of software
(archive unpackers, assorted garbage collectors, email MTAs, snapshot
remover scripts, download managers, etc) uses to estimate how much space
is available without conditions (except quotas, although arguably those
should be included too).  Applications that are privileged still use
the unprivileged f_bavail number so their decisions based on free space
don't disrupt unprivileged applications.

It's generally better to underestimate than to overestimate f_bavail.
Historically filesystems have reserved extra space to avoid various
problems in low-disk conditions, and application software has adapted
to that well over the years.  Also, admin people are more pleasantly
surprised when it turns out that they had more space than f_bavail,
instead of when they had less.

The rule should be:  if we have some space, but it is not available for
data extents in the current allocation mode, don't add it to f_bavail
in statvfs.  I think this rule handles all of these examples well.

That would mean that we get cases where we add a drive to a full
filesystem and it doesn't immediately give you any new f_bavail space.
That may be an unexpected result for a naive admin, but much less
unexpected than having all the new space show up in f_bavail when it
is not available for allocation in the current data profile!  Better
to have the surprising behavior earlier than later.

On to examples...


But a more even case is downright common and likely. Say you run a
nice old-fashoned MUTT mail-spool. most of your files are small
enough to live in metadata. You start with one drive. and allocate 2
single-data and 10 metatata (5xDup). Then you add a second drive of
equal size. (the metadata just switched to DUP-as-RAID1-alike mode)
And then you do a dconvert=raid0.

That uneven allocation of metadata will be a 2GiB difference between
the two drives forever.
So do you shave 2GiB off of your @size?

Yes.  f_blocks is the total size of all allocated chunks plus all free
space allocated by the current data profile.


Agreed. This is what my patch designed by.

   That 2GiB should disappear
from such a calculation.


Do you shave @2GiB off your @available?

Yes, because it's _not_ available until something changes to make it
available (e.g. balance to get rid of the dup metadata, change the
metadata profile to dup or single, or change the data profile to single).

The 2GiB could be added to f_bfree, but that might still be confusing
for people and software.


Do you overreport your available by @2GiB and end up _still_ having
things available when you get your ENOSPC?

No.  ENOSPC when f_bavail  0 is very bad.


Yes, it is very bad.

  Low-available-space admin
alerts will not be triggered.  Automated mitigation software will not be
activated.  Service daemons will start transactions they cannot complete.


How about this ::

/dev/sda == |Sf|Sf|Mf|Mf|Mf|Mf|Sf|Sf|Sp|Mp|Mp| .5GiB free|
/dev/sdb == |10 GiB free |

Operator fills his drive, then adds a second one, then _foolishly_
tries to convert it to RAID0 when the power fails. In order to check
the FS he boots with no_balance. Then his maintenance window closes
and he has to go back into production, at which point he forgets (or
isn't allowed) to do the balance. The flags are set but now no more
extents can be allocated.

Size is 20GiB, slack is 10.5GiB. 

Re: Standards Problems [Was: [PATCH v2 1/3] Btrfs: get more accurate output in df command.]

2015-01-05 Thread Dongsheng Yang

On 12/27/2014 09:10 AM, Robert White wrote:

On 12/23/2014 04:31 AM, Dongsheng Yang wrote:

On 12/18/2014 12:07 PM, Robert White wrote:

...

Thanx
Yang

. xaE






Fine. but you still haven't told me/us what you thing df (really 
fsstat() ) should report in those cases.


Go back to that email. Grab some of those cases. Then tell me what 
your patch will report and why it makes more sense than what is 
reported now.


For code to be correct it _must_ be correct for the special cases. 
You don't get to just ignore the special cases.


So what are your specific answers to those cases?


Great to hear that we can stop the endless discussion of FS level VS 
device level.


Then we can come back to discuss the special cases you provided. I give 
you some answer
in another mail. And make a change in my patch to cover the case of 
un-finished

balance.

Thanx

.



--
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


[PATCH v2 1/3] Btrfs: get more accurate output in df command.

2015-01-05 Thread Dongsheng Yang
When function btrfs_statfs() calculate the tatol size of fs, it is calculating
the total size of disks and then dividing it by a factor. But in some usecase,
the result is not good to user.
Example:
# mkfs.btrfs -f /dev/vdf1 /dev/vdf2 -d raid1
# mount /dev/vdf1 /mnt
# dd if=/dev/zero of=/mnt/zero bs=1M count=1000
# df -h /mnt
Filesystem  Size  Used Avail Use% Mounted on
/dev/vdf1   3.0G 1018M  1.3G  45% /mnt
# btrfs fi show /dev/vdf1
Label: none  uuid: f85d93dc-81f4-445d-91e5-6a5cd9563294
Total devices 2 FS bytes used 1001.53MiB
devid1 size 2.00GiB used 1.85GiB path /dev/vdf1
devid2 size 4.00GiB used 1.83GiB path /dev/vdf2
a. df -h should report Size as 2GiB rather than as 3GiB.
Because this is 2 device raid1, the limiting factor is devid 1 @2GiB.

b. df -h should report Avail as 0.97GiB or less, rather than as 1.3GiB.
1.85   (the capacity of the allocated chunk)
   -1.018  (the file stored)
   +(2-1.85=0.15)  (the residual capacity of the disks
considering a raid1 fs)
   ---
=   0.97

This patch drops the factor at all and calculate the size observable to
user without considering which raid level the data is in and what's the
size exactly in disk.
After this patch applied:
# mkfs.btrfs -f /dev/vdf1 /dev/vdf2 -d raid1
# mount /dev/vdf1 /mnt
# dd if=/dev/zero of=/mnt/zero bs=1M count=1000
# df -h /mnt
Filesystem  Size  Used Avail Use% Mounted on
/dev/vdf1   2.0G  1.3G  713M  66% /mnt
# df /mnt
Filesystem 1K-blocksUsed Available Use% Mounted on
/dev/vdf12097152 1359424729536  66% /mnt
# btrfs fi show /dev/vdf1
Label: none  uuid: e98c1321-645f-4457-b20d-4f41dc1cf2f4
Total devices 2 FS bytes used 1001.55MiB
devid1 size 2.00GiB used 1.85GiB path /dev/vdf1
devid2 size 4.00GiB used 1.83GiB path /dev/vdf2
a). The @Size is 2G as we expected.
b). @Available is 700M = 1.85G - 1.3G + (2G - 1.85G).
c). @Used is changed to 1.3G rather than 1018M as above. Because
this patch do not treat the free space in metadata chunk
and system chunk as available to user. It's true, user can
not use these space to store data, then it should not be
thought as available. At the same time, it will make the
@Used + @Available == @Size as possible to user.

Signed-off-by: Dongsheng Yang yangds.f...@cn.fujitsu.com
---
Changelog:
- account free space a block group by a block group,
treat the block group in unexpected raid level as used.

 fs/btrfs/ctree.h   |  1 -
 fs/btrfs/extent-tree.c | 41 
 fs/btrfs/super.c   | 74 --
 3 files changed, 42 insertions(+), 74 deletions(-)

diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
index 7e60741..0b9d5c0 100644
--- a/fs/btrfs/ctree.h
+++ b/fs/btrfs/ctree.h
@@ -3478,7 +3478,6 @@ int btrfs_set_block_group_ro(struct btrfs_root *root,
 void btrfs_set_block_group_rw(struct btrfs_root *root,
  struct btrfs_block_group_cache *cache);
 void btrfs_put_block_group_cache(struct btrfs_fs_info *info);
-u64 btrfs_account_ro_block_groups_free_space(struct btrfs_space_info *sinfo);
 int btrfs_error_unpin_extent_range(struct btrfs_root *root,
   u64 start, u64 end);
 int btrfs_discard_extent(struct btrfs_root *root, u64 bytenr,
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index a80b971..f9bf8ac 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -8578,47 +8578,6 @@ int btrfs_force_chunk_alloc(struct btrfs_trans_handle 
*trans,
  CHUNK_ALLOC_FORCE);
 }
 
-/*
- * helper to account the unused space of all the readonly block group in the
- * space_info. takes mirrors into account.
- */
-u64 btrfs_account_ro_block_groups_free_space(struct btrfs_space_info *sinfo)
-{
-   struct btrfs_block_group_cache *block_group;
-   u64 free_bytes = 0;
-   int factor;
-
-   /* It's df, we don't care if it's racey */
-   if (list_empty(sinfo-ro_bgs))
-   return 0;
-
-   spin_lock(sinfo-lock);
-   list_for_each_entry(block_group, sinfo-ro_bgs, ro_list) {
-   spin_lock(block_group-lock);
-
-   if (!block_group-ro) {
-   spin_unlock(block_group-lock);
-   continue;
-   }
-
-   if (block_group-flags  (BTRFS_BLOCK_GROUP_RAID1 |
- BTRFS_BLOCK_GROUP_RAID10 |
- BTRFS_BLOCK_GROUP_DUP))
-   factor = 2;
-   else
-   factor = 1;
-
-   free_bytes += (block_group-key.offset -
-  btrfs_block_group_used(block_group-item)) *
-  factor;
-
-   spin_unlock

[PATCH v2 2/3] Btrfs: raid56: simplify the parameter of nr_parity_stripes().

2015-01-05 Thread Dongsheng Yang
We just need the type of a chunk to calculate the number of parity stripes,
but we have to pass a structure of lookup_map to it. This will prevent some
callers to use it where there is no a convenient lookup_map to be passed.

This patch replace the parameter of struct map_lookup * with a profile type.
Then we can use it more easily.

Signed-off-by: Dongsheng Yang yangds.f...@cn.fujitsu.com
Reviewed-by: Satoru Takeuchi takeuchi_sat...@jp.fujitsu.com
---
 fs/btrfs/raid56.h  | 8 
 fs/btrfs/volumes.c | 2 +-
 2 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/fs/btrfs/raid56.h b/fs/btrfs/raid56.h
index 31d4a15..d2f5690 100644
--- a/fs/btrfs/raid56.h
+++ b/fs/btrfs/raid56.h
@@ -19,11 +19,11 @@
 
 #ifndef __BTRFS_RAID56__
 #define __BTRFS_RAID56__
-static inline int nr_parity_stripes(struct map_lookup *map)
+static inline int nr_parity_stripes(u64 type)
 {
-   if (map-type  BTRFS_BLOCK_GROUP_RAID5)
+   if (type  BTRFS_BLOCK_GROUP_RAID5)
return 1;
-   else if (map-type  BTRFS_BLOCK_GROUP_RAID6)
+   else if (type  BTRFS_BLOCK_GROUP_RAID6)
return 2;
else
return 0;
@@ -31,7 +31,7 @@ static inline int nr_parity_stripes(struct map_lookup *map)
 
 static inline int nr_data_stripes(struct map_lookup *map)
 {
-   return map-num_stripes - nr_parity_stripes(map);
+   return map-num_stripes - nr_parity_stripes(map-type);
 }
 #define RAID5_P_STRIPE ((u64)-2)
 #define RAID6_Q_STRIPE ((u64)-1)
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
index 50c5a87..fedf76e 100644
--- a/fs/btrfs/volumes.c
+++ b/fs/btrfs/volumes.c
@@ -5181,7 +5181,7 @@ static int __btrfs_map_block(struct btrfs_fs_info 
*fs_info, int rw,
 
/* RAID[56] write or recovery. Return all stripes */
num_stripes = map-num_stripes;
-   max_errors = nr_parity_stripes(map);
+   max_errors = nr_parity_stripes(map-type);
 
raid_map = kmalloc_array(num_stripes, sizeof(u64),
   GFP_NOFS);
-- 
1.8.4.2

--
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] btrfs: get the accurate value of used_bytes in btrfs_get_block_group_info().

2015-01-05 Thread Dongsheng Yang

Ping.

IOCTL of BTRFS_IOC_SPACE_INFO currently does not report
the data used but not synced to user.  Then btrfs fi df will
give user a wrong numbers before sync. This patch solve
this problem.

On 10/27/2014 08:38 PM, Dongsheng Yang wrote:

Reproducer:
# mkfs.btrfs -f -b 20G /dev/sdb
# mount /dev/sdb /mnt/test
# fallocate  -l 17G /mnt/test/largefile
# btrfs fi df /mnt/test
Data, single: total=17.49GiB, used=6.00GiB - only 6G, but actually it 
should be 17G.
System, DUP: total=8.00MiB, used=16.00KiB
System, single: total=4.00MiB, used=0.00B
Metadata, DUP: total=1.00GiB, used=112.00KiB
Metadata, single: total=8.00MiB, used=0.00B
GlobalReserve, single: total=16.00MiB, used=0.00B
# sync
# btrfs fi df /mnt/test
Data, single: total=17.49GiB, used=17.00GiB - After sync, it is 
expected.
System, DUP: total=8.00MiB, used=16.00KiB
System, single: total=4.00MiB, used=0.00B
Metadata, DUP: total=1.00GiB, used=112.00KiB
Metadata, single: total=8.00MiB, used=0.00B
GlobalReserve, single: total=16.00MiB, used=0.00B

The value of 6.00GiB is actually calculated in btrfs_get_block_group_info()
by adding the @block_group-item-used for each group together. In this way,
it did not consider the bytes in cache.

This patch adds the value of @pinned, @reserved and @bytes_super in
struct btrfs_block_group_cache to make sure we can get the accurate @used_bytes.

Reported-by: Qu Wenruo quwen...@cn.fujitsu.com
Signed-off-by: Dongsheng Yang yangds.f...@cn.fujitsu.com
---
  fs/btrfs/ioctl.c | 4 
  1 file changed, 4 insertions(+)

diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
index 33c80f5..bc2aaeb 100644
--- a/fs/btrfs/ioctl.c
+++ b/fs/btrfs/ioctl.c
@@ -3892,6 +3892,10 @@ void btrfs_get_block_group_info(struct list_head 
*groups_list,
space-total_bytes += block_group-key.offset;
space-used_bytes +=
btrfs_block_group_used(block_group-item);
+   /* Add bytes-info in cache */
+   space-used_bytes += block_group-pinned;
+   space-used_bytes += block_group-reserved;
+   space-used_bytes += block_group-bytes_super;
}
  }
  


--
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] Fixing quota error when removing files from a limit exceeded subvols

2015-01-04 Thread Dongsheng Yang
On Sat, Jan 3, 2015 at 10:29 PM, Khaled Ahmed khaled@gmail.com wrote:
 Hi Yang,

 This is how to reproduce the bug,

 [root@algodev ~]# uname -r
 3.18.0+

 [root@algodev ~]# btrfs version
 Btrfs v3.18-2-g6938452-dirty

 [root@algodev ~]# btrfs quota enable LOOP/
 [root@algodev ~]# btrfs qgroup show  LOOP/
 qgroupid rfer  excl
    
 0/5  16384 16384

 [root@algodev ~]# btrfs subvol create LOOP/subvol1
 Create subvolume 'LOOP/subvol1'

 [root@algodev ~]# btrfs qgroup limit 1g LOOP/subvol1/

 [root@algodev ~]# btrfs qgroup show  LOOP/
 qgroupid rfer  excl
    
 0/5  16384 16384
 0/25816384 16384

 [root@algodev ~]# dd if=/dev/zero of=LOOP/subvol1/bigfile
 dd: writing to ‘LOOP/subvol1/bigfile’: Disk quota exceeded
 2097018+0 records in
 2097017+0 records out
 1073672704 bytes (1.1 GB) copied, 10.0759 s, 107 MB/s

 [root@algodev ~]# rm -f LOOP/subvol1/bigfile
 rm: cannot remove ‘LOOP/subvol1/bigfile’: Disk quota exceeded

Hi Ahmed,
Okey, thanx for your example.

a). I guess your problem is getting a EQUOTA when remove a file here.
It's because we need to reserve some metadata in transaction of btrfs_unlink().

b). I think you patch here will not solve your problem. The root cause is
current quota in btrfs is accounting data and metadata together.

c). I admit getting a EQUOTA is strange when you did not writing anything but
only remove a file. I had a plan in my TODO list which is making qgroup to
limit and account the size in three modes, data, metadata and both.
Then in this case
if you only limit the size of data, you will not get a EQUOTA any more.

Thanx
Yang
 [root@algodev ~]#

 Best Regards,
 ~Khaled Ahmed


 On Jan 3, 2015, at 4:09 AM, Dongsheng Yang dongsheng081...@gmail.com wrote:

 Hi Khaled,

 Could you give use more description about the problem this patch
 is trying to solve? Maybe an example will help a lot to understand it.

 Thanx

 On Fri, Jan 2, 2015 at 7:48 AM, Khaled Ahmed khaled@gmail.com wrote:
 Signed-off-by: Khaled Ahmed khaled@gmail.com
 ---
 fs/btrfs/qgroup.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

 diff --git a/fs/btrfs/qgroup.c b/fs/btrfs/qgroup.c
 index 48b60db..b85200d 100644
 --- a/fs/btrfs/qgroup.c
 +++ b/fs/btrfs/qgroup.c
 @@ -2408,14 +2408,14 @@ int btrfs_qgroup_reserve(struct btrfs_root *root, 
 u64 num_bytes)

if ((qg-lim_flags  BTRFS_QGROUP_LIMIT_MAX_RFER) 
qg-reserved + (s64)qg-rfer + num_bytes 
 -   qg-max_rfer) {
 +   qg-max_rfer - 1 ) {
ret = -EDQUOT;
goto out;
}

if ((qg-lim_flags  BTRFS_QGROUP_LIMIT_MAX_EXCL) 
qg-reserved + (s64)qg-excl + num_bytes 
 -   qg-max_excl) {
 +   qg-max_excl - 1) {
ret = -EDQUOT;
goto out;
}
 --
 2.1.0

 --
 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

--
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


[PATCH v3 0/3] Btrfs: Enhancment for qgroup.

2015-01-04 Thread Dongsheng Yang
Hi Josef and others,

This patch set is about enhancing qgroup.

[1/3]: fix a bug about qgroup leak when we exceed quota limit,
It is reviewd by Josef.
[2/3]: introduce a new accounter in qgroup to close a window where
user will exceed the limit by qgroup. It looks good to Josef.
[3/3]: a new patch to fix a bug reported by Satoru.

BTW, I have some other plan about qgroup in my TODO list:

Kernel:
a). adjust the accounters in parent qgroup when we move
the child qgroup.
Currently, when we move a qgroup, the parent qgroup
will not updated at the same time. This will cause some wrong
numbers in qgroup.

b). add a ioctl to show the qgroup info.
Command btrfs qgroup show is showing the qgroup info
read from qgroup tree. But there is some information in memory
which is not synced into device. Then it will show some outdate
number.

c). limit and account size in 3 modes, data, metadata and both.
qgroup is accounting the size both of data and metadata
togather, but to a user, the data size is the most useful to them.

d). remove a subvolume related qgroup when subvolume is deleted and
there is no other reference to it.

user-tool:
a). Add the unit of B/K/M/G to btrfs qgroup show.
b). get the information via ioctl rather than reading it from
btree. Will keep the old way as a fallback for compatiblity.

Any comment and sugguestion is welcome. :)

Yang

Dongsheng Yang (3):
  Btrfs: qgroup: free reserved in exceeding quota.
  Btrfs: qgroup: Introduce a may_use to account
space_info-bytes_may_use.
  Btrfs: qgroup, Account data space in more proper timings.

 fs/btrfs/extent-tree.c | 41 +++---
 fs/btrfs/file.c|  9 ---
 fs/btrfs/inode.c   | 18 -
 fs/btrfs/qgroup.c  | 68 +++---
 fs/btrfs/qgroup.h  |  4 +++
 5 files changed, 117 insertions(+), 23 deletions(-)

-- 
1.8.4.2

--
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


[PATCH v3 3/3] Btrfs: qgroup, Account data space in more proper timings.

2015-01-04 Thread Dongsheng Yang
Currenly, in data writing, -reserved is accounted in
fill_delalloc(), but -may_use is released in clear_bit_hook()
which is called by btrfs_finish_ordered_io(). That's too late,
that said, between fill_delalloc() and btrfs_finish_ordered_io(),
the data is doublely accounted by qgroup. It will cause some
unexpected -EDQUOT.

Example:
# btrfs quota enable /root/btrfs-auto-test/
# btrfs subvolume create /root/btrfs-auto-test//sub
Create subvolume '/root/btrfs-auto-test/sub'
# btrfs qgroup limit 1G /root/btrfs-auto-test//sub
dd if=/dev/zero of=/root/btrfs-auto-test//sub/file bs=1024 count=150
dd: error writing '/root/btrfs-auto-test//sub/file': Disk quota exceeded
681353+0 records in
681352+0 records out
697704448 bytes (698 MB) copied, 8.15563 s, 85.5 MB/s
It's (698 MB) when we got an -EDQUOT, but we limit it by 1G.

This patch move the btrfs_qgroup_reserve/free() for data from
btrfs_delalloc_reserve/release_metadata() to btrfs_check_data_free_space()
and btrfs_free_reserved_data_space(). Then the accounter in qgroup
will be updated at the same time with the accounter in space_info updated.
In this way, the unexpected -EDQUOT will be killed.

Reported-by: Satoru Takeuchi takeuchi_sat...@jp.fujitsu.com
Signed-off-by: Dongsheng Yang yangds.f...@cn.fujitsu.com
---
 fs/btrfs/extent-tree.c | 16 +---
 fs/btrfs/file.c|  9 -
 2 files changed, 9 insertions(+), 16 deletions(-)

diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index d1a7ce0..67c2e28 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -3774,12 +3774,16 @@ commit_trans:
  data_sinfo-flags, bytes, 1);
return -ENOSPC;
}
+   ret = btrfs_qgroup_reserve(root, bytes);
+   if (ret)
+   goto out;
data_sinfo-bytes_may_use += bytes;
trace_btrfs_space_reservation(root-fs_info, space_info,
  data_sinfo-flags, bytes, 1);
+out:
spin_unlock(data_sinfo-lock);
 
-   return 0;
+   return ret;
 }
 
 /*
@@ -3796,6 +3800,7 @@ void btrfs_free_reserved_data_space(struct inode *inode, 
u64 bytes)
data_sinfo = root-fs_info-data_sinfo;
spin_lock(data_sinfo-lock);
WARN_ON(data_sinfo-bytes_may_use  bytes);
+   btrfs_qgroup_free(root, bytes);
data_sinfo-bytes_may_use -= bytes;
trace_btrfs_space_reservation(root-fs_info, space_info,
  data_sinfo-flags, bytes, 0);
@@ -5191,8 +5196,7 @@ int btrfs_delalloc_reserve_metadata(struct inode *inode, 
u64 num_bytes)
spin_unlock(BTRFS_I(inode)-lock);
 
if (root-fs_info-quota_enabled) {
-   ret = btrfs_qgroup_reserve(root, num_bytes +
-  nr_extents * root-nodesize);
+   ret = btrfs_qgroup_reserve(root, nr_extents * root-nodesize);
if (ret)
goto out_fail;
}
@@ -5200,8 +5204,7 @@ int btrfs_delalloc_reserve_metadata(struct inode *inode, 
u64 num_bytes)
ret = reserve_metadata_bytes(root, block_rsv, to_reserve, flush);
if (unlikely(ret)) {
if (root-fs_info-quota_enabled)
-   btrfs_qgroup_free(root, num_bytes +
-   nr_extents * root-nodesize);
+   btrfs_qgroup_free(root, nr_extents * root-nodesize);
goto out_fail;
}
 
@@ -5319,8 +5322,7 @@ void btrfs_delalloc_release_metadata(struct inode *inode, 
u64 num_bytes)
trace_btrfs_space_reservation(root-fs_info, delalloc,
  btrfs_ino(inode), to_free, 0);
if (root-fs_info-quota_enabled) {
-   btrfs_qgroup_free(root, num_bytes +
-   dropped * root-nodesize);
+   btrfs_qgroup_free(root, dropped * root-nodesize);
}
 
btrfs_block_rsv_release(root, root-fs_info-delalloc_block_rsv,
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c
index e409025..0ab1333 100644
--- a/fs/btrfs/file.c
+++ b/fs/btrfs/file.c
@@ -2527,7 +2527,6 @@ static long btrfs_fallocate(struct file *file, int mode,
 {
struct inode *inode = file_inode(file);
struct extent_state *cached_state = NULL;
-   struct btrfs_root *root = BTRFS_I(inode)-root;
u64 cur_offset;
u64 last_byte;
u64 alloc_start;
@@ -2555,11 +2554,6 @@ static long btrfs_fallocate(struct file *file, int mode,
ret = btrfs_check_data_free_space(inode, alloc_end - alloc_start);
if (ret)
return ret;
-   if (root-fs_info-quota_enabled) {
-   ret = btrfs_qgroup_reserve(root, alloc_end - alloc_start);
-   if (ret)
-   goto out_reserve_fail;
-   }
 
mutex_lock(inode-i_mutex);
ret = inode_newsize_ok(inode

[PATCH v3 1/3] Btrfs: qgroup: free reserved in exceeding quota.

2015-01-04 Thread Dongsheng Yang
When we exceed quota limit in writing, we will free
some reserved extent when we need to drop but not free
account in qgroup. It means, each time we exceed quota
in writing, there will be some remain space in qg-reserved
we can not use any more. If things go on like this, the
all space will be ate up.

Signed-off-by: Dongsheng Yang yangds.f...@cn.fujitsu.com
Reviewed-by: Josef Bacik jba...@fb.com
---
 fs/btrfs/extent-tree.c | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index a80b971..88b4e32 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -5275,8 +5275,11 @@ out_fail:
to_free = 0;
}
spin_unlock(BTRFS_I(inode)-lock);
-   if (dropped)
+   if (dropped) {
+   if (root-fs_info-quota_enabled)
+   btrfs_qgroup_free(root, dropped * root-nodesize);
to_free += btrfs_calc_trans_metadata_size(root, dropped);
+   }
 
if (to_free) {
btrfs_block_rsv_release(root, block_rsv, to_free);
-- 
1.8.4.2

--
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] Fixing quota error when removing files from a limit exceeded subvols

2015-01-02 Thread Dongsheng Yang
Hi Khaled,

Could you give use more description about the problem this patch
is trying to solve? Maybe an example will help a lot to understand it.

Thanx

On Fri, Jan 2, 2015 at 7:48 AM, Khaled Ahmed khaled@gmail.com wrote:
 Signed-off-by: Khaled Ahmed khaled@gmail.com
 ---
  fs/btrfs/qgroup.c | 4 ++--
  1 file changed, 2 insertions(+), 2 deletions(-)

 diff --git a/fs/btrfs/qgroup.c b/fs/btrfs/qgroup.c
 index 48b60db..b85200d 100644
 --- a/fs/btrfs/qgroup.c
 +++ b/fs/btrfs/qgroup.c
 @@ -2408,14 +2408,14 @@ int btrfs_qgroup_reserve(struct btrfs_root *root, u64 
 num_bytes)

 if ((qg-lim_flags  BTRFS_QGROUP_LIMIT_MAX_RFER) 
 qg-reserved + (s64)qg-rfer + num_bytes 
 -   qg-max_rfer) {
 +   qg-max_rfer - 1 ) {
 ret = -EDQUOT;
 goto out;
 }

 if ((qg-lim_flags  BTRFS_QGROUP_LIMIT_MAX_EXCL) 
 qg-reserved + (s64)qg-excl + num_bytes 
 -   qg-max_excl) {
 +   qg-max_excl - 1) {
 ret = -EDQUOT;
 goto out;
 }
 --
 2.1.0

 --
 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
--
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 v2 2/2] Btrfs: qgroup: Introduce a may_use to account space_info-bytes_may_use.

2014-12-27 Thread Dongsheng Yang
On Fri, Dec 26, 2014 at 1:43 PM, Satoru Takeuchi
takeuchi_sat...@jp.fujitsu.com wrote:
 Hi Yang,

 On 2014/12/26 10:32, Dongsheng Yang wrote:

 Hi Satoru,

 I saw your mail of [BUG] Quota Ignored On write problem still exist
 with 3.16-rc5
 http://news.gmane.org/find-root.php?message_id=53C8DEB0.1060404%40jp.fujitsu.com
 in gmane.
 I guess this patch will fix the problem you mentioned.
 Could you help to give a try?


 Although it reached disk quota before writing whole 1.5GB,
 the copied size was only about 700 MB. In this case,
 expected behavior is to reach disk quota just after
 writing 1 GB.

Hi Satoru-san,

After some more investigation, I did meet this problem you described here.
There is a window between reserved += num_bytes and may_use -= num_bytes.
And the similar problem exists in real space accounting. I am cooking a patch
to solve this problem.

Thanx for your test a lot.

Yang

 * 3.19-rc1 without your two v2 patches

 ===
 + mkfs.btrfs -f /dev/vdb
 Btrfs v3.17
 See http://btrfs.wiki.kernel.org for more information.

 Turning ON incompat feature 'extref': increased hardlink limit per file to
 65536
 fs created label (null) on /dev/vdb
 nodesize 16384 leafsize 16384 sectorsize 4096 size 30.00GiB
 + mount /dev/vdb /root/btrfs-auto-test/
 + ret=0
 + btrfs quota enable /root/btrfs-auto-test/
 + btrfs subvolume create /root/btrfs-auto-test//sub
 Create subvolume '/root/btrfs-auto-test/sub'
 + btrfs qgroup limit 1G /root/btrfs-auto-test//sub
 + dd if=/dev/zero of=/root/btrfs-auto-test//sub/file bs=1024 count=150
 150+0 records in
 150+0 records out
 153600 bytes (1.5 GB) copied, 25.6601 s, 59.9 MB/s
 ===

 * 3.19-rc1 with your two v2 patches

 ===
 + mkfs.btrfs -f /dev/vdb
 Btrfs v3.17
 See http://btrfs.wiki.kernel.org for more information.

 Turning ON incompat feature 'extref': increased hardlink limit per file to
 65536
 fs created label (null) on /dev/vdb
 nodesize 16384 leafsize 16384 sectorsize 4096 size 30.00GiB
 + mount /dev/vdb /root/btrfs-auto-test/
 + ret=0
 + btrfs quota enable /root/btrfs-auto-test/
 + btrfs subvolume create /root/btrfs-auto-test//sub
 Create subvolume '/root/btrfs-auto-test/sub'
 + btrfs qgroup limit 1G /root/btrfs-auto-test//sub
 + dd if=/dev/zero of=/root/btrfs-auto-test//sub/file bs=1024 count=150
 dd: error writing '/root/btrfs-auto-test//sub/file': Disk quota exceeded
 681353+0 records in
 681352+0 records out
 697704448 bytes (698 MB) copied, 8.15563 s, 85.5 MB/s
 ===

 Thanks,
 Satoru


 Thanx
 Yang


 On 12/12/2014 04:44 PM, Dongsheng Yang wrote:

 Currently, for pre_alloc or delay_alloc, the bytes will be accounted
 in space_info by the three guys.
 space_info-bytes_may_use --- space_info-reserved --- space_info-used.
 But on the other hand, in qgroup, there are only two counters to account
 the
 bytes, qgroup-reserved and qgroup-excl. And qg-reserved accounts
 bytes in space_info-bytes_may_use and qg-excl accounts bytes in
 space_info-used. So the bytes in space_info-reserved is not accounted
 in qgroup. If so, there is a window we can exceed the quota limit when
 bytes is in space_info-reserved.

 Example:
 # btrfs quota enable /mnt
 # btrfs qgroup limit -e 10M /mnt
 # for((i=0;i20;i++));do fallocate -l 1M /mnt/data$i; done
 # sync
 # btrfs qgroup show -pcre /mnt
 qgroupid rfer excl max_rfer max_excl parent  child
      --  -
 0/5  20987904 20987904 010485760 --- ---

 qg-excl is 20987904 larger than max_excl 10485760.

 This patch introduce a new counter named may_use to qgroup, then
 there are three counters in qgroup to account bytes in space_info
 as below.
 space_info-bytes_may_use --- space_info-reserved --- space_info-used.
 qgroup-may_use   --- qgroup-reserved --- qgroup-excl

 With this patch applied:
 # btrfs quota enable /mnt
 # btrfs qgroup limit -e 10M /mnt
 # for((i=0;i20;i++));do fallocate -l 1M /mnt/data$i; done
 fallocate: /mnt/data9: fallocate failed: Disk quota exceeded
 fallocate: /mnt/data10: fallocate failed: Disk quota exceeded
 fallocate: /mnt/data11: fallocate failed: Disk quota exceeded
 fallocate: /mnt/data12: fallocate failed: Disk quota exceeded
 fallocate: /mnt/data13: fallocate failed: Disk quota exceeded
 fallocate: /mnt/data14: fallocate failed: Disk quota exceeded
 fallocate: /mnt/data15: fallocate failed: Disk quota exceeded
 fallocate: /mnt/data16: fallocate failed: Disk quota exceeded
 fallocate: /mnt/data17: fallocate failed: Disk quota exceeded
 fallocate: /mnt/data18: fallocate failed: Disk quota exceeded
 fallocate: /mnt/data19

Re: [PATCH v2 2/2] Btrfs: qgroup: Introduce a may_use to account space_info-bytes_may_use.

2014-12-25 Thread Dongsheng Yang

On 12/26/2014 01:43 PM, Satoru Takeuchi wrote:

Hi Yang,

On 2014/12/26 10:32, Dongsheng Yang wrote:

Hi Satoru,

I saw your mail of [BUG] Quota Ignored On write problem still 
exist with 3.16-rc5 
http://news.gmane.org/find-root.php?message_id=53C8DEB0.1060404%40jp.fujitsu.com 
in gmane.

I guess this patch will fix the problem you mentioned.
Could you help to give a try?


Although it reached disk quota before writing whole 1.5GB,
the copied size was only about 700 MB. In this case,
expected behavior is to reach disk quota just after
writing 1 GB.


Hi Satoru,
Thanx for your testing a lot. But stranger, I tried it in 3.19-rc1 and 
3.18, both works well
writing 1GB. Could you give me some more information about your testing 
machine?

And could you execute sync  btrfs qgroup show -pecr $MNT after writing?

*3.19-rc1 with my 2/2 patch applied.
===
[root@atest-guest linux_btrfs]# uname -a
Linux atest-guest 3.19.0-rc1+ #66 SMP Fri Dec 26 10:38:12 EST 2014 
x86_64 x86_64 x86_64 GNU/Linux

[root@atest-guest linux_btrfs]# sh quota.sh
umount: /mnt: not mounted
Btrfs v3.17-1-gbef9fd4
See http://btrfs.wiki.kernel.org for more information.

Turning ON incompat feature 'extref': increased hardlink limit per file 
to 65536

fs created label (null) on /dev/vdb
nodesize 16384 leafsize 16384 sectorsize 4096 size 50.00GiB
Create subvolume '/mnt/quota_test'
dd: error writing \u2018/mnt/quota_test/test\u2019: Disk quota exceeded
999842+0 records in
999841+0 records out
1023837184 bytes (1.0 GB) copied, 8.06996 s, 127 MB/s
[PASS] quota works correctly
[root@atest-guest linux_btrfs]# sync
[root@atest-guest linux_btrfs]# df -h /mnt/
Filesystem  Size  Used Avail Use% Mounted on
/dev/vdb 50G  996M   49G   2% /mnt
[root@atest-guest linux_btrfs]# btrfs qgroup show -pecr /mnt/
qgroupid rfer   excl   max_rfer   max_excl parent  child
           --  -
0/5  16384  16384  0  0--- ---
0/2561023868928 1023868928 102400 0--- ---
=


* 3.19-rc1 without your two v2 patches

=== 


+ mkfs.btrfs -f /dev/vdb
Btrfs v3.17
See http://btrfs.wiki.kernel.org for more information.

Turning ON incompat feature 'extref': increased hardlink limit per 
file to 65536

fs created label (null) on /dev/vdb
nodesize 16384 leafsize 16384 sectorsize 4096 size 30.00GiB
+ mount /dev/vdb /root/btrfs-auto-test/
+ ret=0
+ btrfs quota enable /root/btrfs-auto-test/
+ btrfs subvolume create /root/btrfs-auto-test//sub
Create subvolume '/root/btrfs-auto-test/sub'
+ btrfs qgroup limit 1G /root/btrfs-auto-test//sub
+ dd if=/dev/zero of=/root/btrfs-auto-test//sub/file bs=1024 
count=150

150+0 records in
150+0 records out
153600 bytes (1.5 GB) copied, 25.6601 s, 59.9 MB/s
=== 



* 3.19-rc1 with your two v2 patches

=== 


+ mkfs.btrfs -f /dev/vdb
Btrfs v3.17
See http://btrfs.wiki.kernel.org for more information.

Turning ON incompat feature 'extref': increased hardlink limit per 
file to 65536

fs created label (null) on /dev/vdb
nodesize 16384 leafsize 16384 sectorsize 4096 size 30.00GiB
+ mount /dev/vdb /root/btrfs-auto-test/
+ ret=0
+ btrfs quota enable /root/btrfs-auto-test/
+ btrfs subvolume create /root/btrfs-auto-test//sub
Create subvolume '/root/btrfs-auto-test/sub'
+ btrfs qgroup limit 1G /root/btrfs-auto-test//sub
+ dd if=/dev/zero of=/root/btrfs-auto-test//sub/file bs=1024 
count=150

dd: error writing '/root/btrfs-auto-test//sub/file': Disk quota exceeded
681353+0 records in
681352+0 records out
697704448 bytes (698 MB) copied, 8.15563 s, 85.5 MB/s
=== 



Thanks,
Satoru



Thanx
Yang

On 12/12/2014 04:44 PM, Dongsheng Yang wrote:

Currently, for pre_alloc or delay_alloc, the bytes will be accounted
in space_info by the three guys.
space_info-bytes_may_use --- space_info-reserved --- 
space_info-used.
But on the other hand, in qgroup, there are only two counters to 
account the

bytes, qgroup-reserved and qgroup-excl. And qg-reserved accounts
bytes in space_info-bytes_may_use and qg-excl accounts bytes in
space_info-used. So the bytes in space_info-reserved is not accounted
in qgroup. If so, there is a window we can exceed the quota limit when
bytes is in space_info-reserved.

Example:
# btrfs quota enable /mnt
# btrfs qgroup limit -e 10M /mnt
# for((i=0;i20;i++));do fallocate -l 1M /mnt/data$i; done
# sync
# btrfs qgroup show -pcre /mnt
qgroupid rfer excl max_rfer max_excl parent  child
     --  -
0/5

Re: [PATCH v2 2/2] Btrfs: qgroup: Introduce a may_use to account space_info-bytes_may_use.

2014-12-25 Thread Dongsheng Yang

On 12/26/2014 02:49 PM, Dongsheng Yang wrote:

On 12/26/2014 01:43 PM, Satoru Takeuchi wrote:

Hi Yang,

On 2014/12/26 10:32, Dongsheng Yang wrote:

Hi Satoru,

I saw your mail of [BUG] Quota Ignored On write problem still 
exist with 3.16-rc5 
http://news.gmane.org/find-root.php?message_id=53C8DEB0.1060404%40jp.fujitsu.com 
in gmane.

I guess this patch will fix the problem you mentioned.
Could you help to give a try?


Although it reached disk quota before writing whole 1.5GB,
the copied size was only about 700 MB. In this case,
expected behavior is to reach disk quota just after
writing 1 GB.


Hi Satoru,
Thanx for your testing a lot. But stranger 


Typo, strange. :)

I tried it in 3.19-rc1 and 3.18, both works well
writing 1GB. Could you give me some more information about your 
testing machine?
And could you execute sync  btrfs qgroup show -pecr $MNT after 
writing?


*3.19-rc1 with my 2/2 patch applied.


I also tried with the two patches applied, and got the same result.

Thanx

===
[root@atest-guest linux_btrfs]# uname -a
Linux atest-guest 3.19.0-rc1+ #66 SMP Fri Dec 26 10:38:12 EST 2014 
x86_64 x86_64 x86_64 GNU/Linux

[root@atest-guest linux_btrfs]# sh quota.sh
umount: /mnt: not mounted
Btrfs v3.17-1-gbef9fd4
See http://btrfs.wiki.kernel.org for more information.

Turning ON incompat feature 'extref': increased hardlink limit per 
file to 65536

fs created label (null) on /dev/vdb
nodesize 16384 leafsize 16384 sectorsize 4096 size 50.00GiB
Create subvolume '/mnt/quota_test'
dd: error writing \u2018/mnt/quota_test/test\u2019: Disk quota exceeded
999842+0 records in
999841+0 records out
1023837184 bytes (1.0 GB) copied, 8.06996 s, 127 MB/s
[PASS] quota works correctly
[root@atest-guest linux_btrfs]# sync
[root@atest-guest linux_btrfs]# df -h /mnt/
Filesystem  Size  Used Avail Use% Mounted on
/dev/vdb 50G  996M   49G   2% /mnt
[root@atest-guest linux_btrfs]# btrfs qgroup show -pecr /mnt/
qgroupid rfer   excl   max_rfer   max_excl parent  child
           --  -
0/5  16384  16384  0  0--- ---
0/2561023868928 1023868928 102400 0--- ---
=


* 3.19-rc1 without your two v2 patches

=== 


+ mkfs.btrfs -f /dev/vdb
Btrfs v3.17
See http://btrfs.wiki.kernel.org for more information.

Turning ON incompat feature 'extref': increased hardlink limit per 
file to 65536

fs created label (null) on /dev/vdb
nodesize 16384 leafsize 16384 sectorsize 4096 size 30.00GiB
+ mount /dev/vdb /root/btrfs-auto-test/
+ ret=0
+ btrfs quota enable /root/btrfs-auto-test/
+ btrfs subvolume create /root/btrfs-auto-test//sub
Create subvolume '/root/btrfs-auto-test/sub'
+ btrfs qgroup limit 1G /root/btrfs-auto-test//sub
+ dd if=/dev/zero of=/root/btrfs-auto-test//sub/file bs=1024 
count=150

150+0 records in
150+0 records out
153600 bytes (1.5 GB) copied, 25.6601 s, 59.9 MB/s
=== 



* 3.19-rc1 with your two v2 patches

=== 


+ mkfs.btrfs -f /dev/vdb
Btrfs v3.17
See http://btrfs.wiki.kernel.org for more information.

Turning ON incompat feature 'extref': increased hardlink limit per 
file to 65536

fs created label (null) on /dev/vdb
nodesize 16384 leafsize 16384 sectorsize 4096 size 30.00GiB
+ mount /dev/vdb /root/btrfs-auto-test/
+ ret=0
+ btrfs quota enable /root/btrfs-auto-test/
+ btrfs subvolume create /root/btrfs-auto-test//sub
Create subvolume '/root/btrfs-auto-test/sub'
+ btrfs qgroup limit 1G /root/btrfs-auto-test//sub
+ dd if=/dev/zero of=/root/btrfs-auto-test//sub/file bs=1024 
count=150

dd: error writing '/root/btrfs-auto-test//sub/file': Disk quota exceeded
681353+0 records in
681352+0 records out
697704448 bytes (698 MB) copied, 8.15563 s, 85.5 MB/s
=== 



Thanks,
Satoru



Thanx
Yang

On 12/12/2014 04:44 PM, Dongsheng Yang wrote:

Currently, for pre_alloc or delay_alloc, the bytes will be accounted
in space_info by the three guys.
space_info-bytes_may_use --- space_info-reserved --- 
space_info-used.
But on the other hand, in qgroup, there are only two counters to 
account the

bytes, qgroup-reserved and qgroup-excl. And qg-reserved accounts
bytes in space_info-bytes_may_use and qg-excl accounts bytes in
space_info-used. So the bytes in space_info-reserved is not 
accounted

in qgroup. If so, there is a window we can exceed the quota limit when
bytes is in space_info-reserved.

Example:
# btrfs quota enable /mnt
# btrfs qgroup limit -e 10M /mnt
# for((i=0;i20;i++));do fallocate -l 1M /mnt/data$i; done
# sync

Re: Standards Problems [Was: [PATCH v2 1/3] Btrfs: get more accurate output in df command.]

2014-12-23 Thread Dongsheng Yang

On 12/18/2014 12:07 PM, Robert White wrote:
I don't disagree with the _ideal_ of your patch. I just think that 
it's impossible to implement it without lying to the user or making 
things just as bad in a different way. I would _like_ you to be right. 
But my thing is finding and quantifying failure cases and the entire 
question is full of fail.



...


See you keep giving me these examples where the history of the 
filesystem is uniform. It was made a certain way and stayed that way. 
But in real life this sort of thing is going to happen and your patch 
simply report's a _different_ _wrong_ number. A _friendlier_ wrong 
number, I'll grant you that, but still wrong.




Hi Robert, sorry for the late. (It's busy to deal with some other work.)

Yes, you are providing some examples here to show that in some cases the
numbers from df is not helpful to understand the real space state in 
disk. But

I'm afraid we can not blame df reporting a wrong number. You could say
Hey df, you are stupid, we can store the small file in metadata to exceed
your @size.. But he just reports the information from what he is seeing 
from FS level honestly.
He is reporting what he can see, and do not care about the other things 
out of

his business.

The all special cases you provided in this thread, actually lead to one 
result that
Btrfs is special, df command will report an improper in some case.. It 
means
we need some other methods to tell user about the space info. And yes, 
we had. It's

btrfs fi df.

You are trying to make df showing information as more as possible, even 
change
the behaviour of df in btrfs to show the numbers of different meaning 
with what it
is in other filesystems. And my answer is keeping df command doing what 
he want,

and solve the problems in our private df , btrfs fi df.

Thanx
Yang

. xaE



--
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: Standards Problems [Was: [PATCH v2 1/3] Btrfs: get more accurate output in df command.]

2014-12-17 Thread Dongsheng Yang

On 12/17/2014 03:52 AM, Robert White wrote:

On 12/16/2014 03:30 AM, Dongsheng Yang wrote:


Hi Robert, thanx for your proposal about this.

IMHO, output of df command shoud be more friendly to user.
Well, I think we have a disagreement on this point, let's take a look at
what the zfs is doing.

/dev/sda7- 10G
/dev/sda8- 10G
# zpool create myzpool mirror /dev/sda7 /dev/sda8 -f
# df -h /myzpool/
Filesystem  Size  Used Avail Use% Mounted on
myzpool 9.8G   21K  9.8G   1% /myzpool

That said that df command should tell user the space info they can see.
It means the output is the information from the FS level rather than
device level or _storage_manager level.


That's great for ZFS, but ZFS isn't BTRFS. ZFS can't get caught 
halfway between existing modailties and sit there forever. ZFS doesn't 
restructure itself. So the simple answer you want isn't _possible_ 
outside very simple cases.


So again, you've displayed a _simple_ case as if it covers or 
addresses all the complex cases.


(I don't have the storage to actually do the exercise) But what do you 
propose the correct answer is for the following case:



/dev/sda - 7.5G
/dev/sdb - 7.5G

mkfs.btrfs /dev/sd{a,b} -d raid0
mount /dev/sda /mnt
dd if=/dev/urandom of=/mnt/consumed bs=1G count=7
btrfsck balance start -dconvert=raid1 -dlimit=1 /mnt
(wait)
/bin/df


The filesystem is now in a superposition where all future blocks are 
going to be written as raid1, one 2G stripe has been converted into 
two two-gig stripes that have been mirrored, and six gig is still RAID0.




Similar with your mail about inline file case, I think this is another 
thing.


I really appreciate your persistence and so much analyse in semasiology.
I think I will never convince you at this point even with thousands mails
to express myself. What about implementing your proposal here and sending
a patchset at least with RFC. Then it can be more clear to us and we can 
make

the choice more easily. :)

Again, below is all points from my side:

The df command we discussed here is on the top level which is directly
facing the user.

1), For a linux user, he does not care about the detail how the data is
stored in devices. They do not care even not know what's Single, what
does DUP mean, and how a fs implement the RAID10. What they want to
know is *what is the size of the filesystem I am using and how much
space is still available to me*. That's what I said by FS space level

2). For a btrfs user, they know about the single, dup and RAIDX. When they
want to know what's the raid level in each space info, they can use btrfs
fi df to print the information they want.

3). Device level. for debugging.
Sometimes, you need to know how the each chunk is stored in device. Please
use btrfs-debug-tree to show details you want as more as possible.

4). df in ZFS is showing the FS space information.

5). For the elder btrfs_statfs(), We have discussed about df command
and chosen to hide the detail information to user.
And only show the FS space information to user. Current btrfs_statfs() 
is working like

this.

6). IIUC, you are saying that:
 a). BTRFS is not ZFS, df in zfs is not referenced to us.
 b). Current btrfs_statfs() is woring in a wrong way, we
   need to reimplement it from another new view point.

I am not sure your proposal here is not better. As I said above,
I am pleased to see a demo of it. If it works better, I am really
very happy to agree with you in this argument.

My patch could be objected, but the problem in current btrfs_statfs()
should be fixed by some ways. If you submit a better solution, I am pleased
to see btrfs becoming better. :)

Thanx
Yang

In your proposal we now have
@size=7G
@used=??? (clearly 7G, at the least, is consumed)
@filesize[consumed]=7G

@available is really messed up since there is now _probably_ 1G of one 
of the original raid0 extents with free space and so available, almost 
all of the single RAID1 metadata block, Room for three more metadata 
stripes, and room for one more RAID1 extent.


so @available=2-ish gigs.

But since statfs() pivots on @size and @available /bin/df is going to 
report @used as 3-ish gigs even though we've got an uncompressed and 
uncompressable @7G file.


NOW waht if we went the _other_ way?

/dev/sda - 7.5G
/dev/sdb - 7.5G

mkfs.btrfs /dev/sd{a,b} -d raid1
mount /dev/sda /mnt
dd if=/dev/urandom of=/mnt/consumed bs=1G count=7
btrfsck balance start -dconvert=raid0 -dlimit=1 /mnt
(wait)
/bin/df

filesystem is _full_ when the convert starts.

@size=14Gig
@used=7G
@actual_available=0
@reported_available=??? (at least 2x1G extents are up for grabs so 
minimum 2G)

@reported_used=???
@calculated_used=???

We are either back to reporting available space when non-trivial 
allocation will report ENOSPC (if I did the math right etc).


Now do partial conversions to other formats and repeat the exercise.
Now add or remove storage here-or-there.

The working set and the current model are not _required_

Re: Standards Problems [Was: [PATCH v2 1/3] Btrfs: get more accurate output in df command.]

2014-12-16 Thread Dongsheng Yang

On 12/16/2014 11:30 AM, Robert White wrote:

On 12/15/2014 01:36 AM, Robert White wrote:

So we don't just hand-wave over statfs(). We include the
dev_item.bytes_excluded in the superblock and we decide once-and-for-all
(with any geometry creation, or completed conversion) how many bytes
just _can't_ be reached but only once we _know_ they cant be reached.
And we memorialize that unreachable data in the superblocks.

Thereafter we report the raw numbers after subtracting anything we know
cannot be reached.

All other helpful solutions are NP-complete and insoluble.


On multiple re-readings of my own words and running off to the POSIX 
definitions _and_ kernel sources (which don't agree).


The practical bits first ::

I would add a -c | --compatable option to btrfs fi df
that let it produce /bin/df format-compatable output that gave the 
real numbers as defined near the end.



/dev/sda 1TiB
/dev/sdb 2TiB


mkfs.btrfs /dev/sd{a,b} -d raid1

@size=3TiB @used=0TiB @available=2TiB

The above would be ideal. But POSIX says no. f_blocks is defined 
(only in the comments) as total data blocks in the filesystem and 
/bin/df pivots on that assumption, so the only usable option left is ::


@size=2TiB @used=0TiB @available=2TiB

After which @used would be the real, raw space consumed. If it takes 
2GiB or 4GiB to store 1GiB (q.v. RAID 1 and 10) then @used would go up 
by that 2 or 4 GiB.


Hi Robert, thanx for your proposal about this.

IMHO, output of df command shoud be more friendly to user.
Well, I think we have a disagreement on this point, let's take a look at 
what the zfs is doing.


/dev/sda7- 10G
/dev/sda8- 10G
# zpool create myzpool mirror /dev/sda7 /dev/sda8 -f
# df -h /myzpool/
Filesystem  Size  Used Avail Use% Mounted on
myzpool 9.8G   21K  9.8G   1% /myzpool

That said that df command should tell user the space info they can see.
It means the output is the information from the FS level rather than 
device level or _storage_manager level.


Thanx
Yang


Given the not-displayed, not reported, excluded_by_geometry values 
(e.g. @waste) the equation should always be ::


@size - @waste = @used + @available

The fact that /bin/df doesn't display all four values is just tough, 
The fact that it calculates one for us is really annoying, 
show-super would be the place to go find the truth.


The @waste value is soft because while 1TiB of /dev/sdb that is not 
going to be used isn't a _particular_ 1TiB. It could be low blocks or 
high blocks or randomly distributed blocks that end up not having data.


So keeping with my thought that (ideally) @size should be the safe dd 
size for doing a raw-block transcribe of the devices and filesystem, 
it is most correct for @size to be real storage size. But sadly, posix 
didn't define that value for that role, so we are forced to munge 
around. (particularly since /bin/df calculates stuff for us).



Calculation of the @waste would have to happen in two phases. At 
initiation phase of any convert @waste would be set to zero. At 
completion of any _full_ convert, when we know that there are no 
leftover bits that could lead to rampant mis-report, @waste would be 
calculated for each device as a dev_item. Then the total would be 
stored as a global item.


btrfs tools would report all four items.

statfs() would have to report (@size-@waste) and @available, but 
that's a problem with limits to the assumptions made by statfs() 
designers two decades ago.


I don't know which numbers we keep on hand and which we derive so...

@available, if calculated dynamically would be
sum(@size, -@waste, -@used).

@used, if calculated dynamically, would be
sum(@size, -@waste, -@available).

This would also keep all the determinations of @waste well defined and 
relegated to specific, infrequently executed blocks of code.


GIVEN ALSO ::

The BTRFS dynamic internal layout allows for completely valid states 
that are inconsistent with the current filesystem flags... Such as it 
is legal to set the RAID1 mode for data but still having RAID0, RAID5, 
and any manner of other extents present... there is no finite solution 
to every particular layout that exists.


This condition is even _mandatory_ in an evolving system. May persist 
if conversion is interrupted and then the balance is aborted. And 
might be purely legal if you supply a convert option and limit the 
number of blocks to process in the same run.


Each individual extent block is it's own master in terms of what mode 
the filesystem is actally in when that extent is being accessed. This 
fact is _unchangeable_.



STANDARDS REFERENCES and Issues...

The actual standard from POSIX at The Open Group refers to f_blocks as 
Total number of blocks on file system in units of f_frsize.


See :: 
http://pubs.opengroup.org/onlinepubs/009695399/basedefs/sys/statvfs.h.html


The linux kernel source and man pages say total data blocks in 
filesystem.


I don't know where/when/why the total blocks got re-qualified as 
total 

Re: Standards Problems [Was: [PATCH v2 1/3] Btrfs: get more accurate output in df command.]

2014-12-16 Thread Dongsheng Yang
On Tue, Dec 16, 2014 at 7:30 PM, Dongsheng Yang
yangds.f...@cn.fujitsu.com wrote:
 On 12/16/2014 11:30 AM, Robert White wrote:

 On 12/15/2014 01:36 AM, Robert White wrote:

 So we don't just hand-wave over statfs(). We include the
 dev_item.bytes_excluded in the superblock and we decide once-and-for-all
 (with any geometry creation, or completed conversion) how many bytes
 just _can't_ be reached but only once we _know_ they cant be reached.
 And we memorialize that unreachable data in the superblocks.

 Thereafter we report the raw numbers after subtracting anything we know
 cannot be reached.

 All other helpful solutions are NP-complete and insoluble.


 On multiple re-readings of my own words and running off to the POSIX
 definitions _and_ kernel sources (which don't agree).

 The practical bits first ::

 I would add a -c | --compatable option to btrfs fi df
 that let it produce /bin/df format-compatable output that gave the real
 numbers as defined near the end.


 /dev/sda 1TiB
 /dev/sdb 2TiB


 mkfs.btrfs /dev/sd{a,b} -d raid1

 @size=3TiB @used=0TiB @available=2TiB

 The above would be ideal. But POSIX says no. f_blocks is defined (only
 in the comments) as total data blocks in the filesystem and /bin/df pivots
 on that assumption, so the only usable option left is ::

 @size=2TiB @used=0TiB @available=2TiB

 After which @used would be the real, raw space consumed. If it takes 2GiB
 or 4GiB to store 1GiB (q.v. RAID 1 and 10) then @used would go up by that 2
 or 4 GiB.


 Hi Robert, thanx for your proposal about this.

 IMHO, output of df command shoud be more friendly to user.
 Well, I think we have a disagreement on this point, let's take a look at
 what the zfs is doing.

 /dev/sda7- 10G
 /dev/sda8- 10G
 # zpool create myzpool mirror /dev/sda7 /dev/sda8 -f
 # df -h /myzpool/
 Filesystem  Size  Used Avail Use% Mounted on
 myzpool 9.8G   21K  9.8G   1% /myzpool

 That said that df command should tell user the space info they can see.
 It means the output is the information from the FS level rather than device
 level or _storage_manager level.

Addition:

There are some other ways to get the space information in btrfs, btrfs
fi df, btrfs fi show, btrfs-debug-tree.

The df command we discussed here is on the top level which is directly
facing the user. Let me try to show the difference in different level.

1), TOP level, for a linux user: df command.
For a linux user, he does not care about the detail how the data is
stored in devices.
They do not care even not know what's Single, what does DUP mean, and how
a fs implement the RAID10. What they want to know is *what is the size
of the filesystem
I am using and how much space is still available to me*. That's what I
said by FS space level)

2). Middle level, for a btrfs user: btrfs fi df/show.
For a btrfs user, they know about the single, dup and RAIDX. When they
want to know
what's the raid level in each space info, they can use btrfs fi df to
print the information
they want.

3). Device level. for debugging.
Sometimes, you need to know how the each chunk is stored in device. Please
use btrfs-debug-tree to show details you want as more as possible.

After all, I would say, the information you want to show is *not*
incorrect to me, but it's not the
business of df command.

Thanx

 Thanx
 Yang


 Given the not-displayed, not reported, excluded_by_geometry values (e.g.
 @waste) the equation should always be ::

 @size - @waste = @used + @available

 The fact that /bin/df doesn't display all four values is just tough, The
 fact that it calculates one for us is really annoying, show-super would be
 the place to go find the truth.

 The @waste value is soft because while 1TiB of /dev/sdb that is not going
 to be used isn't a _particular_ 1TiB. It could be low blocks or high blocks
 or randomly distributed blocks that end up not having data.

 So keeping with my thought that (ideally) @size should be the safe dd
 size for doing a raw-block transcribe of the devices and filesystem, it is
 most correct for @size to be real storage size. But sadly, posix didn't
 define that value for that role, so we are forced to munge around.
 (particularly since /bin/df calculates stuff for us).


 Calculation of the @waste would have to happen in two phases. At
 initiation phase of any convert @waste would be set to zero. At completion
 of any _full_ convert, when we know that there are no leftover bits that
 could lead to rampant mis-report, @waste would be calculated for each device
 as a dev_item. Then the total would be stored as a global item.

 btrfs tools would report all four items.

 statfs() would have to report (@size-@waste) and @available, but that's a
 problem with limits to the assumptions made by statfs() designers two
 decades ago.

 I don't know which numbers we keep on hand and which we derive so...

 @available, if calculated dynamically would be
 sum(@size, -@waste, -@used).

 @used, if calculated dynamically, would be
 sum(@size

Re: [PATCH v2 1/3] Btrfs: get more accurate output in df command.

2014-12-16 Thread Dongsheng Yang
Hi Goffredo,

On Tue, Dec 16, 2014 at 1:47 AM, Goffredo Baroncelli kreij...@inwind.it wrote:
 I Yang,

 On 12/14/2014 12:29 PM, Dongsheng Yang wrote:
 On Sat, Dec 13, 2014 at 3:25 AM, Goffredo Baroncelli kreij...@inwind.it 
 wrote:
 On 12/11/2014 09:31 AM, Dongsheng Yang wrote:
 When function btrfs_statfs() calculate the tatol size of fs, it is 
 calculating
 the total size of disks and then dividing it by a factor. But in some 
 usecase,
 the result is not good to user.


 I Yang; during my test I discovered an error:

 $ sudo lvcreate -L +10G -n disk vgtest
 $ sudo /home/ghigo/mkfs.btrfs -f /dev/vgtest/disk
 Btrfs v3.17
 See http://btrfs.wiki.kernel.org for more information.

 Turning ON incompat feature 'extref': increased hardlink limit per file to 
 65536
 fs created label (null) on /dev/vgtest/disk
 nodesize 16384 leafsize 16384 sectorsize 4096 size 10.00GiB
 $ sudo mount /dev/vgtest/disk /mnt/btrfs1/
 $ df /mnt/btrfs1/
 Filesystem  1K-blocksUsed Available Use% Mounted on
 /dev/mapper/vgtest-disk   9428992 1069312   8359680  12% /mnt/btrfs1
 $ sudo ~/btrfs fi df /mnt/btrfs1/
 Data, single: total=8.00MiB, used=256.00KiB
 System, DUP: total=8.00MiB, used=16.00KiB
 System, single: total=4.00MiB, used=0.00B
 Metadata, DUP: total=1.00GiB, used=112.00KiB
 Metadata, single: total=8.00MiB, used=0.00B
 GlobalReserve, single: total=16.00MiB, used=0.00B

 What seems me strange is the 9428992KiB of total disk space as reported
 by df. About 600MiB are missing !

 Without your patch, I got:

 $ df /mnt/btrfs1/
 Filesystem  1K-blocks  Used Available Use% Mounted on
 /dev/mapper/vgtest-disk  10485760 16896   8359680   1% /mnt/btrfs1


 Hi Goffredo, thanx for pointing this. Let me try to show the reason of it.

 In this case you provided here, the metadata is 1G in DUP. It means
 we spent 2G device space for it. But from the view point of user, they
 can only see 9G size for this fs. It's show as below:
  1G
 -| Filesystem space (9G)
 | \
 |  \
 |   \
 |2G  \
 -||- Device space (10G)
 DUP   |

 The main idea about the new btrfs_statfs() is hiding the detail in Device
 space and only show the information in the FS space level.

 I am not entirely convinced. On the basis of your statement, I would find a 
 difference of 1G or 1G/2... but missing are 600MB...

Ha, forgot to clarify this one. 9428992K is almost 9G actually.
9G = (9 * 2^20)K = 9437184K.

So, as I showed in the graphic, @size is 9G. :)

 Grzegorz found a difference of 2.3GB (but on a bigger disk).

 Looking at your patch set, it seems to me that the computation of the
 total disk space is done differently than before.

 Before, the total disk space was

 - buf-f_blocks = div_u64(btrfs_super_total_bytes(disk_super), factor);
 - buf-f_blocks = bits;

 I read this as: total disk space is the sum of the disk size (corrected by a
 factor depending by the profile).

 Instead after your patches the total disk space is

 + buf-f_blocks = total_alloc + total_free_data;

 This means that if a disk is not fully mapped by chunks, there is a difference
 between the total disk space and the value reported by df.

 May be that you are highlighting a bug elsewhere (not caused by your patch) ?

 BTW
 I will continue my tests...

Thank you very much. :)

Yang

 BR
 G.Baroncelli


 Actually, the similar idea is adopted in btrfs fi df.

 Example:
 # lvcreate -L +10G -n disk Group0
 # mkfs.btrfs -f /dev/Group0/disk
 # dd if=/dev/zero of=/mnt/data bs=1M count=10240
 dd: error writing ‘/mnt/data’: No space left on device
 8163+0 records in
 8162+0 records out
 8558477312 bytes (8.6 GB) copied, 207.565 s, 41.2 MB/s
 # df /mnt
 Filesystem  1K-blocksUsed Available Use% Mounted on
 /dev/mapper/Group0-disk   9428992 8382896  2048 100% /mnt
 # btrfs fi df /mnt
 Data, single: total=7.97GiB, used=7.97GiB
 System, DUP: total=8.00MiB, used=16.00KiB
 System, single: total=4.00MiB, used=0.00B
 Metadata, DUP: total=1.00GiB, used=8.41MiB
 Metadata, single: total=8.00MiB, used=0.00B
 GlobalReserve, single: total=16.00MiB, used=0.00B

 Now, the all space is used and got a ENOSPC error.
 But from the output of btrfs fi df. We can only find almost 9G (data
 8G + metadata 1G)
 is used. The difference is that it show the DUP here to make
 it more clear.

 Wish this description is clear to you :).

 If there is anything confusing or sounds incorrect to you, please point it 
 out.

 Thanx
 Yang


 Example:
   # mkfs.btrfs -f /dev/vdf1 /dev/vdf2 -d raid1
   # mount /dev/vdf1 /mnt
   # dd if=/dev/zero of=/mnt/zero bs=1M count=1000
   # df -h /mnt
 Filesystem  Size  Used Avail Use% Mounted on
 /dev/vdf1   3.0G 1018M  1.3G  45% /mnt
   # btrfs fi show /dev/vdf1
 Label: none  uuid: f85d93dc-81f4-445d-91e5-6a5cd9563294
   Total devices 2 FS bytes used 1001.53MiB
   devid1 size 2.00GiB used 1.85GiB path /dev/vdf1
   devid2 size

Re: [PATCH v2 1/3] Btrfs: get more accurate output in df command.

2014-12-15 Thread Dongsheng Yang

On 12/15/2014 03:49 PM, Robert White wrote:

On 12/14/2014 10:06 PM, Robert White wrote:

On 12/14/2014 05:21 PM, Dongsheng Yang wrote:

Anyone have some suggestion about it?

(... strong advocacy for raw numbers...)


Hi Robert, thanx for your so detailed reply.

You are proposing to report the raw numbers in df command, right?

Let's compare the space information in FS level and Device level.

Example:
/dev/sda == 1TiB
/dev/sdb == 2TiB

mkfs.btrfs /dev/sda /dev/sdb -d raid1

(1). If we report the raw numbers in df command, we will get the result of
@size=3T, @used=0 @available=3T. It's not a bad idea until now, as you said
user can consider the raid when they are using the fs. Then if we fill 
1T data

into it. we will get @size=3, @used=2T, @avalable=1T. And at this moment, we
will get ENOSPC when writing any more data. It's unacceptable.  Why you
tell me there is 1T space available, but I can't write one byte into it?

(2). Actually, there was an elder btrfs_statfs(), it reported the raw 
numbers to user.
To solve the problem mentioned in (1), we need report the space 
information in the FS level.

Current btrfs_statfs() is designed like this, but not working in any cases.
My new btrfs_statfs() here is following this design and implementing it
to show a *better* output to user.

Thanx
Yang


Concise Example to attempt to be clearer:

/dev/sda == 1TiB
/dev/sdb == 2TiB
/dev/sdc == 3TiB
/dev/sdd == 3TiB

mkfs.btrfs /dev/sd{a..d} -d raid0
mount /dev/sda /mnt

Now compare ::

#!/bin/bash
dd if=/dev/urandom of=/mnt/example bs=1G

vs

#!/bin/bash
typeset -i counter
for ((counter=0;;counter++)); do
dd if=/dev/urandom of=/mnt/example$conter bs=44 count=1
done

vs

#!/bin/bash
typeset -i counter
for ((counter=0;;counter++)); do
dd if=/dev/urandom of=/mnt/example$conter bs=44 count=1
done 
dd if=/dev/urandom of=/mnt/example bs=1G

Now repeat the above 3 models for
mkfs.btrfs /dev/sd{a..d} -d raid5


..

As you watch these six examples evolve you can ponder the ultimate 
futility of doing adaptive prediction within statfs().


Then go back and change the metadata from the default of RAID1 to 
RAID5 or RAID6 or RAID10.


Then go back and try

mkfs.btrfs /dev/sd{a..d} -d raid10

then balance when the big file runs out of space, then resume the big 
file with oflag=append


..

Unlike _all_ our predecessors, we are active at both the semantic file 
storage level _and_ the physical media management level.


None of the prior filesystems match this new ground exactly.

The only real option is to expose the raw numbers and then tell people 
the corner cases.


Absolutely unavailable blocks, such as the massive waste of 5TiB in 
the above sized media if raid10 were selected for both data and 
metadata would be subtracted from size if and only if it's 
_impossible_ for it to be accessed by this sort of restriction. But 
even in this case, the correct answer for size is 4TiB because that 
exactly answers how big is this filesystem.


It might be worth having a dev_item.bytes_excluded or unusable or 
whatever to account for the difference between total_bytes and 
bytes_used and the implicit bytes available. This would account for 
the 0,1,2,2 TiB that a raid10 of the example sizes could never reach 
in the current geometry. I'm betting that this sort of number also 
shows up as some number of sectors in any filesystem that has an odd 
tidbit of size up at the top where no structure is ever gong to fit. 
That's just a feature of the way disks use GB instead of GiB and msdos 
style partitions love the number 63.


So resize sets the size. Geometry limitations may reduce the effective 
size by some, or a _lot_, but then the used-vs-available should _not_ 
try to correct for whatever geometry is in use. Even when it might be 
simple because if it does it well in the simple cases like 
raid10/raid10, it would have to botch it up on the hard cases.



.



--
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 v2 1/3] Btrfs: get more accurate output in df command.

2014-12-14 Thread Dongsheng Yang
On Sat, Dec 13, 2014 at 3:25 AM, Goffredo Baroncelli kreij...@inwind.it wrote:
 On 12/11/2014 09:31 AM, Dongsheng Yang wrote:
 When function btrfs_statfs() calculate the tatol size of fs, it is 
 calculating
 the total size of disks and then dividing it by a factor. But in some 
 usecase,
 the result is not good to user.


 I Yang; during my test I discovered an error:

 $ sudo lvcreate -L +10G -n disk vgtest
 $ sudo /home/ghigo/mkfs.btrfs -f /dev/vgtest/disk
 Btrfs v3.17
 See http://btrfs.wiki.kernel.org for more information.

 Turning ON incompat feature 'extref': increased hardlink limit per file to 
 65536
 fs created label (null) on /dev/vgtest/disk
 nodesize 16384 leafsize 16384 sectorsize 4096 size 10.00GiB
 $ sudo mount /dev/vgtest/disk /mnt/btrfs1/
 $ df /mnt/btrfs1/
 Filesystem  1K-blocksUsed Available Use% Mounted on
 /dev/mapper/vgtest-disk   9428992 1069312   8359680  12% /mnt/btrfs1
 $ sudo ~/btrfs fi df /mnt/btrfs1/
 Data, single: total=8.00MiB, used=256.00KiB
 System, DUP: total=8.00MiB, used=16.00KiB
 System, single: total=4.00MiB, used=0.00B
 Metadata, DUP: total=1.00GiB, used=112.00KiB
 Metadata, single: total=8.00MiB, used=0.00B
 GlobalReserve, single: total=16.00MiB, used=0.00B

 What seems me strange is the 9428992KiB of total disk space as reported
 by df. About 600MiB are missing !

 Without your patch, I got:

 $ df /mnt/btrfs1/
 Filesystem  1K-blocks  Used Available Use% Mounted on
 /dev/mapper/vgtest-disk  10485760 16896   8359680   1% /mnt/btrfs1


Hi Goffredo, thanx for pointing this. Let me try to show the reason of it.

In this case you provided here, the metadata is 1G in DUP. It means
we spent 2G device space for it. But from the view point of user, they
can only see 9G size for this fs. It's show as below:
 1G
-| Filesystem space (9G)
| \
|  \
|   \
|2G  \
-||- Device space (10G)
DUP   |

The main idea about the new btrfs_statfs() is hiding the detail in Device
space and only show the information in the FS space level.

Actually, the similar idea is adopted in btrfs fi df.

Example:
# lvcreate -L +10G -n disk Group0
# mkfs.btrfs -f /dev/Group0/disk
# dd if=/dev/zero of=/mnt/data bs=1M count=10240
dd: error writing ‘/mnt/data’: No space left on device
8163+0 records in
8162+0 records out
8558477312 bytes (8.6 GB) copied, 207.565 s, 41.2 MB/s
# df /mnt
Filesystem  1K-blocksUsed Available Use% Mounted on
/dev/mapper/Group0-disk   9428992 8382896  2048 100% /mnt
# btrfs fi df /mnt
Data, single: total=7.97GiB, used=7.97GiB
System, DUP: total=8.00MiB, used=16.00KiB
System, single: total=4.00MiB, used=0.00B
Metadata, DUP: total=1.00GiB, used=8.41MiB
Metadata, single: total=8.00MiB, used=0.00B
GlobalReserve, single: total=16.00MiB, used=0.00B

Now, the all space is used and got a ENOSPC error.
But from the output of btrfs fi df. We can only find almost 9G (data
8G + metadata 1G)
is used. The difference is that it show the DUP here to make
it more clear.

Wish this description is clear to you :).

If there is anything confusing or sounds incorrect to you, please point it out.

Thanx
Yang


 Example:
   # mkfs.btrfs -f /dev/vdf1 /dev/vdf2 -d raid1
   # mount /dev/vdf1 /mnt
   # dd if=/dev/zero of=/mnt/zero bs=1M count=1000
   # df -h /mnt
 Filesystem  Size  Used Avail Use% Mounted on
 /dev/vdf1   3.0G 1018M  1.3G  45% /mnt
   # btrfs fi show /dev/vdf1
 Label: none  uuid: f85d93dc-81f4-445d-91e5-6a5cd9563294
   Total devices 2 FS bytes used 1001.53MiB
   devid1 size 2.00GiB used 1.85GiB path /dev/vdf1
   devid2 size 4.00GiB used 1.83GiB path /dev/vdf2
 a. df -h should report Size as 2GiB rather than as 3GiB.
 Because this is 2 device raid1, the limiting factor is devid 1 @2GiB.

 b. df -h should report Avail as 0.97GiB or less, rather than as 1.3GiB.
 1.85   (the capacity of the allocated chunk)
-1.018  (the file stored)
+(2-1.85=0.15)  (the residual capacity of the disks
 considering a raid1 fs)
---
 =   0.97

 This patch drops the factor at all and calculate the size observable to
 user without considering which raid level the data is in and what's the
 size exactly in disk.
 After this patch applied:
   # mkfs.btrfs -f /dev/vdf1 /dev/vdf2 -d raid1
   # mount /dev/vdf1 /mnt
   # dd if=/dev/zero of=/mnt/zero bs=1M count=1000
   # df -h /mnt
 Filesystem  Size  Used Avail Use% Mounted on
 /dev/vdf1   2.0G  1.3G  713M  66% /mnt
   # df /mnt
 Filesystem 1K-blocksUsed Available Use% Mounted on
 /dev/vdf12097152 1359424729536  66% /mnt
   # btrfs fi show /dev/vdf1
 Label: none  uuid: e98c1321-645f-4457-b20d-4f41dc1cf2f4
   Total devices 2 FS bytes used 1001.55MiB
   devid1 size 2.00GiB used 1.85GiB path /dev/vdf1
   devid2 size 4.00GiB used 1.83GiB path /dev/vdf2
 a). The @Size is 2G as we

Re: [PATCH v2 1/3] Btrfs: get more accurate output in df command.

2014-12-14 Thread Dongsheng Yang

On 12/14/2014 10:32 PM, Grzegorz Kowal wrote:

Hi,

I see another problem on 1 device fs after applying this patch. I set
up 30GB system partition:

in gdisk key 'i'
Partition size: 62914560 sectors (30.0 GiB) - 62914560 * 512 =
32212254720 = 30.0GiB

before applying the patch df -B1 shows

Filesystem1B-blocks UsedAvailable Use% Mounted on
/dev/sda3  32212254720  18149384192  12821815296  59% /

The total size matches exactly the one reported by gdisk.

After applying the patch df -B1 shows

Filesystem1B-blocks UsedAvailable Use% Mounted on
/dev/sda3   29761732608  17037860864  12723871744  58% /

The total size is 29761732608 bytes now, which is 2337 MiB (2.28GB)
smaller then the partition size.


Hi Grzegorz, this is very similar with the question discussed in my last 
mail. I believe
the 2.28GB is used for metadata in DUP level. That said, there is a 
space of almost
4.56GB (2.28*2GB) used for metadata and the metadata is in DUP level. 
Then user can

only see a 2.28GB from the FS space level.

2.28G
-| Filesystem space (27.72G)
| \
|  \
|   \
| 4.56GB \
-||- Device space (30.0G)
DUP   |

The main idea in new btrfs_statfs() is to consider the space information
in a FS level rather than the device space level. Then the @size in df
is the size in FS space level. As we all agree to report @size
as 5G in the case of mkfs.btrfs /dev/vdb (5G) /dev/vdc (5G) -d raid1,
this means we are agreed to think the df in a FS space without showing
the detail in device space. In this time, the total size in FS space is  
27.72G,

so the @size in df is 27.72G.

Does it make sense to you?

As there are 2 complaints for the same change of @size in df, I have to
say it maybe not so easy to understand.

Anyone have some suggestion about it?

Thanx
Yang


IMHO the total size should correspond exactly to the partition size,
at least in the case of fs on one device, and anything used by the
file system and user should go to the used space.

Am I missing something here?

Thanks,
Grzegorz

On Sun, Dec 14, 2014 at 12:27 PM, Grzegorz Kowal
custos.men...@gmail.com wrote:

Hi,

I see another problem on 1 device fs after applying this patch. I set up
30GB system partition:

in gdisk key 'i'
Partition size: 62914560 sectors (30.0 GiB) - 62914560 * 512 = 32212254720
= 30.0GiB

before applying the patch df -B1 shows

Filesystem1B-blocks UsedAvailable Use% Mounted on
/dev/sda3  32212254720  18149384192  12821815296  59% /

The total size matches exactly the one reported by gdisk.

After applying the patch df -B1 shows

Filesystem1B-blocks UsedAvailable Use% Mounted on
/dev/sda3   29761732608  17037860864  12723871744  58% /

The total size is 29761732608 bytes now, which is 2337 MiB (2.28GB) smaller
then the partition size.

IMHO the total size should correspond exactly to the partition size, at
least in the case of fs on one device, and anything used by the file system
and user should go to the used space.

Am I missing something here?

Thanks,
Grzegorz





On Sun, Dec 14, 2014 at 9:29 AM, Dongsheng Yang dongsheng081...@gmail.com
wrote:

On Sat, Dec 13, 2014 at 3:25 AM, Goffredo Baroncelli kreij...@inwind.it
wrote:

On 12/11/2014 09:31 AM, Dongsheng Yang wrote:

When function btrfs_statfs() calculate the tatol size of fs, it is
calculating
the total size of disks and then dividing it by a factor. But in some
usecase,
the result is not good to user.


I Yang; during my test I discovered an error:

$ sudo lvcreate -L +10G -n disk vgtest
$ sudo /home/ghigo/mkfs.btrfs -f /dev/vgtest/disk
Btrfs v3.17
See http://btrfs.wiki.kernel.org for more information.

Turning ON incompat feature 'extref': increased hardlink limit per file
to 65536
fs created label (null) on /dev/vgtest/disk
 nodesize 16384 leafsize 16384 sectorsize 4096 size 10.00GiB
$ sudo mount /dev/vgtest/disk /mnt/btrfs1/
$ df /mnt/btrfs1/
Filesystem  1K-blocksUsed Available Use% Mounted on
/dev/mapper/vgtest-disk   9428992 1069312   8359680  12% /mnt/btrfs1
$ sudo ~/btrfs fi df /mnt/btrfs1/
Data, single: total=8.00MiB, used=256.00KiB
System, DUP: total=8.00MiB, used=16.00KiB
System, single: total=4.00MiB, used=0.00B
Metadata, DUP: total=1.00GiB, used=112.00KiB
Metadata, single: total=8.00MiB, used=0.00B
GlobalReserve, single: total=16.00MiB, used=0.00B

What seems me strange is the 9428992KiB of total disk space as reported
by df. About 600MiB are missing !

Without your patch, I got:

$ df /mnt/btrfs1/
Filesystem  1K-blocks  Used Available Use% Mounted on
/dev/mapper/vgtest-disk  10485760 16896   8359680   1% /mnt/btrfs1


Hi Goffredo, thanx for pointing this. Let me try to show the reason of it.

In this case you provided here, the metadata is 1G in DUP. It means
we spent 2G device space for it. But from the view point of user, they
can only see 9G size for this fs. It's show as below:
  1G

Re: [PATCH v2 1/3] Btrfs: get more accurate output in df command.

2014-12-13 Thread Dongsheng Yang

On 12/13/2014 02:00 AM, Goffredo Baroncelli wrote:

On 12/11/2014 09:31 AM, Dongsheng Yang wrote:

When function btrfs_statfs() calculate the tatol size of fs, it is calculating
the total size of disks and then dividing it by a factor. But in some usecase,
the result is not good to user.

I am checking it; to me it seems a good improvement. However
I noticed that df now doesn't seem to report anymore the space consumed
by the meta-data chunk; eg:

# I have two disks of 5GB each
$ sudo ~/mkfs.btrfs -f -m raid1 -d raid1 /dev/vgtest/disk /dev/vgtest/disk1

$ df -h /mnt/btrfs1/
Filesystem   Size  Used Avail Use% Mounted on
/dev/mapper/vgtest-disk  5.0G  1.1G  4.0G  21% /mnt/btrfs1

$ sudo btrfs fi show
Label: none  uuid: 884414c6-9374-40af-a5be-3949cdf6ad0b
Total devices 2 FS bytes used 640.00KB
devid2 size 5.00GB used 2.01GB path /dev/dm-1
devid1 size 5.00GB used 2.03GB path /dev/dm-0

$ sudo ./btrfs fi df /mnt/btrfs1/
Data, RAID1: total=1.00GiB, used=512.00KiB
Data, single: total=8.00MiB, used=0.00B
System, RAID1: total=8.00MiB, used=16.00KiB
System, single: total=4.00MiB, used=0.00B
Metadata, RAID1: total=1.00GiB, used=112.00KiB
Metadata, single: total=8.00MiB, used=0.00B
GlobalReserve, single: total=16.00MiB, used=0.00B

In this case the filesystem is empty (it was a new filesystem !). However a
1G metadata chunk was already allocated. This is the reasons why the free
space is only 4Gb.


Actually, in the original btrfs_statfs(), the space in metadata chunk 
was also not be considered
as available. But you will get 5G in this case with original 
btrfs_statfs() because there is a bug
in it. As I use another implementation to calculate the @available in df 
command, I did not

mention this problem. I can describe it as below.

In original btrfs_statfs(), we only consider the free space in data 
chunk as available.


list_for_each_entry_rcu(found, head, list) {
if (found-flags  BTRFS_BLOCK_GROUP_DATA) {
int i;

total_free_data += found-disk_total - 
found-disk_used;


In the later, we will add the total_free_data to @available in output of df.
buf-f_bavail = total_free_data;
BUT:
This is incorrect! It should be:
  buf-f_bavail = div_u64(total_free_data, factor);
That said this bug will add one more (data_chunk_disk_total - 
data_chunk_disk_used = 1G)
to @available by mistake. Unfortunately, the free space in 
metadata_chunk is also 1G.


Then we will get 5G in this case you provided here.

Conclusion:
Even in the original btrfs_statfs(), the free space in metadata is 
also considered as not available.
But one bug in it make it to be misunderstood. My new btrfs_statfs() 
still consider the free space

in metadata as not available, furthermore, I add it into @used.


On my system the ratio metadata/data is 234MB/8.82GB = ~3%, so ignoring the
metadata chunk from the free space may not be a big problem.






Example:
# mkfs.btrfs -f /dev/vdf1 /dev/vdf2 -d raid1
# mount /dev/vdf1 /mnt
# dd if=/dev/zero of=/mnt/zero bs=1M count=1000
# df -h /mnt
Filesystem  Size  Used Avail Use% Mounted on
/dev/vdf1   3.0G 1018M  1.3G  45% /mnt
# btrfs fi show /dev/vdf1
Label: none  uuid: f85d93dc-81f4-445d-91e5-6a5cd9563294
Total devices 2 FS bytes used 1001.53MiB
devid1 size 2.00GiB used 1.85GiB path /dev/vdf1
devid2 size 4.00GiB used 1.83GiB path /dev/vdf2
a. df -h should report Size as 2GiB rather than as 3GiB.
Because this is 2 device raid1, the limiting factor is devid 1 @2GiB.

b. df -h should report Avail as 0.97GiB or less, rather than as 1.3GiB.
 1.85   (the capacity of the allocated chunk)
-1.018  (the file stored)
+(2-1.85=0.15)  (the residual capacity of the disks
 considering a raid1 fs)
---
=   0.97

This patch drops the factor at all and calculate the size observable to
user without considering which raid level the data is in and what's the
size exactly in disk.
After this patch applied:
# mkfs.btrfs -f /dev/vdf1 /dev/vdf2 -d raid1
# mount /dev/vdf1 /mnt
# dd if=/dev/zero of=/mnt/zero bs=1M count=1000
# df -h /mnt
Filesystem  Size  Used Avail Use% Mounted on
/dev/vdf1   2.0G  1.3G  713M  66% /mnt
# df /mnt
Filesystem 1K-blocksUsed Available Use% Mounted on
/dev/vdf12097152 1359424729536  66% /mnt
# btrfs fi show /dev/vdf1
Label: none  uuid: e98c1321-645f-4457-b20d-4f41dc1cf2f4
Total devices 2 FS bytes used 1001.55MiB
devid1 size 2.00GiB used 1.85GiB path /dev/vdf1
devid2 size 4.00GiB used 1.83GiB path /dev/vdf2
a). The @Size is 2G as we expected.
b). @Available is 700M = 1.85G - 1.3G + (2G - 1.85G).
c). @Used is changed to 1.3G rather than 1018M as above. Because
 this patch do not treat the free space in metadata chunk

Re: [PATCH v2 1/3] Btrfs: get more accurate output in df command.

2014-12-13 Thread Dongsheng Yang

On 12/13/2014 08:50 AM, Duncan wrote:

Goffredo Baroncelli posted on Fri, 12 Dec 2014 19:00:20 +0100 as
excerpted:


$ sudo ./btrfs fi df /mnt/btrfs1/
Data, RAID1: total=1.00GiB, used=512.00KiB
Data, single: total=8.00MiB, used=0.00B
System, RAID1: total=8.00MiB, used=16.00KiB
System, single: total=4.00MiB, used=0.00B
Metadata, RAID1: total=1.00GiB, used=112.00KiB
Metadata, single: total=8.00MiB, used=0.00B
GlobalReserve, single: total=16.00MiB, used=0.00B

In this case the filesystem is empty (it was a new filesystem !).
However a 1G metadata chunk was already allocated. This is the reasons
why the free space is only 4Gb.

Trivial(?) correction.

Metadata chunks are quarter-gig, not 1 gig.  So that's 4 quarter-gig
metadata chunks allocated, not a (one/single) 1-gig metadata chunk.


Sorry but from my reading of the code, I have to say that in this case 
it is 1G.


Maybe I should be wrong, I would say, yes, the chunk_size for btrfs which is
smaller than 50G is 256M by default. But in mkfs, we alloc 1G for the first
metadata chunk.



On my system the ratio metadata/data is 234MB/8.82GB = ~3%, so ignoring
the metadata chunk from the free space may not be a big problem.

Presumably your use-case is primarily reasonably large files; too large
for their data to be tucked directly into metadata instead of allocating
an extent from a data chunk.

That's not always going to be the case.  And given the multi-device
default allocation of raid1 metadata, single data, files small enough to
fit into metadata have a default size effect double their actual size!
(Tho it can be noted that given btrfs' 4 KiB standard block size, without
metadata packing there'd still be an outsized effect for files smaller
than half that, 2 KiB or under, but there it'd be in data chunks, not
metadata.)



--
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


[PATCH v2 2/2] Btrfs: qgroup: Introduce a may_use to account space_info-bytes_may_use.

2014-12-12 Thread Dongsheng Yang
Currently, for pre_alloc or delay_alloc, the bytes will be accounted
in space_info by the three guys.
space_info-bytes_may_use --- space_info-reserved --- space_info-used.
But on the other hand, in qgroup, there are only two counters to account the
bytes, qgroup-reserved and qgroup-excl. And qg-reserved accounts
bytes in space_info-bytes_may_use and qg-excl accounts bytes in
space_info-used. So the bytes in space_info-reserved is not accounted
in qgroup. If so, there is a window we can exceed the quota limit when
bytes is in space_info-reserved.

Example:
# btrfs quota enable /mnt
# btrfs qgroup limit -e 10M /mnt
# for((i=0;i20;i++));do fallocate -l 1M /mnt/data$i; done
# sync
# btrfs qgroup show -pcre /mnt
qgroupid rfer excl max_rfer max_excl parent  child
     --  -
0/5  20987904 20987904 010485760 --- ---

qg-excl is 20987904 larger than max_excl 10485760.

This patch introduce a new counter named may_use to qgroup, then
there are three counters in qgroup to account bytes in space_info
as below.
space_info-bytes_may_use --- space_info-reserved --- space_info-used.
qgroup-may_use   --- qgroup-reserved --- qgroup-excl

With this patch applied:
# btrfs quota enable /mnt
# btrfs qgroup limit -e 10M /mnt
# for((i=0;i20;i++));do fallocate -l 1M /mnt/data$i; done
fallocate: /mnt/data9: fallocate failed: Disk quota exceeded
fallocate: /mnt/data10: fallocate failed: Disk quota exceeded
fallocate: /mnt/data11: fallocate failed: Disk quota exceeded
fallocate: /mnt/data12: fallocate failed: Disk quota exceeded
fallocate: /mnt/data13: fallocate failed: Disk quota exceeded
fallocate: /mnt/data14: fallocate failed: Disk quota exceeded
fallocate: /mnt/data15: fallocate failed: Disk quota exceeded
fallocate: /mnt/data16: fallocate failed: Disk quota exceeded
fallocate: /mnt/data17: fallocate failed: Disk quota exceeded
fallocate: /mnt/data18: fallocate failed: Disk quota exceeded
fallocate: /mnt/data19: fallocate failed: Disk quota exceeded
# sync
# btrfs qgroup show -pcre /mnt
qgroupid rferexclmax_rfer max_excl parent  child
   --  -
0/5  9453568 9453568 010485760 --- ---

Reported-by: Cyril SCETBON cyril.scet...@free.fr
Signed-off-by: Dongsheng Yang yangds.f...@cn.fujitsu.com
---
Changelog:
v1 - v2:
Remove the redundant check for fs_info-quota_enabled.

 fs/btrfs/extent-tree.c | 20 ++-
 fs/btrfs/inode.c   | 18 -
 fs/btrfs/qgroup.c  | 68 +++---
 fs/btrfs/qgroup.h  |  4 +++
 4 files changed, 104 insertions(+), 6 deletions(-)

diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index 014b7f2..f4ad737 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -5500,8 +5500,12 @@ static int pin_down_extent(struct btrfs_root *root,
 
set_extent_dirty(root-fs_info-pinned_extents, bytenr,
 bytenr + num_bytes - 1, GFP_NOFS | __GFP_NOFAIL);
-   if (reserved)
+   if (reserved) {
+   btrfs_qgroup_update_reserved_bytes(root-fs_info,
+  root-root_key.objectid,
+  num_bytes, -1);
trace_btrfs_reserved_extent_free(root, bytenr, num_bytes);
+   }
return 0;
 }
 
@@ -6230,6 +6234,9 @@ void btrfs_free_tree_block(struct btrfs_trans_handle 
*trans,
btrfs_update_reserved_bytes(cache, buf-len, RESERVE_FREE, 0);
trace_btrfs_reserved_extent_free(root, buf-start, buf-len);
pin = 0;
+   btrfs_qgroup_update_reserved_bytes(root-fs_info,
+  root-root_key.objectid,
+  buf-len, -1);
}
 out:
if (pin)
@@ -6964,7 +6971,11 @@ static int __btrfs_free_reserved_extent(struct 
btrfs_root *root,
else {
btrfs_add_free_space(cache, start, len);
btrfs_update_reserved_bytes(cache, len, RESERVE_FREE, delalloc);
+   btrfs_qgroup_update_reserved_bytes(root-fs_info,
+  root-root_key.objectid,
+  len, -1);
}
+
btrfs_put_block_group(cache);
 
trace_btrfs_reserved_extent_free(root, start, len);
@@ -7200,6 +7211,9 @@ int btrfs_alloc_logged_file_extent(struct 
btrfs_trans_handle *trans,
BUG_ON(ret); /* logic error */
ret = alloc_reserved_file_extent(trans, root, 0, root_objectid,
 0, owner, offset, ins, 1);
+   btrfs_qgroup_update_reserved_bytes(root-fs_info,
+  root-root_key.objectid

[PATCH v2 1/2] Btrfs: qgroup: free reserved in exceeding quota.

2014-12-12 Thread Dongsheng Yang
When we exceed quota limit in writing, we will free
some reserved extent when we need to drop but not free
account in qgroup. It means, each time we exceed quota
in writing, there will be some remain space in qg-reserved
we can not use any more. If things go on like this, the
all space will be ate up.

Signed-off-by: Dongsheng Yang yangds.f...@cn.fujitsu.com
Reviewed-by: Josef Bacik jba...@fb.com
---
 fs/btrfs/extent-tree.c | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index a84e00d..014b7f2 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -5262,8 +5262,11 @@ out_fail:
to_free = 0;
}
spin_unlock(BTRFS_I(inode)-lock);
-   if (dropped)
+   if (dropped) {
+   if (root-fs_info-quota_enabled)
+   btrfs_qgroup_free(root, dropped * root-nodesize);
to_free += btrfs_calc_trans_metadata_size(root, dropped);
+   }
 
if (to_free) {
btrfs_block_rsv_release(root, block_rsv, to_free);
-- 
1.8.4.2

--
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] Btrfs: get more accurate output in fd command.

2014-12-11 Thread Dongsheng Yang

On 12/11/2014 03:05 AM, Goffredo Baroncelli wrote:

On 12/10/2014 04:02 PM, Dongsheng Yang wrote:

On Wed, Dec 10, 2014 at 9:21 PM, Duncan 1i5t5.dun...@cox.net wrote:

Robert White posted on Wed, 10 Dec 2014 02:53:40 -0800 as excerpted:

[...]

And in the example, the mkfs was supplied with two devices, so there's no
dup metadata remaining from a formerly single-device filesystem, either.
(Tho there will be the small single-mode stubs, empty, remaining from the
mkfs process, as no balance has been run to delete them yet, but those
are much smaller and empty.)

Yes. One question not related here: how about delete them in the end of mkfs?

Thanx

A btrfs balance should remove them. If you don't want to balance a full
filesystem, you can filter the chunk by usage (set a low usage).
Recently it was discussed in a tread...


Thanx Goffredo, it works well to me.


BR
Goffredo




--
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


  1   2   >