From b88ce3ced2123752f6da25abba119ae117bcc771 Mon Sep 17 00:00:00 2001 From: Zhihao Cheng Date: Mon, 11 Nov 2024 16:36:39 +0800 Subject: ubifs-utils: Extract UBI opening/closing/volume_check_empty functions into a new source file Move UBI opening/closing/volume_check_empty functions into common/super.c. These functions will be used in fsck. Signed-off-by: Zhihao Cheng Signed-off-by: David Oberhollenzer --- ubifs-utils/common/super.c | 123 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 123 insertions(+) create mode 100644 ubifs-utils/common/super.c (limited to 'ubifs-utils/common/super.c') diff --git a/ubifs-utils/common/super.c b/ubifs-utils/common/super.c new file mode 100644 index 0000000..eee0197 --- /dev/null +++ b/ubifs-utils/common/super.c @@ -0,0 +1,123 @@ +#include +#include +#include +#include +#include +#include +#include + +#include "defs.h" + +/** + * open_ubi - open the libubi. + * @c: the UBIFS file-system description object + * @node: name of the UBI volume character device to fetch information about + * + * This function opens libubi, and initialize device & volume information + * according to @node. Returns %0 in case of success and %-1 in case of failure. + */ +int open_ubi(struct ubifs_info *c, const char *node) +{ + struct stat st; + + if (stat(node, &st) || !S_ISCHR(st.st_mode)) + return -1; + + c->libubi = libubi_open(); + if (!c->libubi) + return -1; + if (ubi_get_vol_info(c->libubi, node, &c->vi)) + goto out_err; + if (ubi_get_dev_info1(c->libubi, c->vi.dev_num, &c->di)) + goto out_err; + + return 0; + +out_err: + close_ubi(c); + return -1; +} + +void close_ubi(struct ubifs_info *c) +{ + if (c->libubi) { + libubi_close(c->libubi); + c->libubi = NULL; + } +} + +/** + * open_target - open the output target. + * @c: the UBIFS file-system description object + * + * Open the output target. The target can be an UBI volume + * or a file. + * + * Returns %0 in case of success and %-1 in case of failure. + */ +int open_target(struct ubifs_info *c) +{ + if (c->libubi) { + c->dev_fd = open(c->dev_name, O_RDWR | O_EXCL); + + if (c->dev_fd == -1) + return sys_errmsg("cannot open the UBI volume '%s'", + c->dev_name); + if (ubi_set_property(c->dev_fd, UBI_VOL_PROP_DIRECT_WRITE, 1)) { + close(c->dev_fd); + return sys_errmsg("ubi_set_property(set direct_write) failed"); + } + } else { + c->dev_fd = open(c->dev_name, O_CREAT | O_RDWR | O_TRUNC, + S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH); + if (c->dev_fd == -1) + return sys_errmsg("cannot create output file '%s'", + c->dev_name); + } + return 0; +} + + +/** + * close_target - close the output target. + * @c: the UBIFS file-system description object + * + * Close the output target. If the target was an UBI + * volume, also close libubi. + * + * Returns %0 in case of success and %-1 in case of failure. + */ +int close_target(struct ubifs_info *c) +{ + if (c->dev_fd >= 0) { + if (c->libubi && ubi_set_property(c->dev_fd, UBI_VOL_PROP_DIRECT_WRITE, 0)) + return sys_errmsg("ubi_set_property(clear direct_write) failed"); + if (close(c->dev_fd) == -1) + return sys_errmsg("cannot close the target '%s'", c->dev_name); + } + return 0; +} + +/** + * check_volume_empty - check if the UBI volume is empty. + * @c: the UBIFS file-system description object + * + * This function checks if the UBI volume is empty by looking if its LEBs are + * mapped or not. + * + * Returns %0 in case of success, %1 is the volume is not empty, + * and a negative error code in case of failure. + */ +int check_volume_empty(struct ubifs_info *c) +{ + int lnum, err; + + for (lnum = 0; lnum < c->vi.rsvd_lebs; lnum++) { + err = ubi_is_mapped(c->dev_fd, lnum); + if (err < 0) + return err; + if (err == 1) + return 1; + } + return 0; +} -- cgit v1.2.3