SchOS/include/fs/blkdev.h
Nexoniarz a1c965da1e include: one folder per subsystem, and includes that name it
Sixty-five headers sat side by side in include/, so `#include "irq.h"`
said nothing about where irq.h was or what it belonged to, and errno.h,
stat.h and fcntl.h at the top shadowed the system's for any host tool
built with -I./include. They are in folders now -- arch/ core/ fs/
dev/ gfx/ net/ uapi/ (and ldls/ for the Linux driver layer) -- and
every include names the folder, as Linux's do: "core/proc.h".

Done mechanically and checked the hard way: the kernel built from this
tree disassembles identically to the one built from the tree before
it. The full image boots, and userland is the same set of programs.
Paths in docs and comments follow; docs/guides/layout.md has a table
of what is where, and tools/fix-includes.py rewrites old-style
includes from the folders in the tree, for code written before this.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01S1giNvrHTrPMPw7V6x1kQ4
2026-10-23 15:05:12 +02:00

76 lines
3.9 KiB
C

// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
// Block devices that are found rather than assumed.
//
// The first four device numbers are fixed and always were: IDE 0 and 1, the
// ramdisk, the first USB stick. Everything since -- a SATA disk behind AHCI,
// an NVMe namespace, and every partition on any of them -- registers here at
// probe time and is handed the next free number from BLKDEV_FIRST.
//
// A partition is a block device in its own right, with block 0 at its first
// sector. That is the whole of partition support from a filesystem's side:
// SchFS on /dev/sata0p2 sees a volume that starts at zero, exactly as it would
// on a whole disk, and needs to know nothing about GPT -- which is also what
// a Linux driver for SchFS will see when it is handed /dev/sda2.
#define BLKDEV_FIRST 4
// Disks and partitions together. A laptop's NVMe drive alone often carries
// eight partitions, and a stick or an SD card more, so 16 ran out.
#define NBLKDEV 32 // device numbers 4..35, below SCHFS_DEV (64)
// The GPT partition type of a SchFS volume, as it is written and printed:
// 47138FA9-B79C-47A6-9F7D-AC1F7F572D5E. sgdisk and fdisk accept it as is.
// Generated for SchFS on 2026-10-22; nothing else uses it.
#define SCHFS_GPT_TYPE "47138FA9-B79C-47A6-9F7D-AC1F7F572D5E"
// What a driver supplies. `rw` moves `count` of the device's own sectors at
// `lba` to or from `buf`, a kernel address; it is never asked for more than
// BSIZE bytes at once. Returns 0, or -1 if the device refused.
struct blkdev_ops {
int (*rw)(void *priv, uint64 lba, uint32 count, void *buf, int write);
int (*flush)(void *priv); // 0 when there is nothing to flush
};
// Register a whole disk. Its partition table, if it has one, is read here and
// every partition registered after it. Returns the disk's device number, or
// -1 if the table is full.
int blkdev_register(const char *name, const struct blkdev_ops *ops,
void *priv, uint64 nsectors, uint32 secsize);
// The disk has gone -- a USB stick pulled out. Removes it and every partition
// on it, and drops whatever the buffer cache still holds for them, so that a
// different disk given the same number later is not served the old one's
// blocks. A filesystem still mounted from it fails on its next access.
void blkdev_unregister(int dev);
void binval(uint dev); // kernel/dev/bio.c
struct buf *bgetblk(uint dev, uint64 blockno); // bread() without the read
int blkdev_present(uint dev);
void blkdev_rw(struct buf *b);
int blkdev_flush(uint dev);
// For the root probe: the registered devices in order, partitions after the
// 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);
// 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);