diff --git a/sbin/newfs_msdos/mkfs_msdos.c b/sbin/newfs_msdos/mkfs_msdos.c index 065e3c5f4192..423fbbcadcc5 100644 --- a/sbin/newfs_msdos/mkfs_msdos.c +++ b/sbin/newfs_msdos/mkfs_msdos.c @@ -249,7 +249,7 @@ 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; + u_int extra_res, alignment, alignto, saved_x, attempts=0; bool set_res, set_spf, set_spc; int fd, fd1, rv; struct msdos_options o = *op; @@ -412,8 +412,12 @@ mkfs_msdos(const char *fname, const char *dtype, const struct msdos_options *op) } bpb.bpbFATs = o.num_FAT; } - if (o.directory_entries) - bpb.bpbRootDirEnts = o.directory_entries; + if (o.directory_entries) { + bpb.bpbRootDirEnts = roundup(o.directory_entries, + bpb.bpbBytesPerSec / sizeof(struct de)); + if (bpb.bpbBytesPerSec == 0 || o.directory_entries >= MAXU16) + bpb.bpbRootDirEnts = MAXU16; + } if (o.media_descriptor_set) { if (o.media_descriptor < 0xf0) { warnx("illegal media descriptor (%#x)", o.media_descriptor); @@ -564,14 +568,20 @@ mkfs_msdos(const char *fname, const char *dtype, const struct msdos_options *op) 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; + alignto = bpb.bpbSecPerClust; + else + alignto = PAGE_SIZE / bpb.bpbBytesPerSec; + if (alignto > 1) { + /* align data clusters */ + alignment = (bpb.bpbResSectors + bpb.bpbBigFATsecs * bpb.bpbFATs + rds) % + alignto; + if (alignment != 0) + extra_res += alignto - alignment; + } } attempts++; - } while (o.align && alignment != 0 && attempts < 2); + } while (alignment != 0 && attempts < 2); if (o.align && alignment != 0) warnx("warning: Alignment failed."); diff --git a/sbin/newfs_msdos/newfs_msdos.8 b/sbin/newfs_msdos/newfs_msdos.8 index efa69c058453..816b5fc867b4 100644 --- a/sbin/newfs_msdos/newfs_msdos.8 +++ b/sbin/newfs_msdos/newfs_msdos.8 @@ -23,7 +23,7 @@ .\" OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN .\" IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.Dd January 12, 2024 +.Dd June 2, 2024 .Dt NEWFS_MSDOS 8 .Os .Sh NAME @@ -91,7 +91,13 @@ 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. +Attempt to cluster align the data area, useful for SD card. +If neither the +.Fl A +nor +.Fl r +option is used, the number of reserved sectors is set to a value that aligns +the start of the data area to a multiple of the page size of the host. .It Fl B Ar boot Get bootstrap from file. .It Fl C Ar create-size @@ -167,6 +173,12 @@ is 2. Number of hidden sectors. .It Fl r Ar reserved Number of reserved sectors. +If neither the +.Fl A +nor +.Fl r +option is used, the number of reserved sectors is set to a value that aligns +the start of the data area to a multiple of the page size of the host. .It Fl s Ar total File system size. .It Fl u Ar track-size