aboutsummaryrefslogtreecommitdiffstats
path: root/tools/blktap2
diff options
context:
space:
mode:
authorKeir Fraser <keir.fraser@citrix.com>2009-12-17 06:27:57 +0000
committerKeir Fraser <keir.fraser@citrix.com>2009-12-17 06:27:57 +0000
commit4515e6d82b23366933055b0ad60d8ed89f5a2b92 (patch)
treec07557a5b58cadbd0de42669b2ed898b37626e76 /tools/blktap2
parent06d2e6455f6333c7049f72d41f8c89a1a9884e51 (diff)
downloadxen-4515e6d82b23366933055b0ad60d8ed89f5a2b92.tar.gz
xen-4515e6d82b23366933055b0ad60d8ed89f5a2b92.tar.bz2
xen-4515e6d82b23366933055b0ad60d8ed89f5a2b92.zip
Reads from read only parent disk images are intercepted, and are used to detect
potentially sharable memory pages. Signed-off-by: Grzegorz Milos <Grzegorz.Milos@citrix.com>
Diffstat (limited to 'tools/blktap2')
-rw-r--r--tools/blktap2/drivers/Makefile3
-rw-r--r--tools/blktap2/drivers/tapdisk-vbd.c52
-rw-r--r--tools/blktap2/drivers/tapdisk.h2
3 files changed, 54 insertions, 3 deletions
diff --git a/tools/blktap2/drivers/Makefile b/tools/blktap2/drivers/Makefile
index 97f27b56d3..b70ca7ddc0 100644
--- a/tools/blktap2/drivers/Makefile
+++ b/tools/blktap2/drivers/Makefile
@@ -14,6 +14,7 @@ CFLAGS += -Wno-unused
CFLAGS += -fno-strict-aliasing
CFLAGS += -I../lib -I../../libxc
CFLAGS += -I../include -I../../include
+CFLAGS += $(CFLAGS_libxenctrl)
CFLAGS += -I $(LIBAIO_DIR)
CFLAGS += -I $(MEMSHR_DIR)
CFLAGS += -D_GNU_SOURCE
@@ -37,7 +38,7 @@ else
CRYPT_LIB += -lcrypto
endif
-LDFLAGS_img := $(CRYPT_LIB) -lpthread -lz -lm
+LDFLAGS_img := $(LDFLAGS_libxenctrl) $(CRYPT_LIB) -lpthread -lz -lm
LIBS += -L$(LIBVHDDIR) -lvhd
diff --git a/tools/blktap2/drivers/tapdisk-vbd.c b/tools/blktap2/drivers/tapdisk-vbd.c
index 07504cf7da..14507b3830 100644
--- a/tools/blktap2/drivers/tapdisk-vbd.c
+++ b/tools/blktap2/drivers/tapdisk-vbd.c
@@ -1418,11 +1418,26 @@ tapdisk_vbd_complete_vbd_request(td_vbd_t *vbd, td_vbd_request_t *vreq)
}
}
+static uint64_t
+tapdisk_vbd_breq_get_sector(blkif_request_t *breq, td_request_t treq)
+{
+ int seg, nsects;
+ uint64_t sector_nr = breq->sector_number;
+
+ for(seg=0; seg < treq.sidx; seg++) {
+ nsects = breq->seg[seg].last_sect - breq->seg[seg].first_sect + 1;
+ sector_nr += nsects;
+ }
+
+ return sector_nr;
+}
+
static void
__tapdisk_vbd_complete_td_request(td_vbd_t *vbd, td_vbd_request_t *vreq,
td_request_t treq, int res)
{
int err;
+ td_image_t *image = treq.image;
err = (res <= 0 ? res : -res);
vbd->secs_pending -= treq.secs;
@@ -1440,7 +1455,18 @@ __tapdisk_vbd_complete_td_request(td_vbd_t *vbd, td_vbd_request_t *vreq,
(treq.op == TD_OP_WRITE ? "write" : "read"),
treq.secs, treq.sec);
}
- }
+ } else
+ if(treq.op == TD_OP_READ && td_flag_test(image->flags, TD_OPEN_RDONLY)) {
+ uint64_t hnd = treq.memshr_hnd;
+ uint16_t uid = image->memshr_id;
+ blkif_request_t *breq = &vreq->req;
+ uint64_t sec = tapdisk_vbd_breq_get_sector(breq, treq);
+ int secs = breq->seg[treq.sidx].last_sect -
+ breq->seg[treq.sidx].first_sect + 1;
+
+ if(hnd != 0)
+ memshr_vbd_complete_ro_request(hnd, uid, sec, secs);
+ }
tapdisk_vbd_complete_vbd_request(vbd, vreq);
}
@@ -1492,7 +1518,29 @@ __tapdisk_vbd_reissue_td_request(td_vbd_t *vbd,
break;
case TD_OP_READ:
- td_queue_read(parent, treq);
+ if(td_flag_test(parent->flags, TD_OPEN_RDONLY))
+ {
+ int ret, seg = treq.sidx;
+ blkif_request_t *breq = &vreq->req;
+
+ ret = memshr_vbd_issue_ro_request(treq.buf,
+ breq->seg[seg].gref,
+ parent->memshr_id,
+ treq.sec,
+ treq.secs,
+ &treq.memshr_hnd);
+ if(ret == 0)
+ {
+ /* Reset memshr handle. This'll prevent
+ * memshr_vbd_complete_ro_request being called */
+ treq.memshr_hnd = 0;
+ td_complete_request(treq, 0);
+ }
+ else
+ td_queue_read(parent, treq);
+ }
+ else
+ td_queue_read(parent, treq);
break;
}
diff --git a/tools/blktap2/drivers/tapdisk.h b/tools/blktap2/drivers/tapdisk.h
index b1a91c77f2..bd6835e5e8 100644
--- a/tools/blktap2/drivers/tapdisk.h
+++ b/tools/blktap2/drivers/tapdisk.h
@@ -131,6 +131,8 @@ struct td_request {
uint64_t id;
int sidx;
void *private;
+
+ uint64_t memshr_hnd;
};
/*