• Josef Bacik's avatar
    fs: add a filemap_fdatawrite_wbc helper · 5a798493
    Josef Bacik authored
    Btrfs sometimes needs to flush dirty pages on a bunch of dirty inodes in
    order to reclaim metadata reservations.  Unfortunately most helpers in
    this area are too smart for us:
    
    1) The normal filemap_fdata* helpers only take range and sync modes, and
       don't give any indication of how much was written, so we can only
       flush full inodes, which isn't what we want in most cases.
    2) The normal writeback path requires us to have the s_umount sem held,
       but we can't unconditionally take it in this path because we could
       deadlock.
    3) The normal writeback path also skips inodes with I_SYNC set if we
       write with WB_SYNC_NONE.  This isn't the behavior we want under heavy
       ENOSPC pressure, we want to actually make sure the pages are under
       writeback before returning, and if another thread is in the middle of
       writing the file we may return before they're under writeback and
       miss our ordered extents and not properly wait for completion.
    4) sync_inode() uses the normal writeback path and has the same problem
       as #3.
    
    What we really want is to call do_writepages() with our wbc.  This way
    we can make sure that writeback is actually started on the pages, and we
    can control how many pages are written as a whole as we write many
    inodes using the same wbc.  Accomplish this with a new helper that does
    just that so we can use it for our ENOSPC flushing infrastructure.
    Reviewed-by: default avatarNikolay Borisov <nborisov@suse.com>
    Reviewed-by: default avatarChristoph Hellwig <hch@lst.de>
    Signed-off-by: default avatarJosef Bacik <josef@toxicpanda.com>
    Reviewed-by: default avatarDavid Sterba <dsterba@suse.com>
    Signed-off-by: default avatarDavid Sterba <dsterba@suse.com>
    5a798493
filemap.c 108 KB