Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 67290f41 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
* 'xen/xenbus' of git://git.kernel.org/pub/scm/linux/kernel/git/jeremy/xen:
  xenbus: Fix memory leak on release
  xenbus: avoid zero returns from read()
  xenbus: add missing wakeup in concurrent read/write
  xenbus: allow any xenbus command over /proc/xen/xenbus
  xenfs/xenbus: report partial reads/writes correctly
parents 5cdec1fc 6a5b3bef
Loading
Loading
Loading
Loading
+13 −18
Original line number Original line Diff line number Diff line
@@ -122,6 +122,7 @@ static ssize_t xenbus_file_read(struct file *filp,
	int ret;
	int ret;


	mutex_lock(&u->reply_mutex);
	mutex_lock(&u->reply_mutex);
again:
	while (list_empty(&u->read_buffers)) {
	while (list_empty(&u->read_buffers)) {
		mutex_unlock(&u->reply_mutex);
		mutex_unlock(&u->reply_mutex);
		if (filp->f_flags & O_NONBLOCK)
		if (filp->f_flags & O_NONBLOCK)
@@ -144,7 +145,7 @@ static ssize_t xenbus_file_read(struct file *filp,
		i += sz - ret;
		i += sz - ret;
		rb->cons += sz - ret;
		rb->cons += sz - ret;


		if (ret != sz) {
		if (ret != 0) {
			if (i == 0)
			if (i == 0)
				i = -EFAULT;
				i = -EFAULT;
			goto out;
			goto out;
@@ -160,6 +161,8 @@ static ssize_t xenbus_file_read(struct file *filp,
					struct read_buffer, list);
					struct read_buffer, list);
		}
		}
	}
	}
	if (i == 0)
		goto again;


out:
out:
	mutex_unlock(&u->reply_mutex);
	mutex_unlock(&u->reply_mutex);
@@ -407,6 +410,7 @@ static int xenbus_write_watch(unsigned msg_type, struct xenbus_file_priv *u)


		mutex_lock(&u->reply_mutex);
		mutex_lock(&u->reply_mutex);
		rc = queue_reply(&u->read_buffers, &reply, sizeof(reply));
		rc = queue_reply(&u->read_buffers, &reply, sizeof(reply));
		wake_up(&u->read_waitq);
		mutex_unlock(&u->reply_mutex);
		mutex_unlock(&u->reply_mutex);
	}
	}


@@ -455,7 +459,7 @@ static ssize_t xenbus_file_write(struct file *filp,


	ret = copy_from_user(u->u.buffer + u->len, ubuf, len);
	ret = copy_from_user(u->u.buffer + u->len, ubuf, len);


	if (ret == len) {
	if (ret != 0) {
		rc = -EFAULT;
		rc = -EFAULT;
		goto out;
		goto out;
	}
	}
@@ -488,21 +492,6 @@ static ssize_t xenbus_file_write(struct file *filp,
	msg_type = u->u.msg.type;
	msg_type = u->u.msg.type;


	switch (msg_type) {
	switch (msg_type) {
	case XS_TRANSACTION_START:
	case XS_TRANSACTION_END:
	case XS_DIRECTORY:
	case XS_READ:
	case XS_GET_PERMS:
	case XS_RELEASE:
	case XS_GET_DOMAIN_PATH:
	case XS_WRITE:
	case XS_MKDIR:
	case XS_RM:
	case XS_SET_PERMS:
		/* Send out a transaction */
		ret = xenbus_write_transaction(msg_type, u);
		break;

	case XS_WATCH:
	case XS_WATCH:
	case XS_UNWATCH:
	case XS_UNWATCH:
		/* (Un)Ask for some path to be watched for changes */
		/* (Un)Ask for some path to be watched for changes */
@@ -510,7 +499,8 @@ static ssize_t xenbus_file_write(struct file *filp,
		break;
		break;


	default:
	default:
		ret = -EINVAL;
		/* Send out a transaction */
		ret = xenbus_write_transaction(msg_type, u);
		break;
		break;
	}
	}
	if (ret != 0)
	if (ret != 0)
@@ -555,6 +545,7 @@ static int xenbus_file_release(struct inode *inode, struct file *filp)
	struct xenbus_file_priv *u = filp->private_data;
	struct xenbus_file_priv *u = filp->private_data;
	struct xenbus_transaction_holder *trans, *tmp;
	struct xenbus_transaction_holder *trans, *tmp;
	struct watch_adapter *watch, *tmp_watch;
	struct watch_adapter *watch, *tmp_watch;
	struct read_buffer *rb, *tmp_rb;


	/*
	/*
	 * No need for locking here because there are no other users,
	 * No need for locking here because there are no other users,
@@ -573,6 +564,10 @@ static int xenbus_file_release(struct inode *inode, struct file *filp)
		free_watch_adapter(watch);
		free_watch_adapter(watch);
	}
	}


	list_for_each_entry_safe(rb, tmp_rb, &u->read_buffers, list) {
		list_del(&rb->list);
		kfree(rb);
	}
	kfree(u);
	kfree(u);


	return 0;
	return 0;