Skip to content

Commit

Permalink
Merge branch 'xen/xenbus' of git://git.kernel.org/pub/scm/linux/kerne…
Browse files Browse the repository at this point in the history
…l/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
  • Loading branch information
Linus Torvalds committed Jan 21, 2011
2 parents 5cdec1f + 6a5b3be commit 67290f4
Showing 1 changed file with 13 additions and 18 deletions.
31 changes: 13 additions & 18 deletions drivers/xen/xenfs/xenbus.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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;
Expand All @@ -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);
Expand Down Expand Up @@ -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);
}

Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -488,29 +492,15 @@ 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 */
ret = xenbus_write_watch(msg_type, u);
break;

default:
ret = -EINVAL;
/* Send out a transaction */
ret = xenbus_write_transaction(msg_type, u);
break;
}
if (ret != 0)
Expand Down Expand Up @@ -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,
Expand All @@ -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;
Expand Down

0 comments on commit 67290f4

Please sign in to comment.