From patchwork Fri Sep 13 10:58:04 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jeffrey Layton X-Patchwork-Id: 11144375 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 8F9D8912 for ; Fri, 13 Sep 2019 10:58:10 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 6556121479 for ; Fri, 13 Sep 2019 10:58:10 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1568372290; bh=xTthybmuTE2hi+1VU+wPKx1CKEtzS271P9b305s10vA=; h=From:To:Cc:Subject:Date:In-Reply-To:References:List-ID:From; b=oTfjSH2LCs6E2XfZvRdbRcpyTKfGPR8eTa5Sz9hCv7wtd5L5TtFSrOB6sm9Snzy47 1FfXuOnRZY+tPxIXKO1db2dTlbWvtsL/6iZh/UmTkDnImD3VO07XSJLLJgXD6rPm+r zN7gZL3o9b9qcL6t6+m2eKlN1NkHu0r9qPxVqokE= Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2387889AbfIMK6J (ORCPT ); Fri, 13 Sep 2019 06:58:09 -0400 Received: from mail.kernel.org ([198.145.29.99]:48100 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2387424AbfIMK6J (ORCPT ); Fri, 13 Sep 2019 06:58:09 -0400 Received: from tleilax.poochiereds.net.com (68-20-15-154.lightspeed.rlghnc.sbcglobal.net [68.20.15.154]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id E22252089F; Fri, 13 Sep 2019 10:58:07 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1568372288; bh=xTthybmuTE2hi+1VU+wPKx1CKEtzS271P9b305s10vA=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=ghUqX0xEYCBLWrQhoNP5vpo0WhWPup+L8OBy5zBJJ5GFwpO1uEXjaGbyHQ4rtuY1u DlLmKCNmMKKYx+E9fW6nG7avG74Y9Ry6Kevq2zbpkqAc040nhB9iEWlJIbcNdi44om vbynN2Oz7254PVRlpvrl4LmUI2znBZanLDXxptgU= From: Jeff Layton To: coreutils@gnu.org Cc: adilger@dilger.ca, dhowells@redhat.com, ceph-devel@vger.kernel.org, linux-fsdevel@vger.kernel.org Subject: [coreutils PATCH v2 1/2] stat: move struct statx to struct stat conversion routines to new header Date: Fri, 13 Sep 2019 06:58:04 -0400 Message-Id: <20190913105805.24669-2-jlayton@kernel.org> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190913105805.24669-1-jlayton@kernel.org> References: <20190913105805.24669-1-jlayton@kernel.org> MIME-Version: 1.0 Sender: linux-fsdevel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org * move statx_timestamp_to_timespec and statx_to_stat to a new header --- src/stat.c | 32 +------------------------------ src/statx.h | 54 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 55 insertions(+), 31 deletions(-) create mode 100644 src/statx.h diff --git a/src/stat.c b/src/stat.c index ee68f1682bc8..f2bf0dcb7901 100644 --- a/src/stat.c +++ b/src/stat.c @@ -73,6 +73,7 @@ #include "strftime.h" #include "find-mount-point.h" #include "xvasprintf.h" +#include "statx.h" #if HAVE_STATX && defined STATX_INO # define USE_STATX 1 @@ -1245,37 +1246,6 @@ static bool dont_sync; static bool force_sync; #if USE_STATX -/* Much of the format printing requires a struct stat or timespec */ -static struct timespec -statx_timestamp_to_timespec (struct statx_timestamp tsx) -{ - struct timespec ts; - - ts.tv_sec = tsx.tv_sec; - ts.tv_nsec = tsx.tv_nsec; - return ts; -} - -static void -statx_to_stat (struct statx *stx, struct stat *stat) -{ - stat->st_dev = makedev (stx->stx_dev_major, stx->stx_dev_minor); - stat->st_ino = stx->stx_ino; - stat->st_mode = stx->stx_mode; - stat->st_nlink = stx->stx_nlink; - stat->st_uid = stx->stx_uid; - stat->st_gid = stx->stx_gid; - stat->st_rdev = makedev (stx->stx_rdev_major, stx->stx_rdev_minor); - stat->st_size = stx->stx_size; - stat->st_blksize = stx->stx_blksize; -/* define to avoid sc_prohibit_stat_st_blocks. */ -# define SC_ST_BLOCKS st_blocks - stat->SC_ST_BLOCKS = stx->stx_blocks; - stat->st_atim = statx_timestamp_to_timespec (stx->stx_atime); - stat->st_mtim = statx_timestamp_to_timespec (stx->stx_mtime); - stat->st_ctim = statx_timestamp_to_timespec (stx->stx_ctime); -} - static unsigned int fmt_to_mask (char fmt) { diff --git a/src/statx.h b/src/statx.h new file mode 100644 index 000000000000..a98ec10de380 --- /dev/null +++ b/src/statx.h @@ -0,0 +1,54 @@ +/* statx -> stat conversion functions for coreutils + Copyright (C) 2019 Free Software Foundation, Inc. + + 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 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will 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, see . */ + +#ifndef COREUTILS_STATX_H +# define COREUTILS_STATX_H + +#include + +#if HAVE_STATX && defined STATX_INO +/* Much of the format printing requires a struct stat or timespec */ +static inline struct timespec +statx_timestamp_to_timespec (struct statx_timestamp tsx) +{ + struct timespec ts; + + ts.tv_sec = tsx.tv_sec; + ts.tv_nsec = tsx.tv_nsec; + return ts; +} + +static inline void +statx_to_stat (struct statx *stx, struct stat *stat) +{ + stat->st_dev = makedev (stx->stx_dev_major, stx->stx_dev_minor); + stat->st_ino = stx->stx_ino; + stat->st_mode = stx->stx_mode; + stat->st_nlink = stx->stx_nlink; + stat->st_uid = stx->stx_uid; + stat->st_gid = stx->stx_gid; + stat->st_rdev = makedev (stx->stx_rdev_major, stx->stx_rdev_minor); + stat->st_size = stx->stx_size; + stat->st_blksize = stx->stx_blksize; +/* define to avoid sc_prohibit_stat_st_blocks. */ +# define SC_ST_BLOCKS st_blocks + stat->SC_ST_BLOCKS = stx->stx_blocks; + stat->st_atim = statx_timestamp_to_timespec (stx->stx_atime); + stat->st_mtim = statx_timestamp_to_timespec (stx->stx_mtime); + stat->st_ctim = statx_timestamp_to_timespec (stx->stx_ctime); +} +#endif /* HAVE_STATX && defined STATX_INO */ +#endif /* COREUTILS_STATX_H */ From patchwork Fri Sep 13 10:58:05 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jeffrey Layton X-Patchwork-Id: 11144381 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 00FD9184E for ; Fri, 13 Sep 2019 10:58:13 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id D4E0A2084F for ; Fri, 13 Sep 2019 10:58:12 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1568372292; bh=MDxzN3viBo9XfwZp9lDIicUT4RQBxPKTfc7l/HQje/4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:List-ID:From; b=QZOVhpJifBdgSu+V7qoS+yLOnscL/IrC795JARKmW2QPO8p4SgqQeSJ+U/S1Qd+o1 mgEmH8Am4Femi3FGjBaeHdjMgycitgoIgAQRPRTd/MJ4V6WkfejM3850IfAYsihQ5y BKzKeTn6dtmnM8LwprzqGEfvlbtgPQ7WlgK1Iv2I= Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2387896AbfIMK6L (ORCPT ); Fri, 13 Sep 2019 06:58:11 -0400 Received: from mail.kernel.org ([198.145.29.99]:48114 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2387865AbfIMK6K (ORCPT ); Fri, 13 Sep 2019 06:58:10 -0400 Received: from tleilax.poochiereds.net.com (68-20-15-154.lightspeed.rlghnc.sbcglobal.net [68.20.15.154]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 9AEE8208C2; Fri, 13 Sep 2019 10:58:08 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1568372289; bh=MDxzN3viBo9XfwZp9lDIicUT4RQBxPKTfc7l/HQje/4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=qRLsjvBqQisTcqzNX6bpHNh9Yvu1286Qljt8hHXFw9UD3Gc3lX6UJC9xB8acW2IzK q/6LTGZEkjxu/gVkP+y85AXwd3vzH+5mzd2XfpUiNCqC8orSfJLkIDociYkhnF6Xqp GTar3nG9cwM/x7Vr8bt5JImBKATU6jnAYmVJDMc8= From: Jeff Layton To: coreutils@gnu.org Cc: adilger@dilger.ca, dhowells@redhat.com, ceph-devel@vger.kernel.org, linux-fsdevel@vger.kernel.org Subject: [coreutils PATCH v2 2/2] ls: use statx instead of stat when available Date: Fri, 13 Sep 2019 06:58:05 -0400 Message-Id: <20190913105805.24669-3-jlayton@kernel.org> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190913105805.24669-1-jlayton@kernel.org> References: <20190913105805.24669-1-jlayton@kernel.org> MIME-Version: 1.0 Sender: linux-fsdevel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org * add wrapper functions for stat/lstat/fstat calls, and add variants for when we are only interested in specific info * add statx-enabled functions and set the request mask based on the output format and what values are needed * for loop detection, use AT_STATX_DONT_SYNC since we're only interested in the dev/ino and that should never change --- src/ls.c | 106 +++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 99 insertions(+), 7 deletions(-) diff --git a/src/ls.c b/src/ls.c index 120ce153e340..003a69aaa280 100644 --- a/src/ls.c +++ b/src/ls.c @@ -114,6 +114,7 @@ #include "xgethostname.h" #include "c-ctype.h" #include "canonicalize.h" +#include "statx.h" /* Include last to avoid a clash of include guards with some premature versions of libcap. @@ -1063,6 +1064,97 @@ dired_dump_obstack (const char *prefix, struct obstack *os) } } +#if HAVE_STATX && defined STATX_INO +static unsigned int +calc_req_mask (void) +{ + unsigned int mask = STATX_MODE; + + if (print_inode) + mask |= STATX_INO; + if (format == long_format) { + mask |= STATX_NLINK | STATX_SIZE; + if (print_owner || print_author) + mask |= STATX_UID; + if (print_group) + mask |= STATX_GID; + } + return mask; +} + +static int +do_statx (int fd, const char *name, struct stat *st, int flags, + unsigned int mask) +{ + struct statx stx; + int ret = statx (fd, name, flags, mask, &stx); + if (ret >= 0) + statx_to_stat (&stx, st); + return ret; +} + +static inline int +do_stat (const char *name, struct stat *st) +{ + return do_statx (AT_FDCWD, name, st, 0, calc_req_mask()); +} + +static inline int +do_lstat (const char *name, struct stat *st) +{ + return do_statx (AT_FDCWD, name, st, AT_SYMLINK_NOFOLLOW, calc_req_mask()); +} + +static inline int +stat_for_mode (const char *name, struct stat *st) +{ + return do_statx (AT_FDCWD, name, st, 0, STATX_MODE); +} + +/* dev+ino should be static, so no need to sync with backing store */ +static inline int +stat_for_ino (const char *name, struct stat *st) +{ + return do_statx (AT_FDCWD, name, st, AT_STATX_DONT_SYNC, STATX_INO); +} + +static inline int +fstat_for_ino (int fd, struct stat *st) +{ + return do_statx (fd, "", st, AT_EMPTY_PATH|AT_STATX_DONT_SYNC, STATX_INO); +} +#else +static inline int +do_stat (const char *name, struct stat *st) +{ + return stat (name, st); +} + +static inline int +do_lstat (const char *name, struct stat *st) +{ + return lstat (name, st); +} + +static inline int +stat_for_mode (const char *name, struct stat *st) +{ + return stat (name, st); +} + +static inline int +stat_for_ino (const char *name, struct stat *st) +{ + return stat (name, st); +} + +static inline int +fstat_for_ino (int fd, struct stat *st) +{ + return fstat (fd, st); +} +#endif + /* Return the address of the first plain %b spec in FMT, or NULL if there is no such spec. %5b etc. do not match, so that user widths/flags are honored. */ @@ -2737,10 +2829,10 @@ print_dir (char const *name, char const *realname, bool command_line_arg) struct stat dir_stat; int fd = dirfd (dirp); - /* If dirfd failed, endure the overhead of using stat. */ + /* If dirfd failed, endure the overhead of stat'ing by path */ if ((0 <= fd - ? fstat (fd, &dir_stat) - : stat (name, &dir_stat)) < 0) + ? fstat_for_ino (fd, &dir_stat) + : stat_for_ino (name, &dir_stat)) < 0) { file_failure (command_line_arg, _("cannot determine device and inode of %s"), name); @@ -3202,7 +3294,7 @@ gobble_file (char const *name, enum filetype type, ino_t inode, switch (dereference) { case DEREF_ALWAYS: - err = stat (full_name, &f->stat); + err = do_stat (full_name, &f->stat); do_deref = true; break; @@ -3211,7 +3303,7 @@ gobble_file (char const *name, enum filetype type, ino_t inode, if (command_line_arg) { bool need_lstat; - err = stat (full_name, &f->stat); + err = do_stat (full_name, &f->stat); do_deref = true; if (dereference == DEREF_COMMAND_LINE_ARGUMENTS) @@ -3231,7 +3323,7 @@ gobble_file (char const *name, enum filetype type, ino_t inode, FALLTHROUGH; default: /* DEREF_NEVER */ - err = lstat (full_name, &f->stat); + err = do_lstat (full_name, &f->stat); do_deref = false; break; } @@ -3320,7 +3412,7 @@ gobble_file (char const *name, enum filetype type, ino_t inode, they won't be traced and when no indicator is needed. */ if (linkname && (file_type <= indicator_style || check_symlink_mode) - && stat (linkname, &linkstats) == 0) + && stat_for_mode(linkname, &linkstats) == 0) { f->linkok = true; f->linkmode = linkstats.st_mode;