summaryrefslogtreecommitdiff
path: root/utils.c
diff options
context:
space:
mode:
authorWang Shilong <wangsl.fnst@cn.fujitsu.com>2013-07-15 19:36:50 +0800
committerDavid Sterba <dsterba@suse.cz>2013-08-09 14:32:36 +0200
commitc125b7cf43aac815782ded0a0f36060e81c79726 (patch)
tree6d954a3f9e39f834bc96643bf5c574bdc9cea00e /utils.c
parentc118c21b3e855c37c01db4be5746055629b70a19 (diff)
Btrfs-progs: fix closing of opendir()
valgrind complains open_file_or_dir() causes a memory leak.That is because if we open a directoy by opendir(), and then we should call closedir() to free memory. Signed-off-by: Wang Shilong <wangsl.fnst@cn.fujitsu.com> Signed-off-by: David Sterba <dsterba@suse.cz> Signed-off-by: Chris Mason <chris.mason@fusionio.com>
Diffstat (limited to 'utils.c')
-rw-r--r--utils.c35
1 files changed, 21 insertions, 14 deletions
diff --git a/utils.c b/utils.c
index ac6b4bb4..08002e55 100644
--- a/utils.c
+++ b/utils.c
@@ -31,7 +31,6 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <uuid/uuid.h>
-#include <dirent.h>
#include <fcntl.h>
#include <unistd.h>
#include <mntent.h>
@@ -728,7 +727,7 @@ out:
*
* On error, return -1, errno should be set.
*/
-int open_path_or_dev_mnt(const char *path)
+int open_path_or_dev_mnt(const char *path, DIR **dirstream)
{
char mp[BTRFS_PATH_NAME_MAX + 1];
int fdmnt;
@@ -742,9 +741,9 @@ int open_path_or_dev_mnt(const char *path)
errno = EINVAL;
return -1;
}
- fdmnt = open_file_or_dir(mp);
+ fdmnt = open_file_or_dir(mp, dirstream);
} else {
- fdmnt = open_file_or_dir(path);
+ fdmnt = open_file_or_dir(path, dirstream);
}
return fdmnt;
@@ -1498,11 +1497,10 @@ u64 parse_size(char *s)
return strtoull(s, NULL, 10) * mult;
}
-int open_file_or_dir(const char *fname)
+int open_file_or_dir(const char *fname, DIR **dirstream)
{
int ret;
struct stat st;
- DIR *dirstream;
int fd;
ret = stat(fname, &st);
@@ -1510,20 +1508,29 @@ int open_file_or_dir(const char *fname)
return -1;
}
if (S_ISDIR(st.st_mode)) {
- dirstream = opendir(fname);
- if (!dirstream) {
+ *dirstream = opendir(fname);
+ if (!*dirstream)
return -2;
- }
- fd = dirfd(dirstream);
+ fd = dirfd(*dirstream);
} else {
fd = open(fname, O_RDWR);
}
if (fd < 0) {
- return -3;
+ fd = -3;
+ if (*dirstream)
+ closedir(*dirstream);
}
return fd;
}
+void close_file_or_dir(int fd, DIR *dirstream)
+{
+ if (dirstream)
+ closedir(dirstream);
+ else if (fd >= 0)
+ close(fd);
+}
+
int get_device_info(int fd, u64 devid,
struct btrfs_ioctl_dev_info_args *di_args)
{
@@ -1556,6 +1563,7 @@ int get_fs_info(char *path, struct btrfs_ioctl_fs_info_args *fi_args,
struct btrfs_fs_devices *fs_devices_mnt = NULL;
struct btrfs_ioctl_dev_info_args *di_args;
char mp[BTRFS_PATH_NAME_MAX + 1];
+ DIR *dirstream = NULL;
memset(fi_args, 0, sizeof(*fi_args));
@@ -1586,7 +1594,7 @@ int get_fs_info(char *path, struct btrfs_ioctl_fs_info_args *fi_args,
}
/* at this point path must not be for a block device */
- fd = open_file_or_dir(path);
+ fd = open_file_or_dir(path, &dirstream);
if (fd < 0) {
ret = -errno;
goto out;
@@ -1623,8 +1631,7 @@ int get_fs_info(char *path, struct btrfs_ioctl_fs_info_args *fi_args,
BUG_ON(ndevs == 0);
ret = 0;
out:
- if (fd != -1)
- close(fd);
+ close_file_or_dir(fd, dirstream);
return ret;
}