From 9f58d3503a1368673609db1962e4a584261b62eb Mon Sep 17 00:00:00 2001 From: "Matthew L. Creech" Date: Thu, 5 May 2011 16:33:20 -0400 Subject: UBIFS: add a superblock flag for free space fix-up The 'space_fixup' flag can be set in the superblock of a new filesystem by mkfs.ubifs to indicate that any eraseblocks with free space remaining should be fixed-up the first time it's mounted (after which the flag is un-set). This means that the UBIFS image has been flashed by a "dumb" flasher and the free space has been actually programmed (writing all 0xFFs), so this free space cannot be used. UBIFS fixes the free space up by re-writing the contents of all LEBs with free space using the atomic LEB change UBI operation. Artem: improved commit message, add some more commentaries to the code. Signed-off-by: Matthew L. Creech Signed-off-by: Artem Bityutskiy --- fs/ubifs/debug.c | 2 ++ fs/ubifs/sb.c | 1 + fs/ubifs/ubifs-media.h | 2 ++ fs/ubifs/ubifs.h | 2 ++ 4 files changed, 7 insertions(+) (limited to 'fs/ubifs') diff --git a/fs/ubifs/debug.c b/fs/ubifs/debug.c index b5ba2ea..f46d77e 100644 --- a/fs/ubifs/debug.c +++ b/fs/ubifs/debug.c @@ -316,6 +316,8 @@ void dbg_dump_node(const struct ubifs_info *c, const void *node) printk(KERN_DEBUG "\tflags %#x\n", sup_flags); printk(KERN_DEBUG "\t big_lpt %u\n", !!(sup_flags & UBIFS_FLG_BIGLPT)); + printk(KERN_DEBUG "\t space_fixup %u\n", + !!(sup_flags & UBIFS_FLG_SPACE_FIXUP)); printk(KERN_DEBUG "\tmin_io_size %u\n", le32_to_cpu(sup->min_io_size)); printk(KERN_DEBUG "\tleb_size %u\n", diff --git a/fs/ubifs/sb.c b/fs/ubifs/sb.c index cad60b5..93d6928 100644 --- a/fs/ubifs/sb.c +++ b/fs/ubifs/sb.c @@ -617,6 +617,7 @@ int ubifs_read_superblock(struct ubifs_info *c) c->vfs_sb->s_time_gran = le32_to_cpu(sup->time_gran); memcpy(&c->uuid, &sup->uuid, 16); c->big_lpt = !!(sup_flags & UBIFS_FLG_BIGLPT); + c->space_fixup = !!(sup_flags & UBIFS_FLG_SPACE_FIXUP); /* Automatically increase file system size to the maximum size */ c->old_leb_cnt = c->leb_cnt; diff --git a/fs/ubifs/ubifs-media.h b/fs/ubifs/ubifs-media.h index b922f03..e24380c 100644 --- a/fs/ubifs/ubifs-media.h +++ b/fs/ubifs/ubifs-media.h @@ -408,9 +408,11 @@ enum { * Superblock flags. * * UBIFS_FLG_BIGLPT: if "big" LPT model is used if set + * UBIFS_FLG_SPACE_FIXUP: first-mount "fixup" of free space within LEBs needed */ enum { UBIFS_FLG_BIGLPT = 0x02, + UBIFS_FLG_SPACE_FIXUP = 0x04, }; /** diff --git a/fs/ubifs/ubifs.h b/fs/ubifs/ubifs.h index a2f9d4e..8e27553 100644 --- a/fs/ubifs/ubifs.h +++ b/fs/ubifs/ubifs.h @@ -1014,6 +1014,7 @@ struct ubifs_debug_info; * @cmt_wq: wait queue to sleep on if the log is full and a commit is running * * @big_lpt: flag that LPT is too big to write whole during commit + * @space_fixup: flag indicating that free space in LEBs needs to be cleaned up * @no_chk_data_crc: do not check CRCs when reading data nodes (except during * recovery) * @bulk_read: enable bulk-reads @@ -1253,6 +1254,7 @@ struct ubifs_info { wait_queue_head_t cmt_wq; unsigned int big_lpt:1; + unsigned int space_fixup:1; unsigned int no_chk_data_crc:1; unsigned int bulk_read:1; unsigned int default_compr:2; -- cgit v1.1