History

fs: Add invalidate_folio() aops method

This is used in preference to invalidatepage, if defined.

Matthew Wilcox (Oracle) committed 4 years ago

Commit 128d1f81 parent 020df9b4 files · +21 −12Browse files

Unified · Split

4 files
  1. Documentation/filesystems/locking.rst +7 −6
  2. Documentation/filesystems/vfs.rst +6 −5
  3. include/linux/fs.h +1 −0
  4. mm/truncate.c +7 −1
Documentation/filesystems/locking.rst+7−6
@@ -250,6 +250,7 @@ prototypes:: · 249 unmodified lines
250250 loff_t pos, unsigned len, unsigned copied,
251251 struct page *page, void *fsdata);
252252 sector_t (*bmap)(struct address_space *, sector_t);
253+ void (*invalidate_folio) (struct folio *, size_t start, size_t len);
253254 void (*invalidatepage) (struct page *, unsigned int, unsigned int);
254255 int (*releasepage) (struct page *, int);
255256 void (*freepage)(struct page *);
@@ -278,6 +279,7 @@ readpages: no shared · 22 unmodified lines
278279 write_begin: locks the page exclusive
279280 write_end: yes, unlocks exclusive
280281 bmap:
282+invalidate_folio: yes exclusive
281283 invalidatepage: yes exclusive
282284 releasepage: yes
283285 freepage: yes
@@ -370,13 +372,12 @@ not locked. · 86 unmodified lines
370372 filesystems and by the swapper. The latter will eventually go away. Please,
371373 keep it that way and don't breed new callers.
372374
373−->invalidatepage() is called when the filesystem must attempt to drop
375+->invalidate_folio() is called when the filesystem must attempt to drop
374376 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, ...).
380381
381382 ->releasepage() is called when the kernel is about to try to drop the
382383 buffers from the page in preparation for freeing it. It returns zero to
Documentation/filesystems/vfs.rst+6−5
@@ -735,6 +735,7 @@ cache in your filesystem. The following members are defined: · 734 unmodified lines
735735 loff_t pos, unsigned len, unsigned copied,
736736 struct page *page, void *fsdata);
737737 sector_t (*bmap)(struct address_space *, sector_t);
738+ void (*invalidate_folio) (struct folio *, size_t start, size_t len);
738739 void (*invalidatepage) (struct page *, unsigned int, unsigned int);
739740 int (*releasepage) (struct page *, int);
740741 void (*freepage)(struct page *);
@@ -868,15 +869,15 @@ cache in your filesystem. The following members are defined: · 127 unmodified lines
868869 to find out where the blocks in the file are and uses those
869870 addresses directly.
870871
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
874875 address space. This generally corresponds to either a
875876 truncation, punch hole or a complete invalidation of the address
876877 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
878879 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
880881 released, because the page must be able to be completely
881882 discarded. This may be done by calling the ->releasepage
882883 function, but in this case the release MUST succeed.
include/linux/fs.h+1−0
@@ -387,6 +387,7 @@ struct address_space_operations { · 386 unmodified lines
387387
388388 /* Unfortunately this kludge is needed for FIBMAP. Don't use it */
389389 sector_t (*bmap)(struct address_space *, sector_t);
390+ void (*invalidate_folio) (struct folio *, size_t offset, size_t len);
390391 void (*invalidatepage) (struct page *, unsigned int, unsigned int);
391392 int (*releasepage) (struct page *, gfp_t);
392393 void (*freepage)(struct page *);
mm/truncate.c+7−1
@@ -154,9 +154,15 @@ static int invalidate_exceptional_entry2(struct address_space *mapping, · 153 unmodified lines
154154 */
155155 void folio_invalidate(struct folio *folio, size_t offset, size_t length)
156156 {
157+ const struct address_space_operations *aops = folio->mapping->a_ops;
157158 void (*invalidatepage)(struct page *, unsigned int, unsigned int);
158159
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;
160166 #ifdef CONFIG_BLOCK
161167 if (!invalidatepage)
162168 invalidatepage = block_invalidatepage;

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t