[Cluster-devel] [GFS2 PATCH] GFS2: Make rename not save dirent location

Steven Whitehouse swhiteho at redhat.com
Wed Oct 1 13:11:20 UTC 2014


Hi,

On 29/09/14 13:52, Bob Peterson wrote:
> Hi,
>
> This patch fixes a regression in the patch "GFS2: Remember directory
> insert point", commit 2b47dad866d04f14c328f888ba5406057b8c7d33.
> The problem had to do with the rename function: The function found
> space for the new dirent, and remembered that location. But then the
> old dirent was removed, which often moved the eligible location for
> the renamed dirent. Putting the new dirent at the saved location
> caused file system corruption.
>
> This patch adds a new "save_loc" variable to struct gfs2_diradd.
> If 1, the dirent location is saved. If 0, the dirent location is not
> saved and the buffer_head is released as per previous behavior.
>
> Regards,
>
> Bob Peterson
> Red Hat File Systems
Now in the -nmw git tree. Thanks,

Steve.

> Signed-off-by: Bob Peterson <rpeterso at redhat.com>
> ---
> diff --git a/fs/gfs2/dir.c b/fs/gfs2/dir.c
> index 1a349f9..5d4261f 100644
> --- a/fs/gfs2/dir.c
> +++ b/fs/gfs2/dir.c
> @@ -2100,8 +2100,13 @@ int gfs2_diradd_alloc_required(struct inode *inode, const struct qstr *name,
>   	}
>   	if (IS_ERR(dent))
>   		return PTR_ERR(dent);
> -	da->bh = bh;
> -	da->dent = dent;
> +
> +	if (da->save_loc) {
> +		da->bh = bh;
> +		da->dent = dent;
> +	} else {
> +		brelse(bh);
> +	}
>   	return 0;
>   }
>   
> diff --git a/fs/gfs2/dir.h b/fs/gfs2/dir.h
> index 126c65d..e1b309c 100644
> --- a/fs/gfs2/dir.h
> +++ b/fs/gfs2/dir.h
> @@ -23,6 +23,7 @@ struct gfs2_diradd {
>   	unsigned nr_blocks;
>   	struct gfs2_dirent *dent;
>   	struct buffer_head *bh;
> +	int save_loc;
>   };
>   
>   extern struct inode *gfs2_dir_search(struct inode *dir,
> diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c
> index 9516f5c..fcf42ea 100644
> --- a/fs/gfs2/inode.c
> +++ b/fs/gfs2/inode.c
> @@ -600,7 +600,7 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry,
>   	int error, free_vfs_inode = 0;
>   	u32 aflags = 0;
>   	unsigned blocks = 1;
> -	struct gfs2_diradd da = { .bh = NULL, };
> +	struct gfs2_diradd da = { .bh = NULL, .save_loc = 1, };
>   
>   	if (!name->len || name->len > GFS2_FNAMESIZE)
>   		return -ENAMETOOLONG;
> @@ -900,7 +900,7 @@ static int gfs2_link(struct dentry *old_dentry, struct inode *dir,
>   	struct gfs2_inode *ip = GFS2_I(inode);
>   	struct gfs2_holder ghs[2];
>   	struct buffer_head *dibh;
> -	struct gfs2_diradd da = { .bh = NULL, };
> +	struct gfs2_diradd da = { .bh = NULL, .save_loc = 1, };
>   	int error;
>   
>   	if (S_ISDIR(inode->i_mode))
> @@ -1338,7 +1338,7 @@ static int gfs2_rename(struct inode *odir, struct dentry *odentry,
>   	struct gfs2_rgrpd *nrgd;
>   	unsigned int num_gh;
>   	int dir_rename = 0;
> -	struct gfs2_diradd da = { .nr_blocks = 0, };
> +	struct gfs2_diradd da = { .nr_blocks = 0, .save_loc = 0, };
>   	unsigned int x;
>   	int error;
>   




More information about the Cluster-devel mailing list