Skip to content

fix open-write-close chatter during SendObject #128

Merged
jfdelnero merged 5 commits intoviveris:masterfrom
js731ca:fix-open-close-chatter
Jul 8, 2025
Merged

fix open-write-close chatter during SendObject #128
jfdelnero merged 5 commits intoviveris:masterfrom
js731ca:fix-open-close-chatter

Conversation

@js731ca
Copy link
Contributor

@js731ca js731ca commented Mar 30, 2025

The current implementation that handles MTP_OPERATION_SEND_PARTIAL_OBJECT would repeatedly open;write;close during a transfer of a large file.
Which is undesirable when other processes in the system want to register with inotify to watch create/modify/close on a folder/file where access is provided over mtp.

The solution implemented here is to simply keep the file-descriptors around and open over the stream of SendPartialObject chunks.

The order of MTP operations is (or seems to be, always?):
BeginEditObject, SendPartialObject x chunk-size, EndEditObject.
Now the first SendPartial would open() the file, and the trailing EndEdit would then close() it.

# Before:
$> inotifywatch /mnt/data/mtp-storage/
total  modify  close_write  open  filename
33368  29652   1858         1858  /mnt/data/mtp-storage/


# After (uploading a new file):
$> inotifywatch /mnt/data/mtp-storage/
total  access  modify  close_write  close_nowrite  open  create  filename
29696  10      29669   3            5              8     1       /mnt/data/mtp-storage/

# After (overwriting the same file):
$> inotifywatch /mnt/data/mtp-storage/
total  modify  close_write  open  filename
29692  29690   1            1     /mnt/data/mtp-storage/

The first couple of commits only refactor/deduplicate/move code around - and are (intentionally) split into small parts for ease of review ;-)
The last commit is the change this PR is actually interested in.

CC @bith3ad @gujie-leica

js731ca added 4 commits March 30, 2025 09:17
Make the fs_handles_db::fs_entry keep track of open'ed files
descriptors internally.

To that end the helper functions entry_open/_read/_close have been
refactored to have a common signature and now manage/operate on the
internal file-descriptor.

Signed-off-by: Johannes Schneider <johannes.schneider@leica-geosystems.com>
Refactor the SendObject operation to deduplicate some code that is
already provided by the entry_open/_close helper functions.

For that only the per-use-case file open flags had to be moved, the
remaining code then was the same as found in entry_open, and could be
replaced by it.

Signed-off-by: Johannes Schneider <johannes.schneider@leica-geosystems.com>
Remove a (now) redundant if block, shifting the enclosing code one
indent left = no functional changes.

Signed-off-by: Johannes Schneider <johannes.schneider@leica-geosystems.com>
Avoid multiple open-write-close operations when handling large files
through the SEND_PARTIAL_OBJECT, by simply keeping the file-descriptor
open, and only closing it with the finalizing END_EDIT_OBJECT
operation.

This avoids generating unnecessary inotify(open/modify/close) events
on the OS side running the mtp-responder.

Signed-off-by: Johannes Schneider <johannes.schneider@leica-geosystems.com>
@jfdelnero
Copy link
Member

I didn't checked the modifications yet, but have you tried to do some unexpected disconnections or similar tests to check that the file(s) are correctly closed by umtpd ?

@js731ca
Copy link
Contributor Author

js731ca commented Apr 17, 2025

I didn't checked the modifications yet, but have you tried to do some unexpected disconnections or similar tests to check that the file(s) are correctly closed by umtpd ?

very good point - not yet, will do!

When closing a session or disconnecting the gadget, have any remaining
file-handles closed as well, so that in case of an aborted or
otherwise interrupted transfer nothing is held open.

Signed-off-by: Johannes Schneider <johannes.schneider@leica-geosystems.com>
@js731ca
Copy link
Contributor Author

js731ca commented Jun 2, 2025

your intuition was spot on: there was one line missing to cleanup/close stale file handles - added with 5a26ef1
what i've also (now) tried was to simply abort the file transfer, as well as physically disconnecting the usb cable - both looked Ok: in the first case the file handle was still open until the next mtp operation comes around, which is IMO expected since the device can't know if the transfer just stalled or was aborted, the second scenario closed the gadget side and did the cleanup

@jfdelnero jfdelnero merged commit a25525a into viveris:master Jul 8, 2025
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants