From: Brian Foster <bfoster@redhat.com>
To: kaixuxia <xiakaixu1987@gmail.com>
Cc: fstests@vger.kernel.org, linux-xfs@vger.kernel.org,
guaneryu@gmail.com, newtongao@tencent.com,
jasperwang@tencent.com
Subject: Re: [PATCH v2 2/4] fsstress: add NOREPLACE and WHITEOUT renameat2 support
Date: Tue, 29 Oct 2019 09:39:48 -0400 [thread overview]
Message-ID: <20191029133948.GE41131@bfoster> (raw)
In-Reply-To: <f7b2754cc5648b70379357d6210a4dc194e44de0.1572057903.git.kaixuxia@tencent.com>
On Sat, Oct 26, 2019 at 07:18:36PM +0800, kaixuxia wrote:
> Support the renameat2(NOREPLACE and WHITEOUT) syscall in fsstress.
>
> The fent id correlates with filename and the filename correlates
> to type in flist, and the RWHITEOUT operation would leave a dev
> node around with whatever the name of the source file was, so in
> order to maintain filelist/filename integrity, we should restrict
> RWHITEOUT source file to device nodes.
>
> Signed-off-by: kaixuxia <kaixuxia@tencent.com>
> ---
Looks good to me:
Reviewed-by: Brian Foster <bfoster@redhat.com>
> ltp/fsstress.c | 105 ++++++++++++++++++++++++++++++++++++++++++++++++---------
> 1 file changed, 90 insertions(+), 15 deletions(-)
>
> diff --git a/ltp/fsstress.c b/ltp/fsstress.c
> index 95285f1..ecc1adc 100644
> --- a/ltp/fsstress.c
> +++ b/ltp/fsstress.c
> @@ -44,6 +44,35 @@ io_context_t io_ctx;
> #define IOV_MAX 1024
> #endif
>
> +#ifndef HAVE_RENAMEAT2
> +#if !defined(SYS_renameat2) && defined(__x86_64__)
> +#define SYS_renameat2 316
> +#endif
> +
> +#if !defined(SYS_renameat2) && defined(__i386__)
> +#define SYS_renameat2 353
> +#endif
> +
> +static int renameat2(int dfd1, const char *path1,
> + int dfd2, const char *path2,
> + unsigned int flags)
> +{
> +#ifdef SYS_renameat2
> + return syscall(SYS_renameat2, dfd1, path1, dfd2, path2, flags);
> +#else
> + errno = ENOSYS;
> + return -1;
> +#endif
> +}
> +#endif
> +
> +#ifndef RENAME_NOREPLACE
> +#define RENAME_NOREPLACE (1 << 0) /* Don't overwrite target */
> +#endif
> +#ifndef RENAME_WHITEOUT
> +#define RENAME_WHITEOUT (1 << 2) /* Whiteout source */
> +#endif
> +
> #define FILELEN_MAX (32*4096)
>
> typedef enum {
> @@ -85,6 +114,8 @@ typedef enum {
> OP_READV,
> OP_REMOVEFATTR,
> OP_RENAME,
> + OP_RNOREPLACE,
> + OP_RWHITEOUT,
> OP_RESVSP,
> OP_RMDIR,
> OP_SETATTR,
> @@ -203,6 +234,8 @@ void readlink_f(int, long);
> void readv_f(int, long);
> void removefattr_f(int, long);
> void rename_f(int, long);
> +void rnoreplace_f(int, long);
> +void rwhiteout_f(int, long);
> void resvsp_f(int, long);
> void rmdir_f(int, long);
> void setattr_f(int, long);
> @@ -262,6 +295,8 @@ opdesc_t ops[] = {
> /* remove (delete) extended attribute */
> { OP_REMOVEFATTR, "removefattr", removefattr_f, 1, 1 },
> { OP_RENAME, "rename", rename_f, 2, 1 },
> + { OP_RNOREPLACE, "rnoreplace", rnoreplace_f, 2, 1 },
> + { OP_RWHITEOUT, "rwhiteout", rwhiteout_f, 2, 1 },
> { OP_RESVSP, "resvsp", resvsp_f, 1, 1 },
> { OP_RMDIR, "rmdir", rmdir_f, 1, 1 },
> /* set attribute flag (FS_IOC_SETFLAGS ioctl) */
> @@ -354,7 +389,7 @@ int open_path(pathname_t *, int);
> DIR *opendir_path(pathname_t *);
> void process_freq(char *);
> int readlink_path(pathname_t *, char *, size_t);
> -int rename_path(pathname_t *, pathname_t *);
> +int rename_path(pathname_t *, pathname_t *, int);
> int rmdir_path(pathname_t *);
> void separate_pathname(pathname_t *, char *, pathname_t *);
> void show_ops(int, char *);
> @@ -1519,7 +1554,7 @@ readlink_path(pathname_t *name, char *lbuf, size_t lbufsiz)
> }
>
> int
> -rename_path(pathname_t *name1, pathname_t *name2)
> +rename_path(pathname_t *name1, pathname_t *name2, int mode)
> {
> char buf1[NAME_MAX + 1];
> char buf2[NAME_MAX + 1];
> @@ -1528,14 +1563,18 @@ rename_path(pathname_t *name1, pathname_t *name2)
> pathname_t newname2;
> int rval;
>
> - rval = rename(name1->path, name2->path);
> + if (mode == 0)
> + rval = rename(name1->path, name2->path);
> + else
> + rval = renameat2(AT_FDCWD, name1->path,
> + AT_FDCWD, name2->path, mode);
> if (rval >= 0 || errno != ENAMETOOLONG)
> return rval;
> separate_pathname(name1, buf1, &newname1);
> separate_pathname(name2, buf2, &newname2);
> if (strcmp(buf1, buf2) == 0) {
> if (chdir(buf1) == 0) {
> - rval = rename_path(&newname1, &newname2);
> + rval = rename_path(&newname1, &newname2, mode);
> assert(chdir("..") == 0);
> }
> } else {
> @@ -1555,7 +1594,7 @@ rename_path(pathname_t *name1, pathname_t *name2)
> append_pathname(&newname2, "../");
> append_pathname(&newname2, name2->path);
> if (chdir(buf1) == 0) {
> - rval = rename_path(&newname1, &newname2);
> + rval = rename_path(&newname1, &newname2, mode);
> assert(chdir("..") == 0);
> }
> } else {
> @@ -1563,7 +1602,7 @@ rename_path(pathname_t *name1, pathname_t *name2)
> append_pathname(&newname1, "../");
> append_pathname(&newname1, name1->path);
> if (chdir(buf2) == 0) {
> - rval = rename_path(&newname1, &newname2);
> + rval = rename_path(&newname1, &newname2, mode);
> assert(chdir("..") == 0);
> }
> }
> @@ -4215,8 +4254,17 @@ out:
> free_pathname(&f);
> }
>
> +struct print_flags renameat2_flags [] = {
> + { RENAME_NOREPLACE, "NOREPLACE"},
> + { RENAME_WHITEOUT, "WHITEOUT"},
> + { -1, NULL}
> +};
> +
> +#define translate_renameat2_flags(mode) \
> + ({translate_flags(mode, "|", renameat2_flags);})
> +
> void
> -rename_f(int opno, long r)
> +do_renameat2(int opno, long r, int mode)
> {
> fent_t *dfep;
> int e;
> @@ -4228,14 +4276,17 @@ rename_f(int opno, long r)
> int oldid;
> int parid;
> int oldparid;
> + int which;
> int v;
> int v1;
>
> /* get an existing path for the source of the rename */
> init_pathname(&f);
> - if (!get_fname(FT_ANYm, r, &f, &flp, &fep, &v1)) {
> + which = (mode == RENAME_WHITEOUT) ? FT_DEVm : FT_ANYm;
> + if (!get_fname(which, r, &f, &flp, &fep, &v1)) {
> if (v1)
> - printf("%d/%d: rename - no filename\n", procid, opno);
> + printf("%d/%d: rename - no source filename\n",
> + procid, opno);
> free_pathname(&f);
> return;
> }
> @@ -4261,7 +4312,7 @@ rename_f(int opno, long r)
> free_pathname(&f);
> return;
> }
> - e = rename_path(&f, &newf) < 0 ? errno : 0;
> + e = rename_path(&f, &newf, mode) < 0 ? errno : 0;
> check_cwd();
> if (e == 0) {
> int xattr_counter = fep->xattr_counter;
> @@ -4272,16 +4323,22 @@ rename_f(int opno, long r)
> if (flp - flist == FT_DIR)
> fix_parent(oldid, id);
>
> - del_from_flist(flp - flist, fep - flp->fents);
> - add_to_flist(flp - flist, id, parid, xattr_counter);
> + if (mode == RENAME_WHITEOUT) {
> + fep->xattr_counter = 0;
> + add_to_flist(flp - flist, id, parid, xattr_counter);
> + } else {
> + del_from_flist(flp - flist, fep - flp->fents);
> + add_to_flist(flp - flist, id, parid, xattr_counter);
> + }
> }
> if (v) {
> - printf("%d/%d: rename %s to %s %d\n", procid, opno, f.path,
> + printf("%d/%d: rename(%s) %s to %s %d\n", procid,
> + opno, translate_renameat2_flags(mode), f.path,
> newf.path, e);
> if (e == 0) {
> - printf("%d/%d: rename del entry: id=%d,parent=%d\n",
> + printf("%d/%d: rename source entry: id=%d,parent=%d\n",
> procid, opno, oldid, oldparid);
> - printf("%d/%d: rename add entry: id=%d,parent=%d\n",
> + printf("%d/%d: rename target entry: id=%d,parent=%d\n",
> procid, opno, id, parid);
> }
> }
> @@ -4290,6 +4347,24 @@ rename_f(int opno, long r)
> }
>
> void
> +rename_f(int opno, long r)
> +{
> + do_renameat2(opno, r, 0);
> +}
> +
> +void
> +rnoreplace_f(int opno, long r)
> +{
> + do_renameat2(opno, r, RENAME_NOREPLACE);
> +}
> +
> +void
> +rwhiteout_f(int opno, long r)
> +{
> + do_renameat2(opno, r, RENAME_WHITEOUT);
> +}
> +
> +void
> resvsp_f(int opno, long r)
> {
> int e;
> --
> 1.8.3.1
>
next prev parent reply other threads:[~2019-10-29 13:39 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-10-26 11:18 [PATCH v2 0/4] xfstests: add deadlock between the AGI and AGF with RENAME_WHITEOUT test kaixuxia
2019-10-26 11:18 ` [PATCH v2 1/4] fsstress: show the real file id and parid in rename_f() kaixuxia
2019-10-26 11:18 ` [PATCH v2 2/4] fsstress: add NOREPLACE and WHITEOUT renameat2 support kaixuxia
2019-10-29 13:39 ` Brian Foster [this message]
2019-10-26 11:18 ` [PATCH v2 3/4] fsstress: add EXCHANGE " kaixuxia
2019-10-29 13:40 ` Brian Foster
2019-10-30 3:17 ` kaixuxia
2019-10-30 12:40 ` Brian Foster
2019-10-31 1:51 ` kaixuxia
2019-10-26 11:18 ` [PATCH v2 4/4] xfs: test the deadlock between the AGI and AGF with RENAME_WHITEOUT kaixuxia
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20191029133948.GE41131@bfoster \
--to=bfoster@redhat.com \
--cc=fstests@vger.kernel.org \
--cc=guaneryu@gmail.com \
--cc=jasperwang@tencent.com \
--cc=linux-xfs@vger.kernel.org \
--cc=newtongao@tencent.com \
--cc=xiakaixu1987@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox