summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorXin Li <delphij@google.com>2018-06-19 10:18:20 -0700
committerandroid-build-merger <android-build-merger@google.com>2018-06-19 10:18:20 -0700
commit93156a8e99fbd4794b3eb5bde5ddace2b9da9bbd (patch)
tree62eb8f9177960d43ce3cc65cc18908780e6f0bf3
parent78dd8c6f6fee10ef3ab7f3dd0e5015086ff7901f (diff)
parent5c6235eb93d54f6483e55d94d2271970cf8e9d8b (diff)
downloadnewfs_msdos-93156a8e99fbd4794b3eb5bde5ddace2b9da9bbd.tar.gz
Integrate FreeBSD r335189 for -A option. am: 4d60a2217e
am: 5c6235eb93 Change-Id: If08f129615c197a4b66642f1a271a620d431f393
-rw-r--r--mkfs_msdos.c125
-rw-r--r--mkfs_msdos.h5
-rw-r--r--newfs_msdos.87
-rw-r--r--newfs_msdos.c11
4 files changed, 97 insertions, 51 deletions
diff --git a/mkfs_msdos.c b/mkfs_msdos.c
index 1697e21..a10f769 100644
--- a/mkfs_msdos.c
+++ b/mkfs_msdos.c
@@ -27,7 +27,7 @@
#ifndef lint
static const char rcsid[] =
- "$FreeBSD: head/sbin/newfs_msdos/mkfs_msdos.c 327570 2018-01-05 05:34:14Z imp $";
+ "$FreeBSD: head/sbin/newfs_msdos/mkfs_msdos.c 335189 2018-06-15 06:03:40Z delphij $";
#endif /* not lint */
#include <sys/param.h>
@@ -242,6 +242,8 @@ mkfs_msdos(const char *fname, const char *dtype, const struct msdos_options *op)
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 @@ mkfs_msdos(const char *fname, const char *dtype, const struct msdos_options *op)
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;
diff --git a/mkfs_msdos.h b/mkfs_msdos.h
index 4e1fe38..acd5615 100644
--- a/mkfs_msdos.h
+++ b/mkfs_msdos.h
@@ -1,4 +1,4 @@
-/* $FreeBSD: head/sbin/newfs_msdos/mkfs_msdos.h 318355 2017-05-16 17:04:50Z emaste $ */
+/* $FreeBSD: head/sbin/newfs_msdos/mkfs_msdos.h 335189 2018-06-15 06:03:40Z delphij $ */
/* $NetBSD: mkfs_msdos.h,v 1.3 2015/10/16 17:38:17 christos Exp $ */
/*-
@@ -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 @@ AOPT('u', uint16_t, sectors_per_track, 1, "Sectors per track")
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;
diff --git a/newfs_msdos.8 b/newfs_msdos.8
index 61639f5..10ec59b 100644
--- a/newfs_msdos.8
+++ b/newfs_msdos.8
@@ -23,9 +23,9 @@
.\" OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
.\" IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.\"
-.\" $FreeBSD: head/sbin/newfs_msdos/newfs_msdos.8 318366 2017-05-16 19:03:26Z emaste $
+.\" $FreeBSD: head/sbin/newfs_msdos/newfs_msdos.8 335189 2018-06-15 06:03:40Z delphij $
.\"
-.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 @@ Build the filesystem at the specified offset in bytes in the device or file.
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
diff --git a/newfs_msdos.c b/newfs_msdos.c
index 2fab87c..cd03164 100644
--- a/newfs_msdos.c
+++ b/newfs_msdos.c
@@ -29,7 +29,7 @@
#ifndef lint
static const char rcsid[] =
- "$FreeBSD: head/sbin/newfs_msdos/newfs_msdos.c 326276 2017-11-27 15:37:16Z pfg $";
+ "$FreeBSD: head/sbin/newfs_msdos/newfs_msdos.c 335189 2018-06-15 06:03:40Z delphij $";
#endif /* not lint */
#include <sys/param.h>
@@ -76,7 +76,7 @@ get_tstamp(const char *b)
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 @@ main(int argc, char *argv[])
case 'N':
o.no_create = 1;
break;
+ case 'A':
+ o.align = true;
+ break;
case 'B':
o.bootstrap = optarg;
break;
@@ -175,6 +178,10 @@ main(int argc, char *argv[])
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);