From patchwork Fri Apr 19 10:53:45 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Filipe Manana X-Patchwork-Id: 10909395 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 DDC4114DB for ; Fri, 19 Apr 2019 18:33:07 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id D4E3128C6D for ; Fri, 19 Apr 2019 18:33:07 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id C9A2228D9E; Fri, 19 Apr 2019 18:33:07 +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 74B7E28C6D for ; Fri, 19 Apr 2019 18:33:07 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727094AbfDSScz (ORCPT ); Fri, 19 Apr 2019 14:32:55 -0400 Received: from mail.kernel.org ([198.145.29.99]:53882 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727782AbfDSS3R (ORCPT ); Fri, 19 Apr 2019 14:29:17 -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 34628218FD; Fri, 19 Apr 2019 10:53:51 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1555671232; bh=6sznOSxUxOgb9ELlknscYeWRRT9ONpA3sEm9TI1UQ7c=; h=From:To:Cc:Subject:Date:From; b=Wqlfc7yhO5/uV9rPSqQa+mUy/lRe7mtxNvalD474aiA4elzVZ+F7Ou+ilpGbT8vKb ao2OAGFr0QaQqK99r/1wTIqSSkkEBW1ErIp9OsKexekMYighnnDM3YILKqcE1erSFQ 6ikSG5iqUFdULGgfQXTzXcdTNeXNS+EsQOfBmPRM= From: fdmanana@kernel.org To: fstests@vger.kernel.org Cc: linux-btrfs@vger.kernel.org, Filipe Manana Subject: [PATCH v4 1/7] fsstress: allow fsync on directories too Date: Fri, 19 Apr 2019 11:53:45 +0100 Message-Id: <20190419105345.11777-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. V3: Simplified helper to open file or directory, removed no longer needed helper for closing file or directory. V4: No changes. ltp/fsstress.c | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/ltp/fsstress.c b/ltp/fsstress.c index 41a0155e..72c574da 100644 --- a/ltp/fsstress.c +++ b/ltp/fsstress.c @@ -324,6 +324,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); int open_path(pathname_t *, int); DIR *opendir_path(pathname_t *); void process_freq(char *); @@ -1385,6 +1386,22 @@ namerandpad(int id, char *buf, int i) } int +open_file_or_dir(pathname_t *name, int flags) +{ + int fd; + + fd = open_path(name, flags); + if (fd != -1) + return fd; + if (fd == -1 && errno != EISDIR) + return fd; + /* Directories can not be opened in write mode. */ + flags &= ~O_WRONLY; + flags |= O_RDONLY | O_DIRECTORY; + return open_path(name, flags); +} + +int open_path(pathname_t *name, int oflag) { char buf[NAME_MAX + 1]; @@ -3455,13 +3472,13 @@ fsync_f(int opno, long r) int v; 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); e = fd < 0 ? errno : 0; check_cwd(); if (fd < 0) { From patchwork Fri Apr 19 10:53:58 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Filipe Manana X-Patchwork-Id: 10909385 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 4D00914DB for ; Fri, 19 Apr 2019 18:31:28 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 437B728C6D for ; Fri, 19 Apr 2019 18:31:28 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 3764628DB3; Fri, 19 Apr 2019 18:31:28 +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 E543928C6D for ; Fri, 19 Apr 2019 18:31:27 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727761AbfDSSbV (ORCPT ); Fri, 19 Apr 2019 14:31:21 -0400 Received: from mail.kernel.org ([198.145.29.99]:53888 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727944AbfDSS3S (ORCPT ); Fri, 19 Apr 2019 14:29:18 -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 E3C58218FF; Fri, 19 Apr 2019 10:54:02 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1555671243; bh=tDP6vqZu2GRscN2nvtTTBzUNCU8DnNFN7lQq2VCIACg=; h=From:To:Cc:Subject:Date:From; b=KREVQm1BUro412Ozh3kxdYeH8Gg0rmmKLQtedF1bqTvZi9oMhSAaYWoP9Tg+yG6bD fF+plUeaqudFbjgkLAvC7lpzZdP6mtgAnRPHTkC1J5MHyxzI/neW+5GR1RsQPM/jUn N8BBwqW66LEpzcR0FSDNl0sgripnQiLV788FS13Q= From: fdmanana@kernel.org To: fstests@vger.kernel.org Cc: linux-btrfs@vger.kernel.org, Filipe Manana Subject: [PATCH v4 2/7] fsstress: allow afsync on directories too Date: Fri, 19 Apr 2019 11:53:58 +0100 Message-Id: <20190419105358.11833-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. V3: Use the new simplified helper for opening a file or directory. V4: No changes. ltp/fsstress.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ltp/fsstress.c b/ltp/fsstress.c index 72c574da..3ec19143 100644 --- a/ltp/fsstress.c +++ b/ltp/fsstress.c @@ -1395,8 +1395,8 @@ open_file_or_dir(pathname_t *name, int flags) return fd; if (fd == -1 && errno != EISDIR) return fd; - /* Directories can not be opened in write mode. */ - flags &= ~O_WRONLY; + /* Directories can not be opened in write mode nor direct mode. */ + flags &= ~(O_WRONLY | O_DIRECT); flags |= O_RDONLY | O_DIRECTORY; return open_path(name, flags); } @@ -1774,13 +1774,13 @@ afsync_f(int opno, long r) struct io_event event; 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); e = fd < 0 ? errno : 0; check_cwd(); if (fd < 0) { From patchwork Fri Apr 19 10:54:08 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Filipe Manana X-Patchwork-Id: 10909403 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 3DE4E922 for ; Fri, 19 Apr 2019 18:33:30 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 3352C28C6D for ; Fri, 19 Apr 2019 18:33:30 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 2717728D9E; Fri, 19 Apr 2019 18:33:30 +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 5ADBF28C6D for ; Fri, 19 Apr 2019 18:33:29 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728034AbfDSSdW (ORCPT ); Fri, 19 Apr 2019 14:33:22 -0400 Received: from mail.kernel.org ([198.145.29.99]:53894 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727590AbfDSS3Q (ORCPT ); Fri, 19 Apr 2019 14:29:16 -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 78F2D21900; Fri, 19 Apr 2019 10:54:13 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1555671254; bh=o74CXUPN/VaDtIkLGsVYZ6wO4z9lqKVGvmM5V7gHnaE=; h=From:To:Cc:Subject:Date:From; b=OwOu1prsm7scshfHSdB5esoJDRXu2jdK0vVktIyBXgSdCZ1Qfj7I0WZNoo45e6WwH PAToWjVHhqNjjOqZyu61Ar68kS3Y03oDsQ3AdNUO6dd5pLkWyZ7nM5lFka3SGKMBBZ ET+m8J2Gk9cua4X2EFxMjZkWV0W5WMa1AVUq1j8c= From: fdmanana@kernel.org To: fstests@vger.kernel.org Cc: linux-btrfs@vger.kernel.org, Filipe Manana Subject: [PATCH v4 3/7] fsstress: add operation for setting xattrs on files and directories Date: Fri, 19 Apr 2019 11:54:08 +0100 Message-Id: <20190419105408.11883-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. V3: Simplified implementation to not need to open a file descriptor and use a path string instead. V4: Addressed Eryu's comments. ltp/fsstress.c | 154 +++++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 145 insertions(+), 9 deletions(-) diff --git a/ltp/fsstress.c b/ltp/fsstress.c index 3ec19143..b3ff8d92 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); @@ -176,6 +181,7 @@ void fdatasync_f(int, long); void fiemap_f(int, long); void freesp_f(int, long); void fsync_f(int, long); +char *gen_random_string(int); void getattr_f(int, long); void getdents_f(int, long); void link_f(int, long); @@ -194,6 +200,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); @@ -204,6 +211,7 @@ void unlink_f(int, long); void unresvsp_f(int, long); void write_f(int, long); void writev_f(int, long); +char *xattr_flag_to_string(int); opdesc_t ops[] = { /* { OP_ENUM, "name", function, freq, iswrite }, */ @@ -244,7 +252,11 @@ opdesc_t ops[] = { { OP_RENAME, "rename", rename_f, 2, 1 }, { OP_RESVSP, "resvsp", resvsp_f, 1, 1 }, { OP_RMDIR, "rmdir", rmdir_f, 1, 1 }, + /* set attribute flag (FS_IOC_SETFLAGS ioctl) */ { OP_SETATTR, "setattr", setattr_f, 0, 1 }, + /* set extended attribute */ + { OP_SETFATTR, "setfattr", setfattr_f, 2, 1 }, + /* set project id (XFS_IOC_FSSETXATTR ioctl) */ { OP_SETXATTR, "setxattr", setxattr_f, 1, 1 }, { OP_SPLICE, "splice", splice_f, 1, 1 }, { OP_STAT, "stat", stat_f, 1, 0 }, @@ -296,7 +308,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); @@ -315,6 +327,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 *); +int generate_xattr_name(int, char *, int); 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); @@ -716,7 +729,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; @@ -729,6 +742,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 @@ -1122,6 +1136,18 @@ generate_fname(fent_t *fep, int ft, pathname_t *name, int *idp, int *v) return 1; } +int generate_xattr_name(int xattr_num, char *buffer, int buflen) +{ + int ret; + + ret = snprintf(buffer, buflen, "user.x%d", xattr_num); + if (ret < 0) + return ret; + if (ret < buflen) + return 0; + return -EOVERFLOW; +} + /* * Get file * Input: "which" to choose the file-types eg. non-directory @@ -3030,7 +3056,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) { @@ -3495,6 +3521,28 @@ fsync_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; +} + void getattr_f(int opno, long r) { @@ -3551,6 +3599,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; @@ -3559,7 +3608,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); @@ -3586,7 +3635,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); @@ -3626,7 +3675,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); @@ -3664,7 +3713,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); @@ -4040,12 +4089,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, @@ -4168,6 +4219,81 @@ setattr_f(int opno, long r) } void +setfattr_f(int opno, long r) +{ + int e; + pathname_t f; + fent_t *fep; + int v; + int value_len; + char name[XATTR_NAME_BUF_SIZE]; + char *value = NULL; + int flag = 0; + int xattr_num; + + 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); + goto out; + } + 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; + } + + /* + * 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 = generate_xattr_name(xattr_num, name, sizeof(name)); + if (e < 0) { + printf("%d/%d: setfattr - file %s failed to generate xattr name: %d\n", + procid, opno, f.path, e); + goto out; + } + + e = setxattr(f.path, 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); +} + +void stat_f(int opno, long r) { int e; @@ -4229,7 +4355,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); @@ -4498,3 +4624,13 @@ writev_f(int opno, long r) free_pathname(&f); close(fd); } + +char * +xattr_flag_to_string(int flag) +{ + if (flag == XATTR_CREATE) + return "create"; + if (flag == XATTR_REPLACE) + return "replace"; + return "none"; +} From patchwork Fri Apr 19 10:54:22 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Filipe Manana X-Patchwork-Id: 10909409 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 D829F18FD for ; Fri, 19 Apr 2019 18:33:49 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id CF03F28C6D for ; Fri, 19 Apr 2019 18:33:49 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id C395828C79; Fri, 19 Apr 2019 18:33:49 +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 F2DF828D9E for ; Fri, 19 Apr 2019 18:33:48 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728112AbfDSSdl (ORCPT ); Fri, 19 Apr 2019 14:33:41 -0400 Received: from mail.kernel.org ([198.145.29.99]:53916 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727599AbfDSS3Q (ORCPT ); Fri, 19 Apr 2019 14:29:16 -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 DE76821902; Fri, 19 Apr 2019 10:54:25 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1555671266; bh=9RXCj8OHIWsuMAxW2auL4pF8XiqeYUBf+8hsTSCVZJQ=; h=From:To:Cc:Subject:Date:From; b=Ix/VpuROGxQsL0Gz1XX07zQbdYWQFHkIotZHKZltbdFL1Z9NX/WHmH6gsjNdSEASA +Epg+0B16SVyqiD3tmHPZe1CXH4CXyldCr2CfgiDa31jeEn1F2KjTiYatUxhU9wgBg SRKHN+4xKeeHUctYjFWMbxIF44xWGW7BNqfpLlck= From: fdmanana@kernel.org To: fstests@vger.kernel.org Cc: linux-btrfs@vger.kernel.org, Filipe Manana Subject: [PATCH v4 4/7] fsstress: add operation for reading xattrs from files and directories Date: Fri, 19 Apr 2019 11:54:22 +0100 Message-Id: <20190419105422.11934-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. V3: Simplified implementation to not need to open a file descriptor and use a path string instead. V4: Addressed Eryu's comments. ltp/fsstress.c | 73 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) diff --git a/ltp/fsstress.c b/ltp/fsstress.c index b3ff8d92..f24dd42d 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, @@ -184,6 +185,7 @@ void fsync_f(int, long); char *gen_random_string(int); 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); @@ -237,6 +239,8 @@ opdesc_t ops[] = { { OP_FSYNC, "fsync", fsync_f, 1, 1 }, { OP_GETATTR, "getattr", getattr_f, 1, 0 }, { OP_GETDENTS, "getdents", getdents_f, 1, 0 }, + /* get extended attribute */ + { OP_GETFATTR, "getfattr", getfattr_f, 1, 0 }, { OP_LINK, "link", link_f, 1, 1 }, { OP_MKDIR, "mkdir", mkdir_f, 2, 1 }, { OP_MKNOD, "mknod", mknod_f, 2, 1 }, @@ -3594,6 +3598,75 @@ getdents_f(int opno, long r) } void +getfattr_f(int opno, long r) +{ + 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; + + 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); + goto out; + } + 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; + + e = generate_xattr_name(xattr_num, name, sizeof(name)); + if (e < 0) { + printf("%d/%d: getfattr - file %s failed to generate xattr name: %d\n", + procid, opno, f.path, e); + goto out; + } + + value_len = getxattr(f.path, 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) { + e = 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 = getxattr(f.path, 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); +} + +void link_f(int opno, long r) { int e; From patchwork Fri Apr 19 10:54:48 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Filipe Manana X-Patchwork-Id: 10909399 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 981A914DB for ; Fri, 19 Apr 2019 18:33:22 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 8F14728C6D for ; Fri, 19 Apr 2019 18:33:22 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 8362728D9E; Fri, 19 Apr 2019 18:33:22 +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 30ED428C6D for ; Fri, 19 Apr 2019 18:33:22 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726392AbfDSSdN (ORCPT ); Fri, 19 Apr 2019 14:33:13 -0400 Received: from mail.kernel.org ([198.145.29.99]:53884 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727734AbfDSS3R (ORCPT ); Fri, 19 Apr 2019 14:29:17 -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 5377F21904; Fri, 19 Apr 2019 10:54:53 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1555671294; bh=Xz+YD92fkUAft3mcEtYRfZPbUulg1+Ixkkunu7U3XbE=; h=From:To:Cc:Subject:Date:From; b=XC9Z8t+48aFWZYEtX/AIb11BSs12TSyAIxiIriHEVrJZy+82BSuj1cAjSpjFck0jO O7jypPT2/gqI8fWROW03ay6CJufzeA3R9x6/CMPFcNMwyDxMIGpGKlwdRWmXhCLqJz X7Tv4DCugzW6XkKj5UrAl+sHSv0t4uP/GcRH3uhI= From: fdmanana@kernel.org To: fstests@vger.kernel.org Cc: linux-btrfs@vger.kernel.org, Filipe Manana Subject: [PATCH v4 5/7] fsstress: add operation for deleting xattrs from files and directories Date: Fri, 19 Apr 2019 11:54:48 +0100 Message-Id: <20190419105448.11984-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. V3: Simplified implementation to not need to open a file descriptor and use a path string instead. V4: Addressed Eryu's comments. ltp/fsstress.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/ltp/fsstress.c b/ltp/fsstress.c index f24dd42d..74100948 100644 --- a/ltp/fsstress.c +++ b/ltp/fsstress.c @@ -82,6 +82,7 @@ typedef enum { OP_READ, OP_READLINK, OP_READV, + OP_REMOVEFATTR, OP_RENAME, OP_RESVSP, OP_RMDIR, @@ -198,6 +199,7 @@ void insert_f(int, long); void read_f(int, long); void readlink_f(int, long); void readv_f(int, long); +void removefattr_f(int, long); void rename_f(int, long); void resvsp_f(int, long); void rmdir_f(int, long); @@ -253,6 +255,8 @@ opdesc_t ops[] = { { OP_READ, "read", read_f, 1, 0 }, { OP_READLINK, "readlink", readlink_f, 1, 0 }, { OP_READV, "readv", readv_f, 1, 0 }, + /* remove (delete) extended attribute */ + { OP_REMOVEFATTR, "removefattr", removefattr_f, 1, 1 }, { OP_RENAME, "rename", rename_f, 2, 1 }, { OP_RESVSP, "resvsp", resvsp_f, 1, 1 }, { OP_RMDIR, "rmdir", rmdir_f, 1, 1 }, @@ -4115,6 +4119,49 @@ readv_f(int opno, long r) } void +removefattr_f(int opno, long r) +{ + fent_t *fep; + int e; + pathname_t f; + int v; + char name[XATTR_NAME_BUF_SIZE]; + int xattr_num; + + init_pathname(&f); + if (!get_fname(FT_REGFILE | FT_DIRm, r, &f, NULL, &fep, &v)) { + if (v) + printf("%d/%d: removefattr - no filename\n", procid, opno); + goto out; + } + 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; + + e = generate_xattr_name(xattr_num, name, sizeof(name)); + if (e < 0) { + printf("%d/%d: removefattr - file %s failed to generate xattr name: %d\n", + procid, opno, f.path, e); + goto out; + } + + e = removexattr(f.path, name) < 0 ? errno : 0; + if (v) + printf("%d/%d: removefattr file %s name %s %d\n", + procid, opno, f.path, name, e); +out: + free_pathname(&f); +} + +void rename_f(int opno, long r) { fent_t *dfep; From patchwork Fri Apr 19 10:55:00 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Filipe Manana X-Patchwork-Id: 10909391 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 027B017E0 for ; Fri, 19 Apr 2019 18:33:06 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id EDC1828C79 for ; Fri, 19 Apr 2019 18:33:05 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id E201A28C6D; Fri, 19 Apr 2019 18:33:05 +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 8F5C828C79 for ; Fri, 19 Apr 2019 18:33:05 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728217AbfDSScz (ORCPT ); Fri, 19 Apr 2019 14:32:55 -0400 Received: from mail.kernel.org ([198.145.29.99]:53914 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727785AbfDSS3R (ORCPT ); Fri, 19 Apr 2019 14:29:17 -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 08F0721905; Fri, 19 Apr 2019 10:55:05 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1555671306; bh=DCUCna3mHUDw8Zvkxe4Nntuy7Hba1z0r1fDJrMvqC+I=; h=From:To:Cc:Subject:Date:From; b=0JhKbidJjCD2zIdvuENOVED58crFb1aQlBP2xRhCeBLRLZehuSRv1PSATmjEmWC4d KHIUa4Xap5w68pmkb4BVYWDzXB0EE3pn522yjsB/IgIQl6W1cceNzP5ETINb5htpIL 8tJ+mYvSXx7FgmNLJFQ+Eas+caR0AutA+DMCx+/E= From: fdmanana@kernel.org To: fstests@vger.kernel.org Cc: linux-btrfs@vger.kernel.org, Filipe Manana Subject: [PATCH v4 6/7] fsstress: add operation for listing xattrs from files and directories Date: Fri, 19 Apr 2019 11:55:00 +0100 Message-Id: <20190419105500.12034-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. V3: Simplified implementation to not need to open a file descriptor and use a path string instead. V4: Addressed Eryu's comments. ltp/fsstress.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/ltp/fsstress.c b/ltp/fsstress.c index 74100948..450cf4f1 100644 --- a/ltp/fsstress.c +++ b/ltp/fsstress.c @@ -71,6 +71,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); @@ -244,6 +246,8 @@ opdesc_t ops[] = { /* get extended attribute */ { OP_GETFATTR, "getfattr", getfattr_f, 1, 0 }, { OP_LINK, "link", link_f, 1, 1 }, + /* list extent attributes */ + { 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 }, @@ -3723,6 +3727,56 @@ link_f(int opno, long r) } void +listfattr_f(int opno, long r) +{ + fent_t *fep; + int e; + pathname_t f; + int v; + char *buffer = NULL; + int buffer_len; + + 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); + goto out; + } + check_cwd(); + + e = listxattr(f.path, 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 = listxattr(f.path, 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); +} + +void mkdir_f(int opno, long r) { int e; From patchwork Fri Apr 19 10:55: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: 10909411 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 B785B14DB for ; Fri, 19 Apr 2019 18:33:50 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id AE4E628C6D for ; Fri, 19 Apr 2019 18:33:50 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id A325928D9E; Fri, 19 Apr 2019 18:33:50 +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 3077728C6D for ; Fri, 19 Apr 2019 18:33:50 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727975AbfDSSdl (ORCPT ); Fri, 19 Apr 2019 14:33:41 -0400 Received: from mail.kernel.org ([198.145.29.99]:53910 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727574AbfDSS3Q (ORCPT ); Fri, 19 Apr 2019 14:29:16 -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 6442A21909; Fri, 19 Apr 2019 10:55:20 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1555671321; bh=7Q2/2pO/M5iZUWilsbZWtWkqAuNSwPiAGmf9aFbrRoM=; h=From:To:Cc:Subject:Date:From; b=I3qVFZcI07XoPNsIRI834qwrPKvfVcIgAXj3Vlt4F1yLW7v0KPQk2JDFL++OOMPF0 baE3NKfH6DfOkayZ7/BoFrGKvCd1GkF6gU71pVL1xxbx10Mj6tYocN5UkDP2Y8KI8+ Glx0vKb2XDSS4YjJ9bWnvq/JMfXBW0NLOdWMJaZA= From: fdmanana@kernel.org To: fstests@vger.kernel.org Cc: linux-btrfs@vger.kernel.org, Filipe Manana Subject: [PATCH v4 7/7] fssum: add support for checking xattrs Date: Fri, 19 Apr 2019 11:55:16 +0100 Message-Id: <20190419105516.12088-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. V3: No changes from v2 and v1. V4: No changes from v3, v2 and 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]) {