From: Maxim P. <mpa...@pa...> - 2014-07-28 12:58:45
|
On 07/28/2014 02:07 PM, Goswin von Brederlow wrote: > On Thu, Jul 10, 2014 at 01:11:56PM +0200, Miklos Szeredi wrote: >> On Thu, Jul 10, 2014 at 11:32 AM, Maxim Patlasov >> <MPa...@pa...> wrote: >>> FUSE has an architectural peculiarity: it cannot write to an inode, unless it >>> has an associated file open for write. Since the beginning (Apr 30 2008, commit >>> 3be5a52b), FUSE BUG_ON (later WARN_ON) the case when it has to process >>> writeback, but all associated files are closed. The latest relevant commit is >>> 72523425: >>> >>>> Don't bug if there's no writable files found for page writeback. If ever >>>> this is triggered, a WARN_ON helps debugging it much better then a BUG_ON. >>>> >>>> Signed-off-by: Miklos Szeredi <msz...@su...> >>> But that situation can happen in quite a legal way: for example, let's mmap a >>> file, then issue O_DIRECT read to mmapped region and immediately close file >>> and munmap. O_DIRECT will pin some pages, execute IO to them and then mark >>> pages dirty. Here we are. > Why would a read mark the page as dirty? Did you mean a write? You read data from a file to a memory region. If the region happens to be mmap-ed, the read operation marks corresponding page as dirty. > >> Something's not right. Fuse assumes that the file can only be modified >> if there's at least one open file for read-write, otherwise the page >> can't be written back, resulting in fs corruption. >> >> The VFS also assumes in the read-only remount code that if no files >> are open for write then the filesystem can safely be remounted >> read-only and no modifications can occur after that. >> >> The situation you describe above contradict those assumptions. >> >> Removing the warning only makes the problem worse, since now the >> corruption will happen silently. >> >> CC-ing linux-fsdevel and linux-mm. Anyone has a better insight into this? >> >> Thanks, >> Miklos > Lets assume you have the file mmap()ed, you write to it so pages > become dirty and you munmap() it so no file is open for write for the > dirty pages anymore. What should then happen? > > man msync > > msync() flushes changes made to the in-core copy of a file that was > mapped into memory using mmap(2) back to disk. Without use of this > call there is no guarantee that changes are written back before mun- > map(2) is called. To be more precise, the part of the file that corre- > sponds to the memory area starting at addr and having length length is > updated. > > Congratulation, you have run into undefined behaviour. It would be > perfectly alright to simply discard the dirty pages. No, it is not undefined behaviour. munmap(2) flushes changes as well. See munmap(2) man page. > > At unmap/close time the dirty pages should either be discarded or > writeback should start and keep the FD open till it's done. Otherwise, > as Miklos said, you would get writes to read-only filesystems and so on. In your scenario (mmap/write/munmap), fuse ensures that all dirty pages went to writeback (see fuse_vma_close()) at unmap time. That's why you cannot easily trigger that WARN_ON as simple as mmap/write/munmap. Thanks, Maxim |