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;
|
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;
|
||||||
|
|
Loading…
Reference in New Issue