#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; }