diff --git a/mars_device_sio.c b/mars_device_sio.c index 68b8f8c3..ed7699f1 100644 --- a/mars_device_sio.c +++ b/mars_device_sio.c @@ -244,6 +244,22 @@ static void device_sio_ref_io(struct device_sio_output *output, struct mars_ref_ int test; if (unlikely(!output->filp)) { + cb->cb_error = -EINVAL; + goto done; + } + + /* Shortcut when possible + */ + if (S_ISBLK(output->filp->f_mapping->host->i_mode) && output->allow_bio) { + struct block_device *bdev = output->filp->f_mapping->host->i_bdev; +#if 0 + static int count = 10; + if (count-- > 0) + MARS_INF("AHA: %p\n", bdev); +#endif + bio->bi_bdev = bdev; + submit_bio(bio->bi_rw, bio); + return; } if (barrier) { @@ -251,11 +267,6 @@ static void device_sio_ref_io(struct device_sio_output *output, struct mars_ref_ sync_file(output); } - if (unlikely(!output->filp)) { - cb->cb_error = -EINVAL; - goto done; - } - if (rw == READ) { read_aops(output, mref); } else { @@ -423,6 +434,10 @@ static int device_sio_switch(struct device_sio_brick *brick, bool state) int prot = 0600; mm_segment_t oldfs; + if (output->o_direct) { + flags |= O_DIRECT; + MARS_INF("using O_DIRECT on %s\n", path); + } if (state) { oldfs = get_fs(); set_fs(get_ds()); diff --git a/mars_device_sio.h b/mars_device_sio.h index 512d9702..103a3f50 100644 --- a/mars_device_sio.h +++ b/mars_device_sio.h @@ -28,6 +28,10 @@ struct sio_threadinfo { struct device_sio_output { MARS_OUTPUT(device_sio); + // parameters + bool o_direct; + bool allow_bio; + // private struct file *filp; struct sio_threadinfo tinfo[WITH_THREAD+1]; spinlock_t g_lock; diff --git a/mars_test.c b/mars_test.c index 6af6d0a2..e7ac3ea2 100644 --- a/mars_test.c +++ b/mars_test.c @@ -11,11 +11,12 @@ #define TRANS_BUFFERS (32) #define TRANS_MEM (1024 / 4) -//#define CONF_TEST -#define CONF_BUF -#define CONF_USEBUF -#define CONF_TRANS - +//#define CONF_TEST // use intermediate mars_check bricks +//#define CONF_BUF +//#define CONF_USEBUF +//#define CONF_TRANS +#define CONF_DIRECT // use O_DIRECT +//#define CONF_BIO // submit bios directly to device when possible #include #include @@ -46,10 +47,12 @@ static struct trans_logger_brick *_trans_brick = NULL; static struct generic_brick *tbuf_brick = NULL; static struct buf_brick *_tbuf_brick = NULL; static struct generic_brick *tdevice_brick = NULL; +static struct device_sio_brick *_tdevice_brick = NULL; static struct generic_brick *buf_brick = NULL; static struct buf_brick *_buf_brick = NULL; static struct generic_brick *device_brick = NULL; +static struct device_sio_brick *_device_brick = NULL; static void test_endio(struct generic_callback *cb) { @@ -124,7 +127,14 @@ void make_test_instance(void) MARS_DBG("starting....\n"); device_brick = brick(&device_sio_brick_type); + _device_brick = (void*)device_brick; device_brick->outputs[0]->output_name = "/tmp/testfile.img"; +#ifdef CONF_DIRECT + _device_brick->outputs[0]->o_direct = true; +#endif +#ifdef CONF_BIO + _device_brick->outputs[0]->allow_bio = true; +#endif device_brick->ops->brick_switch(device_brick, true); if_brick = brick(&if_device_brick_type); @@ -158,7 +168,14 @@ void make_test_instance(void) #ifdef CONF_TRANS // trans_logger plus Infrastruktur zwischenschalten tdevice_brick = brick(&device_sio_brick_type); + _tdevice_brick = (void*)tdevice_brick; tdevice_brick->outputs[0]->output_name = "/tmp/testfile.log"; +#ifdef CONF_DIRECT + _tdevice_brick->outputs[0]->o_direct = true; +#endif +#ifdef CONF_BIO + _tdevice_brick->outputs[0]->allow_bio = true; +#endif tdevice_brick->ops->brick_switch(tdevice_brick, true); tbuf_brick = brick(&buf_brick_type);