Re: [PATCH 12/13] btrfs-progs: obtain used_bytes in BTRFS_IOC_FS_INFO ioctl

2013-06-25 Thread Anand Jain


kindly ignore this patch, the feature now is implemented
without adding any _new_ ioctl or _new_ parameters.

Thanks, Anand


On 06/21/2013 03:58 PM, Anand Jain wrote:

btrfs-progs has to read fs info from the kernel to
read the latest info instead of reading it from the disks,
which generally is a stale info after certain critical
operation.

getting used_bytes parameter will help to fix
   btrfs filesystem show --kernel
to show the current info of the fs

Signed-off-by: Anand Jain anand.j...@oracle.com
---
  ioctl.h | 3 ++-
  1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/ioctl.h b/ioctl.h
index a40a4a1..d035201 100644
--- a/ioctl.h
+++ b/ioctl.h
@@ -169,7 +169,8 @@ struct btrfs_ioctl_fs_info_args {
__u64 max_id;   /* out */
__u64 num_devices;  /* out */
__u8 fsid[BTRFS_FSID_SIZE]; /* out */
-   __u64 reserved[124];/* pad to 1k */
+   __u64 used_bytes;   /* out */
+   __u64 reserved[123];/* pad to 1k */
  };

  /* balance control ioctl modes */


--
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 12/12 v4] btrfs-progs: introduce btrfs filesystem show --kernel

2013-06-25 Thread Anand Jain
As of now btrfs filesystem show reads directly from
disks. So sometimes output can be stale, mainly when
user want to verify their last operation like,
labeling or device delete or add... etc.

This patch adds --kernel option to the 'filesystem show'
subcli, which will read from the kernel instead of
the disks directly.

This btrfs-progs patch depends on the kernel patch
 btrfs: obtain used_bytes in BTRFS_IOC_FS_INFO ioctl

v3-v4:
dropped the dependence of used_bytes from the ioctl
kernel, Instead used the get_df to calculate the
used space.
dropped the function device_list_add_from_kernel
to update the original device_list_add instead
I have my own print and device filters, this way I
can add the group profile information in the show
output.
v2-v3:
Do the stuffs without adding new ioctl
new dependencies: this patch also depends on
path 9/13 to 12/13 also sent here.
v1-v2:
code optimized to remove redundancy

Signed-off-by: Anand Jain anand.j...@oracle.com

merg

Signed-off-by: Anand Jain anand.j...@oracle.com
---
 cmds-filesystem.c | 166 +++---
 1 file changed, 159 insertions(+), 7 deletions(-)

diff --git a/cmds-filesystem.c b/cmds-filesystem.c
index 5f8c258..a028e1d 100644
--- a/cmds-filesystem.c
+++ b/cmds-filesystem.c
@@ -22,6 +22,9 @@
 #include errno.h
 #include uuid/uuid.h
 #include ctype.h
+#include mntent.h
+#include fcntl.h
+#include linux/limits.h
 
 #include kerncompat.h
 #include ctree.h
@@ -256,8 +259,129 @@ static void print_one_uuid(struct btrfs_fs_devices 
*fs_devices)
printf(\n);
 }
 
