On 29.06.21 г. 16:59, Josef Bacik wrote: > 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. > > Signed-off-by: Josef Bacik <josef@xxxxxxxxxxxxxx> Reviewed-by: Nikolay Borisov <nborisov@xxxxxxxx>