]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
xfs: create a new helper to return a file's allocation unit
authorDarrick J. Wong <djwong@kernel.org>
Wed, 11 Jun 2025 21:01:17 +0000 (14:01 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 27 Jun 2025 10:07:19 +0000 (11:07 +0100)
[ Upstream commit ee20808d848c87a51e176706d81b95a21747d6cf ]

Create a new helper function to calculate the fundamental allocation
unit (i.e. the smallest unit of space we can allocate) of a file.
Things are going to get hairy with range-exchange on the realtime
device, so prepare for this now.

Remove the static attribute from xfs_is_falloc_aligned since the next
patch will need it.

Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Leah Rumancik <leah.rumancik@gmail.com>
Acked-by: "Darrick J. Wong" <djwong@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
fs/xfs/xfs_file.c
fs/xfs/xfs_file.h
fs/xfs/xfs_inode.c
fs/xfs/xfs_inode.h

index 6f7522977f7f766ab9674988b7abc10614fad1a3..3c910e36da69bf33d973d830b7e1511d6d7c0a03 100644 (file)
@@ -39,33 +39,25 @@ static const struct vm_operations_struct xfs_file_vm_ops;
  * Decide if the given file range is aligned to the size of the fundamental
  * allocation unit for the file.
  */
-static bool
+bool
 xfs_is_falloc_aligned(
        struct xfs_inode        *ip,
        loff_t                  pos,
        long long int           len)
 {
-       struct xfs_mount        *mp = ip->i_mount;
-       uint64_t                mask;
-
-       if (XFS_IS_REALTIME_INODE(ip)) {
-               if (!is_power_of_2(mp->m_sb.sb_rextsize)) {
-                       u64     rextbytes;
-                       u32     mod;
-
-                       rextbytes = XFS_FSB_TO_B(mp, mp->m_sb.sb_rextsize);
-                       div_u64_rem(pos, rextbytes, &mod);
-                       if (mod)
-                               return false;
-                       div_u64_rem(len, rextbytes, &mod);
-                       return mod == 0;
-               }
-               mask = XFS_FSB_TO_B(mp, mp->m_sb.sb_rextsize) - 1;
-       } else {
-               mask = mp->m_sb.sb_blocksize - 1;
+       unsigned int            alloc_unit = xfs_inode_alloc_unitsize(ip);
+
+       if (!is_power_of_2(alloc_unit)) {
+               u32     mod;
+
+               div_u64_rem(pos, alloc_unit, &mod);
+               if (mod)
+                       return false;
+               div_u64_rem(len, alloc_unit, &mod);
+               return mod == 0;
        }
 
-       return !((pos | len) & mask);
+       return !((pos | len) & (alloc_unit - 1));
 }
 
 /*
index 7d39e3eca56dc90a24d62c8728dbfa5c2b05c5e2..2ad91f755caf35e57bc338aea6b545be93f10080 100644 (file)
@@ -9,4 +9,7 @@
 extern const struct file_operations xfs_file_operations;
 extern const struct file_operations xfs_dir_file_operations;
 
+bool xfs_is_falloc_aligned(struct xfs_inode *ip, loff_t pos,
+               long long int len);
+
 #endif /* __XFS_FILE_H__ */
index 88d0a088fa862067653f8e862a48882c9e6d6e16..3ccbc31767b3ccdeb25eb7047393c0205729d8b8 100644 (file)
@@ -3775,3 +3775,16 @@ xfs_inode_reload_unlinked(
 
        return error;
 }
+
+/* Returns the size of fundamental allocation unit for a file, in bytes. */
+unsigned int
+xfs_inode_alloc_unitsize(
+       struct xfs_inode        *ip)
+{
+       unsigned int            blocks = 1;
+
+       if (XFS_IS_REALTIME_INODE(ip))
+               blocks = ip->i_mount->m_sb.sb_rextsize;
+
+       return XFS_FSB_TO_B(ip->i_mount, blocks);
+}
index c177c92f3aa578454085c9ed8aaf74e95e594d8d..c4f426eadf8e2f7f2d67df3d23d754a21414f388 100644 (file)
@@ -622,4 +622,6 @@ xfs_inode_unlinked_incomplete(
 int xfs_inode_reload_unlinked_bucket(struct xfs_trans *tp, struct xfs_inode *ip);
 int xfs_inode_reload_unlinked(struct xfs_inode *ip);
 
+unsigned int xfs_inode_alloc_unitsize(struct xfs_inode *ip);
+
 #endif /* __XFS_INODE_H__ */