+/* adds up all the used spaces as reported by the space info ioctl
+ */
+static u64 cal_used_bytes(struct btrfs_ioctl_space_args *si)
+{
+   u64 ret = 0;
+   int i;
+   for (i = 0; i  si-total_spaces; i++)
+   ret += si-spaces[i].used_bytes;
+   return ret;
+}
+
+static int print_one_fs(struct btrfs_ioctl_fs_info_args *fi,
+   struct btrfs_ioctl_dev_info_args *di_n,
+   struct btrfs_ioctl_space_args *si_n, char *label, char *path)
+{
+   int i;
+   char uuidbuf[37];
+   char *sz1;
+   char *sz2;
+   struct btrfs_ioctl_dev_info_args *di = di_n;
+   u64 flags;
+
+   uuid_unparse(fi-fsid, uuidbuf);
+   printf(Label: %s  uuid: %s mounted: %s\n,
+   strlen(label)?label:none, uuidbuf, path);
+   printf(\tGroup profile:);
+   for (i = si_n-total_spaces - 1; i = 0; i--) {
+   flags = si_n-spaces[i].flags;
+   if (flags  BTRFS_BLOCK_GROUP_SYSTEM)
+   continue;
+   printf( %s: %s, group_type_str(flags),
+   group_profile_str(flags));
+   printf( );
+   }
+   printf(\n);
+
+   sz1 = pretty_sizes(cal_used_bytes(si_n));
+   printf(\tTotal devices %llu FS bytes used %s\n,
+   fi-num_devices, sz1);
+   free(sz1);
+
+   for (i = 0; i  fi-num_devices; i++) {
+   di = (struct btrfs_ioctl_dev_info_args *)di_n[i];
+   sz1 = pretty_sizes(di-total_bytes);
+   sz2 = pretty_sizes(di-bytes_used);
+   printf(\tdevid%llu size %s used %s path %s\n,
+   di-devid, sz1, sz2, di-path);
+   free(sz1);
+   free(sz2);
+   }
+
+   printf(\n);
+   return 0;
+}
+
+/* This function checks if the given input parameter is
+ * an uuid or a path
+ * return -1: some error in the given input
+ * return 0: unknow input
+ * return 1: given input is uuid
+ * return 2: given input is path
+ */
+static int check_arg_type(char *input, u8 *processed)
+{
+   int ret = 0;
+   if (!uuid_parse(input, processed))
+   ret = 1;
+   else if (realpath(input, (char *)processed))
+   ret = 2;
+   return ret;
+}
+
+
+static int btrfs_scan_kernel(void *input, int type)
+{
+   int ret = 0, fd;
+   FILE *f;
+   struct mntent *mnt;
+   struct btrfs_ioctl_fs_info_args fi;
+   struct btrfs_ioctl_dev_info_args *di = NULL;
+   struct btrfs_ioctl_space_args *si;
+   char label[BTRFS_LABEL_SIZE];
+
+   if ((f = setmntent (/proc/mounts, r)) == NULL)
+   return -errno;
+
+   while ((mnt = getmntent (f)) != NULL) {
+   if (strcmp(mnt-mnt_type, btrfs))
+   continue;
+   ret = get_fs_info(mnt-mnt_dir, fi, di);
+   if (ret)
+   return ret;
+
+   switch (type) {
+   case 0:
+   break;
+   case 1:
+   if (uuid_compare(fi.fsid, (u8 *)input))
+   continue;
+   break;
+   case 2:
+   if (strcmp(input, mnt-mnt_dir))
+   continue;
+ 

[RESEND] [PATCH] btrfs-progs: avoid memory leak in btrfs_close_devices

2013-06-25 Thread Wang Sheng-Hui


Three kind of structures need to be freed on close:
* All struct btrfs_device managed by fs_devices
* The name field for each struct btrfs_device
* fs_devices structure itself

The same ones for seed_devices.


Signed-off-by: Wang Sheng-Hui shh...@gmail.com
---
 volumes.c |   16 +---
 1 file changed, 13 insertions(+), 3 deletions(-)

diff --git a/volumes.c b/volumes.c
index d6f81f8..257b740 100644
--- a/volumes.c
+++ b/volumes.c
@@ -153,6 +153,16 @@ static int device_list_add(const char *path,
return 0;
 }

+static void btrfs_close_device(struct btrfs_device *device)
+{
+   close(device-fd);
+   device-fd = -1;
+   device-writeable = 0;
+   if (device-name)
+   kfree(device-name);
+   kfree(device);
+}
+
 int btrfs_close_devices(struct btrfs_fs_devices *fs_devices)
 {
struct btrfs_fs_devices *seed_devices;
@@ -161,17 +171,17 @@ int btrfs_close_devices(struct btrfs_fs_devices 
*fs_devices)
 again:
list_for_each(cur, fs_devices-devices) {
device = list_entry(cur, struct btrfs_device, dev_list);
-   close(device-fd);
-   device-fd = -1;
-   device-writeable = 0;
+   btrfs_close_device(device);
}

seed_devices = fs_devices-seed;
fs_devices-seed = NULL;
if (seed_devices) {
+   kfree(fs_devices);
fs_devices = seed_devices;
goto again;
}
+   kfree(fs_devices);

return 0;
 }
--
1.7.10.4

--
To unsubscribe from this list: send the line unsubscribe linux-btrfs in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: hang on 3.9, 3.10-rc5

2013-06-25 Thread Liu Bo
On Fri, Jun 21, 2013 at 08:42:55AM +0200, Clemens Eisserer wrote:
 Hi Jon,
 
  Is this what you are looking for?
  After this, the CPU gets stuck and I have to reboot.
 
 This issue has already been reported:
 https://bugzilla.kernel.org/show_bug.cgi?id=59451

Hi,

Could you please try this patch?

(at least it addresses my ulist_add_merge crash :))

thanks,
liubo

diff --git a/fs/btrfs/ulist.c b/fs/btrfs/ulist.c
index 7b417e2..69a9c32 100644
--- a/fs/btrfs/ulist.c
+++ b/fs/btrfs/ulist.c
@@ -73,7 +73,6 @@ void ulist_fini(struct ulist *ulist)
if (ulist-nodes_alloced  ULIST_SIZE)
kfree(ulist-nodes);
ulist-nodes_alloced = 0;   /* in case ulist_fini is called twice */
-   ulist-root = RB_ROOT;
 }
 EXPORT_SYMBOL(ulist_fini);
 
@@ -205,6 +204,7 @@ int ulist_add_merge(struct ulist *ulist, u64 val, u64 aux,
u64 new_alloced = ulist-nodes_alloced + 128;
struct ulist_node *new_nodes;
void *old = NULL;
+   int i;
 
/*
 * if nodes_alloced == ULIST_SIZE no memory has been allocated
@@ -222,6 +222,17 @@ int ulist_add_merge(struct ulist *ulist, u64 val, u64 aux,
memcpy(new_nodes, ulist-int_nodes,
   sizeof(ulist-int_nodes));
 
+   /*
+* krealloc actually uses memcpy, which does not copy rb_node
+* pointers, so we have to do it ourselves.  Otherwise we may
+* be bitten by crashes.
+*/
+   for (i = 0; i  ulist-nnodes; i++) {
+   rb_erase(ulist-nodes[i].rb_node, ulist-root);
+   ret = ulist_rbtree_insert(ulist, new_nodes[i]);
+   BUG_ON(ret);
+   }
+
ulist-nodes = new_nodes;
ulist-nodes_alloced = new_alloced;
}

--
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: fix crash regarding to ulist_add_merge

2013-06-25 Thread Liu Bo
Several users reported this crash of NULL pointer or general protection,
the story is that we add a rbtree for speedup ulist iteration, and we
use krealloc() to address ulist growth, and krealloc() use memcpy to copy
old data to new memory area, so it's OK for an array as it doesn't use
pointers while it's not OK for a rbtree as it uses pointers.

So krealloc() will mess up our rbtree and it ends up with crash.

Signed-off-by: Liu Bo bo.li@oracle.com
---
 fs/btrfs/ulist.c |   13 -
 1 files changed, 12 insertions(+), 1 deletions(-)

diff --git a/fs/btrfs/ulist.c b/fs/btrfs/ulist.c
index 7b417e2..69a9c32 100644
--- a/fs/btrfs/ulist.c
+++ b/fs/btrfs/ulist.c
@@ -73,7 +73,6 @@ void ulist_fini(struct ulist *ulist)
if (ulist-nodes_alloced  ULIST_SIZE)
kfree(ulist-nodes);
ulist-nodes_alloced = 0;   /* in case ulist_fini is called twice */
-   ulist-root = RB_ROOT;
 }
 EXPORT_SYMBOL(ulist_fini);
 
