common: extract rt extent size for _get_file_block_size
authorDarrick J. Wong <darrick.wong@oracle.com>
Wed, 11 Nov 2020 00:42:59 +0000 (16:42 -0800)
committerEryu Guan <guaneryu@gmail.com>
Sun, 22 Nov 2020 13:54:55 +0000 (21:54 +0800)
_get_file_block_size is intended to return the size (in bytes) of the
fundamental allocation unit for a file.  This is required for remapping
operations like fallocate and reflink, which can only operate on
allocation units.  Since the XFS realtime volume can be configure for
allocation units larger than 1 fs block, we need to factor that in here.

Note that ext* with bigalloc does not allocations to be aligned to the
cluster size, so no update is needed there.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: Chandan Babu R <chandanrlinux@gmail.com>
Signed-off-by: Eryu Guan <guaneryu@gmail.com>
common/rc
common/xfs

index e6a5b07b82be34843f5489c731e10f1c3c505f9e..985472cde3b7c8026bb297340f2b89287993d6f7 100644 (file)
--- a/common/rc
+++ b/common/rc
@@ -3991,11 +3991,18 @@ _get_file_block_size()
                echo "Missing mount point argument for _get_file_block_size"
                exit 1
        fi
                echo "Missing mount point argument for _get_file_block_size"
                exit 1
        fi
-       if [ "$FSTYP" = "ocfs2" ]; then
+
+       case "$FSTYP" in
+       "ocfs2")
                stat -c '%o' $1
                stat -c '%o' $1
-       else
+               ;;
+       "xfs")
+               _xfs_get_file_block_size $1
+               ;;
+       *)
                _get_block_size $1
                _get_block_size $1
-       fi
+               ;;
+       esac
 }
 
 # Get the minimum block size of an fs.
 }
 
 # Get the minimum block size of an fs.
index 79dab0583b40104e3bc95641d23ddfbf39530268..3f5c14baec363783b02492f19d4a771c84118247 100644 (file)
@@ -174,6 +174,26 @@ _scratch_mkfs_xfs()
        return $mkfs_status
 }
 
        return $mkfs_status
 }
 
+# Get the size of an allocation unit of a file.  Normally this is just the
+# block size of the file, but for realtime files, this is the realtime extent
+# size.
+_xfs_get_file_block_size()
+{
+       local path="$1"
+
+       if ! ($XFS_IO_PROG -c "stat -v" "$path" 2>&1 | egrep -q '(rt-inherit|realtime)'); then
+               _get_block_size "$path"
+               return
+       fi
+
+       # Otherwise, call xfs_info until we find a mount point or the root.
+       path="$(readlink -m "$path")"
+       while ! $XFS_INFO_PROG "$path" &>/dev/null && [ "$path" != "/" ]; do
+               path="$(dirname "$path")"
+       done
+       $XFS_INFO_PROG "$path" | grep realtime | sed -e 's/^.*extsz=\([0-9]*\).*$/\1/g'
+}
+
 # xfs_check script is planned to be deprecated. But, we want to
 # be able to invoke "xfs_check" behavior in xfstests in order to
 # maintain the current verification levels.
 # xfs_check script is planned to be deprecated. But, we want to
 # be able to invoke "xfs_check" behavior in xfstests in order to
 # maintain the current verification levels.