linux-fsdevel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Jan Kara <jack@suse.cz>
To: Miklos Szeredi <miklos@szeredi.hu>
Cc: linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org,
	viro@ZenIV.linux.org.uk, torvalds@linux-foundation.org,
	hch@infradead.org, akpm@linux-foundation.org,
	dhowells@redhat.com, zab@redhat.com, jack@suse.cz, tytso@mit.edu,
	mszeredi@suse.cz
Subject: Re: [PATCH 6/7] ext4: rename: split out helper functions
Date: Wed, 2 Oct 2013 14:19:28 +0200	[thread overview]
Message-ID: <20131002121928.GC25126@quack.suse.cz> (raw)
In-Reply-To: <1380643239-16060-7-git-send-email-miklos@szeredi.hu>

On Tue 01-10-13 18:00:38, Miklos Szeredi wrote:
> From: Miklos Szeredi <mszeredi@suse.cz>
> 
> Cross rename (exchange source and dest) will need to call some of these
> helpers for both source and dest, while overwriting rename currently only
> calls them for one or the other.  This also makes the code easier to
> follow.
  The patch looks good to me. You can add:
Reviewed-by: Jan Kara <jack@suse.cz>

								Honza

> 
> Signed-off-by: Miklos Szeredi <mszeredi@suse.cz>
> ---
>  fs/ext4/namei.c | 199 +++++++++++++++++++++++++++++++++++---------------------
>  1 file changed, 126 insertions(+), 73 deletions(-)
> 
> diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c
> index 1348251..fb0f1db 100644
> --- a/fs/ext4/namei.c
> +++ b/fs/ext4/namei.c
> @@ -3014,6 +3014,125 @@ struct ext4_renament {
>  	int parent_inlined;
>  };
>  
> +static int ext4_rename_dir_prepare(handle_t *handle, struct ext4_renament *ent)
> +{
> +	int retval;
> +
> +	ent->dir_bh = ext4_get_first_dir_block(handle, ent->inode,
> +					      &retval, &ent->parent_de,
> +					      &ent->parent_inlined);
> +	if (!ent->dir_bh)
> +		return retval;
> +	if (le32_to_cpu(ent->parent_de->inode) != ent->dir->i_ino)
> +		return -EIO;
> +	BUFFER_TRACE(ent->dir_bh, "get_write_access");
> +	return ext4_journal_get_write_access(handle, ent->dir_bh);
> +}
> +
> +static int ext4_rename_dir_finish(handle_t *handle, struct ext4_renament *ent,
> +				  unsigned dir_ino)
> +{
> +	int retval;
> +
> +	ent->parent_de->inode = cpu_to_le32(dir_ino);
> +	BUFFER_TRACE(ent->dir_bh, "call ext4_handle_dirty_metadata");
> +	if (!ent->parent_inlined) {
> +		if (is_dx(ent->inode)) {
> +			retval = ext4_handle_dirty_dx_node(handle,
> +							   ent->inode,
> +							   ent->dir_bh);
> +		} else {
> +			retval = ext4_handle_dirty_dirent_node(handle,
> +							       ent->inode,
> +							       ent->dir_bh);
> +		}
> +	} else {
> +		retval = ext4_mark_inode_dirty(handle, ent->inode);
> +	}
> +	if (retval) {
> +		ext4_std_error(ent->dir->i_sb, retval);
> +		return retval;
> +	}
> +	return 0;
> +}
> +
> +static int ext4_setent(handle_t *handle, struct ext4_renament *ent,
> +		       unsigned ino, unsigned file_type)
> +{
> +	int retval;
> +
> +	BUFFER_TRACE(ent->bh, "get write access");
> +	retval = ext4_journal_get_write_access(handle, ent->bh);
> +	if (retval)
> +		return retval;
> +	ent->de->inode = cpu_to_le32(ino);
> +	if (EXT4_HAS_INCOMPAT_FEATURE(ent->dir->i_sb,
> +				      EXT4_FEATURE_INCOMPAT_FILETYPE))
> +		ent->de->file_type = file_type;
> +	ent->dir->i_version++;
> +	ent->dir->i_ctime = ent->dir->i_mtime =
> +		ext4_current_time(ent->dir);
> +	ext4_mark_inode_dirty(handle, ent->dir);
> +	BUFFER_TRACE(ent->bh, "call ext4_handle_dirty_metadata");
> +	if (!ent->inlined) {
> +		retval = ext4_handle_dirty_dirent_node(handle,
> +						       ent->dir, ent->bh);
> +		if (unlikely(retval)) {
> +			ext4_std_error(ent->dir->i_sb, retval);
> +			return retval;
> +		}
> +	}
> +	brelse(ent->bh);
> +	ent->bh = NULL;
> +
> +	return 0;
> +}
> +
> +static int ext4_find_delete_entry(handle_t *handle, struct inode *dir,
> +				  const struct qstr *d_name)
> +{
> +	int retval = -ENOENT;
> +	struct buffer_head *bh;
> +	struct ext4_dir_entry_2 *de;
> +
> +	bh = ext4_find_entry(dir, d_name, &de, NULL);
> +	if (bh) {
> +		retval = ext4_delete_entry(handle, dir, de, bh);
> +		brelse(bh);
> +	}
> +	return retval;
> +}
> +
> +static void ext4_rename_delete(handle_t *handle, struct ext4_renament *ent)
> +{
> +	int retval;
> +	/*
> +	 * ent->de could have moved from under us during htree split, so make
> +	 * sure that we are deleting the right entry.  We might also be pointing
> +	 * to a stale entry in the unused part of ent->bh so just checking inum
> +	 * and the name isn't enough.
> +	 */
> +	if (le32_to_cpu(ent->de->inode) != ent->inode->i_ino ||
> +	    ent->de->name_len != ent->dentry->d_name.len ||
> +	    strncmp(ent->de->name, ent->dentry->d_name.name,
> +		    ent->de->name_len)) {
> +		retval = ext4_find_delete_entry(handle, ent->dir,
> +						&ent->dentry->d_name);
> +	} else {
> +		retval = ext4_delete_entry(handle, ent->dir, ent->de, ent->bh);
> +		if (retval == -ENOENT) {
> +			retval = ext4_find_delete_entry(handle, ent->dir,
> +							&ent->dentry->d_name);
> +		}
> +	}
> +
> +	if (retval) {
> +		ext4_warning(ent->dir->i_sb,
> +				"Deleting old file (%lu), %d, error=%d",
> +				ent->dir->i_ino, ent->dir->i_nlink, retval);
> +	}
> +}
> +
>  /*
>   * Anybody can rename anything with this: the permission checks are left to the
>   * higher-level routines.
> @@ -3087,16 +3206,7 @@ static int ext4_rename(struct inode *old_dir, struct dentry *old_dentry,
>  			if (new.dir != old.dir && EXT4_DIR_LINK_MAX(new.dir))
>  				goto end_rename;
>  		}
> -		retval = -EIO;
> -		old.dir_bh = ext4_get_first_dir_block(handle, old.inode,
> -						  &retval, &old.parent_de,
> -						  &old.parent_inlined);
> -		if (!old.dir_bh)
> -			goto end_rename;
> -		if (le32_to_cpu(old.parent_de->inode) != old.dir->i_ino)
> -			goto end_rename;
> -		BUFFER_TRACE(old.dir_bh, "get_write_access");
> -		retval = ext4_journal_get_write_access(handle, old.dir_bh);
> +		retval = ext4_rename_dir_prepare(handle, &old);
>  		if (retval)
>  			goto end_rename;
>  	}
> @@ -3105,29 +3215,10 @@ static int ext4_rename(struct inode *old_dir, struct dentry *old_dentry,
>  		if (retval)
>  			goto end_rename;
>  	} else {
> -		BUFFER_TRACE(new.bh, "get write access");
> -		retval = ext4_journal_get_write_access(handle, new.bh);
> +		retval = ext4_setent(handle, &new,
> +				     old.inode->i_ino, old.de->file_type);
>  		if (retval)
>  			goto end_rename;
> -		new.de->inode = cpu_to_le32(old.inode->i_ino);
> -		if (EXT4_HAS_INCOMPAT_FEATURE(new.dir->i_sb,
> -					      EXT4_FEATURE_INCOMPAT_FILETYPE))
> -			new.de->file_type = old.de->file_type;
> -		new.dir->i_version++;
> -		new.dir->i_ctime = new.dir->i_mtime =
> -					ext4_current_time(new.dir);
> -		ext4_mark_inode_dirty(handle, new.dir);
> -		BUFFER_TRACE(new.bh, "call ext4_handle_dirty_metadata");
> -		if (!new.inlined) {
> -			retval = ext4_handle_dirty_dirent_node(handle,
> -							       new.dir, new.bh);
> -			if (unlikely(retval)) {
> -				ext4_std_error(new.dir->i_sb, retval);
> -				goto end_rename;
> -			}
> -		}
> -		brelse(new.bh);
> -		new.bh = NULL;
>  	}
>  
>  	/*
> @@ -3140,31 +3231,7 @@ static int ext4_rename(struct inode *old_dir, struct dentry *old_dentry,
>  	/*
>  	 * ok, that's it
>  	 */
> -	if (le32_to_cpu(old.de->inode) != old.inode->i_ino ||
> -	    old.de->name_len != old.dentry->d_name.len ||
> -	    strncmp(old.de->name, old.dentry->d_name.name, old.de->name_len) ||
> -	    (retval = ext4_delete_entry(handle, old.dir,
> -					old.de, old.bh)) == -ENOENT) {
> -		/* old.de could have moved from under us during htree split, so
> -		 * make sure that we are deleting the right entry.  We might
> -		 * also be pointing to a stale entry in the unused part of
> -		 * old.bh so just checking inum and the name isn't enough. */
> -		struct buffer_head *old_bh2;
> -		struct ext4_dir_entry_2 *old_de2;
> -
> -		old_bh2 = ext4_find_entry(old.dir, &old.dentry->d_name,
> -					  &old_de2, NULL);
> -		if (old_bh2) {
> -			retval = ext4_delete_entry(handle, old.dir,
> -						   old_de2, old_bh2);
> -			brelse(old_bh2);
> -		}
> -	}
> -	if (retval) {
> -		ext4_warning(old.dir->i_sb,
> -				"Deleting old file (%lu), %d, error=%d",
> -				old.dir->i_ino, old.dir->i_nlink, retval);
> -	}
> +	ext4_rename_delete(handle, &old);
>  
>  	if (new.inode) {
>  		ext4_dec_count(handle, new.inode);
> @@ -3173,24 +3240,10 @@ static int ext4_rename(struct inode *old_dir, struct dentry *old_dentry,
>  	old.dir->i_ctime = old.dir->i_mtime = ext4_current_time(old.dir);
>  	ext4_update_dx_flag(old.dir);
>  	if (old.dir_bh) {
> -		old.parent_de->inode = cpu_to_le32(new.dir->i_ino);
> -		BUFFER_TRACE(old.dir_bh, "call ext4_handle_dirty_metadata");
> -		if (!old.parent_inlined) {
> -			if (is_dx(old.inode)) {
> -				retval = ext4_handle_dirty_dx_node(handle,
> -								   old.inode,
> -								   old.dir_bh);
> -			} else {
> -				retval = ext4_handle_dirty_dirent_node(handle,
> -							old.inode, old.dir_bh);
> -			}
> -		} else {
> -			retval = ext4_mark_inode_dirty(handle, old.inode);
> -		}
> -		if (retval) {
> -			ext4_std_error(old.dir->i_sb, retval);
> +		retval = ext4_rename_dir_finish(handle, &old, new.dir->i_ino);
> +		if (retval)
>  			goto end_rename;
> -		}
> +
>  		ext4_dec_count(handle, old.dir);
>  		if (new.inode) {
>  			/* checked empty_dir above, can't have another parent,
> -- 
> 1.8.1.4
> 
-- 
Jan Kara <jack@suse.cz>
SUSE Labs, CR

  reply	other threads:[~2013-10-02 12:19 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-10-01 16:00 [RFC PATCH 0/7] cross rename Miklos Szeredi
2013-10-01 16:00 ` [PATCH 1/7] vfs: rename: move d_move() up Miklos Szeredi
2013-10-01 16:00 ` [PATCH 2/7] vfs: rename: use common code for dir and non-dir Miklos Szeredi
2013-10-01 16:00 ` [PATCH 3/7] vfs: add renameat2 syscall and cross-rename Miklos Szeredi
2013-10-02 12:26   ` Jan Kara
2013-10-02 14:59     ` Miklos Szeredi
2013-10-01 16:00 ` [PATCH 4/7] ext4: rename: create ext4_renament structure for local vars Miklos Szeredi
2013-10-02 12:01   ` Jan Kara
2013-10-01 16:00 ` [PATCH 5/7] ext4: rename: move EMLINK check up Miklos Szeredi
2013-10-02 12:05   ` Jan Kara
2013-10-01 16:00 ` [PATCH 6/7] ext4: rename: split out helper functions Miklos Szeredi
2013-10-02 12:19   ` Jan Kara [this message]
2013-10-01 16:00 ` [PATCH 7/7] ext4: add cross rename support Miklos Szeredi
2013-10-03  1:58 ` [RFC PATCH 0/7] cross rename H. Peter Anvin
2013-10-03  5:34   ` Linus Torvalds
2013-10-03  5:36     ` H. Peter Anvin
2013-10-04 23:58 ` Andy Lutomirski
2013-10-05  0:11   ` Linus Torvalds

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=20131002121928.GC25126@quack.suse.cz \
    --to=jack@suse.cz \
    --cc=akpm@linux-foundation.org \
    --cc=dhowells@redhat.com \
    --cc=hch@infradead.org \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=miklos@szeredi.hu \
    --cc=mszeredi@suse.cz \
    --cc=torvalds@linux-foundation.org \
    --cc=tytso@mit.edu \
    --cc=viro@ZenIV.linux.org.uk \
    --cc=zab@redhat.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;
as well as URLs for NNTP newsgroup(s).