@@ -205,6 +204,7 @@ int ulist_add_merge(struct ulist *ulist, u64 val, u64 aux,
u64 new_alloced = ulist-nodes_alloced + 128;
struct ulist_node *new_nodes;
void *old = NULL;
+   int i;
 
/*
 * if nodes_alloced == ULIST_SIZE no memory has been allocated
@@ -222,6 +222,17 @@ int ulist_add_merge(struct ulist *ulist, u64 val, u64 aux,
memcpy(new_nodes, ulist-int_nodes,
   sizeof(ulist-int_nodes));
 
+   /*
+* krealloc actually uses memcpy, which does not copy rb_node
+* pointers, so we have to do it ourselves.  Otherwise we may
+* be bitten by crashes.
+*/
+   for (i = 0; i  ulist-nnodes; i++) {
+   rb_erase(ulist-nodes[i].rb_node, ulist-root);
+   ret = ulist_rbtree_insert(ulist, new_nodes[i]);
+   BUG_ON(ret);
+   }
+
ulist-nodes = new_nodes;
ulist-nodes_alloced = new_alloced;
}
-- 
1.7.7

--
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-progs] kerncompat.h: remove offsetof redefinition

2013-06-25 Thread root
From: Cristian Rodríguez crrodrig...@opensuse.org

Must use the version provided by the compiler in stddef.h header
---
 kerncompat.h | 7 +--
 1 file changed, 1 insertion(+), 6 deletions(-)

