All of lore.kernel.org
 help / color / mirror / Atom feed
From: Dave Chinner <david@fromorbit.com>
To: Carlos Maiolino <cmaiolino@redhat.com>
Cc: xfs@oss.sgi.com
Subject: Re: [PATCH 2/2] Add support to RENAME_EXCHANGE flag V8
Date: Fri, 28 Nov 2014 12:38:30 +1100	[thread overview]
Message-ID: <20141128013830.GA16151@dastard> (raw)
In-Reply-To: <1416923368-28322-3-git-send-email-cmaiolino@redhat.com>

On Tue, Nov 25, 2014 at 11:49:28AM -0200, Carlos Maiolino wrote:
> Adds a new function named xfs_cross_rename(), responsible to handle requests
> from sys_renameat2() using RENAME_EXCHANGE flag.
> 
> Changelog:
> 
> 	V2: - refactor xfs_cross_rename() to not duplicate code from xfs_rename()
> 
> 	V3: - fix indentation to avoid 80 column crossing, decrease the amount of
> 	      arguments passed to xfs_cross_rename()
> 	    - Rebase patches over the latest linux code
> 
> 	v4: - use a label/goto statement instead of an if conditional after
> 	      xfs_cross_rename() return, to finish the rename operation
> 	    - Make xfs_cross_rename() static
> 	    - Fix some comments
> 
> 	V5: - Keep all the code under 80 columns
> 
> 	V6: - Ensure i_mode of both files are updated during exchange
> 
> 	V7: - Use struct names instead of typedefs in the xfs_cross_rename()
> 	      definition
> 
> 	V8: - Replace src/target names for better variable names
> 	    - Log and timestamp updates done in different places
> 	    - Fix missing space in comments
> 	    - get rid of {src,tgt}_is_directory and new_parent variables

FYI, Changelog should be in the cover patch 0, not in the commit
message for the individual patch.

