Thread (18 messages) read the whole thread 18 messages, 7 authors, 2011-03-01

Re: [PATCH v2]Btrfs: pwrite blocked when writing from the mmaped buffer of the same page

From: Chris Mason <hidden>
Date: 2011-02-25 19:19:50

Possibly related (same subject, not in this thread)

Excerpts from Mitch Harder's message of 2011-02-25 13:43:37 -0500:
quoted
The loop is more-or-less following this process (from within the
"while (iov_iter_count(&i) > 0) {}" loop):

(1) Reserve some space with btrfs_delalloc_reserve_space()
(2) Prepare the reserved space with prepare_pages()
(3) Call btrfs_copy_from_user() to copy to the prepared space.
-------------> From btrfs_copy_from_user()
(4) ........Try to copy with copied = iov_iter_copy_from_user_atomic()
(5) ........The above operation results with copied == 0. Break and
return with a return value of 0 bytes copied.
(6) There is no special handling for copied == 0 in the "while
(iov_iter_count(&i) > 0) {}" loop, so it loops back around, reserves
some more space, and tries again.

If I look back at how the code was set up before the patch at the head
of this thread was applied (Btrfs: pwrite blocked when writing from
the mmaped buffer of the same page), the btrfs_copy_from_user()
function had some handling for "copied == 0" that would change the
scope of the amount to write, and loop back to try the write again.

I attempted to construct a patch that just reverted the handling for
"copied == 0" in btrfs_copy_from_user(), however, that just resulted
in my computer locking up when it reached the point where it was
previously beginning to allocate disk space.

So, I apologize for not having a patch to address the issue I'm
seeing, but I hope I've added some insight.
Some clarification on my previous message...

After looking at my ftrace log more closely, I can see where Btrfs is
trying to release the allocated pages.  However, the calculation for
the number of dirty_pages is equal to 1 when "copied == 0".

So I'm seeing at least two problems:
(1)  It keeps looping when "copied == 0".
(2)  One dirty page is not being released on every loop even though
"copied == 0" (at least this problem keeps it from being an infinite
loop by eventually exhausting reserveable space on the disk).
Very nice, I think you're exactly right.  I should be able to reproduce this
now, thanks!

-chris
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help