AS_WRITEBACK_MAY_DEADLOCK_ON_RECLAIM was added to avoid waiting on writeback during reclaim for inodes belonging to filesystems where a) waiting on writeback in reclaim may lead to a deadlock or b) a writeback request may never complete due to the nature of the filesystem (unrelated to reclaim) Rename AS_WRITEBACK_MAY_DEADLOCK_ON_RECLAIM to the more generic AS_WRITEBACK_MAY_HANG to reflect mappings where writeback may hang where the cause could be unrelated to reclaim. This allows us to later use AS_WRITEBACK_MAY_HANG to mitigate other scenarios such as possible hangs when sync waits on writeback. Signed-off-by: Joanne Koong --- fs/fuse/file.c | 2 +- include/linux/pagemap.h | 10 +++++----- mm/vmscan.c | 3 +-- 3 files changed, 7 insertions(+), 8 deletions(-) diff --git a/fs/fuse/file.c b/fs/fuse/file.c index f1ef77a0be05..0804c832bcb7 100644 --- a/fs/fuse/file.c +++ b/fs/fuse/file.c @@ -3126,7 +3126,7 @@ void fuse_init_file_inode(struct inode *inode, unsigned int flags) inode->i_fop = &fuse_file_operations; inode->i_data.a_ops = &fuse_file_aops; if (fc->writeback_cache) - mapping_set_writeback_may_deadlock_on_reclaim(&inode->i_data); + mapping_set_writeback_may_hang(&inode->i_data); INIT_LIST_HEAD(&fi->write_files); INIT_LIST_HEAD(&fi->queued_writes); diff --git a/include/linux/pagemap.h b/include/linux/pagemap.h index 09b581c1d878..a895d6b6aabb 100644 --- a/include/linux/pagemap.h +++ b/include/linux/pagemap.h @@ -210,7 +210,7 @@ enum mapping_flags { AS_STABLE_WRITES = 7, /* must wait for writeback before modifying folio contents */ AS_INACCESSIBLE = 8, /* Do not attempt direct R/W access to the mapping */ - AS_WRITEBACK_MAY_DEADLOCK_ON_RECLAIM = 9, + AS_WRITEBACK_MAY_HANG = 9, AS_KERNEL_FILE = 10, /* mapping for a fake kernel file that shouldn't account usage to user cgroups */ /* Bits 16-25 are used for FOLIO_ORDER */ @@ -338,14 +338,14 @@ static inline bool mapping_inaccessible(const struct address_space *mapping) return test_bit(AS_INACCESSIBLE, &mapping->flags); } -static inline void mapping_set_writeback_may_deadlock_on_reclaim(struct address_space *mapping) +static inline void mapping_set_writeback_may_hang(struct address_space *mapping) { - set_bit(AS_WRITEBACK_MAY_DEADLOCK_ON_RECLAIM, &mapping->flags); + set_bit(AS_WRITEBACK_MAY_HANG, &mapping->flags); } -static inline bool mapping_writeback_may_deadlock_on_reclaim(const struct address_space *mapping) +static inline bool mapping_writeback_may_hang(const struct address_space *mapping) { - return test_bit(AS_WRITEBACK_MAY_DEADLOCK_ON_RECLAIM, &mapping->flags); + return test_bit(AS_WRITEBACK_MAY_HANG, &mapping->flags); } static inline gfp_t mapping_gfp_mask(const struct address_space *mapping) diff --git a/mm/vmscan.c b/mm/vmscan.c index 92980b072121..636c18ee2b2c 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c @@ -1216,8 +1216,7 @@ static unsigned int shrink_folio_list(struct list_head *folio_list, } else if (writeback_throttling_sane(sc) || !folio_test_reclaim(folio) || !may_enter_fs(folio, sc->gfp_mask) || - (mapping && - mapping_writeback_may_deadlock_on_reclaim(mapping))) { + (mapping && mapping_writeback_may_hang(mapping))) { /* * This is slightly racy - * folio_end_writeback() might have -- 2.47.3 During superblock writeback waiting, skip inodes where writeback may take an indefinite amount of time or hang, as denoted by the AS_WRITEBACK_MAY_HANG mapping flag. Currently, fuse is the only filesystem with this flag set. For a properly functioning fuse server, writeback requests are completed and there is no issue. However, if there is a bug in the fuse server and it hangs on writeback, then without this change, wait_sb_inodes() will wait forever. Signed-off-by: Joanne Koong Fixes: 0c58a97f919c ("fuse: remove tmp folio for writebacks and internal rb tree") Reported-by: Athul Krishna --- fs/fs-writeback.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c index 2b35e80037fe..eb246e9fbf3d 100644 --- a/fs/fs-writeback.c +++ b/fs/fs-writeback.c @@ -2733,6 +2733,9 @@ static void wait_sb_inodes(struct super_block *sb) if (!mapping_tagged(mapping, PAGECACHE_TAG_WRITEBACK)) continue; + if (mapping_writeback_may_hang(mapping)) + continue; + spin_unlock_irq(&sb->s_inode_wblist_lock); spin_lock(&inode->i_lock); -- 2.47.3