提交 3a75ef6a 编写于 作者: P Peter Maydell

Merge remote-tracking branch 'remotes/kraxel/tags/usb-20190307-pull-request' into staging

usb: mtp fixes, guest-reset switch for usb-host.

# gpg: Signature made Thu 07 Mar 2019 09:53:55 GMT
# gpg:                using RSA key 4CB6D8EED3E87138
# gpg: Good signature from "Gerd Hoffmann (work) <kraxel@redhat.com>" [full]
# gpg:                 aka "Gerd Hoffmann <gerd@kraxel.org>" [full]
# gpg:                 aka "Gerd Hoffmann (private) <kraxel@gmail.com>" [full]
# Primary key fingerprint: A032 8CFF B93A 17A7 9901  FE7D 4CB6 D8EE D3E8 7138

* remotes/kraxel/tags/usb-20190307-pull-request:
  Introduce new "no_guest_reset" parameter for usb-host device
  usb-mtp: prevent null dereference while deleting objects
  usb-mtp: fix some usb_mtp_write_data return paths
  usb-mtp: return incomplete transfer on a lstat failure
Signed-off-by: NPeter Maydell <peter.maydell@linaro.org>
...@@ -1177,9 +1177,7 @@ static int usb_mtp_deletefn(MTPState *s, MTPObject *o, uint32_t trans) ...@@ -1177,9 +1177,7 @@ static int usb_mtp_deletefn(MTPState *s, MTPObject *o, uint32_t trans)
usb_mtp_object_free_one(s, o); usb_mtp_object_free_one(s, o);
success = true; success = true;
} }
} } else if (o->format == FMT_ASSOCIATION) {
if (o->format == FMT_ASSOCIATION) {
if (rmdir(o->path)) { if (rmdir(o->path)) {
partial_delete = true; partial_delete = true;
} else { } else {
...@@ -1591,17 +1589,21 @@ done: ...@@ -1591,17 +1589,21 @@ done:
return ret; return ret;
} }
static void usb_mtp_update_object(MTPObject *parent, char *name) static int usb_mtp_update_object(MTPObject *parent, char *name)
{ {
int ret = -1;
MTPObject *o = MTPObject *o =
usb_mtp_object_lookup_name(parent, name, strlen(name)); usb_mtp_object_lookup_name(parent, name, strlen(name));
if (o) { if (o) {
lstat(o->path, &o->stat); ret = lstat(o->path, &o->stat);
} }
return ret;
} }
static void usb_mtp_write_data(MTPState *s) static int usb_mtp_write_data(MTPState *s)
{ {
MTPData *d = s->data_out; MTPData *d = s->data_out;
MTPObject *parent = MTPObject *parent =
...@@ -1609,6 +1611,7 @@ static void usb_mtp_write_data(MTPState *s) ...@@ -1609,6 +1611,7 @@ static void usb_mtp_write_data(MTPState *s)
char *path = NULL; char *path = NULL;
uint64_t rc; uint64_t rc;
mode_t mask = 0644; mode_t mask = 0644;
int ret = 0;
assert(d != NULL); assert(d != NULL);
...@@ -1617,13 +1620,13 @@ static void usb_mtp_write_data(MTPState *s) ...@@ -1617,13 +1620,13 @@ static void usb_mtp_write_data(MTPState *s)
if (!parent || !s->write_pending) { if (!parent || !s->write_pending) {
usb_mtp_queue_result(s, RES_INVALID_OBJECTINFO, d->trans, usb_mtp_queue_result(s, RES_INVALID_OBJECTINFO, d->trans,
0, 0, 0, 0); 0, 0, 0, 0);
return; return 1;
} }
if (s->dataset.filename) { if (s->dataset.filename) {
path = g_strdup_printf("%s/%s", parent->path, s->dataset.filename); path = g_strdup_printf("%s/%s", parent->path, s->dataset.filename);
if (s->dataset.format == FMT_ASSOCIATION) { if (s->dataset.format == FMT_ASSOCIATION) {
d->fd = mkdir(path, mask); ret = mkdir(path, mask);
goto free; goto free;
} }
d->fd = open(path, O_CREAT | O_WRONLY | d->fd = open(path, O_CREAT | O_WRONLY |
...@@ -1653,15 +1656,21 @@ static void usb_mtp_write_data(MTPState *s) ...@@ -1653,15 +1656,21 @@ static void usb_mtp_write_data(MTPState *s)
goto done; goto done;
} }
if (d->write_status != WRITE_END) { if (d->write_status != WRITE_END) {
return; g_free(path);
return ret;
} else { } else {
/* Only for < 4G file sizes */ /*
if (s->dataset.size != 0xFFFFFFFF && d->offset != s->dataset.size) { * Return an incomplete transfer if file size doesn't match
* for < 4G file or if lstat fails which will result in an incorrect
* file size
*/
if ((s->dataset.size != 0xFFFFFFFF &&
d->offset != s->dataset.size) ||
usb_mtp_update_object(parent, s->dataset.filename)) {
usb_mtp_queue_result(s, RES_INCOMPLETE_TRANSFER, d->trans, usb_mtp_queue_result(s, RES_INCOMPLETE_TRANSFER, d->trans,
0, 0, 0, 0); 0, 0, 0, 0);
goto done; goto done;
} }
usb_mtp_update_object(parent, s->dataset.filename);
} }
} }
...@@ -1676,12 +1685,14 @@ done: ...@@ -1676,12 +1685,14 @@ done:
*/ */
if (d->fd != -1) { if (d->fd != -1) {
close(d->fd); close(d->fd);
d->fd = -1;
} }
free: free:
g_free(s->dataset.filename); g_free(s->dataset.filename);
s->dataset.size = 0; s->dataset.size = 0;
g_free(path); g_free(path);
s->write_pending = false; s->write_pending = false;
return ret;
} }
static void usb_mtp_write_metadata(MTPState *s, uint64_t dlen) static void usb_mtp_write_metadata(MTPState *s, uint64_t dlen)
...@@ -1718,14 +1729,12 @@ static void usb_mtp_write_metadata(MTPState *s, uint64_t dlen) ...@@ -1718,14 +1729,12 @@ static void usb_mtp_write_metadata(MTPState *s, uint64_t dlen)
s->write_pending = true; s->write_pending = true;
if (s->dataset.format == FMT_ASSOCIATION) { if (s->dataset.format == FMT_ASSOCIATION) {
usb_mtp_write_data(s); if (usb_mtp_write_data(s)) {
/* next_handle will be allocated to the newly created dir */ /* next_handle will be allocated to the newly created dir */
if (d->fd == -1) {
usb_mtp_queue_result(s, RES_STORE_FULL, d->trans, usb_mtp_queue_result(s, RES_STORE_FULL, d->trans,
0, 0, 0, 0); 0, 0, 0, 0);
return; return;
} }
d->fd = -1;
} }
usb_mtp_queue_result(s, RES_OK, d->trans, 3, QEMU_STORAGE_ID, usb_mtp_queue_result(s, RES_OK, d->trans, 3, QEMU_STORAGE_ID,
......
...@@ -82,7 +82,7 @@ struct USBHostDevice { ...@@ -82,7 +82,7 @@ struct USBHostDevice {
uint32_t options; uint32_t options;
uint32_t loglevel; uint32_t loglevel;
bool needs_autoscan; bool needs_autoscan;
bool allow_guest_reset;
/* state */ /* state */
QTAILQ_ENTRY(USBHostDevice) next; QTAILQ_ENTRY(USBHostDevice) next;
int seen, errcount; int seen, errcount;
...@@ -1456,6 +1456,10 @@ static void usb_host_handle_reset(USBDevice *udev) ...@@ -1456,6 +1456,10 @@ static void usb_host_handle_reset(USBDevice *udev)
USBHostDevice *s = USB_HOST_DEVICE(udev); USBHostDevice *s = USB_HOST_DEVICE(udev);
int rc; int rc;
if (!s->allow_guest_reset) {
return;
}
trace_usb_host_reset(s->bus_num, s->addr); trace_usb_host_reset(s->bus_num, s->addr);
rc = libusb_reset_device(s->dh); rc = libusb_reset_device(s->dh);
...@@ -1573,6 +1577,7 @@ static Property usb_host_dev_properties[] = { ...@@ -1573,6 +1577,7 @@ static Property usb_host_dev_properties[] = {
DEFINE_PROP_UINT32("productid", USBHostDevice, match.product_id, 0), DEFINE_PROP_UINT32("productid", USBHostDevice, match.product_id, 0),
DEFINE_PROP_UINT32("isobufs", USBHostDevice, iso_urb_count, 4), DEFINE_PROP_UINT32("isobufs", USBHostDevice, iso_urb_count, 4),
DEFINE_PROP_UINT32("isobsize", USBHostDevice, iso_urb_frames, 32), DEFINE_PROP_UINT32("isobsize", USBHostDevice, iso_urb_frames, 32),
DEFINE_PROP_BOOL("guest-reset", USBHostDevice, allow_guest_reset, true),
DEFINE_PROP_UINT32("loglevel", USBHostDevice, loglevel, DEFINE_PROP_UINT32("loglevel", USBHostDevice, loglevel,
LIBUSB_LOG_LEVEL_WARNING), LIBUSB_LOG_LEVEL_WARNING),
DEFINE_PROP_BIT("pipeline", USBHostDevice, options, DEFINE_PROP_BIT("pipeline", USBHostDevice, options,
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册