xfs: create a new helper to return a file's allocation unit
authorDarrick J. Wong <djwong@kernel.org>
Mon, 15 Apr 2024 21:54:10 +0000 (14:54 -0700)
committerDarrick J. Wong <djwong@kernel.org>
Mon, 15 Apr 2024 21:54:10 +0000 (14:54 -0700)
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>
fs/xfs/xfs_file.c
fs/xfs/xfs_file.h
fs/xfs/xfs_inode.c
fs/xfs/xfs_inode.h

index 9961d4b5efbe60adbbd476788cac2b85b42142b1..64278f8acaeee0675567431f7dc089eaef44de89 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 39e6f88e9691a70fe54a17cb54d96806bde1f85e..492dae0efad241e39531cd82a7a4df21321a900f 100644 (file)
@@ -4008,3 +4008,16 @@ xfs_break_layouts(
 
        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 b2dde0e0f265ad1e85e30708cbc6e3882e310ed2..fa3e605901e24269033deeebce2cb3da8d0adc9c 100644 (file)
@@ -625,6 +625,7 @@ int xfs_inode_reload_unlinked(struct xfs_inode *ip);
 bool xfs_ifork_zapped(const struct xfs_inode *ip, int whichfork);
 void xfs_inode_count_blocks(struct xfs_trans *tp, struct xfs_inode *ip,
                xfs_filblks_t *dblocks, xfs_filblks_t *rblocks);
+unsigned int xfs_inode_alloc_unitsize(struct xfs_inode *ip);
 
 struct xfs_dir_update_params {
        const struct xfs_inode  *dp;