Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

USB: usblp: "Big cleanup" breaks O_NONBLOCK

I found the first regresson in the rewritten ("all dynamic" and "no races")
driver. If application uses O_NONBLOCK, I return -EAGAIN despite the URB
being submitted successfuly. This causes the application to resubmit the
same data erroneously.

The fix is to pretend that the transfer has succeeded even if URB was
merely queued. It is the same behaviour as with the old version.

Signed-off-by: Pete Zaitcev <zaitcev@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>

authored by

Pete Zaitcev and committed by
Greg Kroah-Hartman
10e48522 9454c46a

+5 -4
+5 -4
drivers/usb/class/usblp.c
··· 741 741 */ 742 742 rv = usblp_wwait(usblp, !!(file->f_flags&O_NONBLOCK)); 743 743 if (rv < 0) { 744 - /* 745 - * If interrupted, we simply leave the URB to dangle, 746 - * so the ->release will call usb_kill_urb(). 747 - */ 744 + if (rv == -EAGAIN) { 745 + /* Presume that it's going to complete well. */ 746 + writecount += transfer_length; 747 + } 748 + /* Leave URB dangling, to be cleaned on close. */ 748 749 goto collect_error; 749 750 } 750 751