> Signed-off-by: Carlos Maiolino <cmaiolino@redhat.com>
> ---
>  fs/xfs/xfs_inode.c | 112 ++++++++++++++++++++++++++++++++++++++++++++++++++++-
>  fs/xfs/xfs_inode.h |   2 +-
>  fs/xfs/xfs_iops.c  |  15 +++++--
>  3 files changed, 123 insertions(+), 6 deletions(-)
> 
> diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c
> index 8ed049d..5c5ed99 100644
> --- a/fs/xfs/xfs_inode.c
> +++ b/fs/xfs/xfs_inode.c
> @@ -2668,6 +2668,102 @@ xfs_sort_for_rename(
>  	}
>  }
>  
> +/* xfs_cross_rename()
> + *
> + * responsible to handle RENAME_EXCHANGE flag
> + * in renameat2() sytemcall

Comments can use all 80 columns. And the first line of the comment
is "/*" by itself.

> + */
> +STATIC int
> +xfs_cross_rename(
> +	struct xfs_trans	*tp,
> +	struct xfs_inode	*dp1,
> +	struct xfs_name		*name1,
> +	struct xfs_inode	*ip1,
> +	struct xfs_inode	*dp2,
> +	struct xfs_name		*name2,
> +	struct xfs_inode	*ip2,
> +	struct xfs_bmap_free	*free_list,
> +	xfs_fsblock_t		*first_block,
> +	int			spaceres)
> +{
> +	int		error = 0;
> +
> +	/* Replace source inode */

still got source/target in comments that don't make sense. "Swap
inode number for dirent in first parent" might be better...

> +	error = xfs_dir_replace(tp, dp1, name1,
> +				ip2->i_ino,
> +				first_block, free_list, spaceres);
> +	if (error)
> +		goto out;
> +
> +	/* Replace target inode */

	/* Swap inode number for dirent in second parent */

> +	error = xfs_dir_replace(tp, dp2, name2,
> +				ip1->i_ino,
> +				first_block, free_list, spaceres);
> +	if (error)
> +		goto out;
> +	/*
> +	 * If we're renaming one or more directories across different parents,
> +	 * update the respective ".." entries (and link counts) to match the new
> +	 * parents.
> +	 */
> +	if (dp1 != dp2) {
> +
> +		if (S_ISDIR(ip2->i_d.di_mode)) {
> +			error = xfs_dir_replace(tp, ip2, &xfs_name_dotdot,
> +						dp1->i_ino, first_block,
> +						free_list, spaceres);
> +			if (error)
> +				goto out;

now ip2 is modified, so it ctime/mtime dirty.

> +
> +			/* transfer target ".." reference to dp1 */
> +			if (!S_ISDIR(ip1->i_d.di_mode)) {
> +				error = xfs_droplink(tp, dp2);
> +				if (error)
> +					goto out;
> +				error = xfs_bumplink(tp, dp1);
> +				if (error)
> +					goto out;
> +			}
> +			xfs_trans_ichgtime(tp, ip1, XFS_ICHGTIME_CHG);
> +			xfs_trans_ichgtime(tp, ip2,
> +					   XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG);
> +			xfs_trans_log_inode(tp, ip2, XFS_ILOG_CORE);

But now you're unconditionally changing ctime on ip1 without it
having been modified and you aren't logging the change. Why is the
ctime changing (comments, please!)?


> +		}
> +
> +		if (S_ISDIR(ip1->i_d.di_mode)) {
> +			error = xfs_dir_replace(tp, ip1, &xfs_name_dotdot,
> +						dp2->i_ino, first_block,
> +						free_list, spaceres);
> +			if (error)
> +				goto out;

here ip2 is modified

> +
> +			/* transfer src ".." reference to dp2 */
> +			if (!S_ISDIR(ip2->i_d.di_mode)) {
> +				error = xfs_droplink(tp, dp1);
> +				if (error)
> +					goto out;
> +				error = xfs_bumplink(tp, dp2);
> +				if (error)
> +					goto out;
> +			}
> +			xfs_trans_ichgtime(tp, ip1,
> +					   XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG);
> +			xfs_trans_ichgtime(tp, ip2, XFS_ICHGTIME_CHG);
> +			xfs_trans_log_inode(tp, ip1, XFS_ILOG_CORE);

and same again - changing ctime on ip2 without logging it.

> +		}
> +		xfs_trans_ichgtime(tp, dp2,
> +				   XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG);
> +		xfs_trans_log_inode(tp, dp2, XFS_ILOG_CORE);
> +	}
> +	xfs_trans_ichgtime(tp, dp1, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG);
> +	xfs_trans_log_inode(tp, dp1, XFS_ILOG_CORE);

perhaps:

	int	ip1_flags = 0;
	int	ip2_flags = 0;
	int	dp2_flags = 0;

	if (dp1 != dp2)
		dp2_flags = XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG;

		if (S_ISDIR(ip1)) {
			ip1_flags |= XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG;
			ip2_flags |= XFS_ICHGTIME_CHG; /* because ... */
			.....
		}

		if (S_ISDIR(ip2)) {
			ip1_flags |= XFS_ICHGTIME_CHG; /* because ... */
			ip2_flags |= XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG;
			.....
		}
	}

	if (ip1_flags) {
		xfs_trans_ichgtime(tp, ip1, ip1_flags);
		xfs_trans_log_inode(tp, ip1);
	}
	if (ip2_flags) {
		xfs_trans_ichgtime(tp, ip2, ip2_flags);
		xfs_trans_log_inode(tp, ip2);
	}
	if (dp2_flags) {
		xfs_trans_ichgtime(tp, dp2, ip2_flags);
		xfs_trans_log_inode(tp, dp2);
	}
	xfs_trans_ichgtime(tp, dp2, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG);
	xfs_trans_log_inode(tp, dp2);
