Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F141108044
D15672.id.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
7 KB
Referenced Files
None
Subscribers
None
D15672.id.diff
View Options
Index: head/sbin/newfs_msdos/mkfs_msdos.h
===================================================================
--- head/sbin/newfs_msdos/mkfs_msdos.h
+++ head/sbin/newfs_msdos/mkfs_msdos.h
@@ -34,6 +34,7 @@
#include <stdbool.h>
#define ALLOPTS \
AOPT('@', off_t, offset, 0, "Offset in device") \
+AOPT('A', bool, align, -2, "Attempt to cluster align root directory") \
AOPT('B', const char *, bootstrap, -1, "Bootstrap file") \
AOPT('C', off_t, create_size, 0, "Create file") \
AOPT('F', uint8_t, fat_type, 12, "FAT type (12, 16, or 32)") \
@@ -61,7 +62,7 @@
struct msdos_options {
#define AOPT(_opt, _type, _name, _min, _desc) _type _name;
ALLOPTS
-#undef AOPT
+#undef AOPT
uint32_t timestamp_set:1;
uint32_t volume_id_set:1;
uint32_t media_descriptor_set:1;
Index: head/sbin/newfs_msdos/mkfs_msdos.c
===================================================================
--- head/sbin/newfs_msdos/mkfs_msdos.c
+++ head/sbin/newfs_msdos/mkfs_msdos.c
@@ -242,6 +242,8 @@
ssize_t n;
time_t now;
u_int fat, bss, rds, cls, dir, lsn, x, x1, x2;
+ u_int extra_res, alignment, saved_x, attempts=0;
+ bool set_res, set_spf, set_spc;
int fd, fd1, rv;
struct msdos_options o = *op;
@@ -486,50 +488,83 @@
if (bpb.bpbBackup != MAXU16 && x <= bpb.bpbBackup)
x = bpb.bpbBackup + 1;
}
- if (!bpb.bpbResSectors)
- bpb.bpbResSectors = fat == 32 ?
- MAX(x, MAX(16384 / bpb.bpbBytesPerSec, 4)) : x;
- else if (bpb.bpbResSectors < x) {
- warnx("too few reserved sectors (need %d have %d)", x,
- bpb.bpbResSectors);
- goto done;
- }
- if (fat != 32 && !bpb.bpbRootDirEnts)
- bpb.bpbRootDirEnts = DEFRDE;
- rds = howmany(bpb.bpbRootDirEnts, bpb.bpbBytesPerSec / sizeof(struct de));
- if (!bpb.bpbSecPerClust)
- for (bpb.bpbSecPerClust = howmany(fat == 16 ? DEFBLK16 :
- DEFBLK, bpb.bpbBytesPerSec);
- bpb.bpbSecPerClust < MAXSPC &&
- bpb.bpbResSectors +
- howmany((RESFTE + maxcls(fat)) * (fat / BPN),
- bpb.bpbBytesPerSec * NPB) *
- bpb.bpbFATs +
- rds +
- (u_int64_t) (maxcls(fat) + 1) *
- bpb.bpbSecPerClust <= bpb.bpbHugeSectors;
- bpb.bpbSecPerClust <<= 1)
- continue;
- if (fat != 32 && bpb.bpbBigFATsecs > MAXU16) {
- warnx("too many sectors/FAT for FAT12/16");
- goto done;
- }
- x1 = bpb.bpbResSectors + rds;
- x = bpb.bpbBigFATsecs ? bpb.bpbBigFATsecs : 1;
- if (x1 + (u_int64_t)x * bpb.bpbFATs > bpb.bpbHugeSectors) {
- warnx("meta data exceeds file system size");
- goto done;
- }
- x1 += x * bpb.bpbFATs;
- x = (u_int64_t)(bpb.bpbHugeSectors - x1) * bpb.bpbBytesPerSec * NPB /
- (bpb.bpbSecPerClust * bpb.bpbBytesPerSec * NPB + fat /
- BPN * bpb.bpbFATs);
- x2 = howmany((RESFTE + MIN(x, maxcls(fat))) * (fat / BPN),
- bpb.bpbBytesPerSec * NPB);
- if (!bpb.bpbBigFATsecs) {
- bpb.bpbBigFATsecs = x2;
- x1 += (bpb.bpbBigFATsecs - 1) * bpb.bpbFATs;
- }
+
+ extra_res = 0;
+ alignment = 0;
+ set_res = (bpb.bpbResSectors == 0);
+ set_spf = (bpb.bpbBigFATsecs == 0);
+ set_spc = (bpb.bpbSecPerClust == 0);
+ saved_x = x;
+
+ /*
+ * Attempt to align the root directory to cluster if o.align is set.
+ * This is done by padding with reserved blocks. Note that this can
+ * cause other factors to change, which can in turn change the alignment.
+ * This should take at most 2 iterations, as increasing the reserved
+ * amount may cause the FAT size to decrease by 1, requiring another
+ * bpbFATs reserved blocks. If bpbSecPerClust changes, it will
+ * be half of its previous size, and thus will not throw off alignment.
+ */
+ do {
+ x = saved_x;
+ if (set_res)
+ bpb.bpbResSectors = ((fat == 32) ?
+ MAX(x, MAX(16384 / bpb.bpbBytesPerSec, 4)) : x) + extra_res;
+ else if (bpb.bpbResSectors < x) {
+ warnx("too few reserved sectors (need %d have %d)", x,
+ bpb.bpbResSectors);
+ goto done;
+ }
+ if (fat != 32 && !bpb.bpbRootDirEnts)
+ bpb.bpbRootDirEnts = DEFRDE;
+ rds = howmany(bpb.bpbRootDirEnts,
+ bpb.bpbBytesPerSec / sizeof(struct de));
+ if (set_spc) {
+ for (bpb.bpbSecPerClust = howmany(fat == 16 ? DEFBLK16 :
+ DEFBLK, bpb.bpbBytesPerSec);
+ bpb.bpbSecPerClust < MAXSPC && (bpb.bpbResSectors +
+ howmany((RESFTE + maxcls(fat)) * (fat / BPN),
+ bpb.bpbBytesPerSec * NPB) * bpb.bpbFATs +
+ rds +
+ (u_int64_t) (maxcls(fat) + 1) * bpb.bpbSecPerClust) <=
+ bpb.bpbHugeSectors;
+ bpb.bpbSecPerClust <<= 1)
+ continue;
+
+ }
+ if (fat != 32 && bpb.bpbBigFATsecs > MAXU16) {
+ warnx("too many sectors/FAT for FAT12/16");
+ goto done;
+ }
+ x1 = bpb.bpbResSectors + rds;
+ x = bpb.bpbBigFATsecs ? bpb.bpbBigFATsecs : 1;
+ if (x1 + (u_int64_t)x * bpb.bpbFATs > bpb.bpbHugeSectors) {
+ warnx("meta data exceeds file system size");
+ goto done;
+ }
+ x1 += x * bpb.bpbFATs;
+ x = (u_int64_t)(bpb.bpbHugeSectors - x1) * bpb.bpbBytesPerSec * NPB /
+ (bpb.bpbSecPerClust * bpb.bpbBytesPerSec * NPB +
+ fat / BPN * bpb.bpbFATs);
+ x2 = howmany((RESFTE + MIN(x, maxcls(fat))) * (fat / BPN),
+ bpb.bpbBytesPerSec * NPB);
+ if (set_spf) {
+ if (bpb.bpbBigFATsecs == 0)
+ bpb.bpbBigFATsecs = x2;
+ x1 += (bpb.bpbBigFATsecs - 1) * bpb.bpbFATs;
+ }
+ if (set_res) {
+ /* attempt to align root directory */
+ alignment = (bpb.bpbResSectors + bpb.bpbBigFATsecs * bpb.bpbFATs) %
+ bpb.bpbSecPerClust;
+ if (o.align)
+ extra_res += bpb.bpbSecPerClust - alignment;
+ }
+ attempts++;
+ } while (o.align && alignment != 0 && attempts < 2);
+ if (o.align && alignment != 0)
+ warnx("warning: Alignment failed.");
+
cls = (bpb.bpbHugeSectors - x1) / bpb.bpbSecPerClust;
x = (u_int64_t)bpb.bpbBigFATsecs * bpb.bpbBytesPerSec * NPB / (fat / BPN) -
RESFTE;
Index: head/sbin/newfs_msdos/newfs_msdos.8
===================================================================
--- head/sbin/newfs_msdos/newfs_msdos.8
+++ head/sbin/newfs_msdos/newfs_msdos.8
@@ -25,7 +25,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd May 16, 2017
+.Dd June 14, 2018
.Dt NEWFS_MSDOS 8
.Os
.Sh NAME
@@ -35,6 +35,7 @@
.Nm
.Op Fl N
.Op Fl @ Ar offset
+.Op Fl A
.Op Fl B Ar boot
.Op Fl C Ar create-size
.Op Fl F Ar FAT-type
@@ -91,6 +92,8 @@
A suffix s, k, m, g (lower or upper case)
appended to the offset specifies that the
number is in sectors, kilobytes, megabytes or gigabytes, respectively.
+.It Fl A
+Attempt to cluster align root directory, useful for SD card.
.It Fl B Ar boot
Get bootstrap from file.
.It Fl C Ar create-size
Index: head/sbin/newfs_msdos/newfs_msdos.c
===================================================================
--- head/sbin/newfs_msdos/newfs_msdos.c
+++ head/sbin/newfs_msdos/newfs_msdos.c
@@ -76,7 +76,7 @@
int
main(int argc, char *argv[])
{
- static const char opts[] = "@:NB:C:F:I:L:O:S:a:b:c:e:f:h:i:k:m:n:o:r:s:T:u:";
+ static const char opts[] = "@:NAB:C:F:I:L:O:S:a:b:c:e:f:h:i:k:m:n:o:r:s:T:u:";
struct msdos_options o;
const char *fname, *dtype;
char buf[MAXPATHLEN];
@@ -92,6 +92,9 @@
case 'N':
o.no_create = 1;
break;
+ case 'A':
+ o.align = true;
+ break;
case 'B':
o.bootstrap = optarg;
break;
@@ -175,6 +178,10 @@
argv += optind;
if (argc < 1 || argc > 2)
usage();
+ if (o.align) {
+ if (o.hidden_sectors_set)
+ errx(1, "align (-A) is incompatible with -r");
+ }
fname = *argv++;
if (!o.create_size && !strchr(fname, '/')) {
snprintf(buf, sizeof(buf), "%s%s", _PATH_DEV, fname);
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Thu, Jan 1, 11:26 PM (10 h, 51 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
27446978
Default Alt Text
D15672.id.diff (7 KB)
Attached To
Mode
D15672: Add option to cluster-align the start of the root directory
Attached
Detach File
Event Timeline
Log In to Comment