From patchwork Mon Apr 1 12:50:18 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Filipe Manana X-Patchwork-Id: 10879853 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id AB8B01575 for ; Mon, 1 Apr 2019 12:50:35 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 92E682861D for ; Mon, 1 Apr 2019 12:50:35 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 851882876C; Mon, 1 Apr 2019 12:50:35 +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=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,MAILING_LIST_MULTI,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 1705F2861D for ; Mon, 1 Apr 2019 12:50:27 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726637AbfDAMu1 (ORCPT ); Mon, 1 Apr 2019 08:50:27 -0400 Received: from mail.kernel.org ([198.145.29.99]:53238 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725897AbfDAMu1 (ORCPT ); Mon, 1 Apr 2019 08:50:27 -0400 Received: from localhost.localdomain (bl8-197-74.dsl.telepac.pt [85.241.197.74]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id A4C84206B7; Mon, 1 Apr 2019 12:50:25 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1554123026; bh=fEKOGtvEIZr/jPevPjaQ2mAejqegP60lfWPUSSx5plo=; h=From:To:Cc:Subject:Date:From; b=rPzhu8wXHTW6ADvwi3kGkU3+m7zQsW/HmVn/W99pKLOQvbpqs8KYYzvvik9FQEkG/ UylSi5VEE91E9kbSffvMFswbV0NTNCDdtnWck4M9Iv0uh0E9ia7IkzMNzN3kzsXgZU SLNFWvf6PJ1r8kmIu0+f8CSA2Gm3lvkF/C10yHvY= From: fdmanana@kernel.org To: fstests@vger.kernel.org Cc: linux-btrfs@vger.kernel.org, Filipe Manana Subject: [PATCH v2 1/7] fsstress: allow fsync on directories too Date: Mon, 1 Apr 2019 13:50:18 +0100 Message-Id: <20190401125018.10009-1-fdmanana@kernel.org> X-Mailer: git-send-email 2.11.0 Sender: fstests-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: fstests@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Filipe Manana Currently the fsync function can only be performed against regular files. Allow it to operate on directories too, to increase test coverage and allow for chances of finding bugs in a filesystem's implementation of fsync against directories. Signed-off-by: Filipe Manana --- V2: Added helper functions to open and close files or directories. ltp/fsstress.c | 42 +++++++++++++++++++++++++++++++++++++++--- 1 file changed, 39 insertions(+), 3 deletions(-) diff --git a/ltp/fsstress.c b/ltp/fsstress.c index 2223fd7d..1169b840 100644 --- a/ltp/fsstress.c +++ b/ltp/fsstress.c @@ -303,6 +303,7 @@ int attr_remove_path(pathname_t *, const char *, int); int attr_set_path(pathname_t *, const char *, const char *, const int, int); void check_cwd(void); void cleanup_flist(void); +void close_file_or_dir(int, DIR *); int creat_path(pathname_t *, mode_t); void dcache_enter(int, int); void dcache_init(void); @@ -324,6 +325,7 @@ void make_freq_table(void); int mkdir_path(pathname_t *, mode_t); int mknod_path(pathname_t *, mode_t, dev_t); void namerandpad(int, char *, int); +int open_file_or_dir(pathname_t *, int, DIR **); int open_path(pathname_t *, int); DIR *opendir_path(pathname_t *); void process_freq(char *); @@ -852,6 +854,15 @@ cleanup_flist(void) } } +void +close_file_or_dir(int fd, DIR *dir) +{ + if (dir) + closedir(dir); + else + close(fd); +} + int creat_path(pathname_t *name, mode_t mode) { @@ -1385,6 +1396,30 @@ namerandpad(int id, char *buf, int i) } int +open_file_or_dir(pathname_t *name, int flags, DIR **dir) +{ + int fd; + + fd = open_path(name, flags); + if (fd < 0 && errno == EISDIR) { + *dir = opendir_path(name); + if (*dir) { + fd = dirfd(*dir); + if (fd < 0) { + int e = errno; + + closedir(*dir); + *dir = NULL; + errno = e; + } + } + } else { + *dir = NULL; + } + return fd; +} + +int open_path(pathname_t *name, int oflag) { char buf[NAME_MAX + 1]; @@ -3440,15 +3475,16 @@ fsync_f(int opno, long r) pathname_t f; int fd; int v; + DIR *dir; init_pathname(&f); - if (!get_fname(FT_REGFILE, r, &f, NULL, NULL, &v)) { + if (!get_fname(FT_REGFILE | FT_DIRm, r, &f, NULL, NULL, &v)) { if (v) printf("%d/%d: fsync - no filename\n", procid, opno); free_pathname(&f); return; } - fd = open_path(&f, O_WRONLY); + fd = open_file_or_dir(&f, O_WRONLY, &dir); e = fd < 0 ? errno : 0; check_cwd(); if (fd < 0) { @@ -3462,7 +3498,7 @@ fsync_f(int opno, long r) if (v) printf("%d/%d: fsync %s %d\n", procid, opno, f.path, e); free_pathname(&f); - close(fd); + close_file_or_dir(fd, dir); } void From patchwork Mon Apr 1 12:50:33 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Filipe Manana X-Patchwork-Id: 10879857 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id E195B13B5 for ; Mon, 1 Apr 2019 12:50:41 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id CC82A28747 for ; Mon, 1 Apr 2019 12:50:41 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id C0D3428833; Mon, 1 Apr 2019 12:50:41 +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=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,MAILING_LIST_MULTI,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 3D226286BE for ; Mon, 1 Apr 2019 12:50:40 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726163AbfDAMuj (ORCPT ); Mon, 1 Apr 2019 08:50:39 -0400 Received: from mail.kernel.org ([198.145.29.99]:53314 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725882AbfDAMuj (ORCPT ); Mon, 1 Apr 2019 08:50:39 -0400 Received: from localhost.localdomain (bl8-197-74.dsl.telepac.pt [85.241.197.74]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id A5EF42070D; Mon, 1 Apr 2019 12:50:37 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1554123038; bh=WEB3JPm4RZFQ/wLvV4eLZmgt6RT4dBjCbdQbR3XmqKg=; h=From:To:Cc:Subject:Date:From; b=id6ulD5GcZaoPx2E9xSNtvk+ITyv9BXgOYt8aQm6TQnqUc5ifouDEMr5Qrl9N2Hjt ge7kZTqkVHwvZbQNV1h25zxqp+uYcutvzThr6cyztsuSrxt1Bu2/hBzt/QsH0C+2u+ ++RO1ivf/S3vnBc9jSbES0ukDwIVOoI2L2fZpKUQ= From: fdmanana@kernel.org To: fstests@vger.kernel.org Cc: linux-btrfs@vger.kernel.org, Filipe Manana Subject: [PATCH v2 2/7] fsstress: allow afsync on directories too Date: Mon, 1 Apr 2019 13:50:33 +0100 Message-Id: <20190401125033.10059-1-fdmanana@kernel.org> X-Mailer: git-send-email 2.11.0 Sender: fstests-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: fstests@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Filipe Manana Currently the afsync function can only be performed against regular files. Allow it to operate on directories too, to increase test coverage and allow for chances of finding bugs in a filesystem's implementation of fsync against directories. Signed-off-by: Filipe Manana --- V2: Use the helper functions for opening and closing files or directories, introduced in the previous patch. ltp/fsstress.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/ltp/fsstress.c b/ltp/fsstress.c index 1169b840..13d4bebc 100644 --- a/ltp/fsstress.c +++ b/ltp/fsstress.c @@ -1790,15 +1790,16 @@ afsync_f(int opno, long r) struct iocb iocb; struct iocb *iocbs[] = { &iocb }; struct io_event event; + DIR *dir; init_pathname(&f); - if (!get_fname(FT_REGFILE, r, &f, NULL, NULL, &v)) { + if (!get_fname(FT_REGFILE | FT_DIRm, r, &f, NULL, NULL, &v)) { if (v) printf("%d/%d: afsync - no filename\n", procid, opno); free_pathname(&f); return; } - fd = open_path(&f, O_WRONLY | O_DIRECT); + fd = open_file_or_dir(&f, O_WRONLY | O_DIRECT, &dir); e = fd < 0 ? errno : 0; check_cwd(); if (fd < 0) { @@ -1815,7 +1816,7 @@ afsync_f(int opno, long r) printf("%d/%d: afsync - io_submit %s %d\n", procid, opno, f.path, e); free_pathname(&f); - close(fd); + close_file_or_dir(fd, dir); return; } if ((e = io_getevents(io_ctx, 1, 1, &event, NULL)) != 1) { @@ -1823,7 +1824,7 @@ afsync_f(int opno, long r) printf("%d/%d: afsync - io_getevents failed %d\n", procid, opno, e); free_pathname(&f); - close(fd); + close_file_or_dir(fd, dir); return; } @@ -1831,7 +1832,7 @@ afsync_f(int opno, long r) if (v) printf("%d/%d: afsync %s %d\n", procid, opno, f.path, e); free_pathname(&f); - close(fd); + close_file_or_dir(fd, dir); #endif } From patchwork Mon Apr 1 12:50:44 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Filipe Manana X-Patchwork-Id: 10879861 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id C814E1575 for ; Mon, 1 Apr 2019 12:50:52 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id AB999288C7 for ; Mon, 1 Apr 2019 12:50:52 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id A0520288CB; Mon, 1 Apr 2019 12:50:52 +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=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,MAILING_LIST_MULTI,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 8F312286A0 for ; Mon, 1 Apr 2019 12:50:51 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726637AbfDAMuv (ORCPT ); Mon, 1 Apr 2019 08:50:51 -0400 Received: from mail.kernel.org ([198.145.29.99]:53424 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725882AbfDAMuv (ORCPT ); Mon, 1 Apr 2019 08:50:51 -0400 Received: from localhost.localdomain (bl8-197-74.dsl.telepac.pt [85.241.197.74]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 92CB42070D; Mon, 1 Apr 2019 12:50:48 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1554123049; bh=hUdbzuY+mi9zz31D34tUtjCrJX+6zewGr+26WEO9zKU=; h=From:To:Cc:Subject:Date:From; b=O/BYXSAI9xPzmQ4OVBxk4za4GrKs6+m5TP1Y8vHVpDzwrHpqw/pEcXx/1Wnk3EVwV rDfzDaBvTTFDNHPgTd1fRNFeKboSHQRvMzJOOKED/mO/iBxaavR3H2exIxXg+XyAA3 vzpPq+h3/7yOiVt5gitJjyoi4OsEFO749F7wDuHQ= From: fdmanana@kernel.org To: fstests@vger.kernel.org Cc: linux-btrfs@vger.kernel.org, Filipe Manana Subject: [PATCH v2 3/7] fsstress: add operation for setting xattrs on files and directories Date: Mon, 1 Apr 2019 13:50:44 +0100 Message-Id: <20190401125044.10109-1-fdmanana@kernel.org> X-Mailer: git-send-email 2.11.0 Sender: fstests-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: fstests@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Filipe Manana Currently fsstress does not exercise creating, reading or deleting xattrs on files or directories. This change adds support for setting xattrs on files and directories, using only the xattr user namespace (the other namespaces are not general purpose and are used for security, capabilities, ACLs, etc). This adds a counter for each file entry structure that keeps track of the number of xattrs set for the file entry, and each new xattr has a name that includes the counter's value (example: "user.x4"). Values for the xattrs have at most 100 bytes, which is more than the maximum size supported for all major filesystems. Signed-off-by: Filipe Manana --- V2: Use a different name for the operation (setfattr instead of the already taken setxattr) and make use of the helper functions for opening and closing files or directories, introduced in the first patch of this series. ltp/fsstress.c | 150 +++++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 141 insertions(+), 9 deletions(-) diff --git a/ltp/fsstress.c b/ltp/fsstress.c index 13d4bebc..350a2a85 100644 --- a/ltp/fsstress.c +++ b/ltp/fsstress.c @@ -27,6 +27,7 @@ io_context_t io_ctx; #endif #include +#include #ifndef FS_IOC_GETFLAGS #define FS_IOC_GETFLAGS _IOR('f', 1, long) @@ -84,6 +85,7 @@ typedef enum { OP_RESVSP, OP_RMDIR, OP_SETATTR, + OP_SETFATTR, OP_SETXATTR, OP_SPLICE, OP_STAT, @@ -110,6 +112,7 @@ typedef struct opdesc { typedef struct fent { int id; int parent; + int xattr_counter; } fent_t; typedef struct flist { @@ -156,6 +159,8 @@ struct print_string { #define MAXFSIZE ((1ULL << 63) - 1ULL) #define MAXFSIZE32 ((1ULL << 40) - 1ULL) +#define XATTR_NAME_BUF_SIZE 18 + void afsync_f(int, long); void allocsp_f(int, long); void aread_f(int, long); @@ -194,6 +199,7 @@ void rename_f(int, long); void resvsp_f(int, long); void rmdir_f(int, long); void setattr_f(int, long); +void setfattr_f(int, long); void setxattr_f(int, long); void splice_f(int, long); void stat_f(int, long); @@ -245,6 +251,7 @@ opdesc_t ops[] = { { OP_RESVSP, "resvsp", resvsp_f, 1, 1 }, { OP_RMDIR, "rmdir", rmdir_f, 1, 1 }, { OP_SETATTR, "setattr", setattr_f, 0, 1 }, + { OP_SETFATTR, "setfattr", setfattr_f, 4, 1 }, { OP_SETXATTR, "setxattr", setxattr_f, 1, 1 }, { OP_SPLICE, "splice", splice_f, 1, 1 }, { OP_STAT, "stat", stat_f, 1, 0 }, @@ -296,7 +303,7 @@ char *execute_cmd = NULL; int execute_freq = 1; struct print_string flag_str = {0}; -void add_to_flist(int, int, int); +void add_to_flist(int, int, int, int); void append_pathname(pathname_t *, char *); int attr_list_path(pathname_t *, char *, const int, int, attrlist_cursor_t *); int attr_remove_path(pathname_t *, const char *, int); @@ -316,6 +323,7 @@ int fent_to_name(pathname_t *, flist_t *, fent_t *); void fix_parent(int, int); void free_pathname(pathname_t *); int generate_fname(fent_t *, int, pathname_t *, int *, int *); +void generate_xattr_name(int, char *); int get_fname(int, long, pathname_t *, flist_t **, fent_t **, int *); void init_pathname(pathname_t *); int lchown_path(pathname_t *, uid_t, gid_t); @@ -717,7 +725,7 @@ translate_flags(int flags, const char *delim, } void -add_to_flist(int ft, int id, int parent) +add_to_flist(int ft, int id, int parent, int xattr_counter) { fent_t *fep; flist_t *ftp; @@ -730,6 +738,7 @@ add_to_flist(int ft, int id, int parent) fep = &ftp->fents[ftp->nfiles++]; fep->id = id; fep->parent = parent; + fep->xattr_counter = xattr_counter; } void @@ -1132,6 +1141,12 @@ generate_fname(fent_t *fep, int ft, pathname_t *name, int *idp, int *v) return 1; } +void generate_xattr_name(int xattr_num, char *buffer) +{ + memcpy(buffer, "user.x", 6); + sprintf(buffer + 6, "%d", xattr_num); +} + /* * Get file * Input: "which" to choose the file-types eg. non-directory @@ -3036,7 +3051,7 @@ creat_f(int opno, long r) if (xfsctl(f.path, fd, XFS_IOC_FSSETXATTR, &a) < 0) e1 = errno; } - add_to_flist(type, id, parid); + add_to_flist(type, id, parid, 0); close(fd); } if (v) { @@ -3558,6 +3573,7 @@ link_f(int opno, long r) int e; pathname_t f; fent_t *fep; + fent_t *fep_src; flist_t *flp; int id; pathname_t l; @@ -3566,7 +3582,7 @@ link_f(int opno, long r) int v1; init_pathname(&f); - if (!get_fname(FT_NOTDIR, r, &f, &flp, NULL, &v1)) { + if (!get_fname(FT_NOTDIR, r, &f, &flp, &fep_src, &v1)) { if (v1) printf("%d/%d: link - no file\n", procid, opno); free_pathname(&f); @@ -3593,7 +3609,7 @@ link_f(int opno, long r) e = link_path(&f, &l) < 0 ? errno : 0; check_cwd(); if (e == 0) - add_to_flist(flp - flist, id, parid); + add_to_flist(flp - flist, id, parid, fep_src->xattr_counter); if (v) { printf("%d/%d: link %s %s %d\n", procid, opno, f.path, l.path, e); @@ -3633,7 +3649,7 @@ mkdir_f(int opno, long r) e = mkdir_path(&f, 0777) < 0 ? errno : 0; check_cwd(); if (e == 0) - add_to_flist(FT_DIR, id, parid); + add_to_flist(FT_DIR, id, parid, 0); if (v) { printf("%d/%d: mkdir %s %d\n", procid, opno, f.path, e); printf("%d/%d: mkdir add id=%d,parent=%d\n", procid, opno, id, parid); @@ -3671,7 +3687,7 @@ mknod_f(int opno, long r) e = mknod_path(&f, S_IFCHR|0444, 0) < 0 ? errno : 0; check_cwd(); if (e == 0) - add_to_flist(FT_DEV, id, parid); + add_to_flist(FT_DEV, id, parid, 0); if (v) { printf("%d/%d: mknod %s %d\n", procid, opno, f.path, e); printf("%d/%d: mknod add id=%d,parent=%d\n", procid, opno, id, parid); @@ -4047,12 +4063,14 @@ rename_f(int opno, long r) e = rename_path(&f, &newf) < 0 ? errno : 0; check_cwd(); if (e == 0) { + int xattr_counter = fep->xattr_counter; + if (flp - flist == FT_DIR) { oldid = fep->id; fix_parent(oldid, id); } del_from_flist(flp - flist, fep - flp->fents); - add_to_flist(flp - flist, id, parid); + add_to_flist(flp - flist, id, parid, xattr_counter); } if (v) { printf("%d/%d: rename %s to %s %d\n", procid, opno, f.path, @@ -4174,6 +4192,120 @@ setattr_f(int opno, long r) close(fd); } +char *gen_random_string(int len) +{ + static const char charset[] = "0123456789" + "abcdefghijklmnopqrstuvwxyz" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + int i; + char *s; + + if (len == 0) + return NULL; + + s = malloc(len); + if (!s) + return NULL; + + for (i = 0; i < len; i++) + s[i] = charset[random() % sizeof(charset)]; + + return s; +} + +char *xattr_flag_to_string(int flag) +{ + if (flag == XATTR_CREATE) + return "create"; + if (flag == XATTR_REPLACE) + return "replace"; + return "none"; +} + +void +setfattr_f(int opno, long r) +{ + int fd; + int e; + pathname_t f; + fent_t *fep; + int v; + int value_len; + char name[XATTR_NAME_BUF_SIZE]; + char *value; + int flag = 0; + int xattr_num; + DIR *dir; + + init_pathname(&f); + if (!get_fname(FT_REGFILE | FT_DIRm, r, &f, NULL, &fep, &v)) { + if (v) + printf("%d/%d: setfattr - no filename\n", procid, opno); + free_pathname(&f); + return; + } + fd = open_file_or_dir(&f, O_WRONLY, &dir); + e = fd < 0 ? errno : 0; + if (fd < 0) { + if (v) + printf("%d/%d: setfattr - open %s failed %d\n", + procid, opno, f.path, e); + free_pathname(&f); + return; + } + check_cwd(); + + if ((fep->xattr_counter > 0) && (random() % 2)) { + /* + * Use an existing xattr name for replacing its value or + * create again a xattr that was previously deleted. + */ + xattr_num = (random() % fep->xattr_counter) + 1; + if (random() % 2) + flag = XATTR_REPLACE; + } else { + /* Use a new xattr name. */ + xattr_num = fep->xattr_counter + 1; + /* + * Don't always use the create flag because even if our xattr + * counter is 0, we may still have xattrs associated to this + * file (this happens when xattrs are added to a file through + * one of its other hard links), so we can end up updating an + * existing xattr too. + */ + if (random() % 2) + flag = XATTR_CREATE; + } + + generate_xattr_name(xattr_num, name); + + /* + * The maximum supported value size depends on the filesystem + * implementation, but 100 bytes is a safe value for most filesystems + * at least. + */ + value_len = random() % 101; + value = gen_random_string(value_len); + if (!value && value_len > 0) { + if (v) + printf("%d/%d: setfattr - file %s failed to allocate value with %d bytes\n", + procid, opno, f.path, value_len); + goto out; + } + + e = fsetxattr(fd, name, value, value_len, flag) < 0 ? errno : 0; + if (e == 0) + fep->xattr_counter++; + if (v) + printf("%d/%d: setfattr file %s name %s flag %s value length %d: %d\n", + procid, opno, f.path, name, xattr_flag_to_string(flag), + value_len, e); +out: + free(value); + free_pathname(&f); + close_file_or_dir(fd, dir); +} + void stat_f(int opno, long r) { @@ -4236,7 +4368,7 @@ symlink_f(int opno, long r) e = symlink_path(val, &f) < 0 ? errno : 0; check_cwd(); if (e == 0) - add_to_flist(FT_SYM, id, parid); + add_to_flist(FT_SYM, id, parid, 0); free(val); if (v) { printf("%d/%d: symlink %s %d\n", procid, opno, f.path, e); From patchwork Mon Apr 1 12:51:09 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Filipe Manana X-Patchwork-Id: 10879865 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 8B85A13B5 for ; Mon, 1 Apr 2019 12:51:16 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 7511F285E3 for ; Mon, 1 Apr 2019 12:51:16 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 695252876C; Mon, 1 Apr 2019 12:51:16 +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=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,MAILING_LIST_MULTI,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 EE13E285E3 for ; Mon, 1 Apr 2019 12:51:15 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726588AbfDAMvP (ORCPT ); Mon, 1 Apr 2019 08:51:15 -0400 Received: from mail.kernel.org ([198.145.29.99]:53680 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725882AbfDAMvP (ORCPT ); Mon, 1 Apr 2019 08:51:15 -0400 Received: from localhost.localdomain (bl8-197-74.dsl.telepac.pt [85.241.197.74]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 50EB2206B7; Mon, 1 Apr 2019 12:51:13 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1554123074; bh=75/wMniQOrfRns3E6yU2xiNuYpx/zORtHQjM2wocv14=; h=From:To:Cc:Subject:Date:From; b=zN/7qYDVPwqkBYWQvErVFweAjM7xTXShvsgSl6Qs/uHcgyFW/qmhSSm4EuPgpYKr+ 4/yMNGq+ghggL9n8WxH/ixXgP86+WgAKq9/G/g4Tb0m65d9pzmemnzb9aHAwusiKYf PMCAiqKiSegpO1xW3WVVELm3sxZf79hWM0cS9zlw= From: fdmanana@kernel.org To: fstests@vger.kernel.org Cc: linux-btrfs@vger.kernel.org, Filipe Manana Subject: [PATCH v2 4/7] fsstress: add operation for reading xattrs from files and directories Date: Mon, 1 Apr 2019 13:51:09 +0100 Message-Id: <20190401125109.10163-1-fdmanana@kernel.org> X-Mailer: git-send-email 2.11.0 Sender: fstests-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: fstests@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Filipe Manana The previous patch added support for an operation to set xattrs on regular files and directories, this patch just adds one operation to read (get) them. Signed-off-by: Filipe Manana --- V2: Use a different name for the operation (getfattr) and make use of the helper functions for opening and closing files or directories, introduced in the first patch of this series. ltp/fsstress.c | 78 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) diff --git a/ltp/fsstress.c b/ltp/fsstress.c index 350a2a85..53e6a847 100644 --- a/ltp/fsstress.c +++ b/ltp/fsstress.c @@ -69,6 +69,7 @@ typedef enum { OP_FSYNC, OP_GETATTR, OP_GETDENTS, + OP_GETFATTR, OP_LINK, OP_MKDIR, OP_MKNOD, @@ -183,6 +184,7 @@ void freesp_f(int, long); void fsync_f(int, long); void getattr_f(int, long); void getdents_f(int, long); +void getfattr_f(int, long); void link_f(int, long); void mkdir_f(int, long); void mknod_f(int, long); @@ -235,6 +237,7 @@ opdesc_t ops[] = { { OP_FSYNC, "fsync", fsync_f, 1, 1 }, { OP_GETATTR, "getattr", getattr_f, 1, 0 }, { OP_GETDENTS, "getdents", getdents_f, 1, 0 }, + { OP_GETFATTR, "getfattr", getfattr_f, 2, 0 }, { OP_LINK, "link", link_f, 1, 1 }, { OP_MKDIR, "mkdir", mkdir_f, 2, 1 }, { OP_MKNOD, "mknod", mknod_f, 2, 1 }, @@ -3568,6 +3571,81 @@ getdents_f(int opno, long r) } void +getfattr_f(int opno, long r) +{ + int fd; + fent_t *fep; + int e; + pathname_t f; + int v; + char name[XATTR_NAME_BUF_SIZE]; + char *value = NULL; + int value_len; + int xattr_num; + DIR *dir; + + init_pathname(&f); + if (!get_fname(FT_REGFILE | FT_DIRm, r, &f, NULL, &fep, &v)) { + if (v) + printf("%d/%d: getfattr - no filename\n", procid, opno); + free_pathname(&f); + return; + } + fd = open_file_or_dir(&f, O_RDONLY, &dir); + e = fd < 0 ? errno : 0; + if (fd < 0) { + if (v) + printf("%d/%d: getfattr - open %s failed %d\n", + procid, opno, f.path, e); + free_pathname(&f); + return; + } + check_cwd(); + + /* + * If the file/dir has xattrs, pick one randomly, otherwise attempt + * to read a xattr that doesn't exist (fgetxattr should fail with + * errno set to ENOATTR (61) in this case). + */ + if (fep->xattr_counter > 0) + xattr_num = (random() % fep->xattr_counter) + 1; + else + xattr_num = 0; + + generate_xattr_name(xattr_num, name); + + value_len = fgetxattr(fd, name, NULL, 0); + if (value_len < 0) { + if (v) + printf("%d/%d: getfattr file %s name %s failed %d\n", + procid, opno, f.path, name, errno); + goto out; + } + + /* A xattr without value.*/ + if (value_len == 0) + goto out_log; + + value = malloc(value_len); + if (!value) { + if (v) + printf("%d/%d: getfattr file %s failed to allocate buffer with %d bytes\n", + procid, opno, f.path, value_len); + goto out; + } + + e = fgetxattr(fd, name, value, value_len) < 0 ? errno : 0; +out_log: + if (v) + printf("%d/%d: getfattr file %s name %s value length %d %d\n", + procid, opno, f.path, name, value_len, e); +out: + free(value); + free_pathname(&f); + close_file_or_dir(fd, dir); +} + +void link_f(int opno, long r) { int e; From patchwork Mon Apr 1 12:51:29 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Filipe Manana X-Patchwork-Id: 10879869 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id A2D471575 for ; Mon, 1 Apr 2019 12:51:35 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 8CFDF2882D for ; Mon, 1 Apr 2019 12:51:35 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 8B6BB28864; Mon, 1 Apr 2019 12:51:35 +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=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,MAILING_LIST_MULTI,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 2A47E288BA for ; Mon, 1 Apr 2019 12:51:35 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726163AbfDAMve (ORCPT ); Mon, 1 Apr 2019 08:51:34 -0400 Received: from mail.kernel.org ([198.145.29.99]:53924 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725882AbfDAMve (ORCPT ); Mon, 1 Apr 2019 08:51:34 -0400 Received: from localhost.localdomain (bl8-197-74.dsl.telepac.pt [85.241.197.74]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 59C9E206B7; Mon, 1 Apr 2019 12:51:33 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1554123094; bh=5n8X03ptqXbxBooF6nwN4hsWR45oW9Rn9rNDORj2YHo=; h=From:To:Cc:Subject:Date:From; b=JCrFv7Qx9Z7cy11mbF2gIyHKcKNY4MUg6mpkvi+ebSKltJEqDA6AVbQiUd57Y7FX9 A/t06cIWnw7n8GDqB49q4iYDCw8hL2wGIPugh/klct4eNhXmW4vv15uf95L2QqBYVv /ZXAZRJcqP4zOhS6JNkqOkmfSo6Xe4LzkqRghpjs= From: fdmanana@kernel.org To: fstests@vger.kernel.org Cc: linux-btrfs@vger.kernel.org, Filipe Manana Subject: [PATCH v2 5/7] fsstress: add operation for deleting xattrs from files and directories Date: Mon, 1 Apr 2019 13:51:29 +0100 Message-Id: <20190401125129.10213-1-fdmanana@kernel.org> X-Mailer: git-send-email 2.11.0 Sender: fstests-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: fstests@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Filipe Manana The previous patches added support for operations to set and get xattrs on regular files and directories, this patch just adds one operation to delete xattrs on files and directories. Signed-off-by: Filipe Manana --- V2: Use a different name for the operation (delfattr) and make use of the helper functions for opening and closing files or directories, introduced in the first patch of this series. ltp/fsstress.c | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/ltp/fsstress.c b/ltp/fsstress.c index 53e6a847..1694c5a2 100644 --- a/ltp/fsstress.c +++ b/ltp/fsstress.c @@ -60,6 +60,7 @@ typedef enum { OP_COPYRANGE, OP_CREAT, OP_DEDUPERANGE, + OP_DELFATTR, OP_DREAD, OP_DWRITE, OP_FALLOCATE, @@ -175,6 +176,7 @@ void clonerange_f(int, long); void copyrange_f(int, long); void creat_f(int, long); void deduperange_f(int, long); +void delfattr_f(int, long); void dread_f(int, long); void dwrite_f(int, long); void fallocate_f(int, long); @@ -228,6 +230,7 @@ opdesc_t ops[] = { { OP_COPYRANGE, "copyrange", copyrange_f, 4, 1 }, { OP_CREAT, "creat", creat_f, 4, 1 }, { OP_DEDUPERANGE, "deduperange", deduperange_f, 4, 1}, + { OP_DELFATTR, "delfattr", delfattr_f, 2, 1 }, { OP_DREAD, "dread", dread_f, 4, 0 }, { OP_DWRITE, "dwrite", dwrite_f, 4, 1 }, { OP_FALLOCATE, "fallocate", fallocate_f, 1, 1 }, @@ -3066,6 +3069,56 @@ creat_f(int opno, long r) } void +delfattr_f(int opno, long r) +{ + int fd; + fent_t *fep; + int e; + pathname_t f; + int v; + char name[XATTR_NAME_BUF_SIZE]; + int xattr_num; + DIR *dir; + + init_pathname(&f); + if (!get_fname(FT_REGFILE | FT_DIRm, r, &f, NULL, &fep, &v)) { + if (v) + printf("%d/%d: delfattr - no filename\n", procid, opno); + free_pathname(&f); + return; + } + fd = open_file_or_dir(&f, O_WRONLY, &dir); + e = fd < 0 ? errno : 0; + if (fd < 0) { + if (v) + printf("%d/%d: delfattr - open %s failed %d\n", + procid, opno, f.path, e); + free_pathname(&f); + return; + } + check_cwd(); + + /* + * If the file/dir has xattrs, pick one randomly, otherwise attempt to + * remove a xattr that doesn't exist (fremovexattr should fail with + * errno set to ENOATTR (61) in this case). + */ + if (fep->xattr_counter > 0) + xattr_num = (random() % fep->xattr_counter) + 1; + else + xattr_num = 0; + + generate_xattr_name(xattr_num, name); + + e = fremovexattr(fd, name) < 0 ? errno : 0; + if (v) + printf("%d/%d: delfattr file %s name %s %d\n", + procid, opno, f.path, name, e); + free_pathname(&f); + close_file_or_dir(fd, dir); +} + +void dread_f(int opno, long r) { int64_t align; From patchwork Mon Apr 1 12:51:52 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Filipe Manana X-Patchwork-Id: 10879873 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id ADCED13B5 for ; Mon, 1 Apr 2019 12:51:58 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 983FF28675 for ; Mon, 1 Apr 2019 12:51:58 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 8CE0528856; Mon, 1 Apr 2019 12:51:58 +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=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,MAILING_LIST_MULTI,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 216CC288C3 for ; Mon, 1 Apr 2019 12:51:58 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726163AbfDAMv5 (ORCPT ); Mon, 1 Apr 2019 08:51:57 -0400 Received: from mail.kernel.org ([198.145.29.99]:54342 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725882AbfDAMv5 (ORCPT ); Mon, 1 Apr 2019 08:51:57 -0400 Received: from localhost.localdomain (bl8-197-74.dsl.telepac.pt [85.241.197.74]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 01CD42070D; Mon, 1 Apr 2019 12:51:55 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1554123116; bh=L5czfGk/7aSpGUyWoW2t2YHwn+lDW5OMlXiFBEJR7II=; h=From:To:Cc:Subject:Date:From; b=DB/jCteR2CznQdnRL8OLUg2xVkjJngciwH8htQejNRW8sXnciQUimg0gijBIuGKuM Uf/n74o7rbZtBou/SeqnrHvmlGvbN0LArP/J2CKTrl0hSov4V3SVqpLU4OnVPXQlsP 6EX3xv4grw1STL7hRpNJRBNcMDMW1IHwUYRK7M6w= From: fdmanana@kernel.org To: fstests@vger.kernel.org Cc: linux-btrfs@vger.kernel.org, Filipe Manana Subject: [PATCH v2 6/7] fsstress: add operation for listing xattrs from files and directories Date: Mon, 1 Apr 2019 13:51:52 +0100 Message-Id: <20190401125152.10263-1-fdmanana@kernel.org> X-Mailer: git-send-email 2.11.0 Sender: fstests-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: fstests@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Filipe Manana The previous patches added support for operations to set, get and delete xattrs on regular files and directories, this patch just adds an operation to list the xattrs of a file/directory. Signed-off-by: Filipe Manana --- V2: New patch in the series, the first version of the patchset did not include this patch. ltp/fsstress.c | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/ltp/fsstress.c b/ltp/fsstress.c index 1694c5a2..ff560d6e 100644 --- a/ltp/fsstress.c +++ b/ltp/fsstress.c @@ -72,6 +72,7 @@ typedef enum { OP_GETDENTS, OP_GETFATTR, OP_LINK, + OP_LISTFATTR, OP_MKDIR, OP_MKNOD, OP_MREAD, @@ -188,6 +189,7 @@ void getattr_f(int, long); void getdents_f(int, long); void getfattr_f(int, long); void link_f(int, long); +void listfattr_f(int, long); void mkdir_f(int, long); void mknod_f(int, long); void mread_f(int, long); @@ -242,6 +244,7 @@ opdesc_t ops[] = { { OP_GETDENTS, "getdents", getdents_f, 1, 0 }, { OP_GETFATTR, "getfattr", getfattr_f, 2, 0 }, { OP_LINK, "link", link_f, 1, 1 }, + { OP_LISTFATTR, "listfattr", listfattr_f, 1, 0 }, { OP_MKDIR, "mkdir", mkdir_f, 2, 1 }, { OP_MKNOD, "mknod", mknod_f, 2, 1 }, { OP_MREAD, "mread", mread_f, 2, 0 }, @@ -3751,6 +3754,69 @@ link_f(int opno, long r) } void +listfattr_f(int opno, long r) +{ + int fd; + fent_t *fep; + int e; + pathname_t f; + int v; + char *buffer = NULL; + int buffer_len; + DIR *dir; + + init_pathname(&f); + if (!get_fname(FT_REGFILE | FT_DIRm, r, &f, NULL, &fep, &v)) { + if (v) + printf("%d/%d: listfattr - no filename\n", procid, opno); + free_pathname(&f); + return; + } + fd = open_file_or_dir(&f, O_RDONLY, &dir); + e = fd < 0 ? errno : 0; + if (fd < 0) { + if (v) + printf("%d/%d: listfattr - open %s failed %d\n", + procid, opno, f.path, e); + free_pathname(&f); + return; + } + check_cwd(); + + e = flistxattr(fd, NULL, 0); + if (e < 0) { + if (v) + printf("%d/%d: listfattr %s failed %d\n", + procid, opno, f.path, errno); + goto out; + } + buffer_len = e; + if (buffer_len == 0) { + if (v) + printf("%d/%d: listfattr %s - has no extended attributes\n", + procid, opno, f.path); + goto out; + } + + buffer = malloc(buffer_len); + if (!buffer) { + if (v) + printf("%d/%d: listfattr %s failed to allocate buffer with %d bytes\n", + procid, opno, f.path, buffer_len); + goto out; + } + + e = flistxattr(fd, buffer, buffer_len) < 0 ? errno : 0; + if (v) + printf("%d/%d: listfattr %s buffer length %d %d\n", + procid, opno, f.path, buffer_len, e); +out: + free(buffer); + free_pathname(&f); + close_file_or_dir(fd, dir); +} + +void mkdir_f(int opno, long r) { int e; From patchwork Mon Apr 1 12:52:16 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Filipe Manana X-Patchwork-Id: 10879879 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id DAC2713B5 for ; Mon, 1 Apr 2019 12:52:24 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id CBA2728675 for ; Mon, 1 Apr 2019 12:52:24 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id BFBAC288C7; Mon, 1 Apr 2019 12:52:24 +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=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,MAILING_LIST_MULTI,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 3824E28675 for ; Mon, 1 Apr 2019 12:52:23 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726608AbfDAMwW (ORCPT ); Mon, 1 Apr 2019 08:52:22 -0400 Received: from mail.kernel.org ([198.145.29.99]:54698 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725882AbfDAMwW (ORCPT ); Mon, 1 Apr 2019 08:52:22 -0400 Received: from localhost.localdomain (bl8-197-74.dsl.telepac.pt [85.241.197.74]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 7024C2070D; Mon, 1 Apr 2019 12:52:20 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1554123141; bh=Le15WaNmYBj1XRQEEo/Bz1gB6qo50zbm7tOL6Lj2oKk=; h=From:To:Cc:Subject:Date:From; b=tde09yS/9D8YFC2v/i82Ds4m6IkxWwzpggVfAEaqj/0cbYGfWgQpADanar1kLKb/X LTKSj7I/QW2yn/W/ZVj2LtKvpwmtonXqvE7IhyPLQqs7U5+8qwGxTNIqU8xa0GJevw /MAT/KNcM6TrMm9gchIBWlvtwWJ7w6tHahTseZ/U= From: fdmanana@kernel.org To: fstests@vger.kernel.org Cc: linux-btrfs@vger.kernel.org, Filipe Manana Subject: [PATCH v2 7/7] fssum: add support for checking xattrs Date: Mon, 1 Apr 2019 13:52:16 +0100 Message-Id: <20190401125216.10314-1-fdmanana@kernel.org> X-Mailer: git-send-email 2.11.0 Sender: fstests-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: fstests@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Filipe Manana Currently fssum, mostly used for btrfs test cases that test the btrfs send feature, ignores completely the existence of xattrs. This change teaches fssum to find xattrs and make them contribute to the checksum of a filesystem, so that we can catch filesystem bugs regarding missing, corrupt or not supposed to exist xattrs (i.e. that an incremental btrfs send does not forget to create, update or remove xattrs). Signed-off-by: Filipe Manana --- V2: No changes from v1. src/fssum.c | 143 ++++++++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 129 insertions(+), 14 deletions(-) diff --git a/src/fssum.c b/src/fssum.c index f1da72fb..6ba0a95c 100644 --- a/src/fssum.c +++ b/src/fssum.c @@ -20,6 +20,7 @@ #include #include #include +#include #ifdef __SOLARIS__ #include #endif @@ -40,7 +41,6 @@ #endif /* TODO: add hardlink recognition */ -/* TODO: add xattr/acl */ struct excludes { char *path; @@ -71,15 +71,16 @@ enum _flags { FLAG_MTIME, FLAG_CTIME, FLAG_DATA, + FLAG_XATTRS, FLAG_OPEN_ERROR, FLAG_STRUCTURE, NUM_FLAGS }; -const char flchar[] = "ugoamcdes"; +const char flchar[] = "ugoamcdxes"; char line[65536]; -int flags[NUM_FLAGS] = {1, 1, 1, 1, 1, 0, 1, 0, 0}; +int flags[NUM_FLAGS] = {1, 1, 1, 1, 1, 0, 1, 1, 0, 0}; char * getln(char *buf, int size, FILE *fp) @@ -135,7 +136,7 @@ usage(void) fprintf(stderr, " -v : verbose mode (debugging only)\n"); fprintf(stderr, " -r : read checksum or manifest from file\n"); - fprintf(stderr, " -[ugoamcde] : specify which fields to include in checksum calculation.\n"); + fprintf(stderr, " -[ugoamcdxe]: specify which fields to include in checksum calculation.\n"); fprintf(stderr, " u : include uid\n"); fprintf(stderr, " g : include gid\n"); fprintf(stderr, " o : include mode\n"); @@ -143,9 +144,10 @@ usage(void) fprintf(stderr, " a : include atime\n"); fprintf(stderr, " c : include ctime\n"); fprintf(stderr, " d : include file data\n"); + fprintf(stderr, " x : include xattrs\n"); fprintf(stderr, " e : include open errors (aborts otherwise)\n"); fprintf(stderr, " s : include block structure (holes)\n"); - fprintf(stderr, " -[UGOAMCDES]: exclude respective field from calculation\n"); + fprintf(stderr, " -[UGOAMCDXES]: exclude respective field from calculation\n"); fprintf(stderr, " -n : reset all flags\n"); fprintf(stderr, " -N : set all flags\n"); fprintf(stderr, " -x path : exclude path when building checksum (multiple ok)\n"); @@ -221,6 +223,106 @@ sum_to_string(sum_t *dst) } int +namecmp(const void *aa, const void *bb) +{ + char * const *a = aa; + char * const *b = bb; + + return strcmp(*a, *b); +} + +int +sum_xattrs(int fd, sum_t *dst) +{ + ssize_t buflen; + ssize_t len; + char *buf; + char *p; + char **names = NULL; + int num_xattrs = 0; + int ret = 0; + int i; + + buflen = flistxattr(fd, NULL, 0); + if (buflen < 0) + return -errno; + /* no xattrs exist */ + if (buflen == 0) + return 0; + + buf = malloc(buflen); + if (!buf) + return -ENOMEM; + + buflen = flistxattr(fd, buf, buflen); + if (buflen < 0) { + ret = -errno; + goto out; + } + + /* + * Keep the list of xattrs sorted, because the order in which they are + * listed is filesystem dependent, so we want to get the same checksum + * on different filesystems. + */ + + p = buf; + len = buflen; + while (len > 0) { + int keylen; + + keylen = strlen(p) + 1; /* +1 for NULL terminator */ + len -= keylen; + p += keylen; + num_xattrs++; + } + + names = malloc(sizeof(char *) * num_xattrs); + if (!names) { + ret = -ENOMEM; + goto out; + } + + p = buf; + for (i = 0; i < num_xattrs; i++) { + names[i] = p; + p += strlen(p) + 1; /* +1 for NULL terminator */ + } + + qsort(names, num_xattrs, sizeof(char *), namecmp); + + for (i = 0; i < num_xattrs; i++) { + len = fgetxattr(fd, names[i], NULL, 0); + if (len < 0) { + ret = -errno; + goto out; + } + sum_add(dst, names[i], strlen(names[i])); + /* no value */ + if (len == 0) + continue; + p = malloc(len); + if (!p) { + ret = -ENOMEM; + goto out; + } + len = fgetxattr(fd, names[i], p, len); + if (len < 0) { + ret = -errno; + free(p); + goto out; + } + sum_add(dst, p, len); + free(p); + } +out: + free(buf); + free(names); + + return ret; +} + +int sum_file_data_permissive(int fd, sum_t *dst) { int ret; @@ -401,15 +503,6 @@ malformed: excess_file(fn); } -int -namecmp(const void *aa, const void *bb) -{ - char * const *a = aa; - char * const *b = bb; - - return strcmp(*a, *b); -} - void sum(int dirfd, int level, sum_t *dircs, char *path_prefix, char *path_in) { @@ -493,6 +586,28 @@ sum(int dirfd, int level, sum_t *dircs, char *path_prefix, char *path_in) sum_add_time(&meta, st.st_mtime); if (flags[FLAG_CTIME]) sum_add_time(&meta, st.st_ctime); + if (flags[FLAG_XATTRS] && + (S_ISDIR(st.st_mode) || S_ISREG(st.st_mode))) { + fd = openat(dirfd, namelist[i], 0); + if (fd == -1 && flags[FLAG_OPEN_ERROR]) { + sum_add_u64(&meta, errno); + } else if (fd == -1) { + fprintf(stderr, "open failed for %s/%s: %s\n", + path_prefix, path, strerror(errno)); + exit(-1); + } else { + ret = sum_xattrs(fd, &meta); + close(fd); + if (ret < 0) { + fprintf(stderr, + "failed to read xattrs from " + "%s/%s: %s\n", + path_prefix, path, + strerror(-ret)); + exit(-1); + } + } + } if (S_ISDIR(st.st_mode)) { fd = openat(dirfd, namelist[i], 0); if (fd == -1 && flags[FLAG_OPEN_ERROR]) {