Merge branch 'xen/xenbus' of git://git.kernel.org/pub/scm/linux/kernel/git/jeremy/xen
authorLinus Torvalds <torvalds@linux-foundation.org>
Fri, 21 Jan 2011 00:37:28 +0000 (16:37 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Fri, 21 Jan 2011 00:37:28 +0000 (16:37 -0800)
* '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

1  2 
drivers/xen/xenfs/xenbus.c

@@@ -43,7 -43,6 +43,7 @@@
  #include <linux/fs.h>
  #include <linux/poll.h>
  #include <linux/mutex.h>
 +#include <linux/sched.h>
  #include <linux/spinlock.h>
  #include <linux/mount.h>
  #include <linux/pagemap.h>
@@@ -51,7 -50,6 +51,7 @@@
  #include <linux/init.h>
  #include <linux/namei.h>
  #include <linux/string.h>
 +#include <linux/slab.h>
  
  #include "xenfs.h"
  #include "../xenbus/xenbus_comms.h"
@@@ -122,6 -120,7 +122,7 @@@ static ssize_t xenbus_file_read(struct 
        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)
                i += sz - ret;
                rb->cons += sz - ret;
  
-               if (ret != sz) {
+               if (ret != 0) {
                        if (i == 0)
                                i = -EFAULT;
                        goto out;
                                        struct read_buffer, list);
                }
        }
+       if (i == 0)
+               goto again;
  
  out:
        mutex_unlock(&u->reply_mutex);
@@@ -407,6 -408,7 +410,7 @@@ static int xenbus_write_watch(unsigned 
  
                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 -457,7 +459,7 @@@ static ssize_t xenbus_file_write(struc
  
        ret = copy_from_user(u->u.buffer + u->len, ubuf, len);
  
-       if (ret == len) {
+       if (ret != 0) {
                rc = -EFAULT;
                goto out;
        }
        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 */
                break;
  
        default:
-               ret = -EINVAL;
+               /* Send out a transaction */
+               ret = xenbus_write_transaction(msg_type, u);
                break;
        }
        if (ret != 0)
@@@ -555,6 -543,7 +545,7 @@@ static int xenbus_file_release(struct i
        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,
                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;
@@@ -594,5 -587,4 +589,5 @@@ const struct file_operations xenbus_fil
        .open = xenbus_file_open,
        .release = xenbus_file_release,
        .poll = xenbus_file_poll,
 +      .llseek = no_llseek,
  };