public inbox for linux-xfs@vger.kernel.org
 help / color / mirror / Atom feed
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
> 


  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