aboutsummaryrefslogtreecommitdiff
path: root/ubifs-utils/libubifs
diff options
context:
space:
mode:
authorZhihao Cheng <chengzhihao1@huawei.com>2024-11-11 17:01:02 +0800
committerDavid Oberhollenzer <david.oberhollenzer@sigma-star.at>2024-11-11 10:32:45 +0100
commitaa2b50294710caba39c6b01ce99f2f6993a42ed2 (patch)
tree5fb4204cdf996ca00797b191937882dab511c09f /ubifs-utils/libubifs
parent0fb533f5695837f49f3c62c82999b37fa4f244af (diff)
fsck.ubifs: Add fsck support
Add basic process code for fsck.ubifs. There are following modes for fsck: 1. normal mode: Check the filesystem, ask user whether or not to fix the problem as long as inconsistent data is found during fs checking. 2. safe mode: Check and safely repair the filesystem, if there are any data dropping operations needed by fixing, fsck will fail. 3. danger mode: Answer 'yes' to all questions. There two sub modes: a) Check and repair the filesystem according to TNC, data dropping will be reported. If TNC/master/log is corrupted, fsck will fail. b) Check and forcedly repair the filesystem according to TNC, turns to rebuild filesystem if TNC/master/log is corrupted. Always make fsck succeed. 4. check mode: Make no changes to the filesystem, only check the filesystem. 5. rebuild mode: Scan entire UBI volume to find all nodes, and rebuild filesystem, always make fsck success. Signed-off-by: Zhihao Cheng <chengzhihao1@huawei.com> Signed-off-by: David Oberhollenzer <david.oberhollenzer@sigma-star.at>
Diffstat (limited to 'ubifs-utils/libubifs')
-rw-r--r--ubifs-utils/libubifs/budget.c2
-rw-r--r--ubifs-utils/libubifs/debug.c8
-rw-r--r--ubifs-utils/libubifs/super.c52
-rw-r--r--ubifs-utils/libubifs/ubifs.h8
4 files changed, 67 insertions, 3 deletions
diff --git a/ubifs-utils/libubifs/budget.c b/ubifs-utils/libubifs/budget.c
index 54392a9..5550c9a 100644
--- a/ubifs-utils/libubifs/budget.c
+++ b/ubifs-utils/libubifs/budget.c
@@ -201,7 +201,7 @@ long long ubifs_calc_available(const struct ubifs_info *c, int min_idx_lebs)
static int can_use_rp(__unused struct ubifs_info *c)
{
/* Fsck can always use reserved pool. */
- return c->program_type != MKFS_PROGRAM_TYPE;
+ return c->program_type == FSCK_PROGRAM_TYPE;
}
/**
diff --git a/ubifs-utils/libubifs/debug.c b/ubifs-utils/libubifs/debug.c
index a210990..94928da 100644
--- a/ubifs-utils/libubifs/debug.c
+++ b/ubifs-utils/libubifs/debug.c
@@ -1021,7 +1021,11 @@ void ubifs_assert_failed(struct ubifs_info *c, const char *expr,
/*
* Different from linux kernel.
- * There is only one action(readonly) when assertion is failed.
+ * Invoke callback function if there is one, otherwise make filesystem
+ * readonly when assertion is failed.
*/
- ubifs_ro_mode(c, -EINVAL);
+ if (c->assert_failed_cb)
+ c->assert_failed_cb(c);
+ else
+ ubifs_ro_mode(c, -EINVAL);
}
diff --git a/ubifs-utils/libubifs/super.c b/ubifs-utils/libubifs/super.c
index 9fa366f..155489d 100644
--- a/ubifs-utils/libubifs/super.c
+++ b/ubifs-utils/libubifs/super.c
@@ -138,6 +138,53 @@ int close_target(struct ubifs_info *c)
}
/**
+ * ubifs_open_volume - open UBI volume.
+ * @c: the UBIFS file-system description object
+ * @volume_name: the UBI volume name
+ *
+ * Open ubi volume. This function is implemented by open_ubi + open_target.
+ *
+ * Returns %0 in case of success and a negative error code in case of failure.
+ */
+int ubifs_open_volume(struct ubifs_info *c, const char *volume_name)
+{
+ int err;
+
+ err = open_ubi(c, volume_name);
+ if (err) {
+ ubifs_err(c, "cannot open libubi. %s", strerror(errno));
+ return err;
+ }
+
+ err = open_target(c);
+ if (err)
+ close_ubi(c);
+
+ return err;
+}
+
+/**
+ * ubifs_close_volume - close UBI volume.
+ * @c: the UBIFS file-system description object
+ *
+ * Close ubi volume. This function is implemented by close_target + close_ubi.
+ *
+ * Returns %0 in case of success and a negative error code in case of failure.
+ */
+int ubifs_close_volume(struct ubifs_info *c)
+{
+ int err;
+
+ err = close_target(c);
+ if (err)
+ return err;
+
+ close_ubi(c);
+
+ return 0;
+}
+
+/**
* check_volume_empty - check if the UBI volume is empty.
* @c: the UBIFS file-system description object
*
@@ -197,6 +244,11 @@ void init_ubifs_info(struct ubifs_info *c, int program_type)
case MKFS_PROGRAM_TYPE:
c->program_name = MKFS_PROGRAM_NAME;
break;
+ case FSCK_PROGRAM_TYPE:
+ c->program_name = FSCK_PROGRAM_NAME;
+ /* Always check crc for data node. */
+ c->no_chk_data_crc = 0;
+ break;
default:
assert(0);
break;
diff --git a/ubifs-utils/libubifs/ubifs.h b/ubifs-utils/libubifs/ubifs.h
index 2af9d87..babaae8 100644
--- a/ubifs-utils/libubifs/ubifs.h
+++ b/ubifs-utils/libubifs/ubifs.h
@@ -1026,6 +1026,9 @@ struct ubifs_budg_info {
*
* @new_ihead_lnum: used by debugging to check @c->ihead_lnum
* @new_ihead_offs: used by debugging to check @c->ihead_offs
+ *
+ * @private: private information related to specific situation, eg. fsck.
+ * @assert_failed_cb: callback function to handle assertion failure
*/
struct ubifs_info {
struct ubifs_sb_node *sup_node;
@@ -1248,6 +1251,9 @@ struct ubifs_info {
int new_ihead_lnum;
int new_ihead_offs;
+
+ void *private;
+ void (*assert_failed_cb)(const struct ubifs_info *c);
};
extern atomic_long_t ubifs_clean_zn_cnt;
@@ -1684,6 +1690,8 @@ int open_ubi(struct ubifs_info *c, const char *node);
void close_ubi(struct ubifs_info *c);
int open_target(struct ubifs_info *c);
int close_target(struct ubifs_info *c);
+int ubifs_open_volume(struct ubifs_info *c, const char *volume_name);
+int ubifs_close_volume(struct ubifs_info *c);
int check_volume_empty(struct ubifs_info *c);
void init_ubifs_info(struct ubifs_info *c, int program_type);
int init_constants_early(struct ubifs_info *c);