diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-01-20 19:37:28 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-01-20 19:37:28 -0500 |
commit | 67290f41b2715de0e0ae93c9285fcbe37ffc5b22 (patch) | |
tree | 246c05858e243f24c41810ab3a38b7980e3ae5e7 /drivers/xen/xenfs | |
parent | 5cdec1fca2ff128ca0716dc1ef0fc0043e4ae8ab (diff) | |
parent | 6a5b3beff916a19e7672f8c0330b4f82ed367be2 (diff) |
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
Diffstat (limited to 'drivers/xen/xenfs')
-rw-r--r-- | drivers/xen/xenfs/xenbus.c | 31 |
1 files changed, 13 insertions, 18 deletions
diff --git a/drivers/xen/xenfs/xenbus.c b/drivers/xen/xenfs/xenbus.c index 1c1236087f78..bbd000f88af7 100644 --- a/drivers/xen/xenfs/xenbus.c +++ b/drivers/xen/xenfs/xenbus.c | |||
@@ -122,6 +122,7 @@ static ssize_t xenbus_file_read(struct file *filp, | |||
122 | int ret; | 122 | int ret; |
123 | 123 | ||
124 | mutex_lock(&u->reply_mutex); | 124 | mutex_lock(&u->reply_mutex); |
125 | again: | ||
125 | while (list_empty(&u->read_buffers)) { | 126 | while (list_empty(&u->read_buffers)) { |
126 | mutex_unlock(&u->reply_mutex); | 127 | mutex_unlock(&u->reply_mutex); |
127 | if (filp->f_flags & O_NONBLOCK) | 128 | if (filp->f_flags & O_NONBLOCK) |
@@ -144,7 +145,7 @@ static ssize_t xenbus_file_read(struct file *filp, | |||
144 | i += sz - ret; | 145 | i += sz - ret; |
145 | rb->cons += sz - ret; | 146 | rb->cons += sz - ret; |
146 | 147 | ||
147 | if (ret != sz) { | 148 | if (ret != 0) { |
148 | if (i == 0) | 149 | if (i == 0) |
149 | i = -EFAULT; | 150 | i = -EFAULT; |
150 | goto out; | 151 | goto out; |
@@ -160,6 +161,8 @@ static ssize_t xenbus_file_read(struct file *filp, | |||
160 | struct read_buffer, list); | 161 | struct read_buffer, list); |
161 | } | 162 | } |
162 | } | 163 | } |
164 | if (i == 0) | ||
165 | goto again; | ||
163 | 166 | ||
164 | out: | 167 | out: |
165 | mutex_unlock(&u->reply_mutex); | 168 | mutex_unlock(&u->reply_mutex); |
@@ -407,6 +410,7 @@ static int xenbus_write_watch(unsigned msg_type, struct xenbus_file_priv *u) | |||
407 | 410 | ||
408 | mutex_lock(&u->reply_mutex); | 411 | mutex_lock(&u->reply_mutex); |
409 | rc = queue_reply(&u->read_buffers, &reply, sizeof(reply)); | 412 | rc = queue_reply(&u->read_buffers, &reply, sizeof(reply)); |
413 | wake_up(&u->read_waitq); | ||
410 | mutex_unlock(&u->reply_mutex); | 414 | mutex_unlock(&u->reply_mutex); |
411 | } | 415 | } |
412 | 416 | ||
@@ -455,7 +459,7 @@ static ssize_t xenbus_file_write(struct file *filp, | |||
455 | 459 | ||
456 | ret = copy_from_user(u->u.buffer + u->len, ubuf, len); | 460 | ret = copy_from_user(u->u.buffer + u->len, ubuf, len); |
457 | 461 | ||
458 | if (ret == len) { | 462 | if (ret != 0) { |
459 | rc = -EFAULT; | 463 | rc = -EFAULT; |
460 | goto out; | 464 | goto out; |
461 | } | 465 | } |
@@ -488,21 +492,6 @@ static ssize_t xenbus_file_write(struct file *filp, | |||
488 | msg_type = u->u.msg.type; | 492 | msg_type = u->u.msg.type; |
489 | 493 | ||
490 | switch (msg_type) { | 494 | switch (msg_type) { |
491 | case XS_TRANSACTION_START: | ||
492 | case XS_TRANSACTION_END: | ||
493 | case XS_DIRECTORY: | ||
494 | case XS_READ: | ||
495 | case XS_GET_PERMS: | ||
496 | case XS_RELEASE: | ||
497 | case XS_GET_DOMAIN_PATH: | ||
498 | case XS_WRITE: | ||
499 | case XS_MKDIR: | ||
500 | case XS_RM: | ||
501 | case XS_SET_PERMS: | ||
502 | /* Send out a transaction */ | ||
503 | ret = xenbus_write_transaction(msg_type, u); | ||
504 | break; | ||
505 | |||
506 | case XS_WATCH: | 495 | case XS_WATCH: |
507 | case XS_UNWATCH: | 496 | case XS_UNWATCH: |
508 | /* (Un)Ask for some path to be watched for changes */ | 497 | /* (Un)Ask for some path to be watched for changes */ |
@@ -510,7 +499,8 @@ static ssize_t xenbus_file_write(struct file *filp, | |||
510 | break; | 499 | break; |
511 | 500 | ||
512 | default: | 501 | default: |
513 | ret = -EINVAL; | 502 | /* Send out a transaction */ |
503 | ret = xenbus_write_transaction(msg_type, u); | ||
514 | break; | 504 | break; |
515 | } | 505 | } |
516 | if (ret != 0) | 506 | if (ret != 0) |
@@ -555,6 +545,7 @@ static int xenbus_file_release(struct inode *inode, struct file *filp) | |||
555 | struct xenbus_file_priv *u = filp->private_data; | 545 | struct xenbus_file_priv *u = filp->private_data; |
556 | struct xenbus_transaction_holder *trans, *tmp; | 546 | struct xenbus_transaction_holder *trans, *tmp; |
557 | struct watch_adapter *watch, *tmp_watch; | 547 | struct watch_adapter *watch, *tmp_watch; |
548 | struct read_buffer *rb, *tmp_rb; | ||
558 | 549 | ||
559 | /* | 550 | /* |
560 | * No need for locking here because there are no other users, | 551 | * 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) | |||
573 | free_watch_adapter(watch); | 564 | free_watch_adapter(watch); |
574 | } | 565 | } |
575 | 566 | ||
567 | list_for_each_entry_safe(rb, tmp_rb, &u->read_buffers, list) { | ||
568 | list_del(&rb->list); | ||
569 | kfree(rb); | ||
570 | } | ||
576 | kfree(u); | 571 | kfree(u); |
577 | 572 | ||
578 | return 0; | 573 | return 0; |