From patchwork Tue Aug 2 23:52:51 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 9260501 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id AC74760865 for ; Tue, 2 Aug 2016 23:53:36 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 9CD5427F2B for ; Tue, 2 Aug 2016 23:53:36 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 8EDED28508; Tue, 2 Aug 2016 23:53:36 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-4.2 required=2.0 tests=BAYES_00, RCVD_IN_DNSWL_MED, UNPARSEABLE_RELAY autolearn=ham version=3.3.1 Received: from oss.sgi.com (oss.sgi.com [192.48.182.195]) (using TLSv1 with cipher DHE-RSA-CAMELLIA256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 4953527F2B for ; Tue, 2 Aug 2016 23:53:34 +0000 (UTC) Received: from oss.sgi.com (localhost [IPv6:::1]) by oss.sgi.com (Postfix) with ESMTP id B3CF07CA6; Tue, 2 Aug 2016 18:53:33 -0500 (CDT) X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id D9BCA7CA4 for ; Tue, 2 Aug 2016 18:53:31 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id 903A38F8033 for ; Tue, 2 Aug 2016 16:53:31 -0700 (PDT) X-ASG-Debug-ID: 1470182007-0bf8157e6c3dfd30001-NocioJ Received: from aserp1040.oracle.com (aserp1040.oracle.com [141.146.126.69]) by cuda.sgi.com with ESMTP id cE1J6u3CH93K8M59 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 02 Aug 2016 16:53:27 -0700 (PDT) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Effective-Source-IP: aserp1040.oracle.com[141.146.126.69] X-Barracuda-Apparent-Source-IP: 141.146.126.69 Received: from userv0022.oracle.com (userv0022.oracle.com [156.151.31.74]) by aserp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id u72Nr2YT020828 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Tue, 2 Aug 2016 23:53:02 GMT Received: from userv0121.oracle.com (userv0121.oracle.com [156.151.31.72]) by userv0022.oracle.com (8.14.4/8.13.8) with ESMTP id u72Nr2pi022185 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Tue, 2 Aug 2016 23:53:02 GMT Received: from abhmp0011.oracle.com (abhmp0011.oracle.com [141.146.116.17]) by userv0121.oracle.com (8.13.8/8.13.8) with ESMTP id u72Nqs6l014229; Tue, 2 Aug 2016 23:53:00 GMT Received: from localhost (/24.21.211.40) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Tue, 02 Aug 2016 16:52:54 -0700 Date: Tue, 2 Aug 2016 16:52:51 -0700 From: "Darrick J. Wong" To: david@fromorbit.com, eguan@redhat.com Subject: [PATCH] xfs: test attr_list_by_handle cursor iteration Message-ID: <20160802235251.GB8586@birch.djwong.org> X-ASG-Orig-Subj: [PATCH] xfs: test attr_list_by_handle cursor iteration MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.5.24 (2015-08-30) X-Source-IP: userv0022.oracle.com [156.151.31.74] X-Barracuda-Connect: aserp1040.oracle.com[141.146.126.69] X-Barracuda-Start-Time: 1470182007 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Barracuda-Scan-Msg-Size: 8719 X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=BSF_SC0_MISMATCH_TO, UNPARSEABLE_RELAY X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.31704 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 BSF_SC0_MISMATCH_TO Envelope rcpt doesn't match header 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines Cc: Christoph Hellwig , fstests@vger.kernel.org, linux-btrfs@vger.kernel.org, xfs@oss.sgi.com X-BeenThere: xfs@oss.sgi.com X-Mailman-Version: 2.1.14 Precedence: list List-Id: XFS Filesystem from SGI List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: xfs-bounces@oss.sgi.com Sender: xfs-bounces@oss.sgi.com X-Virus-Scanned: ClamAV using ClamSMTP Apparently the XFS attr_list_by_handle ioctl has never actually copied the cursor contents back to user space, which means that iteration has never worked. Add a test case for this and see the patch "xfs: in _attrlist_by_handle, copy the cursor back to userspace". Signed-off-by: Darrick J. Wong --- src/Makefile | 3 - src/attr-list-by-handle-cursor-test.c | 186 +++++++++++++++++++++++++++++++++ tests/xfs/700 | 64 +++++++++++ tests/xfs/700.out | 5 + tests/xfs/group | 1 5 files changed, 258 insertions(+), 1 deletion(-) create mode 100644 src/attr-list-by-handle-cursor-test.c create mode 100755 tests/xfs/700 create mode 100644 tests/xfs/700.out diff --git a/src/Makefile b/src/Makefile index 1bf318b..ae06d50 100644 --- a/src/Makefile +++ b/src/Makefile @@ -20,7 +20,8 @@ LINUX_TARGETS = xfsctl bstat t_mtab getdevicesize preallo_rw_pattern_reader \ bulkstat_unlink_test_modified t_dir_offset t_futimens t_immutable \ stale_handle pwrite_mmap_blocked t_dir_offset2 seek_sanity_test \ seek_copy_test t_readdir_1 t_readdir_2 fsync-tester nsexec cloner \ - renameat2 t_getcwd e4compact test-nextquota punch-alternating + renameat2 t_getcwd e4compact test-nextquota punch-alternating \ + attr-list-by-handle-cursor-test SUBDIRS = diff --git a/src/attr-list-by-handle-cursor-test.c b/src/attr-list-by-handle-cursor-test.c new file mode 100644 index 0000000..5aef79c --- /dev/null +++ b/src/attr-list-by-handle-cursor-test.c @@ -0,0 +1,186 @@ +/* + * Copyright (C) 2016 Oracle. All Rights Reserved. + * + * Author: Darrick J. Wong + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it would be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define ATTRBUFSZ 1024 +#define BSTATBUF_SZ 1024 + +/* Read all the extended attributes of a file handle. */ +void +read_handle_xattrs( + struct xfs_handle *handle, + bool root_space) +{ + struct attrlist_cursor cur; + char attrbuf[ATTRBUFSZ]; + char *firstname = NULL; + struct attrlist *attrlist = (struct attrlist *)attrbuf; + struct attrlist_ent *ent; + int i; + int flags = 0; + int error; + + if (root_space) + flags |= ATTR_ROOT; + + memset(&cur, 0, sizeof(cur)); + while ((error = attr_list_by_handle(handle, sizeof(*handle), + attrbuf, ATTRBUFSZ, flags, + &cur)) == 0) { + for (i = 0; i < attrlist->al_count; i++) { + ent = ATTR_ENTRY(attrlist, i); + + if (i != 0) + continue; + + if (firstname == NULL) { + firstname = malloc(ent->a_valuelen); + memcpy(firstname, ent->a_name, ent->a_valuelen); + } else { + if (memcmp(firstname, ent->a_name, + ent->a_valuelen) == 0) + fprintf(stderr, + "Saw duplicate xattr \"%s\", buggy XFS?\n", + ent->a_name); + else + fprintf(stderr, + "Test passes.\n"); + goto out; + } + } + + if (!attrlist->al_more) + break; + } + +out: + if (firstname) + free(firstname); + if (error) + perror("attr_list_by_handle"); + return; +} + +/* Iterate a range of inodes. */ +void +find_inode( + struct xfs_handle *fshandle, + int fd, + ino_t ino) +{ + struct xfs_fsop_bulkreq bulkreq; + struct xfs_bstat *bstatbuf; + struct xfs_bstat *p; + struct xfs_bstat *endp; + struct xfs_handle handle; + __u64 first_ino = ino & ~63; + __s32 buflenout = 0; + int error; + + bstatbuf = malloc(BSTATBUF_SZ * sizeof(struct xfs_bstat)); + if (!bstatbuf) { + perror("bulkstat malloc"); + return; + } + + bulkreq.lastip = (__u64 *)&first_ino; + bulkreq.icount = BSTATBUF_SZ; + bulkreq.ubuffer = (void *)bstatbuf; + bulkreq.ocount = &buflenout; + + memcpy(&handle.ha_fsid, fshandle, sizeof(handle.ha_fsid)); + handle.ha_fid.fid_len = sizeof(xfs_fid_t) - + sizeof(handle.ha_fid.fid_len); + handle.ha_fid.fid_pad = 0; + while ((error = xfsctl("", fd, XFS_IOC_FSBULKSTAT, &bulkreq)) == 0) { + if (buflenout == 0) + break; + for (p = bstatbuf, endp = bstatbuf + buflenout; p < endp; p++) { + if (p->bs_ino > ino) { + fprintf(stderr, + "Expected ino %llu, got %llu.\n", + (unsigned long long)ino, p->bs_ino); + goto out; + } + + handle.ha_fid.fid_gen = p->bs_gen; + handle.ha_fid.fid_ino = p->bs_ino; + + read_handle_xattrs(&handle, false); + read_handle_xattrs(&handle, true); + goto out; + } + } + + if (error) + perror("bulkstat"); +out: + free(bstatbuf); + return; +} + +int main( + int argc, + char *argv[]) +{ + struct xfs_handle *fshandle; + size_t fshandle_len; + struct stat sb; + int fd; + int error; + + if (argc != 2) { + fprintf(stderr, "Usage: %s filename\n", argv[0]); + return 1; + } + + error = path_to_fshandle(argv[1], (void **)&fshandle, &fshandle_len); + if (error) { + perror("getting fshandle"); + return 2; + } + + fd = open(argv[1], O_RDONLY); + if (fd < 0) { + perror("opening file"); + return 2; + } + + error = fstat(fd, &sb); + if (error) { + perror("fstat file"); + return 2; + } + + find_inode(fshandle, fd, sb.st_ino); + + close(fd); + free_handle(fshandle, fshandle_len); + return 0; +} diff --git a/tests/xfs/700 b/tests/xfs/700 new file mode 100755 index 0000000..4a5680d --- /dev/null +++ b/tests/xfs/700 @@ -0,0 +1,64 @@ +#! /bin/bash +# FS QA Test No. 700 +# +# Check that attr_list_by_handle copies the cursor back to userspace. +# +#----------------------------------------------------------------------- +# Copyright (c) 2016, Oracle and/or its affiliates. All Rights Reserved. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it would be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +#----------------------------------------------------------------------- + +seq=`basename "$0"` +seqres="$RESULT_DIR/$seq" +echo "QA output created by $seq" + +here=`pwd` +tmp=/tmp/$$ +status=1 # failure is the default! +trap "_cleanup; exit \$status" 0 1 2 3 15 + +_cleanup() +{ + cd / + rm -rf "$tmp".* $TEST_DIR/fsmap $TEST_DIR/testout +} + +# get standard environment, filters and checks +. ./common/rc +. ./common/filter +. ./common/attr +. ./common/populate + +# real QA test starts here +_supported_os Linux +_require_scratch +_require_test_program "attr-list-by-handle-cursor-test" + +rm -f "$seqres.full" + +echo "Format and mount" +_scratch_mkfs > "$seqres.full" 2>&1 +_scratch_mount + +echo "Stuff file with xattrs" +mkdir $SCRATCH_MNT/foo +__populate_create_attr $SCRATCH_MNT/foo 100 + +echo "Run test program" +./src/attr-list-by-handle-cursor-test $SCRATCH_MNT/foo + +# success, all done +status=0 +exit diff --git a/tests/xfs/700.out b/tests/xfs/700.out new file mode 100644 index 0000000..493a68a --- /dev/null +++ b/tests/xfs/700.out @@ -0,0 +1,5 @@ +QA output created by 700 +Format and mount +Stuff file with xattrs +Run test program +Test passes. diff --git a/tests/xfs/group b/tests/xfs/group index ff0efa5..ae12e74 100644 --- a/tests/xfs/group +++ b/tests/xfs/group @@ -307,3 +307,4 @@ 325 auto quick clone 326 auto quick clone 327 auto quick clone +700 auto quick