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: Matthew Wilcox (Oracle) <willy@infradead.org>
Signed-off-by: Jan Kara <jack@suse.cz>
Message-Id: <20230921200746.3303942-2-willy@infradead.org>
This commit is contained in:
Matthew Wilcox (Oracle) 2023-09-21 21:07:39 +01:00 committed by Jan Kara
parent 3de6047f18
commit 46f84a9bea

View file

@ -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;