diff options
Diffstat (limited to 'fs/xfs/xfs_iops.c')
| -rw-r--r-- | fs/xfs/xfs_iops.c | 50 | 
1 files changed, 40 insertions, 10 deletions
| diff --git a/fs/xfs/xfs_iops.c b/fs/xfs/xfs_iops.c index 308bebb6dfd2..22c16155f1b4 100644 --- a/fs/xfs/xfs_iops.c +++ b/fs/xfs/xfs_iops.c @@ -98,12 +98,27 @@ xfs_init_security(  static void  xfs_dentry_to_name(  	struct xfs_name	*namep, +	struct dentry	*dentry) +{ +	namep->name = dentry->d_name.name; +	namep->len = dentry->d_name.len; +	namep->type = XFS_DIR3_FT_UNKNOWN; +} + +static int +xfs_dentry_mode_to_name( +	struct xfs_name	*namep,  	struct dentry	*dentry,  	int		mode)  {  	namep->name = dentry->d_name.name;  	namep->len = dentry->d_name.len; -	namep->type = xfs_mode_to_ftype[(mode & S_IFMT) >> S_SHIFT]; +	namep->type = xfs_mode_to_ftype(mode); + +	if (unlikely(namep->type == XFS_DIR3_FT_UNKNOWN)) +		return -EFSCORRUPTED; + +	return 0;  }  STATIC void @@ -119,7 +134,7 @@ xfs_cleanup_inode(  	 * xfs_init_security we must back out.  	 * ENOSPC can hit here, among other things.  	 */ -	xfs_dentry_to_name(&teardown, dentry, 0); +	xfs_dentry_to_name(&teardown, dentry);  	xfs_remove(XFS_I(dir), &teardown, XFS_I(inode));  } @@ -154,8 +169,12 @@ xfs_generic_create(  	if (error)  		return error; +	/* Verify mode is valid also for tmpfile case */ +	error = xfs_dentry_mode_to_name(&name, dentry, mode); +	if (unlikely(error)) +		goto out_free_acl; +  	if (!tmpfile) { -		xfs_dentry_to_name(&name, dentry, mode);  		error = xfs_create(XFS_I(dir), &name, mode, rdev, &ip);  	} else {  		error = xfs_create_tmpfile(XFS_I(dir), dentry, mode, &ip); @@ -248,7 +267,7 @@ xfs_vn_lookup(  	if (dentry->d_name.len >= MAXNAMELEN)  		return ERR_PTR(-ENAMETOOLONG); -	xfs_dentry_to_name(&name, dentry, 0); +	xfs_dentry_to_name(&name, dentry);  	error = xfs_lookup(XFS_I(dir), &name, &cip, NULL);  	if (unlikely(error)) {  		if (unlikely(error != -ENOENT)) @@ -275,7 +294,7 @@ xfs_vn_ci_lookup(  	if (dentry->d_name.len >= MAXNAMELEN)  		return ERR_PTR(-ENAMETOOLONG); -	xfs_dentry_to_name(&xname, dentry, 0); +	xfs_dentry_to_name(&xname, dentry);  	error = xfs_lookup(XFS_I(dir), &xname, &ip, &ci_name);  	if (unlikely(error)) {  		if (unlikely(error != -ENOENT)) @@ -310,7 +329,9 @@ xfs_vn_link(  	struct xfs_name	name;  	int		error; -	xfs_dentry_to_name(&name, dentry, inode->i_mode); +	error = xfs_dentry_mode_to_name(&name, dentry, inode->i_mode); +	if (unlikely(error)) +		return error;  	error = xfs_link(XFS_I(dir), XFS_I(inode), &name);  	if (unlikely(error)) @@ -329,7 +350,7 @@ xfs_vn_unlink(  	struct xfs_name	name;  	int		error; -	xfs_dentry_to_name(&name, dentry, 0); +	xfs_dentry_to_name(&name, dentry);  	error = xfs_remove(XFS_I(dir), &name, XFS_I(d_inode(dentry)));  	if (error) @@ -359,7 +380,9 @@ xfs_vn_symlink(  	mode = S_IFLNK |  		(irix_symlink_mode ? 0777 & ~current_umask() : S_IRWXUGO); -	xfs_dentry_to_name(&name, dentry, mode); +	error = xfs_dentry_mode_to_name(&name, dentry, mode); +	if (unlikely(error)) +		goto out;  	error = xfs_symlink(XFS_I(dir), &name, symname, mode, &cip);  	if (unlikely(error)) @@ -395,6 +418,7 @@ xfs_vn_rename(  {  	struct inode	*new_inode = d_inode(ndentry);  	int		omode = 0; +	int		error;  	struct xfs_name	oname;  	struct xfs_name	nname; @@ -405,8 +429,14 @@ xfs_vn_rename(  	if (flags & RENAME_EXCHANGE)  		omode = d_inode(ndentry)->i_mode; -	xfs_dentry_to_name(&oname, odentry, omode); -	xfs_dentry_to_name(&nname, ndentry, d_inode(odentry)->i_mode); +	error = xfs_dentry_mode_to_name(&oname, odentry, omode); +	if (omode && unlikely(error)) +		return error; + +	error = xfs_dentry_mode_to_name(&nname, ndentry, +					d_inode(odentry)->i_mode); +	if (unlikely(error)) +		return error;  	return xfs_rename(XFS_I(odir), &oname, XFS_I(d_inode(odentry)),  			  XFS_I(ndir), &nname, | 
