]> www.infradead.org Git - linux.git/commitdiff
xfs: enable block size larger than page size support
authorPankaj Raghav <p.raghav@samsung.com>
Thu, 22 Aug 2024 13:50:18 +0000 (15:50 +0200)
committerChristian Brauner <brauner@kernel.org>
Tue, 3 Sep 2024 13:00:52 +0000 (15:00 +0200)
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
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>
fs/xfs/libxfs/xfs_ialloc.c
fs/xfs/libxfs/xfs_shared.h
fs/xfs/xfs_icache.c
fs/xfs/xfs_mount.c
fs/xfs/xfs_super.c
include/linux/pagemap.h

index 0af5b7a33d0554e7018ab338cb97a48760089930..1921b689888b87b3623ebd7144c0f9030ae437f0 100644 (file)
@@ -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. */
index 2f7413afbf46cdfafb93ea15daa7d3b9013a5275..33b84a3a83ff6340cfd146050a057ff27209d6f3 100644 (file)
@@ -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__ */
index cf629302d48e7444cc34ff64d67a9a11ee51dd87..0fcf235e502354b55e0b16396725f1ffaac4960b 100644 (file)
@@ -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);
@@ -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;
 }
 
index 3949f720b5354b025409cf404bbfe2919fd97732..c6933440f80668f33dc165e07356849c5d238a10 100644 (file)
@@ -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))
index 27e9f749c4c7fc75c3385aba2e02ac9fc5d1719d..e8cc7900911eb50e6d58adf512b5fbd162dd66ef 100644 (file)
@@ -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 */
index 4cc170949e9c09e3b6b561d60cc1b6edca528ba6..55b254d951da712683d8a0a59cd8d4b0b960973a 100644 (file)
@@ -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.