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