Commit fdaf9a58 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull page cache updates from Matthew Wilcox:

 - Appoint myself page cache maintainer

 - Fix how scsicam uses the page cache

 - Use the memalloc_nofs_save() API to replace AOP_FLAG_NOFS

 - Remove the AOP flags entirely

 - Remove pagecache_write_begin() and pagecache_write_end()

 - Documentation updates

 - Convert several address_space operations to use folios:
     - is_dirty_writeback
     - readpage becomes read_folio
     - releasepage becomes release_folio
     - freepage becomes free_folio

 - Change filler_t to require a struct file pointer be the first
   argument like ->read_folio

* tag 'folio-5.19' of git://git.infradead.org/users/willy/pagecache: (107 commits)
  nilfs2: Fix some kernel-doc comments
  Appoint myself page cache maintainer
  fs: Remove aops->freepage
  secretmem: Convert to free_folio
  nfs: Convert to free_folio
  orangefs: Convert to free_folio
  fs: Add free_folio address space operation
  fs: Convert drop_buffers() to use a folio
  fs: Change try_to_free_buffers() to take a folio
  jbd2: Convert release_buffer_page() to use a folio
  jbd2: Convert jbd2_journal_try_to_free_buffers to take a folio
  reiserfs: Convert release_buffer_page() to use a folio
  fs: Remove last vestiges of releasepage
  ubifs: Convert to release_folio
  reiserfs: Convert to release_folio
  orangefs: Convert to release_folio
  ocfs2: Convert to release_folio
  nilfs2: Remove comment about releasepage
  nfs: Convert to release_folio
  jfs: Convert to release_folio
  ...
parents 8642174b 516edb45
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -433,11 +433,11 @@ has done a write and then the page it wrote from has been released by the VM,
after which it *has* to look in the cache.

To inform fscache that a page might now be in the cache, the following function
should be called from the ``releasepage`` address space op::
should be called from the ``release_folio`` address space op::

	void fscache_note_page_release(struct fscache_cookie *cookie);

if the page has been released (ie. releasepage returned true).
if the page has been released (ie. release_folio returned true).

Page release and page invalidation should also wait for any mark left on the
page to say that a DIO write is underway from that page::
+1 −1
Original line number Diff line number Diff line
@@ -1256,7 +1256,7 @@ inline encryption hardware will encrypt/decrypt the file contents.
When inline encryption isn't used, filesystems must encrypt/decrypt
the file contents themselves, as described below:

For the read path (->readpage()) of regular files, filesystems can
For the read path (->read_folio()) of regular files, filesystems can
read the ciphertext into the page cache and decrypt it in-place.  The
page lock must be held until decryption has finished, to prevent the
page from becoming visible to userspace prematurely.
+1 −1
Original line number Diff line number Diff line
@@ -559,7 +559,7 @@ already verified). Below, we describe how filesystems implement this.
Pagecache
~~~~~~~~~

For filesystems using Linux's pagecache, the ``->readpage()`` and
For filesystems using Linux's pagecache, the ``->read_folio()`` and
``->readahead()`` methods must be modified to verify pages before they
are marked Uptodate.  Merely hooking ``->read_iter()`` would be
insufficient, since ``->read_iter()`` is not used for memory maps.
+18 −18
Original line number Diff line number Diff line
@@ -237,20 +237,20 @@ address_space_operations
prototypes::

	int (*writepage)(struct page *page, struct writeback_control *wbc);
	int (*readpage)(struct file *, struct page *);
	int (*read_folio)(struct file *, struct folio *);
	int (*writepages)(struct address_space *, struct writeback_control *);
	bool (*dirty_folio)(struct address_space *, struct folio *folio);
	void (*readahead)(struct readahead_control *);
	int (*write_begin)(struct file *, struct address_space *mapping,
				loff_t pos, unsigned len, unsigned flags,
				loff_t pos, unsigned len,
				struct page **pagep, void **fsdata);
	int (*write_end)(struct file *, struct address_space *mapping,
				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);
	int (*releasepage) (struct page *, int);
	void (*freepage)(struct page *);
	bool (*release_folio)(struct folio *, gfp_t);
	void (*free_folio)(struct folio *);
	int (*direct_IO)(struct kiocb *, struct iov_iter *iter);
	bool (*isolate_page) (struct page *, isolate_mode_t);
	int (*migratepage)(struct address_space *, struct page *, struct page *);
