mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-28 14:44:10 +08:00
fs: Add invalidate_folio() aops method
This is used in preference to invalidatepage, if defined. Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org> Tested-by: Damien Le Moal <damien.lemoal@opensource.wdc.com> Acked-by: Damien Le Moal <damien.lemoal@opensource.wdc.com> Tested-by: Mike Marshall <hubcap@omnibond.com> # orangefs Tested-by: David Howells <dhowells@redhat.com> # afs
This commit is contained in:
parent
020df9baea
commit
128d1f8241
@ -250,6 +250,7 @@ prototypes::
|
||||
loff_t pos, unsigned len, unsigned copied,
|
||||
struct page *page, void *fsdata);
|
||||
sector_t (*bmap)(struct address_space *, sector_t);
|
||||
void (*invalidate_folio) (struct folio *, size_t start, size_t len);
|
||||
void (*invalidatepage) (struct page *, unsigned int, unsigned int);
|
||||
int (*releasepage) (struct page *, int);
|
||||
void (*freepage)(struct page *);
|
||||
@ -278,6 +279,7 @@ readpages: no shared
|
||||
write_begin: locks the page exclusive
|
||||
write_end: yes, unlocks exclusive
|
||||
bmap:
|
||||
invalidate_folio: yes exclusive
|
||||
invalidatepage: yes exclusive
|
||||
releasepage: yes
|
||||
freepage: yes
|
||||
@ -370,13 +372,12 @@ not locked.
|
||||
filesystems and by the swapper. The latter will eventually go away. Please,
|
||||
keep it that way and don't breed new callers.
|
||||
|
||||
->invalidatepage() is called when the filesystem must attempt to drop
|
||||
->invalidate_folio() is called when the filesystem must attempt to drop
|
||||
some or all of the buffers from the page when it is being truncated. It
|
||||
returns zero on success. If ->invalidatepage is zero, the kernel uses
|
||||
block_invalidatepage() instead. The filesystem must exclusively acquire
|
||||
invalidate_lock before invalidating page cache in truncate / hole punch path
|
||||
(and thus calling into ->invalidatepage) to block races between page cache
|
||||
invalidation and page cache filling functions (fault, read, ...).
|
||||
returns zero on success. The filesystem must exclusively acquire
|
||||
invalidate_lock before invalidating page cache in truncate / hole punch
|
||||
path (and thus calling into ->invalidate_folio) to block races between page
|
||||
cache invalidation and page cache filling functions (fault, read, ...).
|
||||
|
||||
->releasepage() is called when the kernel is about to try to drop the
|
||||
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:
|
||||
loff_t pos, unsigned len, unsigned copied,
|
||||
struct page *page, void *fsdata);
|
||||
sector_t (*bmap)(struct address_space *, sector_t);
|
||||
void (*invalidate_folio) (struct folio *, size_t start, size_t len);
|
||||
void (*invalidatepage) (struct page *, unsigned int, unsigned int);
|
||||
int (*releasepage) (struct page *, int);
|
||||
void (*freepage)(struct page *);
|
||||
@ -868,15 +869,15 @@ cache in your filesystem. The following members are defined:
|
||||
to find out where the blocks in the file are and uses those
|
||||
addresses directly.
|
||||
|
||||
``invalidatepage``
|
||||
If a page has PagePrivate set, then invalidatepage will be
|
||||
called when part or all of the page is to be removed from the
|
||||
``invalidate_folio``
|
||||
If a folio has private data, then invalidate_folio will be
|
||||
called when part or all of the folio is to be removed from the
|
||||
address space. This generally corresponds to either a
|
||||
truncation, punch hole or a complete invalidation of the address
|
||||
space (in the latter case 'offset' will always be 0 and 'length'
|
||||
will be PAGE_SIZE). Any private data associated with the page
|
||||
will be folio_size()). Any private data associated with the page
|
||||
should be updated to reflect this truncation. If offset is 0
|
||||
and length is PAGE_SIZE, then the private data should be
|
||||
and length is folio_size(), then the private data should be
|
||||
released, because the page must be able to be completely
|
||||
discarded. This may be done by calling the ->releasepage
|
||||
function, but in this case the release MUST succeed.
|
||||
|
@ -387,6 +387,7 @@ struct address_space_operations {
|
||||
|
||||
/* Unfortunately this kludge is needed for FIBMAP. Don't use it */
|
||||
sector_t (*bmap)(struct address_space *, sector_t);
|
||||
void (*invalidate_folio) (struct folio *, size_t offset, size_t len);
|
||||
void (*invalidatepage) (struct page *, unsigned int, unsigned int);
|
||||
int (*releasepage) (struct page *, gfp_t);
|
||||
void (*freepage)(struct page *);
|
||||
|
@ -154,9 +154,15 @@ static int invalidate_exceptional_entry2(struct address_space *mapping,
|
||||
*/
|
||||
void folio_invalidate(struct folio *folio, size_t offset, size_t length)
|
||||
{
|
||||
const struct address_space_operations *aops = folio->mapping->a_ops;
|
||||
void (*invalidatepage)(struct page *, unsigned int, unsigned int);
|
||||
|
||||
invalidatepage = folio->mapping->a_ops->invalidatepage;
|
||||
if (aops->invalidate_folio) {
|
||||
aops->invalidate_folio(folio, offset, length);
|
||||
return;
|
||||
}
|
||||
|
||||
invalidatepage = aops->invalidatepage;
|
||||
#ifdef CONFIG_BLOCK
|
||||
if (!invalidatepage)
|
||||
invalidatepage = block_invalidatepage;
|
||||
|
Loading…
Reference in New Issue
Block a user