]> www.infradead.org Git - mtd-utils.git/commitdiff
mkfs.ubifs: add "-F" option for "free-space fixup"
authorMatthew L. Creech <mlcreech@gmail.com>
Wed, 11 May 2011 21:02:28 +0000 (17:02 -0400)
committerArtem Bityutskiy <Artem.Bityutskiy@nokia.com>
Fri, 20 May 2011 10:16:10 +0000 (13:16 +0300)
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>
mkfs.ubifs/mkfs.ubifs.c
mkfs.ubifs/ubifs-media.h
mkfs.ubifs/ubifs.h

index a306dd6b87da959fa53dbed413965d6d05ceffd8..e3ccb32e69a6c1aee0b5ad1e958656883388f771 100644 (file)
@@ -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);
 }
index a9ecbd9af20dbeb9a0ddefccd21f8b7393ba1d0a..fe62d0efc9591c6b6151db1ca0f9a731ab4587e8 100644 (file)
@@ -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,
 };
 
 /**
index 5c290469803579de833e3cd60ae036b818204e82..f94a52cc2fdce1e342049de5f6e9b7e7f5392701 100644 (file)
@@ -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;