fat: FAT12, FAT16 and FAT32 with long names, read and write
The filesystem every other system can read: a USB stick, an SD card, the EFI system partition. It is here first for the hardware report, which has to leave a machine on something that can be read on another one. mount -t vfat /dev/usb0p1 /mnt (msdos and fat work too; -o ro) Written from Microsoft's specification, and matched to Linux vfat where the specification leaves a choice: 8.3 names with the NT lowercase bits, long-name entries otherwise, Linux's alias rule (REPORTS, then BIGNUM~1), case-insensitive lookup, UTC times, the boot-sector dirty bit, every FAT copy and FSInfo kept up to date. It uses its own sector cache over the new blkdev_xfer, since a partition need not be a whole number of 4 KB blocks, and every operation that changes something reaches the disk before it returns. Inode numbers come from the entry position, or the first cluster for a directory, plus a small table for entries that moved. Around it: - /dev lists every disk and partition the block layer found (major 8, minor = block device), and raw reads and writes on them go by sector. - The ESP and MBR FAT partitions are registered, typed so the root probe passes over them. MBR entries with a bad status byte are skipped, so a superfloppy's boot code is not read as a partition table. - statfs, sync, fsync, umount (EBUSY while in use), shutdown, reboot and the power button all know about FAT. - create undoes and reports a failed ialloc or dirlink (ENOSPC, EINVAL, EPERM) instead of panicking; fs_ops gains refuse_types and no_hardlinks. - filewrite returns a short write instead of panicking on it. - utimensat is implemented. As a stub returning 0 it made toybox touch believe the file existed, so `touch newfile` created nothing on any filesystem. Tested in QEMU against mkfs.vfat images (FAT12 floppy, FAT16 on MBR, FAT32 superfloppy and GPT ESP) by writing, renaming, deleting, filling to ENOSPC and truncating there, then checking with fsck.fat -n and mtools on the host: all clean, contents match. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01S1giNvrHTrPMPw7V6x1kQ4
This commit is contained in:
parent
d90a72e6d3
commit
edb560de66
15 changed files with 2580 additions and 50 deletions
|
|
@ -51,6 +51,23 @@ int blkdev_flush(uint dev);
|
|||
// disk they are on. Returns the device number of the i'th, or -1 past the end.
|
||||
int blkdev_nth(int i);
|
||||
const char *blkdev_name(uint dev);
|
||||
int blkdev_is_schfs(uint dev); // a partition typed SCHFS_GPT_TYPE
|
||||
// 1 for a partition typed SCHFS_GPT_TYPE, 0 for anything that might be SchFS,
|
||||
// and -1 for one whose type says it cannot be -- an EFI system partition, an
|
||||
// MBR FAT type. The root probe takes 1 and then 0, so -1 is never tried: a
|
||||
// FAT partition is mounted as FAT (kernel/fs/fat), not offered as a root.
|
||||
int blkdev_is_schfs(uint dev);
|
||||
|
||||
int blkdev_info(char *buf, int cap); // /proc/partitions
|
||||
|
||||
// Sectors straight to and from a filesystem's own buffer, for one that does
|
||||
// not go through the buffer cache. kernel/fs/fat is: FAT addresses 512-byte
|
||||
// sectors, a partition need not be a whole number of 4 KB blocks, and a
|
||||
// cache block hanging over the end of one is a write into the next.
|
||||
//
|
||||
// `lba` counts the device's own sectors from the start of the partition, and
|
||||
// the transfer is at most BSIZE bytes. Returns 0, or -1 for a transfer out of
|
||||
// range or one the device refused -- it does not panic, because a USB stick
|
||||
// can leave in the middle of one.
|
||||
int blkdev_xfer(uint dev, uint64 lba, uint32 count, void *buf, int write);
|
||||
// Size in sectors and sector size; 0 if there is no such device.
|
||||
uint64 blkdev_sectors(uint dev, uint32 *secsize);
|
||||
|
|
|
|||
Loading…
Reference in a new issue