@@ -262,22 +262,22 @@ prototypes::
	int (*swap_deactivate)(struct file *);

locking rules:
	All except dirty_folio and freepage may block
	All except dirty_folio and free_folio may block

======================	======================== =========	===============
ops			PageLocked(page)	 i_rwsem	invalidate_lock
ops			folio locked		 i_rwsem	invalidate_lock
======================	======================== =========	===============
writepage:		yes, unlocks (see below)
readpage:		yes, unlocks				shared
read_folio:		yes, unlocks				shared
writepages:
dirty_folio		maybe
dirty_folio:		maybe
readahead:		yes, unlocks				shared
write_begin:		locks the page		 exclusive
write_end:		yes, unlocks		 exclusive
bmap:
invalidate_folio:	yes					exclusive
releasepage:		yes
freepage:		yes
release_folio:		yes
free_folio:		yes
direct_IO:
isolate_page:		yes
migratepage:		yes (both)
@@ -289,13 +289,13 @@ swap_activate: no
swap_deactivate:	no
======================	======================== =========	===============

->write_begin(), ->write_end() and ->readpage() may be called from
->write_begin(), ->write_end() and ->read_folio() may be called from
the request handler (/dev/loop).

->readpage() unlocks the page, either synchronously or via I/O
->read_folio() unlocks the folio, either synchronously or via I/O
completion.

->readahead() unlocks the pages that I/O is attempted on like ->readpage().
->readahead() unlocks the folios that I/O is attempted on like ->read_folio().

->writepage() is used for two purposes: for "memory cleansing" and for
"sync".  These are quite different operations and the behaviour may differ
@@ -372,12 +372,12 @@ 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
indicate that the buffers are (or may be) freeable.  If ->releasepage is zero,
the kernel assumes that the fs has no private interest in the buffers.
->release_folio() is called when the kernel is about to try to drop the
buffers from the folio in preparation for freeing it.  It returns false to
indicate that the buffers are (or may be) freeable.  If ->release_folio is
NULL, the kernel assumes that the fs has no private interest in the buffers.

->freepage() is called when the kernel is done dropping the page
->free_folio() is called when the kernel has dropped the folio
from the page cache.

->launder_folio() may be called prior to releasing a folio if
+4 −5
Original line number Diff line number Diff line
@@ -96,7 +96,7 @@ attached to an inode (or NULL if fscache is disabled)::
Buffered Read Helpers
=====================

The library provides a set of read helpers that handle the ->readpage(),
The library provides a set of read helpers that handle the ->read_folio(),
->readahead() and much of the ->write_begin() VM operations and translate them
into a common call framework.

@@ -136,20 +136,19 @@ Read Helper Functions
Three read helpers are provided::

	void netfs_readahead(struct readahead_control *ractl);
	int netfs_readpage(struct file *file,
			   struct page *page);
	int netfs_read_folio(struct file *file,
			   struct folio *folio);
	int netfs_write_begin(struct file *file,
			      struct address_space *mapping,
			      loff_t pos,
			      unsigned int len,
			      unsigned int flags,
			      struct folio **_folio,
			      void **_fsdata);

Each corresponds to a VM address space operation.  These operations use the
state in the per-inode context.

For ->readahead() and ->readpage(), the network filesystem just point directly
For ->readahead() and ->read_folio(), the network filesystem just point directly
at the corresponding read helper; whereas for ->write_begin(), it may be a
little more complicated as the network filesystem might want to flush
conflicting writes or track dirty data and needs to put the acquired folio if
Loading