From nobody Fri Oct 24 12:04:30 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1519167825611681.307014115923; Tue, 20 Feb 2018 15:03:45 -0800 (PST) Received: from localhost ([::1]:58153 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eoGwq-0005gq-Q1 for importer@patchew.org; Tue, 20 Feb 2018 18:03:44 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:34010) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eoGsp-0002lC-8i for qemu-devel@nongnu.org; Tue, 20 Feb 2018 17:59:36 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eoGsk-0005ic-2J for qemu-devel@nongnu.org; Tue, 20 Feb 2018 17:59:35 -0500 Received: from mx3-rdu2.redhat.com ([66.187.233.73]:56454 helo=mx1.redhat.com) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1eoGsj-0005iK-T5 for qemu-devel@nongnu.org; Tue, 20 Feb 2018 17:59:29 -0500 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.rdu2.redhat.com [10.11.54.5]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 529898182D01; Tue, 20 Feb 2018 22:59:24 +0000 (UTC) Received: from gigantic.usersys.redhat.com (dhcp-17-169.bos.redhat.com [10.18.17.169]) by smtp.corp.redhat.com (Postfix) with ESMTP id 2B56EAF010; Tue, 20 Feb 2018 22:59:24 +0000 (UTC) From: Bandan Das To: qemu-devel@nongnu.org Date: Tue, 20 Feb 2018 17:59:02 -0500 Message-Id: <20180220225904.16129-4-bsd@redhat.com> In-Reply-To: <20180220225904.16129-1-bsd@redhat.com> References: <20180220225904.16129-1-bsd@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.11.54.5 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.8]); Tue, 20 Feb 2018 22:59:24 +0000 (UTC) X-Greylist: inspected by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.8]); Tue, 20 Feb 2018 22:59:24 +0000 (UTC) for IP:'10.11.54.5' DOMAIN:'int-mx05.intmail.prod.int.rdu2.redhat.com' HELO:'smtp.corp.redhat.com' FROM:'bsd@redhat.com' RCPT:'' X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 66.187.233.73 Subject: [Qemu-devel] [PATCH v4 3/5] usb-mtp: Support delete of mtp objects X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: peter.maydell@linaro.org, kraxel@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Write of existing objects by the initiator is acheived by making a temporary buffer with the new changes, deleting the old file and then writing a new file with the same name. Also, add a "readonly" property which needs to be set to false for deletion to work. Signed-off-by: Bandan Das --- hw/usb/dev-mtp.c | 123 +++++++++++++++++++++++++++++++++++++++++++++++++++= ++++ 1 file changed, 123 insertions(+) diff --git a/hw/usb/dev-mtp.c b/hw/usb/dev-mtp.c index 63f8f3b90b..5ef77f3e9f 100644 --- a/hw/usb/dev-mtp.c +++ b/hw/usb/dev-mtp.c @@ -46,6 +46,7 @@ enum mtp_code { CMD_GET_OBJECT_HANDLES =3D 0x1007, CMD_GET_OBJECT_INFO =3D 0x1008, CMD_GET_OBJECT =3D 0x1009, + CMD_DELETE_OBJECT =3D 0x100b, CMD_GET_PARTIAL_OBJECT =3D 0x101b, CMD_GET_OBJECT_PROPS_SUPPORTED =3D 0x9801, CMD_GET_OBJECT_PROP_DESC =3D 0x9802, @@ -62,6 +63,8 @@ enum mtp_code { RES_INVALID_STORAGE_ID =3D 0x2008, RES_INVALID_OBJECT_HANDLE =3D 0x2009, RES_INVALID_OBJECT_FORMAT_CODE =3D 0x200b, + RES_STORE_READ_ONLY =3D 0x200e, + RES_PARTIAL_DELETE =3D 0x2012, RES_SPEC_BY_FORMAT_UNSUPPORTED =3D 0x2014, RES_INVALID_PARENT_OBJECT =3D 0x201a, RES_INVALID_PARAMETER =3D 0x201d, @@ -172,6 +175,7 @@ struct MTPState { MTPControl *result; uint32_t session; uint32_t next_handle; + bool readonly; =20 QTAILQ_HEAD(, MTPObject) objects; #ifdef CONFIG_INOTIFY1 @@ -799,6 +803,7 @@ static MTPData *usb_mtp_get_device_info(MTPState *s, MT= PControl *c) CMD_GET_NUM_OBJECTS, CMD_GET_OBJECT_HANDLES, CMD_GET_OBJECT_INFO, + CMD_DELETE_OBJECT, CMD_GET_OBJECT, CMD_GET_PARTIAL_OBJECT, CMD_GET_OBJECT_PROPS_SUPPORTED, @@ -1113,6 +1118,116 @@ static MTPData *usb_mtp_get_object_prop_value(MTPSt= ate *s, MTPControl *c, return d; } =20 +/* Return correct return code for a delete event */ +enum { + ALL_DELETE, + PARTIAL_DELETE, + READ_ONLY, +}; + +/* Assumes that children, if any, have been already freed */ +static void usb_mtp_object_free_one(MTPState *s, MTPObject *o) +{ +#ifndef CONFIG_INOTIFY1 + assert(o->nchildren =3D=3D 0); + QTAILQ_REMOVE(&s->objects, o, next); + g_free(o->name); + g_free(o->path); + g_free(o); +#endif +} + +static int usb_mtp_deletefn(MTPState *s, MTPObject *o, uint32_t trans) +{ + MTPObject *iter, *iter2; + bool partial_delete =3D false; + bool success =3D false; + + /* + * TODO: Add support for Protection Status + */ + + QLIST_FOREACH(iter, &o->children, list) { + if (iter->format =3D=3D FMT_ASSOCIATION) { + QLIST_FOREACH(iter2, &iter->children, list) { + usb_mtp_deletefn(s, iter2, trans); + } + } + } + + if (o->format =3D=3D FMT_UNDEFINED_OBJECT) { + if (remove(o->path)) { + partial_delete =3D true; + } else { + usb_mtp_object_free_one(s, o); + success =3D true; + } + } + + if (o->format =3D=3D FMT_ASSOCIATION) { + if (rmdir(o->path)) { + partial_delete =3D true; + } else { + usb_mtp_object_free_one(s, o); + success =3D true; + } + } + + if (success && partial_delete) { + return PARTIAL_DELETE; + } + if (!success && partial_delete) { + return READ_ONLY; + } + return ALL_DELETE; +} + +static void usb_mtp_object_delete(MTPState *s, uint32_t handle, + uint32_t format_code, uint32_t trans) +{ + MTPObject *o; + int ret; + + /* Return error if store is read-only */ + if (!FLAG_SET(s, MTP_FLAG_WRITABLE)) { + usb_mtp_queue_result(s, RES_STORE_READ_ONLY, + trans, 0, 0, 0, 0); + return; + } + + if (format_code !=3D 0) { + usb_mtp_queue_result(s, RES_SPEC_BY_FORMAT_UNSUPPORTED, + trans, 0, 0, 0, 0); + return; + } + + if (handle =3D=3D 0xFFFFFFF) { + o =3D QTAILQ_FIRST(&s->objects); + } else { + o =3D usb_mtp_object_lookup(s, handle); + } + if (o =3D=3D NULL) { + usb_mtp_queue_result(s, RES_INVALID_OBJECT_HANDLE, + trans, 0, 0, 0, 0); + return; + } + + ret =3D usb_mtp_deletefn(s, o, trans); + if (ret =3D=3D PARTIAL_DELETE) { + usb_mtp_queue_result(s, RES_PARTIAL_DELETE, + trans, 0, 0, 0, 0); + return; + } else if (ret =3D=3D READ_ONLY) { + usb_mtp_queue_result(s, RES_STORE_READ_ONLY, trans, + 0, 0, 0, 0); + return; + } else { + usb_mtp_queue_result(s, RES_OK, trans, + 0, 0, 0, 0); + return; + } +} + static void usb_mtp_command(MTPState *s, MTPControl *c) { MTPData *data_in =3D NULL; @@ -1239,6 +1354,9 @@ static void usb_mtp_command(MTPState *s, MTPControl *= c) return; } break; + case CMD_DELETE_OBJECT: + usb_mtp_object_delete(s, c->argv[0], c->argv[1], c->trans); + return; case CMD_GET_PARTIAL_OBJECT: o =3D usb_mtp_object_lookup(s, c->argv[0]); if (o =3D=3D NULL) { @@ -1545,6 +1663,10 @@ static void usb_mtp_realize(USBDevice *dev, Error **= errp) return; } s->desc =3D strrchr(s->root, '/'); + /* Mark store as RW */ + if (!s->readonly) { + s->flags |=3D (1 << MTP_FLAG_WRITABLE); + } if (s->desc && s->desc[0]) { s->desc =3D g_strdup(s->desc + 1); } else { @@ -1567,6 +1689,7 @@ static const VMStateDescription vmstate_usb_mtp =3D { static Property mtp_properties[] =3D { DEFINE_PROP_STRING("x-root", MTPState, root), DEFINE_PROP_STRING("desc", MTPState, desc), + DEFINE_PROP_BOOL("readonly", MTPState, readonly, true), DEFINE_PROP_END_OF_LIST(), }; =20 --=20 2.14.3