#include <lunaix/mm/valloc.h>
#include <lunaix/syslog.h>
+#include <lunaix/blkpart_gpt.h>
+
#include <lunaix/spike.h>
#define BLOCK_EREAD 1
{
int errno;
struct block_dev* bdev = (struct block_dev*)dev->underlay;
- size_t bsize = bdev->blk_size, rd_block = offset / bsize,
+ size_t bsize = bdev->blk_size, rd_block = offset / bsize + bdev->start_lba,
r = offset % bsize, rd_size = 0;
if (!(len = MIN(len, ((size_t)bdev->end_lba - rd_block + 1) * bsize))) {
if (r) {
tmp_buf = vzalloc(bsize);
rd_size = MIN(len, bsize - r);
- vbuf->buf.size = rd_size;
+ vbuf->buf.size = bsize;
vbuf->buf.buffer = tmp_buf;
- vbuf_alloc(vbuf, buf + rd_size, len - rd_size);
+ if ((len - rd_size)) {
+ vbuf_alloc(vbuf, buf + rd_size, len - rd_size);
+ }
}
req = blkio_vrd(vbuf, rd_block, NULL, NULL, 0);
pwait(&req->wait);
+ // XXX temporary work-around
+ // in case pwait used in proc0. Need a dummy process!
+ wait_if((req->flags & BLKIO_PENDING));
+
if (!(errno = req->errcode)) {
memcpy(buf, tmp_buf + r, rd_size);
errno = len;
__block_write(struct device* dev, void* buf, size_t offset, size_t len)
{
struct block_dev* bdev = (struct block_dev*)dev->underlay;
- size_t bsize = bdev->blk_size, rd_block = offset / bsize,
+ size_t bsize = bdev->blk_size, rd_block = offset / bsize + bdev->start_lba,
r = offset % bsize;
if (!(len = MIN(len, ((size_t)bdev->end_lba - rd_block + 1) * bsize))) {
pwait(&req->wait);
+ // XXX temporary work-around
+ // in case pwait used in proc0. Need a dummy process!
+ wait_if((req->flags & BLKIO_PENDING));
+
int errno = req->errcode;
if (!errno) {
errno = len;
{
struct block_dev* bdev = cake_grab(lbd_pile);
memset(bdev, 0, sizeof(struct block_dev));
-
+ llist_init_head(&bdev->parts);
strncpy(bdev->name, blk_id, PARTITION_NAME_SIZE);
bdev->blkio = blkio_newctx(ioreq_handler);
goto error;
}
+ errno = blkpart_probegpt(bdev->dev);
+ if (errno < 0) {
+ kprintf(KERROR "Corrupted partition table. (%d)", errno);
+ } else if (!errno) {
+ // TODO try other PT parser...
+ }
+
struct twifs_node* dev_root = twifs_dir_node(blk_sysroot, bdev->bdev_id);
blk_set_blkmapping(bdev, dev_root);
fs_export(bdev, dev_root);
strcpy(bdev->bdev_id, dev->name_val);
dev_registry[free_slot++] = bdev;
return 1;
+}
+
+struct block_dev*
+blk_mount_part(struct block_dev* bdev,
+ const char* name,
+ size_t index,
+ u64_t start_lba,
+ u64_t end_lba)
+{
+ struct block_dev* pbdev = cake_grab(lbd_pile);
+ memcpy(pbdev, bdev, sizeof(*bdev));
+
+ struct device* dev =
+ device_addvol(NULL, pbdev, "%sp%d", bdev->bdev_id, index + 1);
+ dev->write = __block_write;
+ dev->read = __block_read;
+
+ pbdev->start_lba = start_lba;
+ pbdev->end_lba = end_lba;
+ pbdev->dev = dev;
+
+ strcpy(pbdev->bdev_id, dev->name_val);
+ if (name) {
+ strncpy(pbdev->name, name, PARTITION_NAME_SIZE);
+ }
+
+ llist_append(&bdev->parts, &pbdev->parts);
+
+ return pbdev;
}
\ No newline at end of file