summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
Diffstat (limited to 'sys')
-rw-r--r--sys/include/sys/disk.h45
-rw-r--r--sys/kern/disk_engine.c12
-rw-r--r--sys/kern/kern_disk.c40
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(&param);
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;
+}