#include "tapdisk.h"
#include "tapdisk-driver.h"
#include "tapdisk-interface.h"
+#include "tapdisk-storage.h"
#define MAX_AIO_REQS TAPDISK_DATA_REQUESTS
goto done;
}
+ driver->storage = tapdisk_storage_type(name);
+
prv->fd = fd;
done:
aio->treq = treq;
aio->state = prv;
- td_prep_read(&aio->tiocb, prv->fd, treq.buf,
+ td_prep_read(driver, &aio->tiocb, prv->fd, treq.buf,
size, offset, tdaio_complete, aio);
td_queue_tiocb(driver, &aio->tiocb);
aio->treq = treq;
aio->state = prv;
- td_prep_write(&aio->tiocb, prv->fd, treq.buf,
+ td_prep_write(driver, &aio->tiocb, prv->fd, treq.buf,
size, offset, tdaio_complete, aio);
td_queue_tiocb(driver, &aio->tiocb);
{
struct tiocb *tiocb = &req->tiocb;
- td_prep_read(tiocb, s->vhd.fd, req->treq.buf,
+ td_prep_read(s->driver, tiocb, s->vhd.fd, req->treq.buf,
vhd_sectors_to_bytes(req->treq.secs),
offset, vhd_complete, req);
td_queue_tiocb(s->driver, tiocb);
{
struct tiocb *tiocb = &req->tiocb;
- td_prep_write(tiocb, s->vhd.fd, req->treq.buf,
+ td_prep_write(s->driver, tiocb, s->vhd.fd, req->treq.buf,
vhd_sectors_to_bytes(req->treq.secs),
offset, vhd_complete, req);
td_queue_tiocb(s->driver, tiocb);
req->treq.sec = blk * index->vhdi.spb;
req->treq.secs = block->table_size >> VHD_SECTOR_SHIFT;
- td_prep_read(&req->tiocb, index->vhdi.fd,
+ td_prep_read(index->driver,
+ &req->tiocb, index->vhdi.fd,
(char *)block->vhdi_block.table, block->table_size,
offset, vhd_index_complete_meta_read, req);
td_queue_tiocb(index->driver, &req->tiocb);
req->index = index;
req->off = offset;
- td_prep_read(&req->tiocb, file->fd, treq.buf, size, offset,
+ td_prep_read(index->driver,
+ &req->tiocb, file->fd, treq.buf, size, offset,
vhd_index_complete_data_read, req);
td_queue_tiocb(index->driver, &req->tiocb);
#include <inttypes.h>
#include "io-optimize.h"
+#include "tapdisk-queue.h"
#include "tapdisk-log.h"
#if (!defined(TEST) && defined(DEBUG))
static int
merge(struct opioctx *ctx, struct iocb *head, struct iocb *io)
{
+ struct tiocb *tiocb = head->data;
+ size_t limit = tiocb->merge_limit;
+
if (head->aio_lio_opcode != io->aio_lio_opcode)
return -EINVAL;
if (!contiguous_iocbs(head, io))
return -EINVAL;
+ if (head->u.c.nbytes + io->u.c.nbytes > limit)
+ return -EINVAL;
+
return merge_tail(ctx, head, io);
}
}
void
-td_prep_read(struct tiocb *tiocb, int fd, char *buf, size_t bytes,
+td_prep_read(td_driver_t *driver,
+ struct tiocb *tiocb, int fd, char *buf, size_t bytes,
long long offset, td_queue_callback_t cb, void *arg)
{
- tapdisk_prep_tiocb(tiocb, fd, 0, buf, bytes, offset, cb, arg);
+ tapdisk_prep_tiocb(tiocb, fd, 0, buf, bytes, offset, driver->storage,
+ cb, arg);
}
void
-td_prep_write(struct tiocb *tiocb, int fd, char *buf, size_t bytes,
+td_prep_write(td_driver_t *driver,
+ struct tiocb *tiocb, int fd, char *buf, size_t bytes,
long long offset, td_queue_callback_t cb, void *arg)
{
- tapdisk_prep_tiocb(tiocb, fd, 1, buf, bytes, offset, cb, arg);
+ tapdisk_prep_tiocb(tiocb, fd, 1, buf, bytes, offset, driver->storage,
+ cb, arg);
}
void
void td_debug(td_image_t *);
void td_queue_tiocb(td_driver_t *, struct tiocb *);
-void td_prep_read(struct tiocb *, int, char *, size_t,
+void td_prep_read(td_driver_t *, struct tiocb *, int, char *, size_t,
long long, td_queue_callback_t, void *);
-void td_prep_write(struct tiocb *, int, char *, size_t,
+void td_prep_write(td_driver_t *, struct tiocb *, int, char *, size_t,
long long, td_queue_callback_t, void *);
void td_panic(void) __attribute__((noreturn));
#include "tapdisk-utils.h"
#include "libaio-compat.h"
+#include "blktap2.h"
+#include "tapdisk-storage.h"
#include "atomicio.h"
#define WARN(_f, _a...) tlog_write(TLOG_WARN, _f, ##_a)
void
tapdisk_prep_tiocb(struct tiocb *tiocb, int fd, int rw, char *buf, size_t size,
- long long offset, td_queue_callback_t cb, void *arg)
+ long long offset, int storage, td_queue_callback_t cb, void *arg)
{
struct iocb *iocb = &tiocb->iocb;
iocb->data = tiocb;
tiocb->cb = cb;
tiocb->arg = arg;
+
+ if (storage == TAPDISK_STORAGE_TYPE_EXT) {
+ size_t block_size = 4<<10; /* should query the fs */
+ tiocb->merge_limit = BLKTAP2_BIO_POOL_SIZE * block_size;
+ } else
+ /* contiguous storage:
+ BLKTAP2_BIO_POOL_SIZE * BIO_MAX_PAGES * PAGE_SIZE */
+ tiocb->merge_limit = SIZE_MAX;
}
void
void *arg;
struct iocb iocb;
+ size_t merge_limit;
+
struct list_head entry;
};
int tapdisk_cancel_tiocbs(struct tqueue *);
int tapdisk_cancel_all_tiocbs(struct tqueue *);
void tapdisk_prep_tiocb(struct tiocb *, int, int, char *, size_t,
- long long, td_queue_callback_t, void *);
+ long long, int, td_queue_callback_t, void *);
#endif
#define BLKTAP2_IO_DEVICE BLKTAP2_DIRECTORY"/tapdev"
#define BLKTAP2_ENOSPC_SIGNAL_FILE "/var/run/tapdisk-enospc"
+#define BLKTAP2_BIO_POOL_SIZE 12
+
struct blktap2_handle {
unsigned int ring;
unsigned int device;