# HG changeset patch
# User Jake Wires <jwires@xxxxxxxxxxxxx>
# Date 1172280367 28800
# Node ID e9bd3267ff237c4435c14aada17397230b42b377
# Parent 5ba3037ea5e11bd578ca12439ee8b4f659fa866f
[TAPDISK] honor read-only attributes when creating tap-based VBDs
Signed-off-by: Jake Wires <jwires@xxxxxxxxxxxxx>
---
tools/blktap/drivers/blktapctrl.c | 2 -
tools/blktap/drivers/block-qcow.c | 2 -
tools/blktap/drivers/tapdisk.c | 40 +++++++++++++++++++++++++++-----------
tools/blktap/drivers/tapdisk.h | 1
tools/blktap/lib/blktaplib.h | 1
tools/blktap/lib/xenbus.c | 7 ++++--
6 files changed, 38 insertions(+), 15 deletions(-)
diff -r 5ba3037ea5e1 -r e9bd3267ff23 tools/blktap/drivers/blktapctrl.c
--- a/tools/blktap/drivers/blktapctrl.c Fri Feb 23 09:40:32 2007 -0800
+++ b/tools/blktap/drivers/blktapctrl.c Fri Feb 23 17:26:07 2007 -0800
@@ -303,6 +303,7 @@ static int write_msg(int fd, int msgtype
msg->type = CTLMSG_PARAMS;
msg->len = msglen;
msg->drivertype = blkif->drivertype;
+ msg->readonly = blkif->readonly;
gettimeofday(&timeout, NULL);
msg->cookie = blkif->cookie;
@@ -410,7 +411,6 @@ static int read_msg(int fd, int msgtype,
if (select(fd+1, &readfds, (fd_set *) 0,
(fd_set *) 0, &timeout) > 0) {
ret = read(fd, buf, msglen);
-
}
if (ret > 0) {
msg = (msg_hdr_t *)buf;
diff -r 5ba3037ea5e1 -r e9bd3267ff23 tools/blktap/drivers/block-qcow.c
--- a/tools/blktap/drivers/block-qcow.c Fri Feb 23 09:40:32 2007 -0800
+++ b/tools/blktap/drivers/block-qcow.c Fri Feb 23 17:26:07 2007 -0800
@@ -422,7 +422,7 @@ static int qtruncate(int fd, off_t lengt
return -1;
if (S_ISBLK(st.st_mode))
return 0;
-
+
sectors = (length + DEFAULT_SECTOR_SIZE - 1)/DEFAULT_SECTOR_SIZE;
current = (st.st_size + DEFAULT_SECTOR_SIZE - 1)/DEFAULT_SECTOR_SIZE;
rem = st.st_size % DEFAULT_SECTOR_SIZE;
diff -r 5ba3037ea5e1 -r e9bd3267ff23 tools/blktap/drivers/tapdisk.c
--- a/tools/blktap/drivers/tapdisk.c Fri Feb 23 09:40:32 2007 -0800
+++ b/tools/blktap/drivers/tapdisk.c Fri Feb 23 17:26:07 2007 -0800
@@ -268,7 +268,8 @@ static int map_new_dev(struct td_state *
}
static struct disk_driver *disk_init(struct td_state *s,
- struct tap_disk *drv, char *name)
+ struct tap_disk *drv,
+ char *name, td_flag_t flags)
{
struct disk_driver *dd;
@@ -285,14 +286,17 @@ static struct disk_driver *disk_init(str
dd->drv = drv;
dd->td_state = s;
dd->name = name;
+ dd->flags = flags;
return dd;
}
-static int open_disk(struct td_state *s, struct tap_disk *drv, char *path)
+static int open_disk(struct td_state *s,
+ struct tap_disk *drv, char *path, td_flag_t flags)
{
int err;
char *dup;
+ td_flag_t pflags;
struct disk_id id;
struct disk_driver *d;
@@ -301,16 +305,17 @@ static int open_disk(struct td_state *s,
return -ENOMEM;
memset(&id, 0, sizeof(struct disk_id));
- s->disks = d = disk_init(s, drv, dup);
+ s->disks = d = disk_init(s, drv, dup, flags);
if (!d)
return -ENOMEM;
- err = drv->td_open(d, path, 0);
+ err = drv->td_open(d, path, flags);
if (err) {
free_driver(d);
s->disks = NULL;
return -ENOMEM;
}
+ pflags = flags | TD_RDONLY;
/* load backing files as necessary */
while ((err = d->drv->td_get_parent_id(d, &id)) == 0) {
@@ -324,11 +329,11 @@ static int open_disk(struct td_state *s,
if (!dup)
goto fail;
- new = disk_init(s, get_driver(id.drivertype), dup);
+ new = disk_init(s, get_driver(id.drivertype), dup, pflags);
if (!new)
goto fail;
- err = new->drv->td_open(new, new->name, TD_RDONLY);
+ err = new->drv->td_open(new, new->name, pflags);
if (err)
goto fail;
@@ -341,6 +346,8 @@ static int open_disk(struct td_state *s,
d = d->next = new;
free(id.name);
}
+
+ s->info |= ((flags & TD_RDONLY) ? VDISK_READONLY : 0);
if (err >= 0)
return 0;
@@ -404,7 +411,8 @@ static int read_msg(char *buf)
goto params_done;
/*Open file*/
- ret = open_disk(s, drv, path);
+ ret = open_disk(s, drv, path,
+ ((msg->readonly) ? TD_RDONLY : 0));
if (ret)
goto params_done;
@@ -510,7 +518,8 @@ void io_done(struct disk_driver *dd, int
if (!run) return; /*We have received signal to close*/
- if (drv->td_do_callbacks(dd, sid) > 0) kick_responses(dd->td_state);
+ if (sid > MAX_IOFD || drv->td_do_callbacks(dd, sid) > 0)
+ kick_responses(dd->td_state);
return;
}
@@ -659,6 +668,12 @@ static void get_io_request(struct td_sta
blkif->pending_list[idx].status = BLKIF_RSP_OKAY;
blkif->pending_list[idx].submitting = 1;
sector_nr = req->sector_number;
+ }
+
+ if ((dd->flags & TD_RDONLY) &&
+ (req->operation == BLKIF_OP_WRITE)) {
+ blkif->pending_list[idx].status = BLKIF_RSP_ERROR;
+ goto send_response;
}
for (i = start_seg; i < req->nr_segments; i++) {
@@ -726,10 +741,12 @@ static void get_io_request(struct td_sta
}
sector_nr += nsects;
}
+ send_response:
blkif->pending_list[idx].submitting = 0;
/* force write_rsp_to_ring for synchronous case */
if (blkif->pending_list[idx].secs_pending == 0)
- dd->early += send_responses(dd, 0, 0, 0, idx, (void
*)0);
+ dd->early += send_responses(dd, 0, 0, 0, idx,
+ (void *)(long)0);
}
out:
@@ -737,7 +754,7 @@ static void get_io_request(struct td_sta
td_for_each_disk(s, dd) {
dd->early += dd->drv->td_submit(dd);
if (dd->early > 0) {
- io_done(dd, 10);
+ io_done(dd, MAX_IOFD + 1);
dd->early = 0;
}
}
@@ -820,7 +837,8 @@ int main(int argc, char *argv[])
dd->early +=
dd->drv->td_submit(dd);
if (dd->early > 0) {
- io_done(dd, 10);
+ io_done(dd,
+ MAX_IOFD + 1);
dd->early = 0;
}
}
diff -r 5ba3037ea5e1 -r e9bd3267ff23 tools/blktap/drivers/tapdisk.h
--- a/tools/blktap/drivers/tapdisk.h Fri Feb 23 09:40:32 2007 -0800
+++ b/tools/blktap/drivers/tapdisk.h Fri Feb 23 17:26:07 2007 -0800
@@ -94,6 +94,7 @@ struct disk_driver {
int early;
char *name;
void *private;
+ td_flag_t flags;
int io_fd[MAX_IOFD];
struct tap_disk *drv;
struct td_state *td_state;
diff -r 5ba3037ea5e1 -r e9bd3267ff23 tools/blktap/lib/blktaplib.h
--- a/tools/blktap/lib/blktaplib.h Fri Feb 23 09:40:32 2007 -0800
+++ b/tools/blktap/lib/blktaplib.h Fri Feb 23 17:26:07 2007 -0800
@@ -173,6 +173,7 @@ typedef struct msg_hdr {
uint16_t len;
uint16_t drivertype;
uint16_t cookie;
+ uint8_t readonly;
} msg_hdr_t;
typedef struct msg_newdev {
diff -r 5ba3037ea5e1 -r e9bd3267ff23 tools/blktap/lib/xenbus.c
--- a/tools/blktap/lib/xenbus.c Fri Feb 23 09:40:32 2007 -0800
+++ b/tools/blktap/lib/xenbus.c Fri Feb 23 17:26:07 2007 -0800
@@ -177,8 +177,11 @@ static void ueblktap_setup(struct xs_han
}
/* Check to see if device is to be opened read-only. */
- asprintf(&path, "%s/%s", bepath, "read-only");
- if (xs_exists(h, path))
+ deverr = xs_gather(h, bepath, "mode", NULL, &path, NULL);
+ if (deverr) {
+ DPRINTF("ERROR: could not find read/write mode\n");
+ goto fail;
+ } else if (path[0] == 'r')
be->readonly = 1;
if (be->blkif == NULL) {
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|