From: Anand Jain <anand.jain@oracle.com>
To: linux-btrfs@vger.kernel.org
Subject: [PATCH 13/13] btrfs-progs: fix memory leaks of device_list_add()
Date: Mon, 8 Jul 2013 15:39:00 +0800 [thread overview]
Message-ID: <1373269140-29733-1-git-send-email-anand.jain@oracle.com> (raw)
In-Reply-To: <1370876190-16520-1-git-send-email-anand.jain@oracle.com>
memory allocated by device_list_add has to be freed, the
function introduced here device_list_remove() would just
go that.
however the challenging part is about where we would
call this function.
there are two ways its handled
the threads calling open_ctree_broken(), open_ctree() and
open_ctree_fd() (which leads call to device_list_add)
would anyway call close_ctree() so we put device_list_remove()
there which will take care of freeing memory.
now for threads calling device_list_add() outside of
open_ctree(), has to call device_list_remove() separately
which can be called as a last function in the thread
this patch just does that.
device_list_remove accepts() NULL (deletes entire list)
or fsid (which would delete only the fsid matched in the
device_fs list). As of now though all calling functions
use NULL, I see potential that we would use fsid when we
have to create a single device list using both the
device-tree and from the btrfs-kernel.
further, mkfs.c thread should call device_list_remove()
as well, however mkfs.c uses a lot of in-flight exits()
which makes it very difficult to bring in this fix into
mkfs.c. I shall be doing it in a separate patch.
Signed-off-by: Anand Jain <anand.jain@oracle.com>
---
cmds-device.c | 4 +++
cmds-filesystem.c | 11 ++++++++-
cmds-replace.c | 2 +
cmds-scrub.c | 3 ++
disk-io.c | 1 +
mkfs.c | 1 +
utils.h | 1 +
volumes.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++-
volumes.h | 3 ++
9 files changed, 79 insertions(+), 3 deletions(-)
diff --git a/cmds-device.c b/cmds-device.c
index 9525fcf..e4a1f1b 100644
--- a/cmds-device.c
+++ b/cmds-device.c
@@ -29,6 +29,7 @@
#include "utils.h"
#include "commands.h"
+#include "volumes.h"
/* FIXME - imported cruft, fix sparse errors and warnings */
#ifdef __CHECKER__
@@ -128,6 +129,7 @@ static int cmd_add_dev(int argc, char **argv)
}
close(fdmnt);
+ device_list_remove(NULL);
if (ret)
return ret+20;
else
@@ -213,6 +215,7 @@ static int cmd_scan_dev(int argc, char **argv)
int ret;
printf("Scanning for Btrfs filesystems\n");
ret = scan_for_btrfs(where, 1);
+ device_list_remove(NULL);
if (ret){
fprintf(stderr, "ERROR: error %d while scanning\n", ret);
return 18;
@@ -397,6 +400,7 @@ static int cmd_dev_stats(int argc, char **argv)
out:
free(di_args);
close(fdmnt);
+ device_list_remove(NULL);
return err;
}
diff --git a/cmds-filesystem.c b/cmds-filesystem.c
index a028e1d..1c26476 100644
--- a/cmds-filesystem.c
+++ b/cmds-filesystem.c
@@ -455,6 +455,7 @@ static int cmd_show(int argc, char **argv)
print_one_uuid(fs_devices);
}
printf("%s\n", BTRFS_BUILD_VERSION);
+ device_list_remove(NULL);
return 0;
}
@@ -683,13 +684,19 @@ static const char * const cmd_label_usage[] = {
static int cmd_label(int argc, char **argv)
{
+ int ret;
if (check_argc_min(argc, 2) || check_argc_max(argc, 3))
usage(cmd_label_usage);
if (argc > 2)
- return set_label(argv[1], argv[2]);
+ ret = set_label(argv[1], argv[2]);
else
- return get_label(argv[1]);
+ ret = get_label(argv[1]);
+
+ if (is_existing_blk_or_reg_file(argv[1]))
+ device_list_remove(NULL);
+
+ return ret;
}
const struct cmd_group filesystem_cmd_group = {
diff --git a/cmds-replace.c b/cmds-replace.c
index c68986a..99a5abc 100644
--- a/cmds-replace.c
+++ b/cmds-replace.c
@@ -340,6 +340,7 @@ static int cmd_start_replace(int argc, char **argv)
}
}
close(fdmnt);
+ device_list_remove(NULL);
return 0;
leave_with_error:
@@ -349,6 +350,7 @@ leave_with_error:
close(fdsrcdev);
if (fddstdev != -1)
close(fddstdev);
+ device_list_remove(NULL);
return -1;
}
diff --git a/cmds-scrub.c b/cmds-scrub.c
index 95dfee3..08aab54 100644
--- a/cmds-scrub.c
+++ b/cmds-scrub.c
@@ -1496,6 +1496,7 @@ out:
unlink(sock_path);
}
close(fdmnt);
+ device_list_remove(NULL);
if (err)
return 1;
@@ -1564,6 +1565,7 @@ static int cmd_scrub_cancel(int argc, char **argv)
out:
if (fdmnt != -1)
close(fdmnt);
+ device_list_remove(NULL);
return ret;
}
@@ -1722,6 +1724,7 @@ out:
free(di_args);
if (fdres > -1)
close(fdres);
+ device_list_remove(NULL);
return err;
}
diff --git a/disk-io.c b/disk-io.c
index 3937e3f..9b72576 100644
--- a/disk-io.c
+++ b/disk-io.c
@@ -1338,6 +1338,7 @@ int close_ctree(struct btrfs_root *root)
}
close_all_devices(fs_info);
+ device_list_remove(NULL);
free_mapping_cache(fs_info);
extent_io_tree_cleanup(&fs_info->extent_cache);
extent_io_tree_cleanup(&fs_info->free_space_cache);
diff --git a/mkfs.c b/mkfs.c
index 95fceb3..5d131dd 100644
--- a/mkfs.c
+++ b/mkfs.c
@@ -1461,6 +1461,7 @@ int main(int ac, char **av)
if (is_block_device(file))
if (test_dev_for_mkfs(file, force_overwrite, estr)) {
fprintf(stderr, "Error: %s", estr);
+ device_list_remove(NULL);
exit(1);
}
}
diff --git a/utils.h b/utils.h
index 1fa1c5a..f5b03a7 100644
--- a/utils.h
+++ b/utils.h
@@ -70,4 +70,5 @@ u64 btrfs_device_size(int fd, struct stat *st);
int test_dev_for_mkfs(char *file, int force_overwrite, char *estr);
int scan_for_btrfs(int where, int update_kernel);
int get_label_mounted(const char *mount_path, char *labelp);
+int is_existing_blk_or_reg_file(const char* filename);
#endif
diff --git a/volumes.c b/volumes.c
index 00c384a..fa27055 100644
--- a/volumes.c
+++ b/volumes.c
@@ -87,7 +87,7 @@ static struct btrfs_fs_devices *find_fsid(u8 *fsid)
return NULL;
}
-static int device_list_add(const char *path,
+int device_list_add(const char *path,
struct btrfs_super_block *disk_super,
u64 devid, struct btrfs_fs_devices **fs_devices_ret)
{
@@ -155,6 +155,60 @@ static int device_list_add(const char *path,
return 0;
}
+/* This will remove given fsid and it devices from the list,
+ * or when arg is NULL it will delete all.
+ */
+int device_list_remove(u8 *fsid)
+{
+ struct list_head *fsids;
+ struct list_head *cur_fsid;
+ struct btrfs_fs_devices *fs_devices;
+ struct list_head *cur_dev;
+ struct btrfs_device *device;
+ int del = 1;
+
+ fsids = btrfs_scanned_uuids();
+ list_for_each(cur_fsid, fsids) {
+ fs_devices = list_entry(cur_fsid, struct btrfs_fs_devices,
+ list);
+ if (fsid && memcmp(fs_devices->fsid, fsid, BTRFS_FSID_SIZE))
+ continue;
+
+ /* first check if all devs are closed before remove */
+ list_for_each(cur_dev, &fs_devices->devices) {
+ device = list_entry(cur_dev,
+ struct btrfs_device, dev_list);
+ if (device->fd > 0) {
+ fprintf(stderr, "attempted to remove device "\
+ "list without closing\n");
+ if (fsid)
+ return 1;
+ else {
+ del = 0;
+ break;
+ }
+ }
+ }
+
+ if (del) {
+ list_for_each(cur_dev, &fs_devices->devices) {
+ device = list_entry(cur_dev,
+ struct btrfs_device, dev_list);
+ list_del(&device->dev_list);
+ if (device->name)
+ kfree(device->name);
+ if (device->label)
+ kfree(device->label);
+ kfree(device);
+ }
+ list_del(&fs_devices->list);
+ kfree(fs_devices);
+ }
+ del = 1;
+ }
+ return 0;
+}
+
int btrfs_close_devices(struct btrfs_fs_devices *fs_devices)
{
struct btrfs_fs_devices *seed_devices;
diff --git a/volumes.h b/volumes.h
index 911f788..55a0b71 100644
--- a/volumes.h
+++ b/volumes.h
@@ -190,4 +190,7 @@ int btrfs_add_system_chunk(struct btrfs_trans_handle *trans,
int btrfs_chunk_readonly(struct btrfs_root *root, u64 chunk_offset);
struct btrfs_device *btrfs_find_device_by_devid(struct btrfs_root *root,
u64 devid, int instance);
+int device_list_add(const char *path, struct btrfs_super_block *disk_super,
+ u64 devid, struct btrfs_fs_devices **fs_devices_ret);
+int device_list_remove(u8 *fsid);
#endif
--
1.7.7.6
next prev parent reply other threads:[~2013-07-08 7:34 UTC|newest]
Thread overview: 56+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-06-10 14:56 [PATCH 0/9] btrfs-progs: coalesce of patches Anand Jain
2013-06-10 14:56 ` [PATCH 1/9] btrfs-progs: btrfs_scan_for_fsid doesn't need all the arguments Anand Jain
2013-06-10 20:00 ` Eric Sandeen
2013-06-11 13:15 ` anand jain
2013-06-10 14:56 ` [PATCH 2/9 v2] btrfs-progs: label option in btrfs filesystem show is not coded Anand Jain
2013-06-10 14:56 ` [PATCH 3/9 v2] btrfs-progs: update device scan usage Anand Jain
2013-06-10 14:56 ` [PATCH 4/9 v3] btrfs-progs: congregate dev scan Anand Jain
2013-06-10 14:56 ` [PATCH 5/9 v2] btrfs-progs: btrfs_scan_one_dir not to skip links when /dev/mapper is provided Anand Jain
2013-06-10 14:56 ` [PATCH 6/9 v2] btrfs-progs: scan /dev/mapper in filesystem show and device scan Anand Jain
2013-06-10 14:56 ` [PATCH 7/9 v3] btrfs-progs: device delete to get errors from the kernel Anand Jain
2013-06-10 14:56 ` [PATCH 8/9] btrfs-progs: get_label_mounted to return label instead of print Anand Jain
2013-06-21 7:41 ` [PATCH 08/13 v2] " Anand Jain
2013-06-10 14:56 ` [PATCH 9/9 v2] btrfs-progs: introduce btrfs filesystem show --kernel Anand Jain
2013-06-10 14:59 ` [PATCH 0/2] btrfs: coalesce of patches Anand Jain
2013-06-10 14:59 ` [PATCH 1/2] btrfs: device delete to get errors from the kernel Anand Jain
2013-06-10 14:59 ` [PATCH 2/2 v2] btrfs: add framework to read fs info and dev info " Anand Jain
2013-06-10 19:40 ` Josef Bacik
2013-06-11 13:10 ` anand jain
2013-06-11 13:15 ` Josef Bacik
2013-06-10 20:30 ` Zach Brown
2013-06-11 14:05 ` anand jain
2013-06-11 17:50 ` Zach Brown
2013-06-11 14:24 ` Josef Bacik
2013-06-21 7:02 ` Anand Jain
2013-06-21 7:32 ` [PATCH 2/2 v3] btrfs: obtain used_bytes in BTRFS_IOC_FS_INFO ioctl Anand Jain
2013-06-24 17:03 ` Josef Bacik
2013-06-25 3:00 ` Anand Jain
2013-07-08 7:39 ` Anand Jain [this message]
2013-07-15 4:58 ` [PATCH 13/13] btrfs-progs: fix memory leaks of device_list_add() Anand Jain
2013-07-15 5:30 ` [PATCH 00/11 v2 (resend)] btrfs-progs: coalesce of patches Anand Jain
2013-07-15 5:30 ` [PATCH 01/11] btrfs-progs: btrfs_scan_for_fsid doesn't need all the arguments Anand Jain
2013-07-15 5:30 ` [PATCH 02/11] btrfs-progs: label option in btrfs filesystem show is not coded Anand Jain
2013-07-15 5:30 ` [PATCH 03/11] btrfs-progs: update device scan usage Anand Jain
2013-07-15 5:30 ` [PATCH 04/11] btrfs-progs: congregate dev scan Anand Jain
2013-07-15 5:30 ` [PATCH 05/11] btrfs-progs: btrfs_scan_one_dir not to skip links when /dev/mapper is provided Anand Jain
2013-08-05 16:53 ` David Sterba
2013-07-15 5:30 ` [PATCH 06/11] btrfs-progs: scan /dev/mapper in filesystem show and device scan Anand Jain
2013-08-05 17:04 ` David Sterba
2013-08-13 4:07 ` anand jain
2013-07-15 5:30 ` [PATCH 07/11] btrfs-progs: device delete to get errors from the kernel Anand Jain
2013-07-15 5:30 ` [PATCH 08/11] btrfs-progs: get_label_mounted to return label instead of print Anand Jain
2013-07-15 5:30 ` [PATCH 09/11] btrfs-progs: move out print in cmd_df to another function Anand Jain
2013-07-15 5:30 ` [PATCH 10/11] btrfs-progs: get string for the group profile and type Anand Jain
2013-07-15 5:30 ` [PATCH 11/11] btrfs-progs: introduce btrfs filesystem show --kernel Anand Jain
2013-08-05 17:36 ` [PATCH 00/11 v2 (resend)] btrfs-progs: coalesce of patches David Sterba
2013-08-06 15:08 ` anand jain
2013-08-08 8:07 ` [PATCH 0/2 v2] introduce btrfs filesystem show --kernel Anand Jain
2013-08-08 8:07 ` [PATCH 1/2] btrfs-progs: move out print in cmd_df to another function Anand Jain
2013-08-08 8:07 ` [PATCH 2/2] btrfs-progs: introduce btrfs filesystem show --kernel Anand Jain
2013-08-08 18:08 ` Zach Brown
2013-08-09 10:57 ` anand jain
2013-08-09 18:03 ` Zach Brown
2013-08-08 8:09 ` [PATCH 0/2] scan /dev/mapper in filesystem show and device scan Anand Jain
2013-08-08 8:09 ` [PATCH 1/2] btrfs-progs: btrfs_scan_one_dir not to skip links when /dev/mapper is provided Anand Jain
2013-08-08 8:09 ` [PATCH 2/2] btrfs-progs: scan /dev/mapper in filesystem show and device scan Anand Jain
2013-08-08 8:10 ` [PATCH 0/2] " anand jain
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1373269140-29733-1-git-send-email-anand.jain@oracle.com \
--to=anand.jain@oracle.com \
--cc=linux-btrfs@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).