From patchwork Tue Mar 28 10:22:31 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Howells X-Patchwork-Id: 9648781 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 BC37A601E9 for ; Tue, 28 Mar 2017 10:32:29 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 9DC8327F81 for ; Tue, 28 Mar 2017 10:32:29 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 92AED28343; Tue, 28 Mar 2017 10:32:29 +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=-6.9 required=2.0 tests=BAYES_00,RCVD_IN_DNSWL_HI autolearn=unavailable version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 2286227F81 for ; Tue, 28 Mar 2017 10:32:29 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754703AbdC1KcY convert rfc822-to-8bit (ORCPT ); Tue, 28 Mar 2017 06:32:24 -0400 Received: from mx1.redhat.com ([209.132.183.28]:54512 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754107AbdC1KcX (ORCPT ); Tue, 28 Mar 2017 06:32:23 -0400 Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.14]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 898717F6A8; Tue, 28 Mar 2017 10:22:33 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com 898717F6A8 Authentication-Results: ext-mx01.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx01.extmail.prod.ext.phx2.redhat.com; spf=pass smtp.mailfrom=dhowells@redhat.com DKIM-Filter: OpenDKIM Filter v2.11.0 mx1.redhat.com 898717F6A8 Received: from warthog.procyon.org.uk (ovpn-120-211.rdu2.redhat.com [10.10.120.211]) by smtp.corp.redhat.com (Postfix) with ESMTP id 23DA17F968; Tue, 28 Mar 2017 10:22:32 +0000 (UTC) Organization: Red Hat UK Ltd. Registered Address: Red Hat UK Ltd, Amberley Place, 107-111 Peascod Street, Windsor, Berkshire, SI4 1TE, United Kingdom. Registered in England and Wales under Company Registration No. 3798903 From: David Howells In-Reply-To: <3791d155-b448-5257-d8b9-8a6f20e12180@sandeen.net> References: <3791d155-b448-5257-d8b9-8a6f20e12180@sandeen.net> <7a090a8e-7204-1b9b-8b31-e7a061b39f87@sandeen.net> To: Eric Sandeen Cc: dhowells@redhat.com, linux-xfs , Andreas Dilger , Christoph Hellwig , fsdevel Subject: [PATCH] xfs_io: changes to statx interface MIME-Version: 1.0 Content-ID: <22057.1490696551.1@warthog.procyon.org.uk> Date: Tue, 28 Mar 2017 11:22:31 +0100 Message-ID: <22058.1490696551@warthog.procyon.org.uk> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.14 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.25]); Tue, 28 Mar 2017 10:22:33 +0000 (UTC) Sender: linux-xfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Eric Sandeen wrote: > Wire up the statx syscall to xfs_io. > > xfs_io> help statx > statx [-O | -m mask][-FDLA] -- extended information about the currently open file > ... I would like to make the attached changes, to make it more capable, except that xfs_io seems to precheck the "-m mask" argument somewhere: [root@andromeda ~]# xfs_io -c statx -m all /dev/null non-numeric mode -- all and interprets "-c" for itself on the command line: [root@andromeda ~]# xfs_io -c statx -c /dev/null command "/dev/null" not found though both these seem to work when used from xfs_io's command prompt. I guess I should switch -c to -C and also -m to -M since it's not a file mode as I think the core is expecting. Also, how do you get xfs_io to tell you what fd it has opened from its own command prompt? I would need to pass that to the -d flag as a dir fd. David --- commit 03e4ca1cdc59aaa362fdd51f079493a1f0da254c Author: David Howells Date: Tue Mar 28 10:42:23 2017 +0100 changes -- To unsubscribe from this list: send the line "unsubscribe linux-xfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html diff --git a/io/stat.c b/io/stat.c index a7aebcd..0b05ec9 100644 --- a/io/stat.c +++ b/io/stat.c @@ -189,12 +189,14 @@ statx_help(void) " Display extended file status.\n" "\n" " Options:\n" -" -m mask -- Specify the field mask for the statx call (default STATX_ALL)\n" +" -c -- Compare against fstat/fstatat on the same file/fd\n" +" -d dirfd -- Use a specific directory fd\n" +" -f -- Do fstat equivalent and operate on fd\n" +" -m mask -- Specify the field mask for the statx call (can also be 'basic' or 'all'; default STATX_ALL)\n" " -A -- Suppress terminal automount traversal\n" " -D -- Don't sync attributes with the server\n" " -F -- Force the attributes to be sync'd with the server\n" " -L -- Follow symlinks (statx link target)\n" -" -O -- Add only basic stats (STATX_BASIC_STATS) to default mask\n" "\n")); } @@ -227,6 +229,65 @@ dump_statx(struct statx *stx) } /* + * Compare the contents of a statx struct with that of a stat struct and check + * that they're the same. + */ +static int +cmp_statx(const struct statx *stx, const struct stat *st) +{ + const char *what = NULL; + +#define cmp(x) \ + do { \ + what = #x; \ + if (stx->stx_##x != st->st_##x) \ + goto mismatch; \ + } while (0) + + cmp(blksize); + cmp(nlink); + cmp(uid); + cmp(gid); + cmp(mode); + cmp(ino); + cmp(size); + cmp(blocks); + +#define devcmp(x) \ + do { \ + what = #x".major"; \ + if (stx->stx_##x##_major != major(st->st_##x)) \ + goto mismatch; \ + what = #x".minor"; \ + if (stx->stx_##x##_minor != minor(st->st_##x)) \ + goto mismatch; \ + } while (0) + + devcmp(dev); + devcmp(rdev); + +#define timecmp(x) \ + do { \ + what = #x".tv_sec"; \ + if (stx->stx_##x##time.tv_sec != st->st_##x##tim.tv_sec) \ + goto mismatch; \ + what = #x".tv_nsec"; \ + if (stx->stx_##x##time.tv_nsec != st->st_##x##tim.tv_nsec) \ + goto mismatch; \ + } while (0) + + timecmp(a); + timecmp(c); + timecmp(m); + + return 0; + +mismatch: + fprintf(stderr, "Mismatch between stat and statx output (%s)\n", what); + return -1; +} + +/* * options: * - input flags - query type * - output style for flags (and all else?) (chars vs. hex?) @@ -239,16 +300,31 @@ statx_f( { int c; struct statx stx; + struct stat st; int atflag = AT_SYMLINK_NOFOLLOW; - unsigned int m_mask = 0; /* mask requested with -m */ - int Oflag = 0, mflag = 0; /* -O or -m was used */ unsigned int mask = STATX_ALL; + int use_fd = 0; + int dirfd = AT_FDCWD; + int compare = 0; - while ((c = getopt(argc, argv, "m:FDLOA")) != EOF) { + while ((c = getopt(argc, argv, "d:cfm:FDLA")) != EOF) { switch (c) { + case 'c': + compare = 1; + break; + case 'd': + dirfd = strtoul(optarg, NULL, 0); + break; + case 'f': + use_fd = 1; + break; case 'm': - m_mask = atoi(optarg); - mflag = 1; + if (strcmp(optarg, "basic") == 0) + mask = STATX_BASIC_STATS; + else if (strcmp(optarg, "all") == 0) + mask = STATX_ALL; + else + mask = strtoul(optarg, NULL, 0); break; case 'F': atflag &= ~AT_STATX_SYNC_TYPE; @@ -261,10 +337,6 @@ statx_f( case 'L': atflag &= ~AT_SYMLINK_NOFOLLOW; break; - case 'O': - mask = STATX_BASIC_STATS; - Oflag = 1; - break; case 'A': atflag |= AT_NO_AUTOMOUNT; break; @@ -273,23 +345,38 @@ statx_f( } } - if (Oflag && mflag) { - printf("Cannot specify both -m mask and -O\n"); - return 0; + memset(&stx, 0xbf, sizeof(stx)); + + if (use_fd) { + if (statx(file->fd, NULL, atflag, mask, &stx) < 0) { + perror("statx"); + return 0; + } + } else { + if (statx(dirfd, file->name, atflag, mask, &stx) < 0) { + perror("statx"); + return 0; + } } - /* -m overrides any other mask options */ - if (mflag) - mask = m_mask; + if (compare) { + if (use_fd) { + if (fstat(file->fd, &st) < 0) { + perror("fstat"); + return 0; + } + } else { + if (fstatat(dirfd, file->name, &st, + atflag & ~AT_STATX_SYNC_TYPE) < 0) { + perror("fstatat"); + return 0; + } + } - memset(&stx, 0xbf, sizeof(stx)); - if (statx(AT_FDCWD, file->name, atflag, mask, &stx) < 0) { - perror("statx"); - return 0; + cmp_statx(&stx, &st); } - + dump_statx(&stx); - return 0; }