Commit 66dabbb6 authored by Christoph Hellwig's avatar Christoph Hellwig Committed by Andrew Morton
Browse files

mm: return an ERR_PTR from __filemap_get_folio

Instead of returning NULL for all errors, distinguish between:

 - no entry found and not asked to allocated (-ENOENT)
 - failed to allocate memory (-ENOMEM)
 - would block (-EAGAIN)

so that callers don't have to guess the error based on the passed in
flags.

Also pass through the error through the direct callers: filemap_get_folio,
filemap_lock_folio filemap_grab_folio and filemap_get_incore_folio.

[hch@lst.de: fix null-pointer deref]
  Link: https://lkml.kernel.org/r/20230310070023.GA13563@lst.de
  Link: https://lkml.kernel.org/r/20230310043137.GA1624890@u2004
Link: https://lkml.kernel.org/r/20230307143410.28031-8-hch@lst.de


Signed-off-by: default avatarChristoph Hellwig <hch@lst.de>
Acked-by: Ryusuke Konishi <konishi.ryusuke@gmail.com> [nilfs2]
Cc: Andreas Gruenbacher <agruenba@redhat.com>
Cc: Hugh Dickins <hughd@google.com>
Cc: Matthew Wilcox (Oracle) <willy@infradead.org>
Cc: Naoya Horiguchi <naoya.horiguchi@linux.dev>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
parent 48c9d113
Loading
Loading
Loading
Loading
+5 −5
Original line number Diff line number Diff line
@@ -319,16 +319,16 @@ static struct afs_read *afs_read_dir(struct afs_vnode *dvnode, struct key *key)
		struct folio *folio;

		folio = filemap_get_folio(mapping, i);
		if (!folio) {
		if (IS_ERR(folio)) {
			if (test_and_clear_bit(AFS_VNODE_DIR_VALID, &dvnode->flags))
				afs_stat_v(dvnode, n_inval);

			ret = -ENOMEM;
			folio = __filemap_get_folio(mapping,
						    i, FGP_LOCK | FGP_CREAT,
						    mapping->gfp_mask);
			if (!folio)
			if (IS_ERR(folio)) {
				ret = PTR_ERR(folio);
				goto error;
			}
			folio_attach_private(folio, (void *)1);
			folio_unlock(folio);
		}
@@ -524,7 +524,7 @@ static int afs_dir_iterate(struct inode *dir, struct dir_context *ctx,
		 */
		folio = __filemap_get_folio(dir->i_mapping, ctx->pos / PAGE_SIZE,
					    FGP_ACCESSED, 0);
		if (!folio) {
		if (IS_ERR(folio)) {
			ret = afs_bad(dvnode, afs_file_error_dir_missing_page);
			break;
		}
+1 −1
Original line number Diff line number Diff line
@@ -115,7 +115,7 @@ static struct folio *afs_dir_get_folio(struct afs_vnode *vnode, pgoff_t index)
	folio = __filemap_get_folio(mapping, index,
				    FGP_LOCK | FGP_ACCESSED | FGP_CREAT,
				    mapping->gfp_mask);
	if (!folio)
	if (IS_ERR(folio))
		clear_bit(AFS_VNODE_DIR_VALID, &vnode->flags);
	else if (folio && !folio_test_private(folio))
		folio_attach_private(folio, (void *)1);
+2 −2
Original line number Diff line number Diff line
@@ -232,7 +232,7 @@ static void afs_kill_pages(struct address_space *mapping,
		_debug("kill %lx (to %lx)", index, last);

		folio = filemap_get_folio(mapping, index);
		if (!folio) {
		if (IS_ERR(folio)) {
			next = index + 1;
			continue;
		}
@@ -270,7 +270,7 @@ static void afs_redirty_pages(struct writeback_control *wbc,
		_debug("redirty %llx @%llx", len, start);

		folio = filemap_get_folio(mapping, index);
		if (!folio) {
		if (IS_ERR(folio)) {
			next = index + 1;
			continue;
		}
+1 −1
Original line number Diff line number Diff line
@@ -5395,7 +5395,7 @@ static void ext4_wait_for_tail_page_commit(struct inode *inode)
	while (1) {
		struct folio *folio = filemap_lock_folio(inode->i_mapping,
				      inode->i_size >> PAGE_SHIFT);
		if (!folio)
		if (IS_ERR(folio))
			return;
		ret = __ext4_journalled_invalidate_folio(folio, offset,
						folio_size(folio) - offset);
+4 −4
Original line number Diff line number Diff line
@@ -141,18 +141,18 @@ mext_folio_double_lock(struct inode *inode1, struct inode *inode2,
	flags = memalloc_nofs_save();
	folio[0] = __filemap_get_folio(mapping[0], index1, fgp_flags,
			mapping_gfp_mask(mapping[0]));
	if (!folio[0]) {
	if (IS_ERR(folio[0])) {
		memalloc_nofs_restore(flags);
		return -ENOMEM;
		return PTR_ERR(folio[0]);
	}

	folio[1] = __filemap_get_folio(mapping[1], index2, fgp_flags,
			mapping_gfp_mask(mapping[1]));
	memalloc_nofs_restore(flags);
	if (!folio[1]) {
	if (IS_ERR(folio[1])) {
		folio_unlock(folio[0]);
		folio_put(folio[0]);
		return -ENOMEM;
		return PTR_ERR(folio[1]);
	}
	/*
	 * __filemap_get_folio() may not wait on folio's writeback if
Loading