Merge branch 'xen/xenbus' of git://git.kernel.org/pub/scm/linux/kernel/git/jeremy/xen
* '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
This commit is contained in:
commit
67290f41b2
|
@ -122,6 +122,7 @@ static ssize_t xenbus_file_read(struct file *filp,
|
|||
int ret;
|
||||
|
||||
mutex_lock(&u->reply_mutex);
|
||||
again:
|
||||
while (list_empty(&u->read_buffers)) {
|
||||
mutex_unlock(&u->reply_mutex);
|
||||
if (filp->f_flags & O_NONBLOCK)
|
||||
|
@ -144,7 +145,7 @@ static ssize_t xenbus_file_read(struct file *filp,
|
|||
i += sz - ret;
|
||||
rb->cons += sz - ret;
|
||||
|
||||
if (ret != sz) {
|
||||
if (ret != 0) {
|
||||
if (i == 0)
|
||||
i = -EFAULT;
|
||||
goto out;
|
||||
|
@ -160,6 +161,8 @@ static ssize_t xenbus_file_read(struct file *filp,
|
|||
struct read_buffer, list);
|
||||
}
|
||||
}
|
||||
if (i == 0)
|
||||
goto again;
|
||||
|
||||
out:
|
||||
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);
|
||||
rc = queue_reply(&u->read_buffers, &reply, sizeof(reply));
|
||||
wake_up(&u->read_waitq);
|
||||
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);
|
||||
|
||||
if (ret == len) {
|
||||
if (ret != 0) {
|
||||
rc = -EFAULT;
|
||||
goto out;
|
||||
}
|
||||
|
@ -488,21 +492,6 @@ static ssize_t xenbus_file_write(struct file *filp,
|
|||
msg_type = u->u.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_UNWATCH:
|
||||
/* (Un)Ask for some path to be watched for changes */
|
||||
|
@ -510,7 +499,8 @@ static ssize_t xenbus_file_write(struct file *filp,
|
|||
break;
|
||||
|
||||
default:
|
||||
ret = -EINVAL;
|
||||
/* Send out a transaction */
|
||||
ret = xenbus_write_transaction(msg_type, u);
|
||||
break;
|
||||
}
|
||||
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_transaction_holder *trans, *tmp;
|
||||
struct watch_adapter *watch, *tmp_watch;
|
||||
struct read_buffer *rb, *tmp_rb;
|
||||
|
||||
/*
|
||||
* 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);
|
||||
}
|
||||
|
||||
list_for_each_entry_safe(rb, tmp_rb, &u->read_buffers, list) {
|
||||
list_del(&rb->list);
|
||||
kfree(rb);
|
||||
}
|
||||
kfree(u);
|
||||
|
||||
return 0;
|
||||
|
|
Loading…
Reference in New Issue