direct-io.hg

changeset 14095:e9bd3267ff23

[TAPDISK] honor read-only attributes when creating tap-based VBDs
Signed-off-by: Jake Wires <jwires@xensource.com>
author Jake Wires <jwires@xensource.com>
date Fri Feb 23 17:26:07 2007 -0800 (2007-02-23)
parents 5ba3037ea5e1
children 8afe591c272b
files tools/blktap/drivers/blktapctrl.c tools/blktap/drivers/block-qcow.c tools/blktap/drivers/tapdisk.c tools/blktap/drivers/tapdisk.h tools/blktap/lib/blktaplib.h tools/blktap/lib/xenbus.c
line diff
     1.1 --- a/tools/blktap/drivers/blktapctrl.c	Fri Feb 23 09:40:32 2007 -0800
     1.2 +++ b/tools/blktap/drivers/blktapctrl.c	Fri Feb 23 17:26:07 2007 -0800
     1.3 @@ -303,6 +303,7 @@ static int write_msg(int fd, int msgtype
     1.4  		msg->type = CTLMSG_PARAMS;
     1.5  		msg->len = msglen;
     1.6  		msg->drivertype = blkif->drivertype;
     1.7 +		msg->readonly = blkif->readonly;
     1.8  
     1.9  		gettimeofday(&timeout, NULL);
    1.10  		msg->cookie = blkif->cookie;
    1.11 @@ -410,7 +411,6 @@ static int read_msg(int fd, int msgtype,
    1.12  	if (select(fd+1, &readfds,  (fd_set *) 0,
    1.13  		  (fd_set *) 0, &timeout) > 0) {
    1.14  		ret = read(fd, buf, msglen);
    1.15 -		
    1.16  	}			
    1.17  	if (ret > 0) {
    1.18  		msg = (msg_hdr_t *)buf;
     2.1 --- a/tools/blktap/drivers/block-qcow.c	Fri Feb 23 09:40:32 2007 -0800
     2.2 +++ b/tools/blktap/drivers/block-qcow.c	Fri Feb 23 17:26:07 2007 -0800
     2.3 @@ -422,7 +422,7 @@ static int qtruncate(int fd, off_t lengt
     2.4  		return -1;
     2.5  	if (S_ISBLK(st.st_mode))
     2.6  		return 0;
     2.7 -	
     2.8 +
     2.9  	sectors = (length + DEFAULT_SECTOR_SIZE - 1)/DEFAULT_SECTOR_SIZE;
    2.10  	current = (st.st_size + DEFAULT_SECTOR_SIZE - 1)/DEFAULT_SECTOR_SIZE;
    2.11  	rem     = st.st_size % DEFAULT_SECTOR_SIZE;
     3.1 --- a/tools/blktap/drivers/tapdisk.c	Fri Feb 23 09:40:32 2007 -0800
     3.2 +++ b/tools/blktap/drivers/tapdisk.c	Fri Feb 23 17:26:07 2007 -0800
     3.3 @@ -268,7 +268,8 @@ static int map_new_dev(struct td_state *
     3.4  }
     3.5  
     3.6  static struct disk_driver *disk_init(struct td_state *s, 
     3.7 -				     struct tap_disk *drv, char *name)
     3.8 +				     struct tap_disk *drv, 
     3.9 +				     char *name, td_flag_t flags)
    3.10  {
    3.11  	struct disk_driver *dd;
    3.12  
    3.13 @@ -285,14 +286,17 @@ static struct disk_driver *disk_init(str
    3.14  	dd->drv      = drv;
    3.15  	dd->td_state = s;
    3.16  	dd->name     = name;
    3.17 +	dd->flags    = flags;
    3.18  
    3.19  	return dd;
    3.20  }
    3.21  
    3.22 -static int open_disk(struct td_state *s, struct tap_disk *drv, char *path)
    3.23 +static int open_disk(struct td_state *s, 
    3.24 +		     struct tap_disk *drv, char *path, td_flag_t flags)
    3.25  {
    3.26  	int err;
    3.27  	char *dup;
    3.28 +	td_flag_t pflags;
    3.29  	struct disk_id id;
    3.30  	struct disk_driver *d;
    3.31  
    3.32 @@ -301,16 +305,17 @@ static int open_disk(struct td_state *s,
    3.33  		return -ENOMEM;
    3.34  
    3.35  	memset(&id, 0, sizeof(struct disk_id));
    3.36 -	s->disks = d = disk_init(s, drv, dup);
    3.37 +	s->disks = d = disk_init(s, drv, dup, flags);
    3.38  	if (!d)
    3.39  		return -ENOMEM;
    3.40  
    3.41 -	err = drv->td_open(d, path, 0);
    3.42 +	err = drv->td_open(d, path, flags);
    3.43  	if (err) {
    3.44  		free_driver(d);
    3.45  		s->disks = NULL;
    3.46  		return -ENOMEM;
    3.47  	}
    3.48 +	pflags = flags | TD_RDONLY;
    3.49  
    3.50  	/* load backing files as necessary */
    3.51  	while ((err = d->drv->td_get_parent_id(d, &id)) == 0) {
    3.52 @@ -324,11 +329,11 @@ static int open_disk(struct td_state *s,
    3.53  		if (!dup)
    3.54  			goto fail;
    3.55  
    3.56 -		new = disk_init(s, get_driver(id.drivertype), dup);
    3.57 +		new = disk_init(s, get_driver(id.drivertype), dup, pflags);
    3.58  		if (!new)
    3.59  			goto fail;
    3.60  
    3.61 -		err = new->drv->td_open(new, new->name, TD_RDONLY);
    3.62 +		err = new->drv->td_open(new, new->name, pflags);
    3.63  		if (err)
    3.64  			goto fail;
    3.65  
    3.66 @@ -342,6 +347,8 @@ static int open_disk(struct td_state *s,
    3.67  		free(id.name);
    3.68  	}
    3.69  
    3.70 +	s->info |= ((flags & TD_RDONLY) ? VDISK_READONLY : 0);
    3.71 +
    3.72  	if (err >= 0)
    3.73  		return 0;
    3.74  
    3.75 @@ -404,7 +411,8 @@ static int read_msg(char *buf)
    3.76  				goto params_done;
    3.77  
    3.78  			/*Open file*/
    3.79 -			ret = open_disk(s, drv, path);
    3.80 +			ret = open_disk(s, drv, path, 
    3.81 +					((msg->readonly) ? TD_RDONLY : 0));
    3.82  			if (ret)
    3.83  				goto params_done;
    3.84  
    3.85 @@ -510,7 +518,8 @@ void io_done(struct disk_driver *dd, int
    3.86  
    3.87  	if (!run) return; /*We have received signal to close*/
    3.88  
    3.89 -	if (drv->td_do_callbacks(dd, sid) > 0) kick_responses(dd->td_state);
    3.90 +	if (sid > MAX_IOFD || drv->td_do_callbacks(dd, sid) > 0)
    3.91 +		kick_responses(dd->td_state);
    3.92  
    3.93  	return;
    3.94  }
    3.95 @@ -661,6 +670,12 @@ static void get_io_request(struct td_sta
    3.96  			sector_nr = req->sector_number;
    3.97  		}
    3.98  
    3.99 +		if ((dd->flags & TD_RDONLY) && 
   3.100 +		    (req->operation == BLKIF_OP_WRITE)) {
   3.101 +			blkif->pending_list[idx].status = BLKIF_RSP_ERROR;
   3.102 +			goto send_response;
   3.103 +		}
   3.104 +
   3.105  		for (i = start_seg; i < req->nr_segments; i++) {
   3.106  			nsects = req->seg[i].last_sect - 
   3.107  				 req->seg[i].first_sect + 1;
   3.108 @@ -726,10 +741,12 @@ static void get_io_request(struct td_sta
   3.109  			}
   3.110  			sector_nr += nsects;
   3.111  		}
   3.112 +	send_response:
   3.113  		blkif->pending_list[idx].submitting = 0;
   3.114  		/* force write_rsp_to_ring for synchronous case */
   3.115  		if (blkif->pending_list[idx].secs_pending == 0)
   3.116 -			dd->early += send_responses(dd, 0, 0, 0, idx, (void *)0);
   3.117 +			dd->early += send_responses(dd, 0, 0, 0, idx, 
   3.118 +						    (void *)(long)0);
   3.119  	}
   3.120  
   3.121   out:
   3.122 @@ -737,7 +754,7 @@ static void get_io_request(struct td_sta
   3.123  	td_for_each_disk(s, dd) {
   3.124  		dd->early += dd->drv->td_submit(dd);
   3.125  		if (dd->early > 0) {
   3.126 -			io_done(dd, 10);
   3.127 +			io_done(dd, MAX_IOFD + 1);
   3.128  			dd->early = 0;
   3.129  		}
   3.130  	}
   3.131 @@ -820,7 +837,8 @@ int main(int argc, char *argv[])
   3.132  						dd->early += 
   3.133  							dd->drv->td_submit(dd);
   3.134  						if (dd->early > 0) {
   3.135 -							io_done(dd, 10);
   3.136 +							io_done(dd, 
   3.137 +								MAX_IOFD + 1);
   3.138  							dd->early = 0;
   3.139  						}
   3.140  					}
     4.1 --- a/tools/blktap/drivers/tapdisk.h	Fri Feb 23 09:40:32 2007 -0800
     4.2 +++ b/tools/blktap/drivers/tapdisk.h	Fri Feb 23 17:26:07 2007 -0800
     4.3 @@ -94,6 +94,7 @@ struct disk_driver {
     4.4  	int early;
     4.5  	char *name;
     4.6  	void *private;
     4.7 +	td_flag_t flags;
     4.8  	int io_fd[MAX_IOFD];
     4.9  	struct tap_disk *drv;
    4.10  	struct td_state *td_state;
     5.1 --- a/tools/blktap/lib/blktaplib.h	Fri Feb 23 09:40:32 2007 -0800
     5.2 +++ b/tools/blktap/lib/blktaplib.h	Fri Feb 23 17:26:07 2007 -0800
     5.3 @@ -173,6 +173,7 @@ typedef struct msg_hdr {
     5.4  	uint16_t   len;
     5.5  	uint16_t   drivertype;
     5.6  	uint16_t   cookie;
     5.7 +	uint8_t    readonly;
     5.8  } msg_hdr_t;
     5.9  
    5.10  typedef struct msg_newdev {
     6.1 --- a/tools/blktap/lib/xenbus.c	Fri Feb 23 09:40:32 2007 -0800
     6.2 +++ b/tools/blktap/lib/xenbus.c	Fri Feb 23 17:26:07 2007 -0800
     6.3 @@ -177,8 +177,11 @@ static void ueblktap_setup(struct xs_han
     6.4  	}
     6.5  
     6.6  	/* Check to see if device is to be opened read-only. */
     6.7 -	asprintf(&path, "%s/%s", bepath, "read-only");
     6.8 -	if (xs_exists(h, path))
     6.9 +	deverr = xs_gather(h, bepath, "mode", NULL, &path, NULL);
    6.10 +	if (deverr) {
    6.11 +		DPRINTF("ERROR: could not find read/write mode\n");
    6.12 +		goto fail;
    6.13 +	} else if (path[0] == 'r')
    6.14  		be->readonly = 1;
    6.15  
    6.16  	if (be->blkif == NULL) {