Commit 46f84a9b authored by Matthew Wilcox (Oracle)'s avatar Matthew Wilcox (Oracle) Committed by Jan Kara
Browse files

ext2: Convert ext2_check_page to ext2_check_folio



Support in this function for large folios is limited to supporting
filesystems with block size > PAGE_SIZE.  This new functionality will only
be supported on machines without HIGHMEM, so the problem of kmap_local
only being able to map a single page in the folio can be ignored.
We will not use large folios for ext2 directories on HIGHMEM machines.

Signed-off-by: default avatarMatthew Wilcox (Oracle) <willy@infradead.org>
Signed-off-by: default avatarJan Kara <jack@suse.cz>
Message-Id: <20230921200746.3303942-2-willy@infradead.org>
parent 3de6047f
Loading
Loading
Loading
Loading
+14 −14
Original line number Diff line number Diff line
@@ -96,19 +96,19 @@ static void ext2_commit_chunk(struct page *page, loff_t pos, unsigned len)
	unlock_page(page);
}

static bool ext2_check_page(struct page *page, int quiet, char *kaddr)
static bool ext2_check_folio(struct folio *folio, int quiet, char *kaddr)
{
	struct inode *dir = page->mapping->host;
	struct inode *dir = folio->mapping->host;
	struct super_block *sb = dir->i_sb;
	unsigned chunk_size = ext2_chunk_size(dir);
	u32 max_inumber = le32_to_cpu(EXT2_SB(sb)->s_es->s_inodes_count);
	unsigned offs, rec_len;
	unsigned limit = PAGE_SIZE;
	unsigned limit = folio_size(folio);
	ext2_dirent *p;
	char *error;

	if ((dir->i_size >> PAGE_SHIFT) == page->index) {
		limit = dir->i_size & ~PAGE_MASK;
	if (dir->i_size < folio_pos(folio) + limit) {
		limit = offset_in_folio(folio, dir->i_size);
		if (limit & (chunk_size - 1))
			goto Ebadsize;
		if (!limit)
@@ -132,7 +132,7 @@ static bool ext2_check_page(struct page *page, int quiet, char *kaddr)
	if (offs != limit)
		goto Eend;
out:
	SetPageChecked(page);
	folio_set_checked(folio);
	return true;

	/* Too bad, we had an error */
@@ -160,22 +160,22 @@ static bool ext2_check_page(struct page *page, int quiet, char *kaddr)
bad_entry:
	if (!quiet)
		ext2_error(sb, __func__, "bad entry in directory #%lu: : %s - "
			"offset=%lu, inode=%lu, rec_len=%d, name_len=%d",
			dir->i_ino, error, (page->index<<PAGE_SHIFT)+offs,
			"offset=%llu, inode=%lu, rec_len=%d, name_len=%d",
			dir->i_ino, error, folio_pos(folio) + offs,
			(unsigned long) le32_to_cpu(p->inode),
			rec_len, p->name_len);
	goto fail;
Eend:
	if (!quiet) {
		p = (ext2_dirent *)(kaddr + offs);
		ext2_error(sb, "ext2_check_page",
		ext2_error(sb, "ext2_check_folio",
			"entry in directory #%lu spans the page boundary"
			"offset=%lu, inode=%lu",
			dir->i_ino, (page->index<<PAGE_SHIFT)+offs,
			"offset=%llu, inode=%lu",
			dir->i_ino, folio_pos(folio) + offs,
			(unsigned long) le32_to_cpu(p->inode));
	}
fail:
	SetPageError(page);
	folio_set_error(folio);
	return false;
}

@@ -195,9 +195,9 @@ static void *ext2_get_page(struct inode *dir, unsigned long n,

	if (IS_ERR(folio))
		return ERR_CAST(folio);
	page_addr = kmap_local_folio(folio, n & (folio_nr_pages(folio) - 1));
	page_addr = kmap_local_folio(folio, 0);
	if (unlikely(!folio_test_checked(folio))) {
		if (!ext2_check_page(&folio->page, quiet, page_addr))
		if (!ext2_check_folio(folio, quiet, page_addr))
			goto fail;
	}
	*page = &folio->page;