Re: [PATCH v5] fsstress: add renameat2 support

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Tue, Oct 22, 2019 at 08:19:37PM +0800, kaixuxia wrote:
> Support the renameat2 syscall in fsstress.
> 
> Signed-off-by: kaixuxia <kaixuxia@xxxxxxxxxxx>
> ---
> Changes in v5:
>  - Fix the RENAME_EXCHANGE flist fents swap problem.
> 
>  ltp/fsstress.c | 202 +++++++++++++++++++++++++++++++++++++++++++++++----------
>  1 file changed, 169 insertions(+), 33 deletions(-)
> 
> diff --git a/ltp/fsstress.c b/ltp/fsstress.c
> index 51976f5..7c59f2d 100644
> --- a/ltp/fsstress.c
> +++ b/ltp/fsstress.c
...
> @@ -4269,16 +4367,31 @@ rename_f(int opno, long r)
>  			oldid = fep->id;
>  			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) {
> +			add_to_flist(FT_DEV, fep->id, fep->parent, 0);
> +			del_from_flist(flp - flist, fep - flp->fents);
> +			add_to_flist(flp - flist, id, parid, xattr_counter);
> +		} else if (mode == RENAME_EXCHANGE) {
> +			if (dflp - flist == FT_DIR) {
> +				oldid = dfep->id;
> +				fix_parent(oldid, fep->id);
> +			}
> +			swap_flist_fents(flp - flist, fep - flp->fents,
> +					 dflp - flist, dfep - dflp->fents);

Hmm.. sorry, but this is still a little confusing. One thing I realized
when running this is that the id correlates with filename and the
filename correlates to type (i.e., fN for files, cN for devs, dN for
dirs, etc.). This means that we can now end up doing something like
this:

0/8: rename(EXCHANGE) c4 to f5 0
0/8: rename source entry: id=5,parent=-1
0/8: rename target entry: id=5,parent=-1

... which leaves an 'f5' device node and 'c4' regular file. Because of
this, I'm wondering if we should just restrict rexchange to files of the
same type and keep this simple. That means we would use the file type of
the source file when looking up a destination to exchange with (instead
of FT_ANY).

With regard to fixing up the flist, this leaves two general cases:

- Between two non-dirs: REXCHANGE f0 <-> d3/f5

The id -> parent relationship actually hasn't changed because both file
entries still exist just as before the call. We've basically just
swapped inodes from the directory tree perspective. This means
xattr_count needs to be swapped between the entries.

- Between two dirs: REXCHANGE d1 <-> d2/d3

I think the same thing applies as above with regard to the parent ids of
the directories themselves. E.g., d3 is still under d2, it just now
needs the xattr_count from the old d1 and vice versa. Additionally, all
of the children of d2/d3 are now under d1 and vice versa, so those
parent ids need to be swapped. That said, we can't just call
fix_parent() to swap all parentid == 1 to 3 and then repeat for 3 -> 1
because that would put everything under 1. Instead, it seems like we
actually need a single fix_parent() sweep to change all 1 -> 3 and 3 ->
1 parent ids in a single pass.

Moving on to RWHITEOUT, the above means that we leave a dev node around
with whatever the name of the source file was. That implies we should
restrict RWHITEOUT to device nodes if we want to maintain
filelist/filename integrity. The immediate question is: would that allow
the associated fstest to still reproduce the deadlock problem? I think
it should, but we should confirm that (i.e., the test now needs to do
'-fmknod=NN' instead of '-fcreat=NN').

Thoughts? Does that all sound reasonable/correct or have I
misinterpreted things?

Finally, given the complexity disparity between the two operations, at
this point I'd suggest to split this into two patches (one for general
renameat2 support + rwhiteout, another for rexchange support on top).

Brian

> +		} 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, fep->id, fep->parent);
> -			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);
>  		}
>  	}
> @@ -4287,6 +4400,29 @@ 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
> +rexchange_f(int opno, long r)
> +{
> +	do_renameat2(opno, r, RENAME_EXCHANGE);
> +}
> +
> +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
> 
> -- 
> kaixuxia





[Index of Archives]     [XFS Filesystem Development (older mail)]     [Linux Filesystem Development]     [Linux Audio Users]     [Yosemite Trails]     [Linux Kernel]     [Linux RAID]     [Linux SCSI]


  Powered by Linux