> +
> +out:
> +	return error;
> +}
> +
>  /*
>   * xfs_rename
>   */
> @@ -2678,7 +2774,8 @@ xfs_rename(
>  	xfs_inode_t	*src_ip,
>  	xfs_inode_t	*target_dp,
>  	struct xfs_name	*target_name,
> -	xfs_inode_t	*target_ip)
> +	xfs_inode_t	*target_ip,
> +	unsigned int	flags)
>  {
>  	xfs_trans_t	*tp = NULL;
>  	xfs_mount_t	*mp = src_dp->i_mount;
> @@ -2706,6 +2803,7 @@ xfs_rename(
>  	cancel_flags = XFS_TRANS_RELEASE_LOG_RES;
>  	spaceres = XFS_RENAME_SPACE_RES(mp, target_name->len);
>  	error = xfs_trans_reserve(tp, &M_RES(mp)->tr_rename, spaceres, 0);
> +
>  	if (error == -ENOSPC) {

Stray new line.

>  		spaceres = 0;
>  		error = xfs_trans_reserve(tp, &M_RES(mp)->tr_rename, 0, 0);
> @@ -2756,6 +2854,17 @@ xfs_rename(
>  	}
>  
>  	/*
> +	 * Handle RENAME_EXCHANGE flags
> +	*/

Comment whitespace still needs fixing.

> +	if (flags & RENAME_EXCHANGE) {
> +		error = xfs_cross_rename(tp, src_dp, src_name, src_ip,
> +					 target_dp, target_name, target_ip,
> +					 &free_list, &first_block, spaceres);
> +		if (error)
> +			goto abort_return;
> +		goto finish_rename;
> +	}
> +	/*
>  	 * Set up the target.
>  	 */

Put an empty line between the "}" and the start of the comment.

>  	if (target_ip == NULL) {
> @@ -2894,6 +3003,7 @@ xfs_rename(
>  	if (new_parent)
>  		xfs_trans_log_inode(tp, target_dp, XFS_ILOG_CORE);
>  
> +finish_rename:
>  	/*
>  	 * If this is a synchronous mount, make sure that the
>  	 * rename transaction goes to disk before returning to
> diff --git a/fs/xfs/xfs_inode.h b/fs/xfs/xfs_inode.h
> index 9af2882..051d9f0 100644
> --- a/fs/xfs/xfs_inode.h
> +++ b/fs/xfs/xfs_inode.h
> @@ -340,7 +340,7 @@ int		xfs_link(struct xfs_inode *tdp, struct xfs_inode *sip,
>  int		xfs_rename(struct xfs_inode *src_dp, struct xfs_name *src_name,
>  			   struct xfs_inode *src_ip, struct xfs_inode *target_dp,
>  			   struct xfs_name *target_name,
> -			   struct xfs_inode *target_ip);
> +			   struct xfs_inode *target_ip, unsigned int flags);
>  
>  void		xfs_ilock(xfs_inode_t *, uint);
>  int		xfs_ilock_nowait(xfs_inode_t *, uint);
> diff --git a/fs/xfs/xfs_iops.c b/fs/xfs/xfs_iops.c
> index 0b8704c..4e5d8ce 100644
> --- a/fs/xfs/xfs_iops.c
> +++ b/fs/xfs/xfs_iops.c
> @@ -387,19 +387,26 @@ xfs_vn_rename(
>  	unsigned int	flags)
>  {
>  	struct inode	*new_inode = ndentry->d_inode;
> +	int		omode = 0;
>  	struct xfs_name	oname;
>  	struct xfs_name	nname;
>  
> -	/* XFS does not support RENAME_EXCHANGE yet */
> -	if (flags & ~RENAME_NOREPLACE)
> +	if (flags & ~(RENAME_NOREPLACE | RENAME_EXCHANGE))
>  		return -EINVAL;
>  
> -	xfs_dentry_to_name(&oname, odentry, 0);
> +	/*
> +	 * if we are exchanging files, we should set
> +	 * i_mode of both files
> +	 */

Comments can use all 80 characters of the line. Also, s/should/need
to/.

Cheers,

Dave.
-- 
Dave Chinner
david@fromorbit.com

_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs

  parent reply	other threads:[~2014-11-28  1:38 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-11-25 13:49 [PATCH 0/2] Add support to RENAME_EXCHANGE flag to XFS V8 Carlos Maiolino
2014-11-25 13:49 ` [PATCH 1/2] Make xfs_vn_rename compliant with renameat2() syscall Carlos Maiolino
2014-11-25 13:49 ` [PATCH 2/2] Add support to RENAME_EXCHANGE flag V8 Carlos Maiolino
2014-11-25 13:51   ` Carlos Maiolino
2014-11-28  1:38   ` Dave Chinner [this message]
  -- strict thread matches above, loose matches on Subject: below --
2014-12-02 14:13 Carlos Maiolino
2014-12-02 14:15 ` Carlos Maiolino
2014-12-02 21:43 ` Dave Chinner

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=20141128013830.GA16151@dastard \
    --to=david@fromorbit.com \
    --cc=cmaiolino@redhat.com \
    --cc=xfs@oss.sgi.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.