diff options
Diffstat (limited to 'sys')
-rw-r--r-- | sys/include/sys/disk.h | 45 | ||||
-rw-r--r-- | sys/kern/disk_engine.c | 12 | ||||
-rw-r--r-- | sys/kern/kern_disk.c | 40 |
3 files changed, 82 insertions, 15 deletions
diff --git a/sys/include/sys/disk.h b/sys/include/sys/disk.h index 0570fe2..4ad068b 100644 --- a/sys/include/sys/disk.h +++ b/sys/include/sys/disk.h @@ -41,6 +41,8 @@ #include <dev/dcdr/cache.h> #endif /* _KERNEL */ +#define DISK_NAME_MAX 64 + /* * V_BSIZE is the virtual block size in bytes used * by the disk framework. The virtual block size is a @@ -74,8 +76,9 @@ _Static_assert((V_BSIZE & 1) == 0, "V_BSIZE must be a power of two"); #define DISK_PARAM_COOKIE 0xD1531001 /* Valid disk operations */ -#define DISK_IO_READ 0x00 -#define DISK_IO_WRITE 0x01 +#define DISK_IO_READ 0x00 /* Read data from the disk */ +#define DISK_IO_WRITE 0x01 /* Write data to disk */ +#define DISK_IO_QUERY 0x02 /* Query disk information */ /* * A disk identifier is a zero-based index into @@ -95,18 +98,30 @@ typedef off_t blkoff_t; typedef uint8_t diskop_t; /* + * Describes basic disk information + * + * @block_size: Hardware block size + * @vblock_size: Virtual block size + * @n_block: Number of blocks total + */ +struct disk_info { + uint32_t block_size; + uint32_t vblock_size; + size_t n_block; +}; + +/* * The disk metadata structure contains information * describing the disk. It is used for Hyra's pbuf * (persistent buffers / sls) support. This structure * is to be stored at the very last sector of the drive. * - * @root_blk: Disk offset to root block - * @n_ublk: Number of usable user blocks + * @canary: Boot canary to verify persistent instance + * @info: Disk attributes */ -struct disk_meta { - char magic[6]; - blkoff_t root_blk; - size_t n_ublk; +struct disk_root { + uint32_t canary; + struct disk_info info; }; /* @@ -141,7 +156,7 @@ struct disk_param { * @res: Pointer to params to be initialized */ __always_inline static inline void -disk_param_init(uint8_t *buf, blkoff_t blk, size_t size, struct disk_param *res) +disk_param_init(void *buf, blkoff_t blk, size_t size, struct disk_param *res) { if (res != NULL) { res->buf = buf; @@ -156,10 +171,13 @@ disk_param_init(uint8_t *buf, blkoff_t blk, size_t size, struct disk_param *res) */ #if !defined(_KERNEL) ssize_t __disk_io(diskid_t id, diskop_t op, const struct disk_param *param); -ssize_t disk_write(diskid_t id, blkoff_t off, const void *buf, size_t len); -ssize_t disk_read(diskid_t id, blkoff_t off, void *buf, size_t len); #endif /* !_KERNEL */ +/* Common disk operations */ +int disk_query(diskid_t id, struct disk_info *res); +ssize_t disk_read(diskid_t id, blkoff_t blk, void *buf, size_t len); +ssize_t disk_write(diskid_t id, blkoff_t blk, const void *buf, size_t len); + #if defined(_KERNEL) /* * Represents a block storage device @@ -173,7 +191,7 @@ ssize_t disk_read(diskid_t id, blkoff_t off, void *buf, size_t len); * @link: TAILQ link */ struct disk { - char name[NAME_MAX]; + char name[DISK_NAME_MAX]; uint32_t cookie; uint16_t bsize; dev_t dev; @@ -185,9 +203,6 @@ struct disk { void *disk_buf_alloc(diskid_t id, size_t len); void disk_buf_free(void *p); -ssize_t disk_read(diskid_t id, blkoff_t blk, void *buf, size_t len); -ssize_t disk_write(diskid_t id, blkoff_t blk, const void *buf, size_t len); - int disk_add(const char *name, dev_t dev, const struct bdevsw *bdev, int flags); int disk_get_id(diskid_t id, struct disk **res); diff --git a/sys/kern/disk_engine.c b/sys/kern/disk_engine.c index a49c15f..1061165 100644 --- a/sys/kern/disk_engine.c +++ b/sys/kern/disk_engine.c @@ -172,6 +172,18 @@ disk_mux_io(diskid_t id, diskop_t opcode, struct disk_param *u_param) param.size ); break; + case DISK_IO_QUERY: + retval = disk_query( + id, + param.buf + ); + + /* Write back info to user program */ + error = copyout(param.buf, param.u_buf, param.size); + if (error < 0) { + retval = error; + } + break; } disk_param_free(¶m); diff --git a/sys/kern/kern_disk.c b/sys/kern/kern_disk.c index 5c09c81..a3fa05e 100644 --- a/sys/kern/kern_disk.c +++ b/sys/kern/kern_disk.c @@ -433,3 +433,43 @@ disk_write(diskid_t id, blkoff_t blk, const void *buf, size_t len) disk_buf_free(tmp); return retval; } + +/* + * Attempt to request attributes from a specific + * device. + * + * @id: ID of disk to query + * @res: Resulting information goes here + * + * This function returns zero on success, otherwise + * a less than zero value is returned. + */ +int +disk_query(diskid_t id, struct disk_info *res) +{ + const struct bdevsw *bdev; + struct disk *dp; + int error; + + if (res == NULL) { + return -EINVAL; + } + + /* Attempt to grab the disk */ + error = disk_get_id(id, &dp); + if (error < 0) { + pr_error("disk_query: bad disk ID %d\n", id); + return error; + } + + bdev = dp->bdev; + if (__unlikely(bdev == NULL)) { + pr_error("disk_query: no bdev for disk %d\n", id); + return -EIO; + } + + res->block_size = dp->bsize; + res->vblock_size = V_BSIZE; + res->n_block = bdev->bsize(dp->dev); + return 0; +} |