diff --git a/kerncompat.h b/kerncompat.h
index 9c116b4..6b4b4ba 100644
--- a/kerncompat.h
+++ b/kerncompat.h
@@ -26,6 +26,7 @@
 #include endian.h
 #include byteswap.h
 #include assert.h
+#include stddef.h
 
 #ifndef READ
 #define READ 0
@@ -234,12 +235,6 @@ static inline long IS_ERR(const void *ptr)
 #define BUG_ON(c) assert(!(c))
 #define WARN_ON(c) assert(!(c))
 
-#undef offsetof
-#ifdef __compiler_offsetof
-#define offsetof(TYPE,MEMBER) __compiler_offsetof(TYPE,MEMBER)
-#else
-#define offsetof(TYPE, MEMBER) ((size_t) ((TYPE *)0)-MEMBER)
-#endif
 
 #define container_of(ptr, type, member) ({  \
 const typeof( ((type *)0)-member ) *__mptr = (ptr);\
-- 
1.8.3.1

--
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-progs] kerncompat.h: remove offsetof redefinition

2013-06-25 Thread Cristian Rodríguez
Must use the version provided by the compiler in stddef.h header
---
 kerncompat.h | 7 +--
 1 file changed, 1 insertion(+), 6 deletions(-)

diff --git a/kerncompat.h b/kerncompat.h
index 9c116b4..6b4b4ba 100644
--- a/kerncompat.h
+++ b/kerncompat.h
@@ -26,6 +26,7 @@
 #include endian.h
 #include byteswap.h
 #include assert.h
+#include stddef.h
 
 #ifndef READ
 #define READ 0
@@ -234,12 +235,6 @@ static inline long IS_ERR(const void *ptr)
 #define BUG_ON(c) assert(!(c))
 #define WARN_ON(c) assert(!(c))
 
-#undef offsetof
-#ifdef __compiler_offsetof
-#define offsetof(TYPE,MEMBER) __compiler_offsetof(TYPE,MEMBER)
-#else
-#define offsetof(TYPE, MEMBER) ((size_t) ((TYPE *)0)-MEMBER)
-#endif
 
 #define container_of(ptr, type, member) ({  \
 const typeof( ((type *)0)-member ) *__mptr = (ptr);\
-- 
1.8.3.1

--
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-progs: Cleanup for using BTRFS_SETGET_STACK instead of raw convert

2013-06-25 Thread Qu Wenruo
Some codes still use the cpu_to_lexx instead of the
BTRFS_SETGET_STACK_FUNCS declared in ctree.h.

Also added some BTRFS_SETGET_STACK_FUNCS for btrfs_header and
btrfs_super.

Signed-off-by: Qu Wenruo quwen...@cn.fujitsu.com
---
 btrfs-convert.c| 2 +-
 btrfs-find-root.c  | 6 +++---
 btrfs-image.c  | 2 +-
 btrfs-show-super.c | 2 +-
 ctree.h| 7 +++
 disk-io.c  | 6 +++---
 utils.c| 4 ++--
 volumes.c  | 2 +-
 8 files changed, 19 insertions(+), 12 deletions(-)

