From: "Daniel P. Berrangé" <berrange@redhat.com>
To: Bandan Das <bsd@redhat.com>
Cc: qemu-devel@nongnu.org, peter.maydell@linaro.org, kraxel@redhat.com
Subject: Re: [Qemu-devel] [PATCH v4 3/5] usb-mtp: Support delete of mtp objects
Date: Wed, 21 Feb 2018 09:37:49 +0000 [thread overview]
Message-ID: <20180221093749.GJ17096@redhat.com> (raw)
In-Reply-To: <20180220225904.16129-4-bsd@redhat.com>
On Tue, Feb 20, 2018 at 05:59:02PM -0500, Bandan Das wrote:
> 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 <bsd@redhat.com>
> ---
> 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 = 0x1007,
> CMD_GET_OBJECT_INFO = 0x1008,
> CMD_GET_OBJECT = 0x1009,
> + CMD_DELETE_OBJECT = 0x100b,
> CMD_GET_PARTIAL_OBJECT = 0x101b,
> CMD_GET_OBJECT_PROPS_SUPPORTED = 0x9801,
> CMD_GET_OBJECT_PROP_DESC = 0x9802,
> @@ -62,6 +63,8 @@ enum mtp_code {
> RES_INVALID_STORAGE_ID = 0x2008,
> RES_INVALID_OBJECT_HANDLE = 0x2009,
> RES_INVALID_OBJECT_FORMAT_CODE = 0x200b,
> + RES_STORE_READ_ONLY = 0x200e,
> + RES_PARTIAL_DELETE = 0x2012,
> RES_SPEC_BY_FORMAT_UNSUPPORTED = 0x2014,
> RES_INVALID_PARENT_OBJECT = 0x201a,
> RES_INVALID_PARAMETER = 0x201d,
> @@ -172,6 +175,7 @@ struct MTPState {
> MTPControl *result;
> uint32_t session;
> uint32_t next_handle;
> + bool readonly;
>
> QTAILQ_HEAD(, MTPObject) objects;
> #ifdef CONFIG_INOTIFY1
> @@ -799,6 +803,7 @@ static MTPData *usb_mtp_get_device_info(MTPState *s, MTPControl *c)
> CMD_GET_NUM_OBJECTS,
> CMD_GET_OBJECT_HANDLES,
> CMD_GET_OBJECT_INFO,
> + CMD_DELETE_OBJECT,
Should we not advertize this in the first place if the device is readonly.
> CMD_GET_OBJECT,
> CMD_GET_PARTIAL_OBJECT,
> CMD_GET_OBJECT_PROPS_SUPPORTED,
> @@ -1113,6 +1118,116 @@ static MTPData *usb_mtp_get_object_prop_value(MTPState *s, MTPControl *c,
> return d;
> }
>
> +/* 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 == 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 = false;
> + bool success = false;
> +
> + /*
> + * TODO: Add support for Protection Status
> + */
> +
> + QLIST_FOREACH(iter, &o->children, list) {
> + if (iter->format == FMT_ASSOCIATION) {
> + QLIST_FOREACH(iter2, &iter->children, list) {
> + usb_mtp_deletefn(s, iter2, trans);
> + }
> + }
> + }
> +
> + if (o->format == FMT_UNDEFINED_OBJECT) {
> + if (remove(o->path)) {
> + partial_delete = true;
> + } else {
> + usb_mtp_object_free_one(s, o);
> + success = true;
> + }
> + }
> +
> + if (o->format == FMT_ASSOCIATION) {
> + if (rmdir(o->path)) {
> + partial_delete = true;
> + } else {
> + usb_mtp_object_free_one(s, o);
> + success = 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 != 0) {
> + usb_mtp_queue_result(s, RES_SPEC_BY_FORMAT_UNSUPPORTED,
> + trans, 0, 0, 0, 0);
> + return;
> + }
> +
> + if (handle == 0xFFFFFFF) {
> + o = QTAILQ_FIRST(&s->objects);
> + } else {
> + o = usb_mtp_object_lookup(s, handle);
> + }
> + if (o == NULL) {
> + usb_mtp_queue_result(s, RES_INVALID_OBJECT_HANDLE,
> + trans, 0, 0, 0, 0);
> + return;
> + }
> +
> + ret = usb_mtp_deletefn(s, o, trans);
> + if (ret == PARTIAL_DELETE) {
> + usb_mtp_queue_result(s, RES_PARTIAL_DELETE,
> + trans, 0, 0, 0, 0);
> + return;
> + } else if (ret == 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 = 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 = usb_mtp_object_lookup(s, c->argv[0]);
> if (o == NULL) {
> @@ -1545,6 +1663,10 @@ static void usb_mtp_realize(USBDevice *dev, Error **errp)
> return;
> }
> s->desc = strrchr(s->root, '/');
> + /* Mark store as RW */
> + if (!s->readonly) {
> + s->flags |= (1 << MTP_FLAG_WRITABLE);
> + }
> if (s->desc && s->desc[0]) {
> s->desc = g_strdup(s->desc + 1);
> } else {
> @@ -1567,6 +1689,7 @@ static const VMStateDescription vmstate_usb_mtp = {
> static Property mtp_properties[] = {
> 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(),
> };
>
> --
> 2.14.3
>
>
Regards,
Daniel
--
|: https://berrange.com -o- https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org -o- https://fstop138.berrange.com :|
|: https://entangle-photo.org -o- https://www.instagram.com/dberrange :|
next prev parent reply other threads:[~2018-02-21 9:37 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-02-20 22:58 [Qemu-devel] [PATCH v4 0/5] Initial write support for MTP objects Bandan Das
2018-02-20 22:59 ` [Qemu-devel] [PATCH v4 1/5] usb-mtp: Add one more argument when building results Bandan Das
2018-02-20 22:59 ` [Qemu-devel] [PATCH v4 2/5] usb-mtp: print parent path in IN_IGNORED trace fn Bandan Das
2018-02-20 22:59 ` [Qemu-devel] [PATCH v4 3/5] usb-mtp: Support delete of mtp objects Bandan Das
2018-02-21 9:37 ` Daniel P. Berrangé [this message]
2018-02-20 22:59 ` [Qemu-devel] [PATCH v4 4/5] usb-mtp: Introduce write support for MTP objects Bandan Das
2018-02-21 9:35 ` Daniel P. Berrangé
2018-02-21 11:11 ` Gerd Hoffmann
2018-02-21 14:33 ` Daniel P. Berrangé
2018-02-21 16:41 ` Bandan Das
2018-02-20 22:59 ` [Qemu-devel] [PATCH v4 5/5] usb-mtp: Advertise SendObjectInfo for write support Bandan Das
2018-02-21 9:36 ` Daniel P. Berrangé
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20180221093749.GJ17096@redhat.com \
--to=berrange@redhat.com \
--cc=bsd@redhat.com \
--cc=kraxel@redhat.com \
--cc=peter.maydell@linaro.org \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).