From patchwork Thu Jun 20 20:59:01 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13706373 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 16A3A74267; Thu, 20 Jun 2024 20:59:01 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1718917142; cv=none; b=H1YC2251fQJuDyvSb9G/oHhQeGYhpPS55SwXH2/8XuO3lsudhEju7FnyBUAb+1KgAJln5yhQnawjM9/bQ/QAPQdup6oa9DxJUonG0IUV5scB/FofThvDc3lo/F/SVLVJmXjkhj40VcZP8cpb2E2q/rNeojjACkyqEElMP+15Q1c= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1718917142; c=relaxed/simple; bh=cCGKIvpusp+L8n26M6HutqBkmgdcbilOUuEoP1GJfOU=; h=Date:Subject:From:To:Cc:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=goQ5afj+JVZaNuLOfXwUxppPSupMGs8RZzmKIvsvIZTQGPK9sFnnN9KrCDpGJunhqgT15nYzZm+BoNed8LOSJIKdIcf/TmFuEh09952I1fnmJAzpV7HqB7+jyJ6hNERuMTxsGbNb1d/DP6SUcdv5jwmH0dKpx60KmMjYnWqzo/c= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=hQODsHpz; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="hQODsHpz" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 85BD4C2BD10; Thu, 20 Jun 2024 20:59:01 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1718917141; bh=cCGKIvpusp+L8n26M6HutqBkmgdcbilOUuEoP1GJfOU=; h=Date:Subject:From:To:Cc:In-Reply-To:References:From; b=hQODsHpz3uDEGtpqYv9QlY6ocnRAI2Vanvl030mL6SZlEUi9eFB6N1+GhPEZdaM2b xvdwdmjJJnBZ1lw/6JkU41DwC4JdM+QAnc9HZlbzDdo4QKCkFYkscjnYxmp7QLP45W VGrcwrJ645T0AnSHXT96Eyq4/xAByya2sAcUfTKGhqfWHwyKbyFpaYQSI4bQFXp4h2 nlfgppnWWNOsG+uxhNvvBkLMZTXNSEloMswyPL6jkBBfb6m1r7SsYHR/Qa5eXBySz8 YdZLM6m60BZ33RM+9d9FWCm0soglzj7eneF+5PRinJ+f2tl2LTHkjJ0JJ2n9bkRsDF P0cZKYxthQTXw== Date: Thu, 20 Jun 2024 13:59:01 -0700 Subject: [PATCH 08/11] common: add helpers for parent pointer tests From: "Darrick J. Wong" To: djwong@kernel.org, zlang@redhat.com Cc: Allison Henderson , Catherine Hoang , fstests@vger.kernel.org, allison.henderson@oracle.com, catherine.hoang@oracle.com, linux-xfs@vger.kernel.org Message-ID: <171891669761.3035255.13957512603260230023.stgit@frogsfrogsfrogs> In-Reply-To: <171891669626.3035255.15795876594098866722.stgit@frogsfrogsfrogs> References: <171891669626.3035255.15795876594098866722.stgit@frogsfrogsfrogs> User-Agent: StGit/0.19 Precedence: bulk X-Mailing-List: fstests@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Allison Henderson Add helper functions in common/parent to parse and verify parent pointers. Also add functions to check that mkfs, kernel, and xfs_io support parent pointers. Signed-off-by: Allison Henderson Signed-off-by: Catherine Hoang Reviewed-by: Darrick J. Wong [djwong: add license and copyright, dont _fail tests immediately, make sure the pptr-generated paths match the dir-generated paths] Signed-off-by: Darrick J. Wong Reviewed-by: Christoph Hellwig --- common/parent | 209 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ common/rc | 3 + common/xfs | 12 +++ 3 files changed, 224 insertions(+) create mode 100644 common/parent diff --git a/common/parent b/common/parent new file mode 100644 index 0000000000..ccdf2bb4bd --- /dev/null +++ b/common/parent @@ -0,0 +1,209 @@ +#! /bin/bash +# SPDX-License-Identifier: GPL-2.0 +# Copyright (c) 2022-2024 Oracle and/or its affiliates. All Rights Reserved. +# +# Parent pointer common functions +# + +# +# parse_parent_pointer parents parent_inode parent_pointer_name +# +# Given a list of parent pointers, find the record that matches +# the given inode and filename +# +# inputs: +# parents : A list of parent pointers in the format of: +# inode/generation/name_length/name +# parent_inode : The parent inode to search for +# parent_name : The parent name to search for +# +# outputs: +# PPINO : Parent pointer inode +# PPGEN : Parent pointer generation +# PPNAME : Parent pointer name +# PPNAME_LEN : Parent pointer name length +# +_xfs_parse_parent_pointer() +{ + local parents=$1 + local pino=$2 + local parent_pointer_name=$3 + + local found=0 + + # Find the entry that has the same inode as the parent + # and parse out the entry info + while IFS=':' read PPINO PPGEN PPNAME_LEN PPNAME; do + if [ "$PPINO" != "$pino" ]; then + continue + fi + + if [ "$PPNAME" != "$parent_pointer_name" ]; then + continue + fi + + found=1 + break + done <<< $(echo "$parents") + + # Check to see if we found anything + # We do not fail the test because we also use this + # routine to verify when parent pointers should + # be removed or updated (ie a rename or a move + # operation changes your parent pointer) + if [ $found -eq "0" ]; then + return 1 + fi + + # Verify the parent pointer name length is correct + if [ "$PPNAME_LEN" -ne "${#parent_pointer_name}" ] + then + echo "*** Bad parent pointer:"\ + "name:$PPNAME, namelen:$PPNAME_LEN" + fi + + #return sucess + return 0 +} + +# +# _xfs_verify_parent parent_path parent_pointer_name child_path +# +# Verify that the given child path lists the given parent as a parent pointer +# and that the parent pointer name matches the given name +# +# Examples: +# +# #simple example +# mkdir testfolder1 +# touch testfolder1/file1 +# verify_parent testfolder1 file1 testfolder1/file1 +# +# # In this above example, we want to verify that "testfolder1" +# # appears as a parent pointer of "testfolder1/file1". Additionally +# # we verify that the name record of the parent pointer is "file1" +# +# +# #hardlink example +# mkdir testfolder1 +# mkdir testfolder2 +# touch testfolder1/file1 +# ln testfolder1/file1 testfolder2/file1_ln +# verify_parent testfolder2 file1_ln testfolder1/file1 +# +# # In this above example, we want to verify that "testfolder2" +# # appears as a parent pointer of "testfolder1/file1". Additionally +# # we verify that the name record of the parent pointer is "file1_ln" +# +_xfs_verify_parent() +{ + local parent_path=$1 + local parent_pointer_name=$2 + local child_path=$3 + + local parent_ppath="$parent_path/$parent_pointer_name" + + # Verify parent exists + if [ ! -d $SCRATCH_MNT/$parent_path ]; then + echo "$SCRATCH_MNT/$parent_path not found" + else + echo "*** $parent_path OK" + fi + + # Verify child exists + if [ ! -f $SCRATCH_MNT/$child_path ]; then + echo "$SCRATCH_MNT/$child_path not found" + else + echo "*** $child_path OK" + fi + + # Verify the parent pointer name exists as a child of the parent + if [ ! -f $SCRATCH_MNT/$parent_ppath ]; then + echo "$SCRATCH_MNT/$parent_ppath not found" + else + echo "*** $parent_ppath OK" + fi + + # Get the inodes of both parent and child + pino="$(stat -c '%i' $SCRATCH_MNT/$parent_path)" + cino="$(stat -c '%i' $SCRATCH_MNT/$child_path)" + + # Get all the parent pointers of the child + parents=($($XFS_IO_PROG -x -c \ + "parent -s -i $pino -n $parent_pointer_name" $SCRATCH_MNT/$child_path)) + if [[ $? != 0 ]]; then + echo "No parent pointers found for $child_path" + fi + + # Parse parent pointer output. + # This sets PPINO PPGEN PPNAME PPNAME_LEN + _xfs_parse_parent_pointer $parents $pino $parent_pointer_name + + # If we didnt find one, bail out + if [ $? -ne 0 ]; then + echo "No parent pointer record found for $parent_path"\ + "in $child_path" + fi + + # Verify the inode generated by the parent pointer name is + # the same as the child inode + pppino="$(stat -c '%i' $SCRATCH_MNT/$parent_ppath)" + if [ $cino -ne $pppino ] + then + echo "Bad parent pointer name value for $child_path."\ + "$SCRATCH_MNT/$parent_ppath belongs to inode $PPPINO,"\ + "but should be $cino" + fi + + # Make sure path printing works by checking that the paths returned + # all point to the same inode. + local tgt="$SCRATCH_MNT/$child_path" + $XFS_IO_PROG -x -c 'parent -p' "$tgt" | while read pptr_path; do + test "$tgt" -ef "$pptr_path" || \ + echo "$tgt parent pointer $pptr_path should be the same file" + done + + echo "*** Verified parent pointer:"\ + "name:$PPNAME, namelen:$PPNAME_LEN" + echo "*** Parent pointer OK for child $child_path" +} + +# +# _xfs_verify_parent parent_pointer_name pino child_path +# +# Verify that the given child path contains no parent pointer entry +# for the given inode and file name +# +_xfs_verify_no_parent() +{ + local parent_pname=$1 + local pino=$2 + local child_path=$3 + + # Verify child exists + if [ ! -f $SCRATCH_MNT/$child_path ]; then + echo "$SCRATCH_MNT/$child_path not found" + else + echo "*** $child_path OK" + fi + + # Get all the parent pointers of the child + local parents=($($XFS_IO_PROG -x -c \ + "parent -s -i $pino -n $parent_pname" $SCRATCH_MNT/$child_path)) + if [[ $? != 0 ]]; then + return 0 + fi + + # Parse parent pointer output. + # This sets PPINO PPGEN PPNAME PPNAME_LEN + _xfs_parse_parent_pointer $parents $pino $parent_pname + + # If we didnt find one, return sucess + if [ $? -ne 0 ]; then + return 0 + fi + + echo "Parent pointer entry found where none should:"\ + "inode:$PPINO, gen:$PPGEN," + "name:$PPNAME, namelen:$PPNAME_LEN" +} diff --git a/common/rc b/common/rc index ba26fda6e6..0e0d49b87a 100644 --- a/common/rc +++ b/common/rc @@ -2742,6 +2742,9 @@ _require_xfs_io_command() echo $testio | grep -q "invalid option" && \ _notrun "xfs_io $command support is missing" ;; + "parent") + testio=`$XFS_IO_PROG -x -c "parent" $TEST_DIR 2>&1` + ;; "pwrite") # -N (RWF_NOWAIT) only works with direct vectored I/O writes local pwrite_opts=" " diff --git a/common/xfs b/common/xfs index b392237575..7706b56260 100644 --- a/common/xfs +++ b/common/xfs @@ -1863,3 +1863,15 @@ _xfs_force_no_pptrs() MKFS_OPTIONS="$MKFS_OPTIONS -n parent=0" } + +# this test requires the xfs parent pointers feature +# +_require_xfs_parent() +{ + _scratch_mkfs_xfs_supported -n parent > /dev/null 2>&1 \ + || _notrun "mkfs.xfs does not support parent pointers" + _scratch_mkfs_xfs -n parent > /dev/null 2>&1 + _try_scratch_mount >/dev/null 2>&1 \ + || _notrun "kernel does not support parent pointers" + _scratch_unmount +}