diff --git a/btrfs-convert.c b/btrfs-convert.c
index 399856f..cb96790 100644
--- a/btrfs-convert.c
+++ b/btrfs-convert.c
@@ -1802,7 +1802,7 @@ static int prepare_system_chunk_sb(struct 
btrfs_super_block *super)
btrfs_set_stack_chunk_num_stripes(chunk, 1);
btrfs_set_stack_chunk_sub_stripes(chunk, 0);
chunk-stripe.devid = super-dev_item.devid;
-   chunk-stripe.offset = cpu_to_le64(0);
+   btrfs_set_stack_stripe_offset(chunk-stripe, 0);
memcpy(chunk-stripe.dev_uuid, super-dev_item.uuid, BTRFS_UUID_SIZE);
btrfs_set_super_sys_array_size(super, sizeof(*key) + sizeof(*chunk));
return 0;
diff --git a/btrfs-find-root.c b/btrfs-find-root.c
index 810d835..d3f4ccc 100644
--- a/btrfs-find-root.c
+++ b/btrfs-find-root.c
@@ -247,10 +247,10 @@ static int search_iobuf(struct btrfs_root *root, void 
*iobuf,
u64 h_byte, h_level, h_gen, h_owner;
 
 // printf(searching %Lu\n, offset + block_off);
-   h_byte = le64_to_cpu(header-bytenr);
-   h_owner = le64_to_cpu(header-owner);
+   h_byte = btrfs_stack_header_bytenr(header);
+   h_owner = btrfs_stack_header_owner(header);
h_level = header-level;
-   h_gen = le64_to_cpu(header-generation);
+   h_gen = btrfs_stack_header_generation(header);
 
if (h_owner != objectid)
goto next;
diff --git a/btrfs-image.c b/btrfs-image.c
index 22239fe..599a35f 100644
--- a/btrfs-image.c
+++ b/btrfs-image.c
@@ -1332,7 +1332,7 @@ static void update_super_old(u8 *buffer)
btrfs_set_stack_chunk_num_stripes(chunk, 1);
btrfs_set_stack_chunk_sub_stripes(chunk, 0);
chunk-stripe.devid = super-dev_item.devid;
-   chunk-stripe.offset = cpu_to_le64(0);
+   btrfs_set_stack_stripe_offset(chunk-stripe, 0);
memcpy(chunk-stripe.dev_uuid, super-dev_item.uuid, BTRFS_UUID_SIZE);
btrfs_set_super_sys_array_size(super, sizeof(*key) + sizeof(*chunk));
csum_block(buffer, 4096);
diff --git a/btrfs-show-super.c b/btrfs-show-super.c
index f587f10..3e2567e 100644
--- a/btrfs-show-super.c
+++ b/btrfs-show-super.c
@@ -186,7 +186,7 @@ static void dump_superblock(struct btrfs_super_block *sb)
s = (char *) sb-magic;
for (i = 0; i  8; i++)
putchar(isprint(s[i]) ? s[i] : '.');
-   if (sb-magic == cpu_to_le64(BTRFS_MAGIC))
+   if (btrfs_super_magic(sb) == BTRFS_MAGIC)
printf( [match]\n);
else
printf( [DON'T MATCH]\n);
diff --git a/ctree.h b/ctree.h
index 3fe14b0..4c2f430 100644
--- a/ctree.h
+++ b/ctree.h
@@ -1712,6 +1712,12 @@ BTRFS_SETGET_HEADER_FUNCS(header_owner, struct 
btrfs_header, owner, 64);
 BTRFS_SETGET_HEADER_FUNCS(header_nritems, struct btrfs_header, nritems, 32);
 BTRFS_SETGET_HEADER_FUNCS(header_flags, struct btrfs_header, flags, 64);
 BTRFS_SETGET_HEADER_FUNCS(header_level, struct btrfs_header, level, 8);
+BTRFS_SETGET_STACK_FUNCS(stack_header_bytenr, struct btrfs_header, bytenr, 64);
+BTRFS_SETGET_STACK_FUNCS(stack_header_nritems, struct btrfs_header, nritems,
+32);
+BTRFS_SETGET_STACK_FUNCS(stack_header_owner, struct btrfs_header, owner, 64);
+BTRFS_SETGET_STACK_FUNCS(stack_header_generation, struct btrfs_header,
+generation, 64);
 
 static inline int btrfs_header_flag(struct extent_buffer *eb, u64 flag)
 {
@@ -1918,6 +1924,7 @@ BTRFS_SETGET_STACK_FUNCS(super_csum_type, struct 
btrfs_super_block,
 csum_type, 16);
 BTRFS_SETGET_STACK_FUNCS(super_cache_generation, struct btrfs_super_block,
 cache_generation, 64);
+BTRFS_SETGET_STACK_FUNCS(super_magic, struct btrfs_super_block, magic, 64);
 
 static inline int btrfs_super_csum_size(struct btrfs_super_block *s)
 {
diff --git a/disk-io.c b/disk-io.c
index 9ffe6e4..4eef029 100644
--- a/disk-io.c
+++ b/disk-io.c
@@ -1104,7 +1104,7 @@ int btrfs_read_dev_super(int fd, struct btrfs_super_block 
*sb, u64 sb_bytenr)
return -1;
 
if (btrfs_super_bytenr(buf) != sb_bytenr ||
-   buf.magic != cpu_to_le64(BTRFS_MAGIC))
+   btrfs_super_magic(buf) != BTRFS_MAGIC)
return -1;
 
memcpy(sb, buf, sizeof(*sb));
@@ -1120,9 +1120,9 @@ int btrfs_read_dev_super(int fd, struct btrfs_super_block 
*sb, u64 sb_bytenr)
if