Anand Jain
2013-Sep-27 16:45 UTC
[PATCH] btrfs-progs: calculate disk space that a subvol could free
It needs a lot more information about the snapshots if snapshot''s life cycle has to be all auto managed by scripts _some day_. this patch is a step towards that. This patch provides the size which would be freed if the subvol/snapshot is deleted. preview: --------------------- btrfs su show /btrfs/sv1 :: Unshared space: 89.09MiB --------------------- v2: rename to ''unshared space'' and edit commit text Signed-off-by: Anand Jain <anand.jain@oracle.com> --- cmds-subvolume.c | 5 ++ utils.c | 154 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ utils.h | 1 + 3 files changed, 160 insertions(+) diff --git a/cmds-subvolume.c b/cmds-subvolume.c index de246ab..0f36cde 100644 --- a/cmds-subvolume.c +++ b/cmds-subvolume.c @@ -809,6 +809,7 @@ static int cmd_subvol_show(int argc, char **argv) int fd = -1, mntfd = -1; int ret = 1; DIR *dirstream1 = NULL, *dirstream2 = NULL; + u64 freeable_bytes; if (check_argc_exact(argc, 2)) usage(cmd_subvol_show_usage); @@ -878,6 +879,8 @@ static int cmd_subvol_show(int argc, char **argv) goto out; } + freeable_bytes = get_subvol_freeable_bytes(fd); + ret = 0; /* print the info */ printf("%s\n", fullpath); @@ -915,6 +918,8 @@ static int cmd_subvol_show(int argc, char **argv) else printf("\tFlags: \t\t\t-\n"); + printf("\tUnshared space: \t%s\n", + pretty_size(freeable_bytes)); /* print the snapshots of the given subvol if any*/ printf("\tSnapshot(s):\n"); filter_set = btrfs_list_alloc_filter_set(); diff --git a/utils.c b/utils.c index ccb5199..ca30485 100644 --- a/utils.c +++ b/utils.c @@ -2062,3 +2062,157 @@ int lookup_ino_rootid(int fd, u64 *rootid) return 0; } + +/* gets the ref count for given extent + * 0 = didn''t find the item + * n = number of references +*/ +u64 get_extent_refcnt(int fd, u64 disk_blk) +{ + int ret = 0, i, e; + struct btrfs_ioctl_search_args args; + struct btrfs_ioctl_search_key *sk = &args.key; + struct btrfs_ioctl_search_header sh; + unsigned long off = 0; + + memset(&args, 0, sizeof(args)); + + sk->tree_id = BTRFS_EXTENT_TREE_OBJECTID; + + sk->min_type = BTRFS_EXTENT_ITEM_KEY; + sk->max_type = BTRFS_EXTENT_ITEM_KEY; + + sk->min_objectid = disk_blk; + sk->max_objectid = disk_blk; + + sk->max_offset = (u64)-1; + sk->max_transid = (u64)-1; + + while (1) { + sk->nr_items = 4096; + + ret = ioctl(fd, BTRFS_IOC_TREE_SEARCH, &args); + e = errno; + if (ret < 0) { + fprintf(stderr, "ERROR: search failed - %s\n", + strerror(e)); + return 0; + } + if (sk->nr_items == 0) + break; + + off = 0; + for (i = 0; i < sk->nr_items; i++) { + struct btrfs_extent_item *ei; + u64 ref; + + memcpy(&sh, args.buf + off, sizeof(sh)); + off += sizeof(sh); + + if (sh.type != BTRFS_EXTENT_ITEM_KEY) { + off += sh.len; + continue; + } + + ei = (struct btrfs_extent_item *)(args.buf + off); + ref = btrfs_stack_extent_refs(ei); + return ref; + } + sk->min_objectid = sh.objectid; + sk->min_offset = sh.offset; + sk->min_type = sh.type; + if (sk->min_offset < (u64)-1) + sk->min_offset++; + else if (sk->min_objectid < (u64)-1) { + sk->min_objectid++; + sk->min_offset = 0; + sk->min_type = 0; + } else + break; + } + return 0; +} + +u64 get_subvol_freeable_bytes(int fd) +{ + int ret = 0, i, e; + struct btrfs_ioctl_search_args args; + struct btrfs_ioctl_search_key *sk = &args.key; + struct btrfs_ioctl_search_header sh; + unsigned long off = 0; + u64 size_bytes = 0; + + memset(&args, 0, sizeof(args)); + + sk->tree_id = 0; + + sk->min_type = BTRFS_EXTENT_DATA_KEY; + sk->max_type = BTRFS_EXTENT_DATA_KEY; + + sk->max_objectid = (u64) -1; + sk->max_offset = (u64)-1; + sk->max_transid = (u64)-1; + + while (1) { + sk->nr_items = 4096; + + ret = ioctl(fd, BTRFS_IOC_TREE_SEARCH, &args); + e = errno; + if (ret < 0) { + fprintf(stderr, "ERROR: search failed - %s\n", + strerror(e)); + return 0; + } + if (sk->nr_items == 0) + break; + + off = 0; + for (i = 0; i < sk->nr_items; i++) { + struct btrfs_file_extent_item *efi; + u64 disk_bytenr = 0; + u64 num_bytes = 0; + u64 refcnt; + u8 type; + + memcpy(&sh, args.buf + off, sizeof(sh)); + off += sizeof(sh); + + if (sh.type != BTRFS_EXTENT_DATA_KEY) { + off += sh.len; + continue; + } + + efi = (struct btrfs_file_extent_item *)(args.buf + off); + type = btrfs_stack_file_extent_type(efi); + + if (type == BTRFS_FILE_EXTENT_INLINE) { + size_bytes ++ btrfs_stack_file_extent_ram_bytes(efi); + goto skip_extent_data; + } + disk_bytenr = btrfs_stack_file_extent_disk_bytenr(efi); + num_bytes = btrfs_stack_file_extent_num_bytes(efi); + + if (disk_bytenr) { + refcnt = get_extent_refcnt(fd, disk_bytenr); + if (refcnt == 1) + size_bytes += num_bytes; + } +skip_extent_data: + off += sh.len; + } + sk->min_objectid = sh.objectid; + sk->min_offset = sh.offset; + sk->min_type = sh.type; + + if (sk->min_offset < (u64)-1) + sk->min_offset++; + else if (sk->min_objectid < (u64)-1) { + sk->min_objectid++; + sk->min_offset = 0; + sk->min_type = 0; + } else + break; + } + return size_bytes; +} diff --git a/utils.h b/utils.h index 0f31db7..4ddcf09 100644 --- a/utils.h +++ b/utils.h @@ -91,5 +91,6 @@ int csum_tree_block(struct btrfs_root *root, struct extent_buffer *buf, int ask_user(char *question); int lookup_ino_rootid(int fd, u64 *rootid); int btrfs_scan_lblkid(int update_kernel); +u64 get_subvol_freeable_bytes(int fd); #endif -- 1.8.4.rc4.1.g0d8beaa -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Zach Brown
2013-Sep-27 19:10 UTC
Re: [PATCH] btrfs-progs: calculate disk space that a subvol could free
> diff --git a/cmds-subvolume.c b/cmds-subvolume.c > index de246ab..0f36cde 100644 > --- a/cmds-subvolume.c > +++ b/cmds-subvolume.c > @@ -809,6 +809,7 @@ static int cmd_subvol_show(int argc, char **argv) > int fd = -1, mntfd = -1; > int ret = 1; > DIR *dirstream1 = NULL, *dirstream2 = NULL; > + u64 freeable_bytes; > > if (check_argc_exact(argc, 2)) > usage(cmd_subvol_show_usage); > @@ -878,6 +879,8 @@ static int cmd_subvol_show(int argc, char **argv) > goto out; > } > > + freeable_bytes = get_subvol_freeable_bytes(fd); > + > ret = 0; > /* print the info */ > printf("%s\n", fullpath); > @@ -915,6 +918,8 @@ static int cmd_subvol_show(int argc, char **argv) > else > printf("\tFlags: \t\t\t-\n"); > > + printf("\tUnshared space: \t%s\n", > + pretty_size(freeable_bytes));There''s no reason to have a local variable: printf("\tUnshared space: \t%s\n", pretty_size(get_subvol_freeable_bytes(fd));> printf("\tSnapshot(s):\n"); > filter_set = btrfs_list_alloc_filter_set(); > diff --git a/utils.c b/utils.c > index ccb5199..ca30485 100644 > --- a/utils.c > +++ b/utils.c > @@ -2062,3 +2062,157 @@ int lookup_ino_rootid(int fd, u64 *rootid) > > return 0; > } > + > +/* gets the ref count for given extent > + * 0 = didn''t find the item > + * n = number of references > +*/ > +u64 get_extent_refcnt(int fd, u64 disk_blk) > +{ > + int ret = 0, i, e; > + struct btrfs_ioctl_search_args args; > + struct btrfs_ioctl_search_key *sk = &args.key; > + struct btrfs_ioctl_search_header sh; > + unsigned long off = 0; > + > + memset(&args, 0, sizeof(args)); > + > + sk->tree_id = BTRFS_EXTENT_TREE_OBJECTID; > + > + sk->min_type = BTRFS_EXTENT_ITEM_KEY; > + sk->max_type = BTRFS_EXTENT_ITEM_KEY; > + > + sk->min_objectid = disk_blk; > + sk->max_objectid = disk_blk; > + > + sk->max_offset = (u64)-1; > + sk->max_transid = (u64)-1; > + > + while (1) { > + sk->nr_items = 4096; > + > + ret = ioctl(fd, BTRFS_IOC_TREE_SEARCH, &args); > + e = errno; > + if (ret < 0) { > + fprintf(stderr, "ERROR: search failed - %s\n", > + strerror(e)); > + return 0; > + } > + if (sk->nr_items == 0) > + break; > + > + off = 0; > + for (i = 0; i < sk->nr_items; i++) { > + struct btrfs_extent_item *ei; > + u64 ref; > + > + memcpy(&sh, args.buf + off, sizeof(sh)); > + off += sizeof(sh); > + > + if (sh.type != BTRFS_EXTENT_ITEM_KEY) { > + off += sh.len; > + continue; > + } > + > + ei = (struct btrfs_extent_item *)(args.buf + off); > + ref = btrfs_stack_extent_refs(ei); > + return ref; > + } > + sk->min_objectid = sh.objectid; > + sk->min_offset = sh.offset; > + sk->min_type = sh.type; > + if (sk->min_offset < (u64)-1) > + sk->min_offset++; > + else if (sk->min_objectid < (u64)-1) { > + sk->min_objectid++; > + sk->min_offset = 0; > + sk->min_type = 0; > + } else > + break; > + } > + return 0; > +}These two fiddly functions only differ in the tree search and what they do with each item. So replace them with a function that takes a description of the search and calls the caller''s callback for each item. typedef void (*item_func_t)(struct btrfs_key *key, void *data, void *arg); int btrfs_for_each_item(int fd, min and max and junk, item_func_t func, void *arg); u64 get_subvol_freeable_bytes(int fd) { u64 size_bytes = 0; btrfs_for_each_item(fd, ...., sum_extents, &size_bytes); return size_bytes; } Etc. You get the idea. - z -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Anand Jain
2013-Sep-28 17:19 UTC
Re: [PATCH] btrfs-progs: calculate disk space that a subvol could free
On 09/28/2013 03:10 AM, Zach Brown wrote:>> diff --git a/cmds-subvolume.c b/cmds-subvolume.c >> index de246ab..0f36cde 100644 >> --- a/cmds-subvolume.c >> +++ b/cmds-subvolume.c >> @@ -809,6 +809,7 @@ static int cmd_subvol_show(int argc, char **argv) >> int fd = -1, mntfd = -1; >> int ret = 1; >> DIR *dirstream1 = NULL, *dirstream2 = NULL; >> + u64 freeable_bytes; >> >> if (check_argc_exact(argc, 2)) >> usage(cmd_subvol_show_usage); >> @@ -878,6 +879,8 @@ static int cmd_subvol_show(int argc, char **argv) >> goto out; >> } >> >> + freeable_bytes = get_subvol_freeable_bytes(fd); >> + >> ret = 0; >> /* print the info */ >> printf("%s\n", fullpath); >> @@ -915,6 +918,8 @@ static int cmd_subvol_show(int argc, char **argv) >> else >> printf("\tFlags: \t\t\t-\n"); >> >> + printf("\tUnshared space: \t%s\n", >> + pretty_size(freeable_bytes)); > > There''s no reason to have a local variable: > > printf("\tUnshared space: \t%s\n", > pretty_size(get_subvol_freeable_bytes(fd)); > > >> printf("\tSnapshot(s):\n"); >> filter_set = btrfs_list_alloc_filter_set(); >> diff --git a/utils.c b/utils.c >> index ccb5199..ca30485 100644 >> --- a/utils.c >> +++ b/utils.c >> @@ -2062,3 +2062,157 @@ int lookup_ino_rootid(int fd, u64 *rootid) >> >> return 0; >> } >> + >> +/* gets the ref count for given extent >> + * 0 = didn''t find the item >> + * n = number of references >> +*/ >> +u64 get_extent_refcnt(int fd, u64 disk_blk) >> +{ >> + int ret = 0, i, e; >> + struct btrfs_ioctl_search_args args; >> + struct btrfs_ioctl_search_key *sk = &args.key; >> + struct btrfs_ioctl_search_header sh; >> + unsigned long off = 0; >> + >> + memset(&args, 0, sizeof(args)); >> + >> + sk->tree_id = BTRFS_EXTENT_TREE_OBJECTID; >> + >> + sk->min_type = BTRFS_EXTENT_ITEM_KEY; >> + sk->max_type = BTRFS_EXTENT_ITEM_KEY; >> + >> + sk->min_objectid = disk_blk; >> + sk->max_objectid = disk_blk; >> + >> + sk->max_offset = (u64)-1; >> + sk->max_transid = (u64)-1; >> + >> + while (1) { >> + sk->nr_items = 4096; >> + >> + ret = ioctl(fd, BTRFS_IOC_TREE_SEARCH, &args); >> + e = errno; >> + if (ret < 0) { >> + fprintf(stderr, "ERROR: search failed - %s\n", >> + strerror(e)); >> + return 0; >> + } >> + if (sk->nr_items == 0) >> + break; >> + >> + off = 0; >> + for (i = 0; i < sk->nr_items; i++) { >> + struct btrfs_extent_item *ei; >> + u64 ref; >> + >> + memcpy(&sh, args.buf + off, sizeof(sh)); >> + off += sizeof(sh); >> + >> + if (sh.type != BTRFS_EXTENT_ITEM_KEY) { >> + off += sh.len; >> + continue; >> + } >> + >> + ei = (struct btrfs_extent_item *)(args.buf + off); >> + ref = btrfs_stack_extent_refs(ei); >> + return ref; >> + } >> + sk->min_objectid = sh.objectid; >> + sk->min_offset = sh.offset; >> + sk->min_type = sh.type; >> + if (sk->min_offset < (u64)-1) >> + sk->min_offset++; >> + else if (sk->min_objectid < (u64)-1) { >> + sk->min_objectid++; >> + sk->min_offset = 0; >> + sk->min_type = 0; >> + } else >> + break; >> + } >> + return 0; >> +} > > These two fiddly functions only differ in the tree search and what they > do with each item. So replace them with a function that takes a > description of the search and calls the caller''s callback for each item. > > typedef void (*item_func_t)(struct btrfs_key *key, void *data, void *arg); > > int btrfs_for_each_item(int fd, min and max and junk, > item_func_t func, void *arg); > > u64 get_subvol_freeable_bytes(int fd) > { > u64 size_bytes = 0; > > btrfs_for_each_item(fd, ...., sum_extents, &size_bytes); > > return size_bytes; > } > > Etc. You get the idea.Will fix them. Thanks ! -Anand -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Anand Jain
2013-Sep-29 15:02 UTC
Re: [PATCH] btrfs-progs: calculate disk space that a subvol could free
>>> >>> + printf("\tUnshared space: \t%s\n", >>> + pretty_size(freeable_bytes)); >> >> There''s no reason to have a local variable: >> >> printf("\tUnshared space: \t%s\n", >> pretty_size(get_subvol_freeable_bytes(fd)); >> >>this is taken care.>> These two fiddly functions only differ in the tree search and what they >> do with each item. So replace them with a function that takes a >> description of the search and calls the caller''s callback for each item. >> >> typedef void (*item_func_t)(struct btrfs_key *key, void *data, void >> *arg); >> >> int btrfs_for_each_item(int fd, min and max and junk, >> item_func_t func, void *arg); >> >> u64 get_subvol_freeable_bytes(int fd) >> { >> u64 size_bytes = 0; >> >> btrfs_for_each_item(fd, ...., sum_extents, &size_bytes); >> >> return size_bytes; >> } >> >> Etc. You get the idea. > > > Will fix them. Thanks ! > > -Anandthis is to avoid duplicate codes, which indeed spans across most of the search functions that''s in there in btrfs-progs. what you suggest is good, but its better to do that collectively. Thanks, Anand -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Anand Jain
2013-Sep-29 15:15 UTC
[PATCH V2] btrfs-progs: device add should check existing FS before adding
as of now, when ''btrfs device add'' adds a device it doesn''t check if the given device contains an existing FS. This patch will change that to check the same. which when true add will fail, and ask user to use -f option to overwrite. further, since now we have test_dev_for_mkfs() function to check if a disk can be used, so this patch will also use this function to test the given device before adding. v2: worked on review comment rebase on 20130920, update man page and review comments Signed-off-by: Anand Jain <anand.jain@oracle.com> --- cmds-device.c | 36 +++++++++++------------------------- man/btrfs.8.in | 6 ++++-- 2 files changed, 15 insertions(+), 27 deletions(-) diff --git a/cmds-device.c b/cmds-device.c index 12c802e..7cfc347 100644 --- a/cmds-device.c +++ b/cmds-device.c @@ -40,6 +40,7 @@ static const char * const cmd_add_dev_usage[] = { "btrfs device add [options] <device> [<device>...] <path>", "Add a device to a filesystem", "-K|--nodiscard do not perform whole device TRIM", + "-f|--force force overwrite existing filesystem on the disk", NULL }; @@ -49,14 +50,17 @@ static int cmd_add_dev(int argc, char **argv) int i, fdmnt, ret=0, e; DIR *dirstream = NULL; int discard = 1; + int force = 0; + char estr[100]; while (1) { int long_index; static struct option long_options[] = { { "nodiscard", optional_argument, NULL, ''K''}, + { "force", no_argument, NULL, ''f''}, { 0, 0, 0, 0 } }; - int c = getopt_long(argc, argv, "K", long_options, + int c = getopt_long(argc, argv, "Kf", long_options, &long_index); if (c < 0) break; @@ -64,6 +68,9 @@ static int cmd_add_dev(int argc, char **argv) case ''K'': discard = 0; break; + case ''f'': + force = 1; + break; default: usage(cmd_add_dev_usage); } @@ -86,19 +93,11 @@ static int cmd_add_dev(int argc, char **argv) struct btrfs_ioctl_vol_args ioctl_args; int devfd, res; u64 dev_block_count = 0; - struct stat st; int mixed = 0; - res = check_mounted(argv[i]); - if (res < 0) { - fprintf(stderr, "error checking %s mount status\n", - argv[i]); - ret++; - continue; - } - if (res == 1) { - fprintf(stderr, "%s is mounted\n", argv[i]); - ret++; + res = test_dev_for_mkfs(argv[i], force, estr); + if (res) { + fprintf(stderr, "%s", estr); continue; } @@ -108,19 +107,6 @@ static int cmd_add_dev(int argc, char **argv) ret++; continue; } - res = fstat(devfd, &st); - if (res) { - fprintf(stderr, "ERROR: Unable to stat ''%s''\n", argv[i]); - close(devfd); - ret++; - continue; - } - if (!S_ISBLK(st.st_mode)) { - fprintf(stderr, "ERROR: ''%s'' is not a block device\n", argv[i]); - close(devfd); - ret++; - continue; - } res = btrfs_prepare_device(devfd, argv[i], 1, &dev_block_count, 0, &mixed, discard); diff --git a/man/btrfs.8.in b/man/btrfs.8.in index 60e02bb..a65ed93 100644 --- a/man/btrfs.8.in +++ b/man/btrfs.8.in @@ -47,7 +47,7 @@ btrfs \- control a btrfs filesystem \fBbtrfs\fP \fB[filesystem] balance status\fP [-v] \fI<path>\fP .PP .PP -\fBbtrfs\fP \fBdevice add\fP [-K] \fI<device>\fP [\fI<device>...\fP] \fI<path>\fP +\fBbtrfs\fP \fBdevice add\fP [-Kf] \fI<device>\fP [\fI<device>...\fP] \fI<path>\fP .PP \fBbtrfs\fP \fBdevice delete\fP \fI<device>\fP [\fI<device>...\fP] \fI<path>\fP .PP @@ -390,7 +390,7 @@ be verbose .RE .TP -\fBdevice add\fR\fI [-K] <dev> \fP[\fI<dev>...\fP] \fI<path>\fR +\fBdevice add\fR\fI [-Kf] <dev> \fP[\fI<dev>...\fP] \fI<path>\fR Add device(s) to the filesystem identified by \fI<path>\fR. If applicable, a whole device discard (TRIM) operation is performed. .RS @@ -398,6 +398,8 @@ If applicable, a whole device discard (TRIM) operation is performed. \fIOptions\fR .IP "\fB-K|--nodiscard\fP" 5 do not perform discard by default +.IP "\fB-f|--force\fP" 5 +force overwrite of existing filesystem on the given disk(s) .RE .TP -- 1.8.4.rc4.1.g0d8beaa -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Anand Jain
2013-Sep-29 15:25 UTC
[PATCH v2] btrfs-progs: calculate disk space that a subvol could free
It needs a lot more information about the snapshots if snapshot''s life cycle has to be all auto managed by scripts _some day_. this patch is a step towards that. This patch provides the size which would be freed if the subvol/snapshot is deleted. preview: --------------------- btrfs su show /btrfs/sv1 :: Unshared space: 89.09MiB --------------------- v2: rename to ''unshared space'' and edit commit text worked on review comments Signed-off-by: Anand Jain <anand.jain@oracle.com> --- cmds-subvolume.c | 2 + utils.c | 154 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ utils.h | 1 + 3 files changed, 157 insertions(+) diff --git a/cmds-subvolume.c b/cmds-subvolume.c index de246ab..d801e00 100644 --- a/cmds-subvolume.c +++ b/cmds-subvolume.c @@ -915,6 +915,8 @@ static int cmd_subvol_show(int argc, char **argv) else printf("\tFlags: \t\t\t-\n"); + printf("\tUnshared space: \t%s\n", + pretty_size(get_subvol_freeable_bytes(fd))); /* print the snapshots of the given subvol if any*/ printf("\tSnapshot(s):\n"); filter_set = btrfs_list_alloc_filter_set(); diff --git a/utils.c b/utils.c index ccb5199..ca30485 100644 --- a/utils.c +++ b/utils.c @@ -2062,3 +2062,157 @@ int lookup_ino_rootid(int fd, u64 *rootid) return 0; } + +/* gets the ref count for given extent + * 0 = didn''t find the item + * n = number of references +*/ +u64 get_extent_refcnt(int fd, u64 disk_blk) +{ + int ret = 0, i, e; + struct btrfs_ioctl_search_args args; + struct btrfs_ioctl_search_key *sk = &args.key; + struct btrfs_ioctl_search_header sh; + unsigned long off = 0; + + memset(&args, 0, sizeof(args)); + + sk->tree_id = BTRFS_EXTENT_TREE_OBJECTID; + + sk->min_type = BTRFS_EXTENT_ITEM_KEY; + sk->max_type = BTRFS_EXTENT_ITEM_KEY; + + sk->min_objectid = disk_blk; + sk->max_objectid = disk_blk; + + sk->max_offset = (u64)-1; + sk->max_transid = (u64)-1; + + while (1) { + sk->nr_items = 4096; + + ret = ioctl(fd, BTRFS_IOC_TREE_SEARCH, &args); + e = errno; + if (ret < 0) { + fprintf(stderr, "ERROR: search failed - %s\n", + strerror(e)); + return 0; + } + if (sk->nr_items == 0) + break; + + off = 0; + for (i = 0; i < sk->nr_items; i++) { + struct btrfs_extent_item *ei; + u64 ref; + + memcpy(&sh, args.buf + off, sizeof(sh)); + off += sizeof(sh); + + if (sh.type != BTRFS_EXTENT_ITEM_KEY) { + off += sh.len; + continue; + } + + ei = (struct btrfs_extent_item *)(args.buf + off); + ref = btrfs_stack_extent_refs(ei); + return ref; + } + sk->min_objectid = sh.objectid; + sk->min_offset = sh.offset; + sk->min_type = sh.type; + if (sk->min_offset < (u64)-1) + sk->min_offset++; + else if (sk->min_objectid < (u64)-1) { + sk->min_objectid++; + sk->min_offset = 0; + sk->min_type = 0; + } else + break; + } + return 0; +} + +u64 get_subvol_freeable_bytes(int fd) +{ + int ret = 0, i, e; + struct btrfs_ioctl_search_args args; + struct btrfs_ioctl_search_key *sk = &args.key; + struct btrfs_ioctl_search_header sh; + unsigned long off = 0; + u64 size_bytes = 0; + + memset(&args, 0, sizeof(args)); + + sk->tree_id = 0; + + sk->min_type = BTRFS_EXTENT_DATA_KEY; + sk->max_type = BTRFS_EXTENT_DATA_KEY; + + sk->max_objectid = (u64) -1; + sk->max_offset = (u64)-1; + sk->max_transid = (u64)-1; + + while (1) { + sk->nr_items = 4096; + + ret = ioctl(fd, BTRFS_IOC_TREE_SEARCH, &args); + e = errno; + if (ret < 0) { + fprintf(stderr, "ERROR: search failed - %s\n", + strerror(e)); + return 0; + } + if (sk->nr_items == 0) + break; + + off = 0; + for (i = 0; i < sk->nr_items; i++) { + struct btrfs_file_extent_item *efi; + u64 disk_bytenr = 0; + u64 num_bytes = 0; + u64 refcnt; + u8 type; + + memcpy(&sh, args.buf + off, sizeof(sh)); + off += sizeof(sh); + + if (sh.type != BTRFS_EXTENT_DATA_KEY) { + off += sh.len; + continue; + } + + efi = (struct btrfs_file_extent_item *)(args.buf + off); + type = btrfs_stack_file_extent_type(efi); + + if (type == BTRFS_FILE_EXTENT_INLINE) { + size_bytes ++ btrfs_stack_file_extent_ram_bytes(efi); + goto skip_extent_data; + } + disk_bytenr = btrfs_stack_file_extent_disk_bytenr(efi); + num_bytes = btrfs_stack_file_extent_num_bytes(efi); + + if (disk_bytenr) { + refcnt = get_extent_refcnt(fd, disk_bytenr); + if (refcnt == 1) + size_bytes += num_bytes; + } +skip_extent_data: + off += sh.len; + } + sk->min_objectid = sh.objectid; + sk->min_offset = sh.offset; + sk->min_type = sh.type; + + if (sk->min_offset < (u64)-1) + sk->min_offset++; + else if (sk->min_objectid < (u64)-1) { + sk->min_objectid++; + sk->min_offset = 0; + sk->min_type = 0; + } else + break; + } + return size_bytes; +} diff --git a/utils.h b/utils.h index 0f31db7..4ddcf09 100644 --- a/utils.h +++ b/utils.h @@ -91,5 +91,6 @@ int csum_tree_block(struct btrfs_root *root, struct extent_buffer *buf, int ask_user(char *question); int lookup_ino_rootid(int fd, u64 *rootid); int btrfs_scan_lblkid(int update_kernel); +u64 get_subvol_freeable_bytes(int fd); #endif -- 1.8.4.rc4.1.g0d8beaa -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Anand Jain
2013-Sep-29 15:26 UTC
Re: [PATCH V2] btrfs-progs: device add should check existing FS before adding
wrong patch sent. Please ignore this. sorry. On 09/29/2013 11:15 PM, Anand Jain wrote:> as of now, when ''btrfs device add'' adds a device it doesn''t > check if the given device contains an existing FS. This > patch will change that to check the same. which when true > add will fail, and ask user to use -f option to overwrite. > > further, since now we have test_dev_for_mkfs() function > to check if a disk can be used, so this patch will also > use this function to test the given device before adding. > > v2: worked on review comment > rebase on 20130920, update man page and review comments > > Signed-off-by: Anand Jain <anand.jain@oracle.com> > --- > cmds-device.c | 36 +++++++++++------------------------- > man/btrfs.8.in | 6 ++++-- > 2 files changed, 15 insertions(+), 27 deletions(-) > > diff --git a/cmds-device.c b/cmds-device.c > index 12c802e..7cfc347 100644 > --- a/cmds-device.c > +++ b/cmds-device.c > @@ -40,6 +40,7 @@ static const char * const cmd_add_dev_usage[] = { > "btrfs device add [options] <device> [<device>...] <path>", > "Add a device to a filesystem", > "-K|--nodiscard do not perform whole device TRIM", > + "-f|--force force overwrite existing filesystem on the disk", > NULL > }; > > @@ -49,14 +50,17 @@ static int cmd_add_dev(int argc, char **argv) > int i, fdmnt, ret=0, e; > DIR *dirstream = NULL; > int discard = 1; > + int force = 0; > + char estr[100]; > > while (1) { > int long_index; > static struct option long_options[] = { > { "nodiscard", optional_argument, NULL, ''K''}, > + { "force", no_argument, NULL, ''f''}, > { 0, 0, 0, 0 } > }; > - int c = getopt_long(argc, argv, "K", long_options, > + int c = getopt_long(argc, argv, "Kf", long_options, > &long_index); > if (c < 0) > break; > @@ -64,6 +68,9 @@ static int cmd_add_dev(int argc, char **argv) > case ''K'': > discard = 0; > break; > + case ''f'': > + force = 1; > + break; > default: > usage(cmd_add_dev_usage); > } > @@ -86,19 +93,11 @@ static int cmd_add_dev(int argc, char **argv) > struct btrfs_ioctl_vol_args ioctl_args; > int devfd, res; > u64 dev_block_count = 0; > - struct stat st; > int mixed = 0; > > - res = check_mounted(argv[i]); > - if (res < 0) { > - fprintf(stderr, "error checking %s mount status\n", > - argv[i]); > - ret++; > - continue; > - } > - if (res == 1) { > - fprintf(stderr, "%s is mounted\n", argv[i]); > - ret++; > + res = test_dev_for_mkfs(argv[i], force, estr); > + if (res) { > + fprintf(stderr, "%s", estr); > continue; > } > > @@ -108,19 +107,6 @@ static int cmd_add_dev(int argc, char **argv) > ret++; > continue; > } > - res = fstat(devfd, &st); > - if (res) { > - fprintf(stderr, "ERROR: Unable to stat ''%s''\n", argv[i]); > - close(devfd); > - ret++; > - continue; > - } > - if (!S_ISBLK(st.st_mode)) { > - fprintf(stderr, "ERROR: ''%s'' is not a block device\n", argv[i]); > - close(devfd); > - ret++; > - continue; > - } > > res = btrfs_prepare_device(devfd, argv[i], 1, &dev_block_count, > 0, &mixed, discard); > diff --git a/man/btrfs.8.in b/man/btrfs.8.in > index 60e02bb..a65ed93 100644 > --- a/man/btrfs.8.in > +++ b/man/btrfs.8.in > @@ -47,7 +47,7 @@ btrfs \- control a btrfs filesystem > \fBbtrfs\fP \fB[filesystem] balance status\fP [-v] \fI<path>\fP > .PP > .PP > -\fBbtrfs\fP \fBdevice add\fP [-K] \fI<device>\fP [\fI<device>...\fP] \fI<path>\fP > +\fBbtrfs\fP \fBdevice add\fP [-Kf] \fI<device>\fP [\fI<device>...\fP] \fI<path>\fP > .PP > \fBbtrfs\fP \fBdevice delete\fP \fI<device>\fP [\fI<device>...\fP] \fI<path>\fP > .PP > @@ -390,7 +390,7 @@ be verbose > .RE > .TP > > -\fBdevice add\fR\fI [-K] <dev> \fP[\fI<dev>...\fP] \fI<path>\fR > +\fBdevice add\fR\fI [-Kf] <dev> \fP[\fI<dev>...\fP] \fI<path>\fR > Add device(s) to the filesystem identified by \fI<path>\fR. > If applicable, a whole device discard (TRIM) operation is performed. > .RS > @@ -398,6 +398,8 @@ If applicable, a whole device discard (TRIM) operation is performed. > \fIOptions\fR > .IP "\fB-K|--nodiscard\fP" 5 > do not perform discard by default > +.IP "\fB-f|--force\fP" 5 > +force overwrite of existing filesystem on the given disk(s) > .RE > .TP > >-- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
David Sterba
2013-Oct-01 13:25 UTC
Re: [PATCH] btrfs-progs: calculate disk space that a subvol could free
On Sun, Sep 29, 2013 at 11:02:29PM +0800, Anand Jain wrote:> this is to avoid duplicate codes, which indeed spans across > most of the search functions that''s in there in btrfs-progs. > what you suggest is good, but its better to do that collectively.Good cleanup idea, added to wiki todo list. -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
David Sterba
2013-Oct-01 13:39 UTC
Re: [PATCH v2] btrfs-progs: calculate disk space that a subvol could free
On Sun, Sep 29, 2013 at 11:25:36PM +0800, Anand Jain wrote:> It needs a lot more information about the snapshots if > snapshot''s life cycle has to be all auto managed by > scripts _some day_. this patch is a step towards that. > > This patch provides the size which would be freed > if the subvol/snapshot is deleted. > preview: > --------------------- > btrfs su show /btrfs/sv1 > :: > Unshared space: 89.09MiBUseful information, but it takes time to calculate the number. The tree search ioctl has significant overhead and seeking all over the extent tree can be also lengthy. I''ve tried it on a random subvolume on a SSD disk and it''s been running 10 minutes already, one cpu is at 100%. david -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Wang Shilong
2013-Oct-01 14:05 UTC
Re: [PATCH v2] btrfs-progs: calculate disk space that a subvol could free
> On Sun, Sep 29, 2013 at 11:25:36PM +0800, Anand Jain wrote: >> It needs a lot more information about the snapshots if >> snapshot''s life cycle has to be all auto managed by >> scripts _some day_. this patch is a step towards that. >> >> This patch provides the size which would be freed >> if the subvol/snapshot is deleted. >> preview: >> --------------------- >> btrfs su show /btrfs/sv1 >> :: >> Unshared space: 89.09MiB > > Useful information, but it takes time to calculate the number. The tree > search ioctl has significant overhead and seeking all over the extent > tree can be also lengthy. I''ve tried it on a random subvolume on a SSD > disk and it''s been running 10 minutes already, one cpu is at 100%.No wonder Anand''s approach is inefficient.In Anand''s approach: Search Every EXTENT_DATA Search every extent''s refs in extent tree. If we want to speed up this progress, i think we can split it into two parts: 1. First to search inline extent_data 2. Secondly search in extent tree to calculate (extent refs=1) This will avoid n*n rather than n+n which is better… Thanks, Wang> > david > -- > To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in > the body of a message to majordomo@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 majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Anand Jain
2013-Oct-07 02:47 UTC
Re: [PATCH v2] btrfs-progs: calculate disk space that a subvol could free
> If we want to speed up this progress, i think we can split it into two parts: > > 1. First to search inline extent_data > 2. Secondly search in extent tree to calculate (extent refs=1) > > This will avoid n*n rather than n+n which is better…(sorry for delay in reply, I was on vacation). Thanks for what might help. I was kind of expecting this when preliminary patch was sent before. Let me try what you suggest and send out v3. I was also thinking if this should be inside kernel facilitated by a new ioctl? so that we avoid number of search ioctl thats required. Thanks, Anand -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Wang Shilong
2013-Oct-07 03:01 UTC
Re: [PATCH v2] btrfs-progs: calculate disk space that a subvol could free
On 10/07/2013 10:47 AM, Anand Jain wrote:> > >> If we want to speed up this progress, i think we can split it into two parts: >> >> 1. First to search inline extent_data >> 2. Secondly search in extent tree to calculate (extent refs=1) >> >> This will avoid n*n rather than n+n which is better… > (sorry for delay in reply, I was on vacation). > > Thanks for what might help. I was kind of expecting > this when preliminary patch was sent before. Let me > try what you suggest and send out v3. > > I was also thinking if this should be inside kernel > facilitated by a new ioctl? so that we avoid number > of search ioctl thats required.Yeah, adding another ioctl maybe help. Anyway, there is another question. Did we need to consider metadata into subvolume''s sole size? Personaly, the answer is yes. Considering a subvolume is filled with a lot of empty files, but we get subvolume''s sole size *0*. Thanks, Wang> > Thanks, Anand > > -- > To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in > the body of a message to majordomo@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 majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Anand Jain
2013-Oct-07 03:22 UTC
Re: [PATCH v2] btrfs-progs: calculate disk space that a subvol could free
On 10/07/2013 11:01 AM, Wang Shilong wrote:> On 10/07/2013 10:47 AM, Anand Jain wrote: >> >> >>> If we want to speed up this progress, i think we can split it into two parts: >>> >>> 1. First to search inline extent_data >>> 2. Secondly search in extent tree to calculate (extent refs=1) >>> >>> This will avoid n*n rather than n+n which is better… >> (sorry for delay in reply, I was on vacation). >> >> Thanks for what might help. I was kind of expecting >> this when preliminary patch was sent before. Let me >> try what you suggest and send out v3. >> >> I was also thinking if this should be inside kernel >> facilitated by a new ioctl? so that we avoid number >> of search ioctl thats required. > Yeah, adding another ioctl maybe help. Anyway, there is another question. > Did we need to consider metadata into subvolume''s sole size? > > Personaly, the answer is yes. Considering a subvolume is filled with a lot > of empty files, but we get subvolume''s sole size *0*.yes. Will consider for an update patch later. Thanks, Anand -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
David Sterba
2013-Oct-08 16:49 UTC
Re: [PATCH v2] btrfs-progs: calculate disk space that a subvol could free
On Mon, Oct 07, 2013 at 10:47:56AM +0800, Anand Jain wrote:> I was also thinking if this should be inside kernel > facilitated by a new ioctl? so that we avoid number > of search ioctl thats required.I think so. And for the feature itself, it can be handy in case where qgroups are not established. david -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Anand Jain
2013-Oct-09 08:03 UTC
Re: [PATCH v2] btrfs-progs: calculate disk space that a subvol could free
Wang,> 1. First to search inline extent_data> 2. Secondly search in extent tree to calculate (extent refs=1)but these extents will be of entire fs, how do you filter it for a subvol ? Thanks, Anand> This will avoid n*n rather than n+n which is better…-- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Wang Shilong
2013-Oct-09 08:35 UTC
Re: [PATCH v2] btrfs-progs: calculate disk space that a subvol could free
On 10/09/2013 04:03 PM, Anand Jain wrote:> Wang, > > >> 1. First to search inline extent_data >> 2. Secondly search in extent tree to calculate (extent refs=1) > but these extents will be of entire fs, how do you filter it for a subvol ?Sorry, this could not be true as i have expected,(we have to iterate extent tree with my approach) If we considered both metadata and data for a subvolume, we just iterate all the extent items in the extent tree and add those extents into subvolume''s sole size iff: 1> extent ref=1 2> backref root=subvol However, this also may come very *slowly* when extent tree comes very large. Thanks, Wang> > > Thanks, Anand > >> This will avoid n*n rather than n+n which is better… > -- > To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in > the body of a message to majordomo@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 majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Wang Shilong
2013-Oct-09 14:17 UTC
Re: [PATCH v2] btrfs-progs: calculate disk space that a subvol could free
Hello David, Anand,> On Mon, Oct 07, 2013 at 10:47:56AM +0800, Anand Jain wrote: >> I was also thinking if this should be inside kernel >> facilitated by a new ioctl? so that we avoid number >> of search ioctl thats required. > > I think so. And for the feature itself, it can be handy in case where > qgroups are not established.Actually, i have not found an effectively way to work out this. Whatever we implement this as an ioctl in kernel space or just in userspace, why not just trigger quota enabled, but not set qgroup limit. If quota been enabled, quota rescan will calculate every subvolume''s referenced and exclusive size(to implement this we have to iterate extent tree though). Luckily, after that, quota itself will track every subvolume''s sole size(exclusive size). Justing using ''btrfs qgroup show'', we can figure out every subvolume''s referenced size and exclusive size easily, i think this is another important use of qgroup. If users want to find top subvolume''s sole size, they can use: btrfs qgroup show <mnt> --sort=+/-excl This approach maybe a little tricky, but it is better than implement an ioctl to calculate one subvolume''s size every time. Thanks, Wang> > david-- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Wang Shilong
2013-Oct-10 03:33 UTC
Re: [PATCH v2] btrfs-progs: calculate disk space that a subvol could free
On 10/10/2013 11:35 AM, Anand Jain wrote:> > If ''btrfs_file_extent_item'' can contain the ref count it would > solve the current problem quite easily. (problem is that, its > of n * n searches to know data extents with its ref for a given > subvol).Just considering btrfs_file_extent_item is not enough, because we should consider metadata(as i have said before).> > But what''r the challenge(s) to have ref count in the > btrfs_file_extent_item ? any thoughts ?Haven''t thought a better idea yet.> > Thanks, Anand > -- > To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in > the body of a message to majordomo@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 majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Anand Jain
2013-Oct-10 03:35 UTC
Re: [PATCH v2] btrfs-progs: calculate disk space that a subvol could free
If ''btrfs_file_extent_item'' can contain the ref count it would solve the current problem quite easily. (problem is that, its of n * n searches to know data extents with its ref for a given subvol). But what''r the challenge(s) to have ref count in the btrfs_file_extent_item ? any thoughts ? Thanks, Anand -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Alex Lyakas
2013-Nov-28 17:39 UTC
Re: [PATCH v2] btrfs-progs: calculate disk space that a subvol could free
Hello Anand, I have sent a similar comment to your email thread in http://www.spinics.net/lists/linux-btrfs/msg27547.html I believe this approach of calculating freeable space is incorrect. Try this: - create a fresh btrfs - create a regular file - write some data into it in such a way, that it was, say 4000 EXTENT_DATA items, so that file tree and extent tree get deep enough - run btrfs-debug-tree and verify that all EXTENT_ITEMs of this file (in the extent tree) have refcnt=1 - create a snapshot of the subvolume - run btrfs-debug-tree again You will see that most (in my case - all) of EXTENT_ITEMs still have refcnt=1. Reason for this is as I mentioned in http://www.spinics.net/lists/linux-btrfs/msg27547.html But if you delete the subvolume, no space will be freed, because all these extents are also shared by the snapshot. Although it seems that your tool will report that all subvolume''s space is freeable (based on refcnt=1). Can you pls try that experiment and comment on it? Perhaps I am missing something here? Thanks! Alex. On Thu, Oct 10, 2013 at 6:33 AM, Wang Shilong <wangsl.fnst@cn.fujitsu.com> wrote:> On 10/10/2013 11:35 AM, Anand Jain wrote: >> >> >> If ''btrfs_file_extent_item'' can contain the ref count it would >> solve the current problem quite easily. (problem is that, its >> of n * n searches to know data extents with its ref for a given >> subvol). > > Just considering btrfs_file_extent_item is not enough, because > we should consider metadata(as i have said before). > >> >> But what''r the challenge(s) to have ref count in the >> btrfs_file_extent_item ? any thoughts ? > > Haven''t thought a better idea yet. > > >> >> Thanks, Anand >> -- >> To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in >> the body of a message to majordomo@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 majordomo@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 majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Wang Shilong
2013-Nov-29 01:34 UTC
Re: [PATCH v2] btrfs-progs: calculate disk space that a subvol could free
Hi Alex, On 11/29/2013 01:39 AM, Alex Lyakas wrote:> Hello Anand, > I have sent a similar comment to your email thread in > http://www.spinics.net/lists/linux-btrfs/msg27547.html > > I believe this approach of calculating freeable space is incorrect. > Try this: > - create a fresh btrfs > - create a regular file > - write some data into it in such a way, that it was, say 4000 > EXTENT_DATA items, so that file tree and extent tree get deep enough > - run btrfs-debug-tree and verify that all EXTENT_ITEMs of this file > (in the extent tree) have refcnt=1 > - create a snapshot of the subvolume > - run btrfs-debug-tree again > > You will see that most (in my case - all) of EXTENT_ITEMs still have > refcnt=1. Reason for this is as I mentioned in > http://www.spinics.net/lists/linux-btrfs/msg27547.html > > But if you delete the subvolume, no space will be freed, because all > these extents are also shared by the snapshot. Although it seems that > your tool will report that all subvolume''s space is freeable (based on > refcnt=1). > > Can you pls try that experiment and comment on it? Perhaps I am > missing something here?I think you are right here, the only way we can make sure whether a extent_item is shared by many roots is to walk backref to find all roots, and if number of roots is 1, we know it''s sole space. If so, i don''t think this should be implemented in user space, Btrfs quota implement such function in kernel space, but it also face a problem that deleting a subvolume will break space accounting(because subvolume deletion won''t iterate the whole fs tree). Thanks, Wang> > Thanks! > Alex. > > > > On Thu, Oct 10, 2013 at 6:33 AM, Wang Shilong > <wangsl.fnst@cn.fujitsu.com> wrote: >> On 10/10/2013 11:35 AM, Anand Jain wrote: >>> >>> If ''btrfs_file_extent_item'' can contain the ref count it would >>> solve the current problem quite easily. (problem is that, its >>> of n * n searches to know data extents with its ref for a given >>> subvol). >> Just considering btrfs_file_extent_item is not enough, because >> we should consider metadata(as i have said before). >> >>> But what''r the challenge(s) to have ref count in the >>> btrfs_file_extent_item ? any thoughts ? >> Haven''t thought a better idea yet. >> >> >>> Thanks, Anand >>> -- >>> To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in >>> the body of a message to majordomo@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 majordomo@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 majordomo@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 majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Anand Jain
2013-Nov-29 01:57 UTC
Re: [PATCH v2] btrfs-progs: calculate disk space that a subvol could free
> If so, i don''t think this should be implemented in user space, Btrfs quota > implement such function in kernel space, but it also face a problem that > deleting a subvolume will break space accounting(because subvolume deletion > won''t iterate the whole fs tree).Hi Alex, Wang. Thanks for comments, as Wang suggested before, I am working on the qgroups to handle our user space requisites here. I will be sending out review patch soon. pls stay tuned. Thanks, Anand -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html