Skip to content

Commit

Permalink
xfs: enable block size larger than page size support
Browse files Browse the repository at this point in the history
Page cache now has the ability to have a minimum order when allocating
a folio which is a prerequisite to add support for block size > page
size.

Signed-off-by: Pankaj Raghav <p.raghav@samsung.com>
Signed-off-by: Luis Chamberlain <mcgrof@kernel.org>
Link: https://lore.kernel.org/r/20240827-xfs-fix-wformat-bs-gt-ps-v1-1-aec6717609e0@kernel.org # fix folded
Link: https://lore.kernel.org/r/20240822135018.1931258-11-kernel@pankajraghav.com
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Dave Chinner <dchinner@redhat.com>
Signed-off-by: Christian Brauner <brauner@kernel.org>
  • Loading branch information
Panky-codes authored and brauner committed Sep 3, 2024
1 parent 713e9f7 commit ff45c33
Show file tree
Hide file tree
Showing 6 changed files with 45 additions and 11 deletions.
5 changes: 5 additions & 0 deletions fs/xfs/libxfs/xfs_ialloc.c
Original file line number Diff line number Diff line change
Expand Up @@ -3033,6 +3033,11 @@ xfs_ialloc_setup_geometry(
igeo->ialloc_align = mp->m_dalign;
else
igeo->ialloc_align = 0;

if (mp->m_sb.sb_blocksize > PAGE_SIZE)
igeo->min_folio_order = mp->m_sb.sb_blocklog - PAGE_SHIFT;
else
igeo->min_folio_order = 0;
}

/* Compute the location of the root directory inode that is laid out by mkfs. */
Expand Down
3 changes: 3 additions & 0 deletions fs/xfs/libxfs/xfs_shared.h
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,9 @@ struct xfs_ino_geometry {
/* precomputed value for di_flags2 */
uint64_t new_diflags2;

/* minimum folio order of a page cache allocation */
unsigned int min_folio_order;

};

#endif /* __XFS_SHARED_H__ */
6 changes: 4 additions & 2 deletions fs/xfs/xfs_icache.c
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,8 @@ xfs_inode_alloc(

/* VFS doesn't initialise i_mode! */
VFS_I(ip)->i_mode = 0;
mapping_set_large_folios(VFS_I(ip)->i_mapping);
mapping_set_folio_min_order(VFS_I(ip)->i_mapping,
M_IGEO(mp)->min_folio_order);

XFS_STATS_INC(mp, vn_active);
ASSERT(atomic_read(&ip->i_pincount) == 0);
Expand Down Expand Up @@ -325,7 +326,8 @@ xfs_reinit_inode(
inode->i_uid = uid;
inode->i_gid = gid;
inode->i_state = state;
mapping_set_large_folios(inode->i_mapping);
mapping_set_folio_min_order(inode->i_mapping,
M_IGEO(mp)->min_folio_order);
return error;
}

Expand Down
1 change: 0 additions & 1 deletion fs/xfs/xfs_mount.c
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,6 @@ xfs_sb_validate_fsb_count(
{
uint64_t max_bytes;

ASSERT(PAGE_SHIFT >= sbp->sb_blocklog);
ASSERT(sbp->sb_blocklog >= BBSHIFT);

if (check_shl_overflow(nblocks, sbp->sb_blocklog, &max_bytes))
Expand Down
28 changes: 20 additions & 8 deletions fs/xfs/xfs_super.c
Original file line number Diff line number Diff line change
Expand Up @@ -1638,16 +1638,28 @@ xfs_fs_fill_super(
goto out_free_sb;
}

/*
* Until this is fixed only page-sized or smaller data blocks work.
*/
if (mp->m_sb.sb_blocksize > PAGE_SIZE) {
xfs_warn(mp,
"File system with blocksize %d bytes. "
"Only pagesize (%ld) or less will currently work.",
size_t max_folio_size = mapping_max_folio_size_supported();

if (!xfs_has_crc(mp)) {
xfs_warn(mp,
"V4 Filesystem with blocksize %d bytes. Only pagesize (%ld) or less is supported.",
mp->m_sb.sb_blocksize, PAGE_SIZE);
error = -ENOSYS;
goto out_free_sb;
error = -ENOSYS;
goto out_free_sb;
}

if (mp->m_sb.sb_blocksize > max_folio_size) {
xfs_warn(mp,
"block size (%u bytes) not supported; Only block size (%zu) or less is supported",
mp->m_sb.sb_blocksize, max_folio_size);
error = -ENOSYS;
goto out_free_sb;
}

xfs_warn(mp,
"EXPERIMENTAL: V5 Filesystem with Large Block Size (%d bytes) enabled.",
mp->m_sb.sb_blocksize);
}

/* Ensure this filesystem fits in the page cache limits */
Expand Down
13 changes: 13 additions & 0 deletions include/linux/pagemap.h
Original file line number Diff line number Diff line change
Expand Up @@ -374,6 +374,19 @@ static inline void mapping_set_gfp_mask(struct address_space *m, gfp_t mask)
#define MAX_XAS_ORDER (XA_CHUNK_SHIFT * 2 - 1)
#define MAX_PAGECACHE_ORDER min(MAX_XAS_ORDER, PREFERRED_MAX_PAGECACHE_ORDER)

/*
* mapping_max_folio_size_supported() - Check the max folio size supported
*
* The filesystem should call this function at mount time if there is a
* requirement on the folio mapping size in the page cache.
*/
static inline size_t mapping_max_folio_size_supported(void)
{
if (IS_ENABLED(CONFIG_TRANSPARENT_HUGEPAGE))
return 1U << (PAGE_SHIFT + MAX_PAGECACHE_ORDER);
return PAGE_SIZE;
}

/*
* mapping_set_folio_order_range() - Set the orders supported by a file.
* @mapping: The address space of the file.
Expand Down

0 comments on commit ff45c33

Please sign in to comment.