From patchwork Wed Mar 29 15:49:49 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Howells X-Patchwork-Id: 9651841 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 7ED24601D7 for ; Wed, 29 Mar 2017 15:49:54 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 70823284F5 for ; Wed, 29 Mar 2017 15:49:54 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 651F1284F9; Wed, 29 Mar 2017 15:49:54 +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=ham 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 97EF4284F5 for ; Wed, 29 Mar 2017 15:49:53 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753515AbdC2Ptx convert rfc822-to-8bit (ORCPT ); Wed, 29 Mar 2017 11:49:53 -0400 Received: from mx1.redhat.com ([209.132.183.28]:52691 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753476AbdC2Ptw (ORCPT ); Wed, 29 Mar 2017 11:49:52 -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 583394E4D8; Wed, 29 Mar 2017 15:49:51 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com 583394E4D8 Authentication-Results: ext-mx09.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx09.extmail.prod.ext.phx2.redhat.com; spf=pass smtp.mailfrom=dhowells@redhat.com DKIM-Filter: OpenDKIM Filter v2.11.0 mx1.redhat.com 583394E4D8 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 2A8CC7F979; Wed, 29 Mar 2017 15:49:50 +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 [ver #3] MIME-Version: 1.0 Content-ID: <8126.1490802589.1@warthog.procyon.org.uk> Date: Wed, 29 Mar 2017 16:49:49 +0100 Message-ID: <8127.1490802589@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.38]); Wed, 29 Mar 2017 15:49:51 +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 Here's my third attempt at changing Eric's statx patch. I've got rid of the compare option to statx and added a raw output option to stat. They're still not directly comparable since the stat output lacks some fields, but it will hopefully be possible to load them into associative arrays in bash and compare them that way. --- -- 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..d2ea854 100644 --- a/io/stat.c +++ b/io/stat.c @@ -44,6 +44,35 @@ filesize(void) return st.st_size; } +static int +dump_raw_stat(struct stat *st) +{ + if (fstat(file->fd, st) < 0) { + perror("fstat"); + return -1; + } + + printf("stat.blksize: %lu\n", st->st_blksize); + printf("stat.nlink: %lu\n", st->st_nlink); + printf("stat.uid: %u\n", st->st_uid); + printf("stat.gid: %u\n", st->st_gid); + printf("stat.mode: 0%o\n", st->st_mode); + printf("stat.ino: %lu\n", st->st_ino); + printf("stat.size: %lu\n", st->st_size); + printf("stat.blocks: %lu\n", st->st_blocks); + printf("stat.atime.tv_sec: %ld\n", st->st_atim.tv_sec); + printf("stat.atime.tv_nsec: %ld\n", st->st_atim.tv_nsec); + printf("stat.ctime.tv_sec: %ld\n", st->st_ctim.tv_sec); + printf("stat.ctime.tv_nsec: %ld\n", st->st_ctim.tv_nsec); + printf("stat.mtime.tv_sec: %ld\n", st->st_mtim.tv_sec); + printf("stat.mtime.tv_nsec: %ld\n", st->st_mtim.tv_nsec); + printf("stat.rdev_major: %u\n", major(st->st_rdev)); + printf("stat.rdev_minor: %u\n", minor(st->st_rdev)); + printf("stat.dev_major: %u\n", major(st->st_dev)); + printf("stat.dev_minor: %u\n", minor(st->st_dev)); + return 0; +} + static char * filetype(mode_t mode) { @@ -74,7 +103,23 @@ stat_f( struct dioattr dio; struct fsxattr fsx, fsxa; struct stat st; - int verbose = (argc == 2 && !strcmp(argv[1], "-v")); + int c, verbose = 0, raw = 0; + + while ((c = getopt(argc, argv, "rv")) != EOF) { + switch (c) { + case 'r': + raw = 1; + break; + case 'v': + verbose = 1; + break; + default: + return command_usage(&stat_cmd); + } + } + + if (raw) + return dump_raw_stat(&st); printf(_("fd.path = \"%s\"\n"), file->name); printf(_("fd.flags = %s,%s,%s%s%s%s%s\n"), @@ -189,12 +234,9 @@ 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" -" -A -- Suppress terminal automount traversal\n" +" -m mask -- Specify the field mask for the statx call (can also be 'basic' or 'all'; default STATX_ALL)\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")); } @@ -202,28 +244,28 @@ statx_help(void) static void dump_statx(struct statx *stx) { - printf("stx_mask: 0x%x\n", stx->stx_mask); - printf("stx_blksize: %u\n", stx->stx_blksize); - printf("stx_attributes: 0x%llx\n", stx->stx_attributes); - printf("stx_nlink: %u\n", stx->stx_nlink); - printf("stx_uid: %u\n", stx->stx_uid); - printf("stx_gid: %u\n", stx->stx_gid); - printf("stx_mode: 0%o\n", stx->stx_mode); - printf("stx_ino: %llu\n", stx->stx_ino); - printf("stx_size: %llu\n", stx->stx_size); - printf("stx_blocks: %llu\n", stx->stx_blocks); - printf("stx_atime.tv_sec: %lld\n", stx->stx_atime.tv_sec); - printf("stx_atime.tv_nsec: %d\n", stx->stx_atime.tv_nsec); - printf("stx_btime.tv_sec: %lld\n", stx->stx_btime.tv_sec); - printf("stx_btime.tv_nsec: %d\n", stx->stx_btime.tv_nsec); - printf("stx_ctime.tv_sec: %lld\n", stx->stx_ctime.tv_sec); - printf("stx_ctime.tv_nsec: %d\n", stx->stx_ctime.tv_nsec); - printf("stx_mtime.tv_sec: %lld\n", stx->stx_mtime.tv_sec); - printf("stx_mtime.tv_nsec: %d\n", stx->stx_mtime.tv_nsec); - printf("stx_rdev_major: %u\n", stx->stx_rdev_major); - printf("stx_rdev_minor: %u\n", stx->stx_rdev_minor); - printf("stx_dev_major: %u\n", stx->stx_dev_major); - printf("stx_dev_minor: %u\n", stx->stx_dev_minor); + printf("stat.mask: 0x%x\n", stx->stx_mask); + printf("stat.blksize: %u\n", stx->stx_blksize); + printf("stat.attributes: 0x%llx\n", stx->stx_attributes); + printf("stat.nlink: %u\n", stx->stx_nlink); + printf("stat.uid: %u\n", stx->stx_uid); + printf("stat.gid: %u\n", stx->stx_gid); + printf("stat.mode: 0%o\n", stx->stx_mode); + printf("stat.ino: %llu\n", stx->stx_ino); + printf("stat.size: %llu\n", stx->stx_size); + printf("stat.blocks: %llu\n", stx->stx_blocks); + printf("stat.atime.tv_sec: %lld\n", stx->stx_atime.tv_sec); + printf("stat.atime.tv_nsec: %d\n", stx->stx_atime.tv_nsec); + printf("stat.btime.tv_sec: %lld\n", stx->stx_btime.tv_sec); + printf("stat.btime.tv_nsec: %d\n", stx->stx_btime.tv_nsec); + printf("stat.ctime.tv_sec: %lld\n", stx->stx_ctime.tv_sec); + printf("stat.ctime.tv_nsec: %d\n", stx->stx_ctime.tv_nsec); + printf("stat.mtime.tv_sec: %lld\n", stx->stx_mtime.tv_sec); + printf("stat.mtime.tv_nsec: %d\n", stx->stx_mtime.tv_nsec); + printf("stat.rdev_major: %u\n", stx->stx_rdev_major); + printf("stat.rdev_minor: %u\n", stx->stx_rdev_minor); + printf("stat.dev_major: %u\n", stx->stx_dev_major); + printf("stat.dev_minor: %u\n", stx->stx_dev_minor); } /* @@ -239,16 +281,18 @@ statx_f( { int c; struct statx stx; - int atflag = AT_SYMLINK_NOFOLLOW; - unsigned int m_mask = 0; /* mask requested with -m */ - int Oflag = 0, mflag = 0; /* -O or -m was used */ + int atflag = 0; unsigned int mask = STATX_ALL; - while ((c = getopt(argc, argv, "m:FDLOA")) != EOF) { + while ((c = getopt(argc, argv, "m:FD")) != EOF) { switch (c) { 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; @@ -258,38 +302,19 @@ statx_f( atflag &= ~AT_STATX_SYNC_TYPE; atflag |= AT_STATX_DONT_SYNC; break; - case 'L': - atflag &= ~AT_SYMLINK_NOFOLLOW; - break; - case 'O': - mask = STATX_BASIC_STATS; - Oflag = 1; - break; - case 'A': - atflag |= AT_NO_AUTOMOUNT; - break; default: return command_usage(&statx_cmd); } } - if (Oflag && mflag) { - printf("Cannot specify both -m mask and -O\n"); - return 0; - } - - /* -m overrides any other mask options */ - if (mflag) - mask = m_mask; - memset(&stx, 0xbf, sizeof(stx)); - if (statx(AT_FDCWD, file->name, atflag, mask, &stx) < 0) { + + if (statx(file->fd, NULL, atflag, mask, &stx) < 0) { perror("statx"); return 0; } - + dump_statx(&stx); - return 0; } @@ -301,7 +326,7 @@ stat_init(void) stat_cmd.argmin = 0; stat_cmd.argmax = 1; stat_cmd.flags = CMD_NOMAP_OK | CMD_FOREIGN_OK; - stat_cmd.args = _("[-v]"); + stat_cmd.args = _("[-rv]"); stat_cmd.oneline = _("information about the currently open file"); statfs_cmd.name = "statfs"; @@ -315,7 +340,7 @@ stat_init(void) statx_cmd.argmin = 0; statx_cmd.argmax = -1; statx_cmd.flags = CMD_NOMAP_OK | CMD_FOREIGN_OK; - statx_cmd.args = _("[-O | -m mask][-FDLAP]"); + statx_cmd.args = _("[-m basic | -m all | -m ][-FD]"); statx_cmd.oneline = _("extended information about the currently open file"); statx_cmd.help = statx_help; diff --git a/man/man8/xfs_io.8 b/man/man8/xfs_io.8 index 77ba760..486ad11 100644 --- a/man/man8/xfs_io.8 +++ b/man/man8/xfs_io.8 @@ -876,24 +876,29 @@ Only available in expert mode and requires privileges. Force the filesystem to shutdown (with or without flushing the log). Only available in expert mode and requires privileges. .TP -.BR stat " [ " \-v " ]" +.BR stat " [ \-" rv " ]" Selected statistics from .BR stat (2) and the XFS_IOC_GETXATTR system call on the current file. If the .B \-v option is specified, the atime (last access), mtime -(last modify), and ctime (last change) timestamps are also displayed. +(last modify), and ctime (last change) timestamps are also displayed. If the +.B \-r +option is specified, the raw output will be dumped in the same form as the +output for the statx command, but with some fields missing. .TP -.BR statx " [ " \-O " | " "\-m mask" " ][ \-" FDLA " ]" +.BR statx " [ " "\-m mask" " ][ \-" FD " ]" Extended information from the statx syscall. .RS 1.0i .PD 0 .TP 0.4i .B \-m mask -Specify the field mask for the statx call (default STATX_ALL) -.TP -.B \-O -Add only basic stats (STATX_BASIC_STATS) to default mask +Specify the field mask for the statx call as an decimal, hex or octal integer +or +.RI \" basic "\" or \"" all \" +to specify the basic stats that +.IR stat () +returns or all the stats known by the header file. All is the default. .TP .B \-F Force the attributes to be sync'd with the server @@ -901,12 +906,6 @@ Force the attributes to be sync'd with the server .B \-D Don't sync attributes with the server .TP -.B \-L -Follow symlinks (statx link target) -.TP -.B \-A -Suppress terminal automount traversal -.TP .RE .IP .TP