mkfs : add boundary-align option
This allow to align fat and start of cluster on a boundary.
This may usefull for some media like sdcard.
Signed-off-by: Matthieu CASTET <castet.matthieu@free.fr>
diff --git a/README.md b/README.md
index 958fe48..2e5f2dc 100644
--- a/README.md
+++ b/README.md
@@ -42,6 +42,10 @@
mkfs.exfat -f /dev/sda1
4. For set volume label, use -l option with string user want.
mkfs.exfat -L "my usb" /dev/sda1
+ 5. To change boundary alignement(KB or MB or Byte) user want
+ mkfs.exfat -b 16777216 /dev/sda1
+ mkfs.exfat -b 16384K /dev/sda1
+ mkfs.exfat -b 16M /dev/sda1
- fsck.exfat:
Check the consistency of your exfat filesystem and optionally repair a corrupted device formatted by exfat.
diff --git a/include/libexfat.h b/include/libexfat.h
index 9c25b7e..6a3ecb8 100644
--- a/include/libexfat.h
+++ b/include/libexfat.h
@@ -28,6 +28,8 @@
#define EXFAT_MAX_NUM_CLUSTER (0xFFFFFFF5)
+#define DEFAULT_BOUNDARY_ALIGNMENT (1024*1024)
+
#define DEFAULT_SECTOR_SIZE (512)
#define VOLUME_LABEL_BUFFER_SIZE (VOLUME_LABEL_MAX_LEN*MB_LEN_MAX+1)
@@ -59,6 +61,7 @@
bool writeable;
unsigned int cluster_size;
unsigned int sec_per_clu;
+ unsigned int boundary_align;
bool quick;
__u16 volume_label[VOLUME_LABEL_MAX_LEN];
int volume_label_len;
diff --git a/lib/libexfat.c b/lib/libexfat.c
index cc840ec..1c0bbc0 100644
--- a/lib/libexfat.c
+++ b/lib/libexfat.c
@@ -165,6 +165,9 @@
if (!ui->cluster_size)
exfat_set_default_cluster_size(bd, ui);
+ if (!ui->boundary_align)
+ ui->boundary_align = DEFAULT_BOUNDARY_ALIGNMENT;
+
if (ioctl(fd, BLKSSZGET, &bd->sector_size) < 0)
bd->sector_size = DEFAULT_SECTOR_SIZE;
bd->sector_size_bits = sector_size_bits(bd->sector_size);
diff --git a/manpages/mkfs.exfat.8 b/manpages/mkfs.exfat.8
index bc7ab4d..0c28f03 100644
--- a/manpages/mkfs.exfat.8
+++ b/manpages/mkfs.exfat.8
@@ -4,6 +4,9 @@
.SH SYNOPSIS
.B mkfs.exfat
[
+.B \-b
+.I boundary_alignement
+] [
.B \-c
.I cluster_size
] [
@@ -36,6 +39,12 @@
.PP
.SH OPTIONS
.TP
+.BI \-b " boundary_alignement"
+Specify the aligment for FAT and start of cluster.
+Boundary alignement can be specified in m/M for megabytes
+and k/K for kilobytes. It should be a power of two.
+Some media like sdcard need this.
+.TP
.BI \-c " cluster_size"
Specify the cluster size. Cluster size can be specified in m/M for megabytes
and k/K for kilobytes.
diff --git a/mkfs/mkfs.c b/mkfs/mkfs.c
index 4abcc41..60999b1 100644
--- a/mkfs/mkfs.c
+++ b/mkfs/mkfs.c
@@ -405,6 +405,7 @@
fprintf(stderr, "Usage: mkfs.exfat\n");
fprintf(stderr, "\t-L | --volume-label=label Set volume label\n");
fprintf(stderr, "\t-c | --cluster-size=size(or suffixed by 'K' or 'M') Specify cluster size\n");
+ fprintf(stderr, "\t-b | --boundary-align=size(or suffixed by 'K' or 'M') Specify boundary alignement\n");
fprintf(stderr, "\t-f | --full-format Full format\n");
fprintf(stderr, "\t-V | --version Show version\n");
fprintf(stderr, "\t-v | --verbose Print debug\n");
@@ -416,6 +417,7 @@
static struct option opts[] = {
{"volume-label", required_argument, NULL, 'L' },
{"cluster-size", required_argument, NULL, 'c' },
+ {"boundary-align", required_argument, NULL, 'b' },
{"full-format", no_argument, NULL, 'f' },
{"version", no_argument, NULL, 'V' },
{"verbose", no_argument, NULL, 'v' },
@@ -427,14 +429,22 @@
static int exfat_build_mkfs_info(struct exfat_blk_dev *bd,
struct exfat_user_input *ui)
{
- if (ui->cluster_size > DEFAULT_BOUNDARY_ALIGNMENT)
- finfo.fat_byte_off = ui->cluster_size;
- else
- finfo.fat_byte_off = DEFAULT_BOUNDARY_ALIGNMENT;
+ int clu_len;
+ if (ui->boundary_align < bd->sector_size) {
+ exfat_err("boundary alignement is too small (min %d)\n",
+ bd->sector_size);
+ return -1;
+ }
+ finfo.fat_byte_off = round_up(24 * bd->sector_size,
+ ui->boundary_align);
finfo.fat_byte_len = round_up((bd->num_clusters * sizeof(int)),
ui->cluster_size);
finfo.clu_byte_off = round_up(finfo.fat_byte_off + finfo.fat_byte_len,
- DEFAULT_BOUNDARY_ALIGNMENT);
+ ui->boundary_align);
+ if (bd->size <= finfo.clu_byte_off) {
+ exfat_err("boundary alignement is too big\n");
+ return -1;
+ }
finfo.total_clu_cnt = (bd->size - finfo.clu_byte_off) /
ui->cluster_size;
if (finfo.total_clu_cnt > EXFAT_MAX_NUM_CLUSTER) {
@@ -444,16 +454,15 @@
finfo.bitmap_byte_off = finfo.clu_byte_off;
finfo.bitmap_byte_len = round_up(finfo.total_clu_cnt, 8) / 8;
- finfo.ut_start_clu = round_up(EXFAT_REVERVED_CLUSTERS *
- ui->cluster_size + finfo.bitmap_byte_len, ui->cluster_size) /
- ui->cluster_size;
- finfo.ut_byte_off = round_up(finfo.bitmap_byte_off +
- finfo.bitmap_byte_len, ui->cluster_size);
+ clu_len = round_up(finfo.bitmap_byte_len, ui->cluster_size);
+
+ finfo.ut_start_clu = EXFAT_FIRST_CLUSTER + clu_len / ui->cluster_size;
+ finfo.ut_byte_off = finfo.bitmap_byte_off + clu_len;
finfo.ut_byte_len = EXFAT_UPCASE_TABLE_SIZE;
- finfo.root_start_clu = round_up(finfo.ut_start_clu * ui->cluster_size
- + finfo.ut_byte_len, ui->cluster_size) / ui->cluster_size;
- finfo.root_byte_off = round_up(finfo.ut_byte_off + finfo.ut_byte_len,
- ui->cluster_size);
+ clu_len = round_up(finfo.ut_byte_len, ui->cluster_size);
+
+ finfo.root_start_clu = finfo.ut_start_clu + clu_len / ui->cluster_size;
+ finfo.root_byte_off = finfo.ut_byte_off + clu_len;
finfo.root_byte_len = sizeof(struct exfat_dentry) * 3;
finfo.volume_serial = get_new_serial();
@@ -544,7 +553,7 @@
return 0;
}
-static long long parse_cluster_size(const char *size)
+static long long parse_size(const char *size)
{
char *data_unit;
unsigned long long byte_size = strtoull(size, &data_unit, 0);
@@ -561,7 +570,7 @@
case '\0':
break;
default:
- exfat_err("Wrong unit input('%c') for cluster size\n",
+ exfat_err("Wrong unit input('%c') for size\n",
*data_unit);
return -EINVAL;
}
@@ -583,7 +592,7 @@
exfat_err("failed to init locale/codeset\n");
opterr = 0;
- while ((c = getopt_long(argc, argv, "n:L:c:fVvh", opts, NULL)) != EOF)
+ while ((c = getopt_long(argc, argv, "n:L:c:b:fVvh", opts, NULL)) != EOF)
switch (c) {
/*
* Make 'n' option fallthrough to 'L' option for for backward
@@ -601,7 +610,7 @@
break;
}
case 'c':
- ret = parse_cluster_size(optarg);
+ ret = parse_size(optarg);
if (ret < 0)
goto out;
else if (ret & (ret - 1)) {
@@ -615,6 +624,17 @@
}
ui.cluster_size = ret;
break;
+ case 'b':
+ ret = parse_size(optarg);
+ if (ret < 0)
+ goto out;
+ else if (ret & (ret - 1)) {
+ exfat_err("boundary align(%d) is not a power of 2)\n",
+ ret);
+ goto out;
+ }
+ ui.boundary_align = ret;
+ break;
case 'f':
ui.quick = false;
break;
diff --git a/mkfs/mkfs.h b/mkfs/mkfs.h
index e4724ea..ffd56e3 100644
--- a/mkfs/mkfs.h
+++ b/mkfs/mkfs.h
@@ -5,7 +5,6 @@
#ifndef _MKFS_H
-#define DEFAULT_BOUNDARY_ALIGNMENT (1024*1024)
#define MIN_NUM_SECTOR (2048)
#define EXFAT_MAX_CLUSTER_SIZE (32*1024*1024)