direct-io.hg

changeset 14148:b67c253d1cdb

linux: Don't allow partial message raeds from xenstore across
save/restore. This patch is an essential companion to
13519:b4a8000e76db6b4b27341.
Signed-off-by: Keir Fraser <keir@xensource.com>
author kfraser@localhost.localdomain
date Tue Feb 27 13:43:01 2007 +0000 (2007-02-27)
parents 339e477d2548
children 8e3899a4f62d
files linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_comms.c linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_comms.h linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c
line diff
     1.1 --- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_comms.c	Tue Feb 27 11:19:25 2007 +0000
     1.2 +++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_comms.c	Tue Feb 27 13:43:01 2007 +0000
     1.3 @@ -137,6 +137,14 @@ int xb_write(const void *data, unsigned 
     1.4  	return 0;
     1.5  }
     1.6  
     1.7 +int xb_wait_for_data_to_read(void)
     1.8 +{
     1.9 +	struct xenstore_domain_interface *intf = xen_store_interface;
    1.10 +	return wait_event_interruptible(
    1.11 +		xb_waitq,
    1.12 +		intf->rsp_cons != intf->rsp_prod);
    1.13 +}
    1.14 +
    1.15  int xb_read(void *data, unsigned len)
    1.16  {
    1.17  	struct xenstore_domain_interface *intf = xen_store_interface;
    1.18 @@ -147,9 +155,7 @@ int xb_read(void *data, unsigned len)
    1.19  		unsigned int avail;
    1.20  		const char *src;
    1.21  
    1.22 -		rc = wait_event_interruptible(
    1.23 -			xb_waitq,
    1.24 -			intf->rsp_cons != intf->rsp_prod);
    1.25 +		rc = xb_wait_for_data_to_read();
    1.26  		if (rc < 0)
    1.27  			return rc;
    1.28  
     2.1 --- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_comms.h	Tue Feb 27 11:19:25 2007 +0000
     2.2 +++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_comms.h	Tue Feb 27 13:43:01 2007 +0000
     2.3 @@ -37,6 +37,7 @@ int xb_init_comms(void);
     2.4  /* Low level routines. */
     2.5  int xb_write(const void *data, unsigned len);
     2.6  int xb_read(void *data, unsigned len);
     2.7 +int xb_wait_for_data_to_read(void);
     2.8  int xs_input_avail(void);
     2.9  extern struct xenstore_domain_interface *xen_store_interface;
    2.10  extern int xen_store_evtchn;
     3.1 --- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c	Tue Feb 27 11:19:25 2007 +0000
     3.2 +++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c	Tue Feb 27 13:43:01 2007 +0000
     3.3 @@ -150,22 +150,6 @@ static void *read_reply(enum xsd_sockmsg
     3.4  	return body;
     3.5  }
     3.6  
     3.7 -/* Emergency write. */
     3.8 -void xenbus_debug_write(const char *str, unsigned int count)
     3.9 -{
    3.10 -	struct xsd_sockmsg msg = { 0 };
    3.11 -
    3.12 -	msg.type = XS_DEBUG;
    3.13 -	msg.len = sizeof("print") + count + 1;
    3.14 -
    3.15 -	mutex_lock(&xs_state.request_mutex);
    3.16 -	xb_write(&msg, sizeof(msg));
    3.17 -	xb_write("print", sizeof("print"));
    3.18 -	xb_write(str, count);
    3.19 -	xb_write("", 1);
    3.20 -	mutex_unlock(&xs_state.request_mutex);
    3.21 -}
    3.22 -
    3.23  void *xenbus_dev_request_and_reply(struct xsd_sockmsg *msg)
    3.24  {
    3.25  	void *ret;
    3.26 @@ -753,27 +737,38 @@ static int process_msg(void)
    3.27  	char *body;
    3.28  	int err;
    3.29  
    3.30 +	err = xb_wait_for_data_to_read();
    3.31 +	if (err)
    3.32 +	    return err;
    3.33 +
    3.34  	msg = kmalloc(sizeof(*msg), GFP_KERNEL);
    3.35  	if (msg == NULL)
    3.36  		return -ENOMEM;
    3.37  
    3.38 +	/*
    3.39 +	 * We are now committed to reading an entire message. Partial reads
    3.40 +	 * across save/restore leave us out of sync with the xenstore daemon.
    3.41 +	 */
    3.42 +	down_read(&xs_state.suspend_mutex);
    3.43 +
    3.44  	err = xb_read(&msg->hdr, sizeof(msg->hdr));
    3.45  	if (err) {
    3.46  		kfree(msg);
    3.47 -		return err;
    3.48 +		goto out;
    3.49  	}
    3.50  
    3.51  	body = kmalloc(msg->hdr.len + 1, GFP_KERNEL);
    3.52  	if (body == NULL) {
    3.53  		kfree(msg);
    3.54 -		return -ENOMEM;
    3.55 +		err = -ENOMEM;
    3.56 +		goto out;
    3.57  	}
    3.58  
    3.59  	err = xb_read(body, msg->hdr.len);
    3.60  	if (err) {
    3.61  		kfree(body);
    3.62  		kfree(msg);
    3.63 -		return err;
    3.64 +		goto out;
    3.65  	}
    3.66  	body[msg->hdr.len] = '\0';
    3.67  
    3.68 @@ -782,7 +777,8 @@ static int process_msg(void)
    3.69  					 &msg->u.watch.vec_size);
    3.70  		if (IS_ERR(msg->u.watch.vec)) {
    3.71  			kfree(msg);
    3.72 -			return PTR_ERR(msg->u.watch.vec);
    3.73 +			err = PTR_ERR(msg->u.watch.vec);
    3.74 +			goto out;
    3.75  		}
    3.76  
    3.77  		spin_lock(&watches_lock);
    3.78 @@ -806,7 +802,9 @@ static int process_msg(void)
    3.79  		wake_up(&xs_state.reply_waitq);
    3.80  	}
    3.81  
    3.82 -	return 0;
    3.83 + out:
    3.84 +	up_read(&xs_state.suspend_mutex);
    3.85 +	return err;
    3.86  }
    3.87  
    3.88  static int xenbus_thread(void *unused)