diff mbox series

[1/9] Killing dirstream: add helpers

Message ID 802bd72e2f67add884e8725ec87063e7554f8f40.1702148009.git.kreijack@inwind.it (mailing list archive)
State New, archived
Headers show
Series Remove unused dirstream variable | expand

Commit Message

Goffredo Baroncelli Dec. 9, 2023, 6:53 p.m. UTC
From: Goffredo Baroncelli <kreijack@inwind.it>

For historical reason the helpers [btrfs_]open_dir... return also
the 'DIR *dirstream' value when a dir is opened.

However this is never used. So avoid calling diropen() and return
only the fd.

This is a preparatory patch that adds some helpers.

Signed-off-by: Goffredo Baroncelli <kreijack@libero.it>
---
 common/open-utils.c | 80 +++++++++++++++++++++++++++++++++++++++++++++
 common/open-utils.h |  5 +++
 2 files changed, 85 insertions(+)
diff mbox series

Patch

diff --git a/common/open-utils.c b/common/open-utils.c
index 111a51d9..61153294 100644
--- a/common/open-utils.c
+++ b/common/open-utils.c
@@ -318,3 +318,83 @@  void close_file_or_dir(int fd, DIR *dirstream)
 }
 
 
+/*
+ * Do the following checks before calling open:
+ * 1: path is in a btrfs filesystem
+ */
+int btrfs_open_fd2(const char *path, bool verbose, bool read_write, bool dir_only)
+{
+	struct statfs stfs;
+	struct stat st;
+	int ret;
+
+	if (stat(path, &st) != 0) {
+		error_on(verbose, "cannot access '%s': %m", path);
+		return -1;
+	}
+
+	if (statfs(path, &stfs) != 0) {
+		error_on(verbose, "cannot access '%s': %m", path);
+		return -1;
+	}
+
+	if (stfs.f_type != BTRFS_SUPER_MAGIC) {
+		error_on(verbose, "not a btrfs filesystem: %s", path);
+		return -2;
+	}
+
+	if (dir_only && !S_ISDIR(st.st_mode)) {
+		error_on(verbose, "not a directory: %s", path);
+		return -3;
+	}
+
+	if (S_ISDIR(st.st_mode) || !read_write)
+		ret = open(path, O_RDONLY);
+	else
+		ret = open(path, O_RDWR);
+	if (ret < 0) {
+		error_on(verbose, "cannot access '%s': %m", path);
+	}
+
+	return ret;
+}
+
+int btrfs_open_file_or_dir_fd(const char *path)
+{
+	return btrfs_open_fd2(path, true, true, false);
+}
+
+int btrfs_open_dir_fd(const char *path)
+{
+	return btrfs_open_fd2(path, true, true, true);
+}
+
+
+/*
+ * Given a pathname, return a filehandle to:
+ * 	the original pathname or,
+ * 	if the pathname is a mounted btrfs device, to its mountpoint.
+ *
+ * On error, return -1, errno should be set.
+ */
+int btrfs_open_mnt_fd(const char *path, bool verbose)
+{
+	char mp[PATH_MAX];
+	int ret;
+
+	if (path_is_block_device(path)) {
+		ret = get_btrfs_mount(path, mp, sizeof(mp));
+		if (ret < 0) {
+			/* not a mounted btrfs dev */
+			error_on(verbose, "'%s' is not a mounted btrfs device",
+				 path);
+			errno = EINVAL;
+			return -1;
+		}
+		ret = btrfs_open_fd2(mp, verbose, true, true);
+	} else {
+		ret = btrfs_open_dir_fd(path);
+	}
+
+	return ret;
+}
diff --git a/common/open-utils.h b/common/open-utils.h
index 3f8c004e..96d99f5d 100644
--- a/common/open-utils.h
+++ b/common/open-utils.h
@@ -39,4 +39,9 @@  int btrfs_open_file_or_dir(const char *path, DIR **dirstream, int verbose);
 
 void close_file_or_dir(int fd, DIR *dirstream);
 
+int btrfs_open_fd2(const char *path, bool verbose, bool read_write, bool dir_only);
+int btrfs_open_file_or_dir_fd(const char *path);
+int btrfs_open_dir_fd(const char *path);
+int btrfs_open_mnt_fd(const char *path, bool verbose);
+
 #endif