This is used in preference to invalidatepage, if defined.
Unified · Split
| @@ -250,6 +250,7 @@ prototypes:: · 249 unmodified lines | ||
| 250 | 250 | loff_t pos, unsigned len, unsigned copied, |
| 251 | 251 | struct page *page, void *fsdata); |
| 252 | 252 | sector_t (*bmap)(struct address_space *, sector_t); |
| 253 | + void (*invalidate_folio) (struct folio *, size_t start, size_t len); | |
| 253 | 254 | void (*invalidatepage) (struct page *, unsigned int, unsigned int); |
| 254 | 255 | int (*releasepage) (struct page *, int); |
| 255 | 256 | void (*freepage)(struct page *); |
| @@ -278,6 +279,7 @@ readpages: no shared · 22 unmodified lines | ||
| 278 | 279 | write_begin: locks the page exclusive |
| 279 | 280 | write_end: yes, unlocks exclusive |
| 280 | 281 | bmap: |
| 282 | +invalidate_folio: yes exclusive | |
| 281 | 283 | invalidatepage: yes exclusive |
| 282 | 284 | releasepage: yes |
| 283 | 285 | freepage: yes |
| @@ -370,13 +372,12 @@ not locked. · 86 unmodified lines | ||
| 370 | 372 | filesystems and by the swapper. The latter will eventually go away. Please, |
| 371 | 373 | keep it that way and don't breed new callers. |
| 372 | 374 | |
| 373 | −->invalidatepage() is called when the filesystem must attempt to drop | |
| 375 | +->invalidate_folio() is called when the filesystem must attempt to drop | |
| 374 | 376 | some or all of the buffers from the page when it is being truncated. It |
| 375 | −returns zero on success. If ->invalidatepage is zero, the kernel uses | |
| 376 | −block_invalidatepage() instead. The filesystem must exclusively acquire | |
| 377 | −invalidate_lock before invalidating page cache in truncate / hole punch path | |
| 378 | −(and thus calling into ->invalidatepage) to block races between page cache | |
| 379 | −invalidation and page cache filling functions (fault, read, ...). | |
| 377 | +returns zero on success. The filesystem must exclusively acquire | |
| 378 | +invalidate_lock before invalidating page cache in truncate / hole punch | |
| 379 | +path (and thus calling into ->invalidate_folio) to block races between page | |
| 380 | +cache invalidation and page cache filling functions (fault, read, ...). | |
| 380 | 381 | |
| 381 | 382 | ->releasepage() is called when the kernel is about to try to drop the |
| 382 | 383 | buffers from the page in preparation for freeing it. It returns zero to |
| @@ -735,6 +735,7 @@ cache in your filesystem. The following members are defined: · 734 unmodified lines | ||
| 735 | 735 | loff_t pos, unsigned len, unsigned copied, |
| 736 | 736 | struct page *page, void *fsdata); |
| 737 | 737 | sector_t (*bmap)(struct address_space *, sector_t); |
| 738 | + void (*invalidate_folio) (struct folio *, size_t start, size_t len); | |
| 738 | 739 | void (*invalidatepage) (struct page *, unsigned int, unsigned int); |
| 739 | 740 | int (*releasepage) (struct page *, int); |
| 740 | 741 | void (*freepage)(struct page *); |
| @@ -868,15 +869,15 @@ cache in your filesystem. The following members are defined: · 127 unmodified lines | ||
| 868 | 869 | to find out where the blocks in the file are and uses those |
| 869 | 870 | addresses directly. |
| 870 | 871 | |
| 871 | −``invalidatepage`` | |
| 872 | − If a page has PagePrivate set, then invalidatepage will be | |
| 873 | − called when part or all of the page is to be removed from the | |
| 872 | +``invalidate_folio`` | |
| 873 | + If a folio has private data, then invalidate_folio will be | |
| 874 | + called when part or all of the folio is to be removed from the | |
| 874 | 875 | address space. This generally corresponds to either a |
| 875 | 876 | truncation, punch hole or a complete invalidation of the address |
| 876 | 877 | space (in the latter case 'offset' will always be 0 and 'length' |
| 877 | − will be PAGE_SIZE). Any private data associated with the page | |
| 878 | + will be folio_size()). Any private data associated with the page | |
| 878 | 879 | should be updated to reflect this truncation. If offset is 0 |
| 879 | − and length is PAGE_SIZE, then the private data should be | |
| 880 | + and length is folio_size(), then the private data should be | |
| 880 | 881 | released, because the page must be able to be completely |
| 881 | 882 | discarded. This may be done by calling the ->releasepage |
| 882 | 883 | function, but in this case the release MUST succeed. |
| @@ -387,6 +387,7 @@ struct address_space_operations { · 386 unmodified lines | ||
| 387 | 387 | |
| 388 | 388 | /* Unfortunately this kludge is needed for FIBMAP. Don't use it */ |
| 389 | 389 | sector_t (*bmap)(struct address_space *, sector_t); |
| 390 | + void (*invalidate_folio) (struct folio *, size_t offset, size_t len); | |
| 390 | 391 | void (*invalidatepage) (struct page *, unsigned int, unsigned int); |
| 391 | 392 | int (*releasepage) (struct page *, gfp_t); |
| 392 | 393 | void (*freepage)(struct page *); |
| @@ -154,9 +154,15 @@ static int invalidate_exceptional_entry2(struct address_space *mapping, · 153 unmodified lines | ||
| 154 | 154 | */ |
| 155 | 155 | void folio_invalidate(struct folio *folio, size_t offset, size_t length) |
| 156 | 156 | { |
| 157 | + const struct address_space_operations *aops = folio->mapping->a_ops; | |
| 157 | 158 | void (*invalidatepage)(struct page *, unsigned int, unsigned int); |
| 158 | 159 | |
| 159 | − invalidatepage = folio->mapping->a_ops->invalidatepage; | |
| 160 | + if (aops->invalidate_folio) { | |
| 161 | + aops->invalidate_folio(folio, offset, length); | |
| 162 | + return; | |
| 163 | + } | |
| 164 | + | |
| 165 | + invalidatepage = aops->invalidatepage; | |
| 160 | 166 | #ifdef CONFIG_BLOCK |
| 161 | 167 | if (!invalidatepage) |
| 162 | 168 | invalidatepage = block_invalidatepage; |