From patchwork Tue Apr 18 18:17:22 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Amir Goldstein X-Patchwork-Id: 9685971 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id CB63B602C2 for ; Tue, 18 Apr 2017 18:17:23 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id BFEE51FFD6 for ; Tue, 18 Apr 2017 18:17:23 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id B4A642022C; Tue, 18 Apr 2017 18:17:23 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.3 required=2.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, RCVD_IN_DNSWL_HI, RCVD_IN_SORBS_SPAM, T_DKIM_INVALID 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 2B48E1FFD6 for ; Tue, 18 Apr 2017 18:17:23 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753411AbdDRSRW (ORCPT ); Tue, 18 Apr 2017 14:17:22 -0400 Received: from mail-wr0-f194.google.com ([209.85.128.194]:36572 "EHLO mail-wr0-f194.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752748AbdDRSRU (ORCPT ); Tue, 18 Apr 2017 14:17:20 -0400 Received: by mail-wr0-f194.google.com with SMTP id o21so116783wrb.3; Tue, 18 Apr 2017 11:17:19 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=yXf8C6nkSqSs3O1W4U9IqMKlvmjAE/CnyQbfvC6MVxI=; b=O64ST313guDeW6ZrZR//C9+AmG6a2/AGUDI7KuBoXtWALxC91O0aPn6u9M2Yu9V5Hg +j/yIoNp7GcDMQQWneVMapI54VdxhzN+7qBiiiypFtW5wOzAIKioOOQEMjHiRQSur20h uUEUZrm0qAWyEcBaktw2J5EF4rHFMD0/5lEL6eT4jA7Pve6C19wwKItBnNLeb1+q4exM xDzHgdY8PVSDAVzH3tjq2FDFrGI7FtioI2f8xvwC00H87reLCghqMJI9bGvOJFkw1yhm Mo0ItR9r0piTXVpdf1l1Y64FoSq6hLiD21xqlAQmShcC7OwOwWOo57Z7uPS86IkUvpzN b97Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=yXf8C6nkSqSs3O1W4U9IqMKlvmjAE/CnyQbfvC6MVxI=; b=q8098wyjsIxi+itNl1Kdc+EPt1R40f9G6ZcRzqVZKzfnjy/GJ8pTeK1B7j2Lk99zW1 Y7Wu9RY34n6furCkL+rIBuVZSYTzP12FTqIMMaoTS9Wp7YeZiqJjCrsygeFCB0sqx6nz esy/n9+qaV67KY7saHKvEeLhFjtfm4cskjJCUhKm1SI7WP5ljyvi9z2lr4bAQbbsQLyk nb9x+OlmqLraWoFE6PnC8oc8ep2uMswauRFl9xpsp1qTQj6VIXF9l9PJQjFs8ghtuPGW oPdaTuQyodnwPQlyR6J9IrBkodsvlnfivEZ2e+mr3QgdOmcVQNVHaVVUZ2vK5fQITI6g CTwA== X-Gm-Message-State: AN3rC/5NzkR8324P8enj4y9O1H/iXheGjwWomtD9nfd6zSRRy+LNy90n nyHW6zCNlJ+v8A== X-Received: by 10.223.139.86 with SMTP id v22mr23192580wra.47.1492539438487; Tue, 18 Apr 2017 11:17:18 -0700 (PDT) Received: from amir-VirtualBox.lan (bzq-79-179-55-127.red.bezeqint.net. [79.179.55.127]) by smtp.gmail.com with ESMTPSA id v126sm15958709wmd.11.2017.04.18.11.17.16 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Tue, 18 Apr 2017 11:17:17 -0700 (PDT) From: Amir Goldstein To: Eryu Guan Cc: Miklos Szeredi , Trond Myklebust , Jeff Layton , "J . Bruce Fields" , fstests@vger.kernel.org, linux-unionfs@vger.kernel.org Subject: [PATCH 2/4] src/open_by_handle: flexible usage options Date: Tue, 18 Apr 2017 21:17:22 +0300 Message-Id: <1492539444-25938-3-git-send-email-amir73il@gmail.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1492539444-25938-1-git-send-email-amir73il@gmail.com> References: <1492539444-25938-1-git-send-email-amir73il@gmail.com> Sender: fstests-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: fstests@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP More usage options for testing open_by_handle, which are needed for testing stable handles across copy up in overlayfs. usage: open_by_handle [-c|-l|-u|-d] [num_files] Examples: 1. Create N test files (nlink=1) under test_dir and exit: $ open_by_handle -c [N] 2. Get file handles, drop caches and try to open by handle (expects success): $ open_by_handle [N] 3. Get file handles, create hardlinks to test files (nlink=2), drop caches and try to open by handle (expects success): $ open_by_handle -l [N] 4. Get file handles, unlink test files w/o the hardlinks (nlink=1), drop caches and try to open by handle (expects success): $ open_by_handle -u [N] 5. Get file handles, unlink test files and hardlinks (nlink=0), drop caches and try to open by handle (expects failure): $ open_by_handle -d [N] Signed-off-by: Amir Goldstein --- src/open_by_handle.c | 93 ++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 80 insertions(+), 13 deletions(-) diff --git a/src/open_by_handle.c b/src/open_by_handle.c index 8f04865..c33a4aa 100644 --- a/src/open_by_handle.c +++ b/src/open_by_handle.c @@ -37,12 +37,12 @@ #include #include -#define NUMFILES 1024 +#define MAXFILES 1024 struct handle { struct file_handle fh; unsigned char fid[MAX_HANDLE_SZ]; -} handle[NUMFILES]; +} handle[MAXFILES]; int main(int argc, char **argv) { @@ -51,18 +51,60 @@ int main(int argc, char **argv) int ret; int failed = 0; char fname[PATH_MAX]; + char fname2[PATH_MAX]; char *test_dir; int mount_fd, mount_id; + int argi = 1, numfiles = 1; + int create = 0, delete = 0, nlink = 1; - if (argc != 2) { - fprintf(stderr, "usage: open_by_handle \n"); + if (argc < 2 || argc > 4) { +usage: + fprintf(stderr, "usage: open_by_handle [-c|-l|-u|-d] [num_files]\n"); + fprintf(stderr, "\n"); + fprintf(stderr, "open_by_handle -c [N] - create N test files under test_dir, get file handles and exit\n"); + fprintf(stderr, "open_by_handle [N] - get file handles, drop caches and try to open by handle (expects success)\n"); + fprintf(stderr, "open_by_handle -l [N] - get file handles, create hardlinks to test files (nlink=2), drop caches and try to open by handle (expects success)\n"); + fprintf(stderr, "open_by_handle -u [N] - get file handles, unlink test files w/o hardlinks (nlink=1), drop caches and try to open by handle (expects success)\n"); + fprintf(stderr, "open_by_handle -d [N] - get file handles, unlink test files and hardlinks (nlink=0), drop caches and try to open by handle (expects failure)\n"); return EXIT_FAILURE; } - test_dir = argv[1]; + if (argv[1][0] == '-') { + if (argv[1][2]) + goto usage; + switch (argv[1][1]) { + case 'c': + create = 1; + break; + case 'l': + nlink = 2; + break; + case 'u': + delete = 1; + nlink = 1; + break; + case 'd': + delete = 1; + nlink = 0; + break; + default: + fprintf(stderr, "illegal option '%s'\n", argv[1]); + case 'h': + goto usage; + } + argi++; + } + test_dir = argv[argi++]; + if (argc > argi) + numfiles = atoi(argv[argi]); + if (!numfiles || numfiles > MAXFILES) { + fprintf(stderr, "illegal value '%s' for num_files\n", argv[argi]); + goto usage; + } + mount_fd = open(test_dir, O_RDONLY|O_DIRECTORY); if (mount_fd < 0) { - perror("open test_dir"); + perror(test_dir); return EXIT_FAILURE; } @@ -70,8 +112,9 @@ int main(int argc, char **argv) * create a large number of files to force allocation of new inode * chunks on disk. */ - for (i=0; i < NUMFILES; i++) { + for (i=0; create && i < numfiles; i++) { sprintf(fname, "%s/file%06d", test_dir, i); + sprintf(fname2, "%s/link%06d", test_dir, i); fd = open(fname, O_RDWR | O_CREAT | O_TRUNC, 0644); if (fd < 0) { printf("Warning (%s,%d), open(%s) failed.\n", __FILE__, __LINE__, fname); @@ -79,13 +122,14 @@ int main(int argc, char **argv) return EXIT_FAILURE; } close(fd); + ret = unlink(fname2); } /* sync to get the new inodes to hit the disk */ sync(); /* create the handles */ - for (i=0; i < NUMFILES; i++) { + for (i=0; i < numfiles; i++) { sprintf(fname, "%s/file%06d", test_dir, i); handle[i].fh.handle_bytes = MAX_HANDLE_SZ; ret = name_to_handle_at(AT_FDCWD, fname, &handle[i].fh, &mount_id, 0); @@ -95,14 +139,32 @@ int main(int argc, char **argv) } } + /* after creating test set only check that fs supports exportfs */ + if (create) + return EXIT_SUCCESS; + + /* hardlink the files */ + for (i=0; nlink > 1 && i < numfiles; i++) { + sprintf(fname, "%s/file%06d", test_dir, i); + sprintf(fname2, "%s/link%06d", test_dir, i); + ret = link(fname, fname2); + if (ret < 0) { + perror("link"); + return EXIT_FAILURE; + } + } + /* unlink the files */ - for (i=0; i < NUMFILES; i++) { + for (i=0; delete && i < numfiles; i++) { sprintf(fname, "%s/file%06d", test_dir, i); + sprintf(fname2, "%s/link%06d", test_dir, i); ret = unlink(fname); if (ret < 0) { perror("unlink"); return EXIT_FAILURE; } + if (!nlink) + ret = unlink(fname2); } /* sync to get log forced for unlink transactions to hit the disk */ @@ -126,17 +188,22 @@ int main(int argc, char **argv) * now try to open the files by the stored handles. Expecting ENOENT * for all of them. */ - for (i=0; i < NUMFILES; i++) { + for (i=0; i < numfiles; i++) { errno = 0; fd = open_by_handle_at(mount_fd, &handle[i].fh, O_RDWR); - if (fd < 0 && (errno == ENOENT || errno == ESTALE)) { + if (nlink && fd >= 0) { + close(fd); + continue; + } else if (!nlink && fd < 0 && (errno == ENOENT || errno == ESTALE)) { continue; } if (fd >= 0) { printf("open_by_handle(%d) opened an unlinked file!\n", i); close(fd); - } else - printf("open_by_handle(%d) returned %d incorrectly on an unlinked file!\n", i, errno); + } else { + printf("open_by_handle(%d) returned %d incorrectly on %s file!\n", i, errno, + nlink ? "a linked" : "an unlinked"); + } failed++; } if (failed)