aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mkfs.ubifs/lpt.c1
-rw-r--r--mkfs.ubifs/mkfs.ubifs.c52
-rw-r--r--mkfs.ubifs/ubifs.h3
3 files changed, 49 insertions, 7 deletions
diff --git a/mkfs.ubifs/lpt.c b/mkfs.ubifs/lpt.c
index 48ae03f..c8fb22c 100644
--- a/mkfs.ubifs/lpt.c
+++ b/mkfs.ubifs/lpt.c
@@ -549,6 +549,7 @@ int create_lpt(struct ubifs_info *c)
c->nhead_lnum = lnum;
c->nhead_offs = ALIGN(len, c->min_io_size);
+ dbg_msg(1, "lpt_sz: %d", c->lpt_sz);
dbg_msg(1, "space_bits: %d", c->space_bits);
dbg_msg(1, "lpt_lnum_bits: %d", c->lpt_lnum_bits);
dbg_msg(1, "lpt_offs_bits: %d", c->lpt_offs_bits);
diff --git a/mkfs.ubifs/mkfs.ubifs.c b/mkfs.ubifs/mkfs.ubifs.c
index 22cee8e..0775972 100644
--- a/mkfs.ubifs/mkfs.ubifs.c
+++ b/mkfs.ubifs/mkfs.ubifs.c
@@ -128,7 +128,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:l:j:U";
+static const char *optstring = "d:r:m:o:D:h?vVe:c:g:f:P:k:x:X:j:R:l:j:U:";
static const struct option longopts[] = {
{"root", 1, NULL, 'r'},
@@ -142,6 +142,7 @@ static const struct option longopts[] = {
{"version", 0, NULL, 'V'},
{"debug-level", 1, NULL, 'g'},
{"jrn-size", 1, NULL, 'j'},
+ {"reserved", 1, NULL, 'R'},
{"compr", 1, NULL, 'x'},
{"favor-percent", 1, NULL, 'X'},
{"fanout", 1, NULL, 'f'},
@@ -162,6 +163,7 @@ static const char *helptext =
"-c, --max-leb-cnt=COUNT maximum logical erase block count\n"
"-o, --output=FILE output to FILE\n"
"-j, --jrn-size=SIZE journal size\n"
+"-R, --reserved=SIZE how much space should be reserved for the super-user\n"
"-x, --compr=TYPE compression type - \"lzo\", \"favor_lzo\", \"zlib\" or\n"
" \"none\" (default: \"lzo\")\n"
"-X, --favor-percent may only be used with favor LZO compression and defines\n"
@@ -188,7 +190,8 @@ static const char *helptext =
"compressors, then it compares which compressor is better. If \"zlib\" compresses 20\n"
"or more percent better than \"lzo\", mkfs.ubifs chooses \"lzo\", otherwise it chooses\n"
"\"zlib\". The \"--favor-percent\" may specify arbitrary threshold instead of the\n"
-"default 20%.\n";
+"default 20%.\n\n"
+"The -R parameter specifies amount of bytes reserved for the super-user.\n";
/**
* make_path - make a path name from a directory and a name.
@@ -318,6 +321,32 @@ static int calc_min_log_lebs(unsigned long long max_bud_bytes)
return log_lebs;
}
+/**
+ * add_space_overhead - add UBIFS overhead.
+ * @size: flash space which should be visible to the user
+ *
+ * UBIFS has overhead, and if we need to reserve @size bytes for the user data,
+ * we have to reserve more flash space, to compensate the overhead. This
+ * function calculates and returns the amount of physical flash space which
+ * should be reserved to provide @size bytes for the user.
+ */
+static long long add_space_overhead(long long size)
+{
+ int divisor, factor, f, max_idx_node_sz;
+
+ /*
+ * Do the opposite to what the 'ubifs_reported_space()' kernel UBIFS
+ * function does.
+ */
+ max_idx_node_sz = ubifs_idx_node_sz(c, c->fanout);
+ f = c->fanout > 3 ? c->fanout >> 1 : 2;
+ divisor = UBIFS_BLOCK_SIZE;
+ factor = UBIFS_MAX_DATA_NODE_SZ;
+ factor += (max_idx_node_sz * 3) / (f - 1);
+ size *= factor;
+ return size / divisor;
+}
+
static inline int is_power_of_2(unsigned long long n)
{
return (n != 0 && ((n & (n - 1)) == 0));
@@ -376,8 +405,9 @@ static int validate_options(void)
"least %d", tmp);
tmp = calc_min_log_lebs(c->max_bud_bytes);
if (c->log_lebs < calc_min_log_lebs(c->max_bud_bytes))
- return err_msg("too few log LEBs, expected at least %d",
- tmp);
+ return err_msg("too few log LEBs, expected at least %d", tmp);
+ if (c->rp_size >= ((long long)c->leb_size * c->max_leb_cnt) / 2)
+ return err_msg("too much reserved space %lld", c->rp_size);
return 0;
}
@@ -574,6 +604,11 @@ static int get_options(int argc, char**argv)
if (c->max_bud_bytes <= 0)
return err_msg("bad maximum amount of buds");
break;
+ case 'R':
+ c->rp_size = get_bytes(optarg);
+ if (c->rp_size < 0)
+ return err_msg("bad reserved bytes count");
+ break;
case 'U':
squash_owner = 1;
break;
@@ -619,6 +654,10 @@ static int get_options(int argc, char**argv)
c->log_lebs += 2;
}
+ if (c->min_io_size < 8)
+ c->min_io_size = 8;
+ c->rp_size = add_space_overhead(c->rp_size);
+
if (verbose) {
printf("mkfs.ubifs\n");
printf("\troot: %s\n", root);
@@ -627,6 +666,7 @@ static int get_options(int argc, char**argv)
printf("\tmax_leb_cnt: %d\n", c->max_leb_cnt);
printf("\toutput: %s\n", output);
printf("\tjrn_size: %llu\n", c->max_bud_bytes);
+ printf("\treserved: %llu\n", c->rp_size);
switch (c->default_compr) {
case UBIFS_COMPR_LZO:
printf("\tcompr: lzo\n");
@@ -644,9 +684,6 @@ static int get_options(int argc, char**argv)
printf("\torph_lebs: %d\n", c->orph_lebs);
}
- if (c->min_io_size < 8)
- c->min_io_size = 8;
-
if (validate_options())
return -1;
@@ -1859,6 +1896,7 @@ static int write_super(void)
sup.lsave_cnt = cpu_to_le32(c->lsave_cnt);
sup.fmt_version = cpu_to_le32(UBIFS_FORMAT_VERSION);
sup.default_compr = cpu_to_le16(c->default_compr);
+ sup.rp_size = cpu_to_le64(c->rp_size);
sup.time_gran = cpu_to_le32(DEFAULT_TIME_GRAN);
uuid_generate_random(sup.uuid);
if (verbose) {
diff --git a/mkfs.ubifs/ubifs.h b/mkfs.ubifs/ubifs.h
index 48a583c..79c7192 100644
--- a/mkfs.ubifs/ubifs.h
+++ b/mkfs.ubifs/ubifs.h
@@ -293,6 +293,8 @@ struct ubifs_znode
* @dark_wm: LEB dark space watermark
*
* @gc_lnum: LEB number used for garbage collection
+ * @rp_size: reserved pool size
+ *
* @space_bits: number of bits needed to record free or dirty space
* @lpt_lnum_bits: number of bits needed to record a LEB number in the LPT
* @lpt_offs_bits: number of bits needed to record an offset in the LPT
@@ -365,6 +367,7 @@ struct ubifs_info
int dark_wm;
int gc_lnum;
+ long long rp_size;
int space_bits;
int lpt_lnum_bits;