@@ -343,6 +343,20 @@ static inline void mapping_set_large_folios(struct address_space *mapping)
__set_bit(AS_LARGE_FOLIO_SUPPORT, &mapping->flags);
}
+/**
+ * mapping_clear_large_folios() - The file disable supports large folios.
+ * @mapping: The file.
+ *
+ * The filesystem have to make sure the file is in atomic context and all
+ * cached folios have been cleared under mapping->invalidate_lock before
+ * calling this function.
+ */
+static inline void mapping_clear_large_folios(struct address_space *mapping)
+{
+ WARN_ON_ONCE(!rwsem_is_locked(&mapping->invalidate_lock));
+ __clear_bit(AS_LARGE_FOLIO_SUPPORT, &mapping->flags);
+}
+
/*
* Large folio support currently depends on THP. These dependencies are
* being worked on but are not yet fixed.
@@ -493,8 +493,11 @@ void page_cache_ra_order(struct readahead_control *ractl,
int err = 0;
gfp_t gfp = readahead_gfp_mask(mapping);
- if (!mapping_large_folio_support(mapping) || ra->size < 4)
+ filemap_invalidate_lock_shared(mapping);
+ if (!mapping_large_folio_support(mapping) || ra->size < 4) {
+ filemap_invalidate_unlock_shared(mapping);
goto fallback;
+ }
limit = min(limit, index + ra->size - 1);
@@ -506,7 +509,6 @@ void page_cache_ra_order(struct readahead_control *ractl,
new_order--;
}
- filemap_invalidate_lock_shared(mapping);
while (index <= limit) {
unsigned int order = new_order;