2011-04-08 19:04:52

by Josef Bacik

[permalink] [raw]
Subject: O_DIRECT and Btrfs == checksumming nightmare

Hello,

So I've been trying to track down checksumming errors Eric Paris was
getting while running Windows 7 in qemu. Turns out we had one valid
problem (we don't deal well with reading with an iovec with two
iov_base's that are the same), and we have a problem with the pages
being changed in flight. I'm not entirely sure the second thing is what
is happening, but I'm looking at finding that out for sure soon. But in
the meantime I've crafted a fun little reproducer that will blow btrfs
up quickly. It just mmaps an anonymous range, fork()'s, and then one
thread does writes/reads with the anonymous map and then the other one
just sits there and loops and changes the anonymous map. This will
result in getting a -EIO on the reader thread pretty quickly and you get
a bunch of checksum errors in your messages.

This is going to screw anybody who needs the pages to be stable during
IO, and since its O_DIRECT we don't get to do any of our normal tricks
to make sure things stay stable. I even tried using set_memory_ro() to
see if I could catch userspace modifying the page and it didn't do
anything. For now in btrfs the plan is to check the crc of the page
when the IO completes (for writes) and if it's not create a bounce
buffer and re-submit that. This sucks, it would be good to have a way
to make sure the pages were stable throughout the IO like we can with
normal pages. Nick, Chris said you had something in mind for this? If
you don't have time to do the actual work I can try and put together a
fix if you can describe what to do. I'm attaching my reproducer here in
case anybody else wants to try it. Thanks,

Josef


Attachments:
modify-dio-in-flight.c (1.97 kB)