aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthew L. Creech <mlcreech@gmail.com>2011-05-11 17:02:28 -0400
committerArtem Bityutskiy <Artem.Bityutskiy@nokia.com>2011-05-20 13:16:10 +0300
commit04665066ebedb0a31335b525fb5f19df32cb8cfe (patch)
treed4a3fbdfcb70a2be76365780b4ca2410b26b81af
parentb5251b5b1d3aea0e724a0c4cd8c95897ecb0c312 (diff)
mkfs.ubifs: add "-F" option for "free-space fixup"
This adds a superblock flag indicating that "free-space fixup" is needed, and allows it to be set by the user via the "-F" command-line option. The first time the filesystem is mounted, this flag will trigger a one-time re-mapping of all LEBs containing free space. This fixes problems seen on some NAND flashes when a non-UBIFS-aware flash programmer is used. Artem: add a bit more help text, tweaked the patch a bit. Thanks to Ben Gardiner <bengardiner@nanometrics.ca> for help. Signed-off-by: Matthew L. Creech <mlcreech@gmail.com> Signed-off-by: Artem Bityutskiy <Artem.Bityutskiy@nokia.com>
-rw-r--r--mkfs.ubifs/mkfs.ubifs.c22
-rw-r--r--mkfs.ubifs/ubifs-media.h2
-rw-r--r--mkfs.ubifs/ubifs.h2
3 files changed, 24 insertions, 2 deletions
diff --git a/mkfs.ubifs/mkfs.ubifs.c b/mkfs.ubifs/mkfs.ubifs.c
index a306dd6..e3ccb32 100644
--- a/mkfs.ubifs/mkfs.ubifs.c
+++ b/mkfs.ubifs/mkfs.ubifs.c
@@ -132,7 +132,7 @@ static struct inum_mapping **hash_table;
/* Inode creation sequence number */
static unsigned long long creat_sqnum;
-static const char *optstring = "d:r:m:o:D:h?vVe:c:g:f:p:k:x:X:j:R:l:j:UQq";
+static const char *optstring = "d:r:m:o:D:h?vVe:c:g:f:Fp:k:x:X:j:R:l:j:UQq";
static const struct option longopts[] = {
{"root", 1, NULL, 'r'},
@@ -150,6 +150,7 @@ static const struct option longopts[] = {
{"compr", 1, NULL, 'x'},
{"favor-percent", 1, NULL, 'X'},
{"fanout", 1, NULL, 'f'},
+ {"space-fixup", 0, NULL, 'F'},
{"keyhash", 1, NULL, 'k'},
{"log-lebs", 1, NULL, 'l'},
{"orph-lebs", 1, NULL, 'p'},
@@ -183,6 +184,8 @@ static const char *helptext =
" how many percent better zlib should compress to make\n"
" mkfs.ubifs use zlib instead of LZO (default 20%)\n"
"-f, --fanout=NUM fanout NUM (default: 8)\n"
+"-F, --space-fixup file-system free space has to be fixed up on first mount\n"
+" (requires kernel version 2.6.40 or greater)\n"
"-k, --keyhash=TYPE key hash type - \"r5\" or \"test\" (default: \"r5\")\n"
"-p, --orph-lebs=COUNT count of erase blocks for orphans (default: 1)\n"
"-D, --devtable=FILE use device table FILE\n"
@@ -221,7 +224,16 @@ static const char *helptext =
"options were introduced: --squash-rino-perm which preserves the old behavior and\n"
"--nosquash-rino-perm which makes mkfs.ubifs use the right permissions for the root\n"
"inode. Now these options are considered depricated and they will be removed later, so\n"
-"do not use them.\n";
+"do not use them.\n\n"
+"The -F parameter is used to set the \"fix up free space\" flag in the superblock,\n"
+"which forces UBIFS to \"fixup\" all the free space which it is going to use. This\n"
+"option is useful to work-around the problem of double free space programming: if the\n"
+"flasher program which flashes the UBI image is unable to skip NAND pages containing\n"
+"only 0xFF bytes, the effect is that some NAND pages are written to twice - first time\n"
+"when flashing the image and the second time when UBIFS is mounted and writes useful\n"
+"data there. A proper UBI-aware flasher should skip such NAND pages, though. Note, this\n"
+"flag may make the first mount very slow, because the \"free space fixup\" procedure\n"
+"takes time. This feature is supported by the Linux kernel starting from version 2.6.40.\n";
/**
* make_path - make a path name from a directory and a name.
@@ -610,6 +622,9 @@ static int get_options(int argc, char**argv)
if (*endp != '\0' || endp == optarg || c->fanout <= 0)
return err_msg("bad fanout %s", optarg);
break;
+ case 'F':
+ c->space_fixup = 1;
+ break;
case 'l':
c->log_lebs = strtol(optarg, &endp, 0);
if (*endp != '\0' || endp == optarg || c->log_lebs <= 0)
@@ -758,6 +773,7 @@ static int get_options(int argc, char**argv)
"r5" : "test");
printf("\tfanout: %d\n", c->fanout);
printf("\torph_lebs: %d\n", c->orph_lebs);
+ printf("\tspace_fixup: %d\n", c->space_fixup);
}
if (validate_options())
@@ -1997,6 +2013,8 @@ static int write_super(void)
}
if (c->big_lpt)
sup.flags |= cpu_to_le32(UBIFS_FLG_BIGLPT);
+ if (c->space_fixup)
+ sup.flags |= cpu_to_le32(UBIFS_FLG_SPACE_FIXUP);
return write_node(&sup, UBIFS_SB_NODE_SZ, UBIFS_SB_LNUM, UBI_LONGTERM);
}
diff --git a/mkfs.ubifs/ubifs-media.h b/mkfs.ubifs/ubifs-media.h
index a9ecbd9..fe62d0e 100644
--- a/mkfs.ubifs/ubifs-media.h
+++ b/mkfs.ubifs/ubifs-media.h
@@ -373,9 +373,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/mkfs.ubifs/ubifs.h b/mkfs.ubifs/ubifs.h
index 5c29046..f94a52c 100644
--- a/mkfs.ubifs/ubifs.h
+++ b/mkfs.ubifs/ubifs.h
@@ -317,6 +317,7 @@ struct ubifs_znode
* @nhead_lnum: LEB number of LPT head
* @nhead_offs: offset of LPT head
* @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
* @lpt_sz: LPT size
*
* @ltab_lnum: LEB number of LPT's own lprops table
@@ -394,6 +395,7 @@ struct ubifs_info
int nhead_lnum;
int nhead_offs;
int big_lpt;
+ int space_fixup;
long long lpt_sz;
int ltab_lnum;