diff options
Diffstat (limited to 'fs/xfs/libxfs/xfs_dir2.c')
| -rw-r--r-- | fs/xfs/libxfs/xfs_dir2.c | 59 | 
1 files changed, 31 insertions, 28 deletions
diff --git a/fs/xfs/libxfs/xfs_dir2.c b/fs/xfs/libxfs/xfs_dir2.c index a76673281514..4821519efad4 100644 --- a/fs/xfs/libxfs/xfs_dir2.c +++ b/fs/xfs/libxfs/xfs_dir2.c @@ -18,6 +18,7 @@  #include "xfs_errortag.h"  #include "xfs_error.h"  #include "xfs_trace.h" +#include "xfs_health.h"  const struct xfs_name xfs_name_dotdot = {  	.name	= (const unsigned char *)"..", @@ -25,6 +26,12 @@ const struct xfs_name xfs_name_dotdot = {  	.type	= XFS_DIR3_FT_DIR,  }; +const struct xfs_name xfs_name_dot = { +	.name	= (const unsigned char *)".", +	.len	= 1, +	.type	= XFS_DIR3_FT_DIR, +}; +  /*   * Convert inode mode to directory entry filetype   */ @@ -104,13 +111,13 @@ xfs_da_mount(  	ASSERT(mp->m_sb.sb_versionnum & XFS_SB_VERSION_DIRV2BIT);  	ASSERT(xfs_dir2_dirblock_bytes(&mp->m_sb) <= XFS_MAX_BLOCKSIZE); -	mp->m_dir_geo = kmem_zalloc(sizeof(struct xfs_da_geometry), -				    KM_MAYFAIL); -	mp->m_attr_geo = kmem_zalloc(sizeof(struct xfs_da_geometry), -				     KM_MAYFAIL); +	mp->m_dir_geo = kzalloc(sizeof(struct xfs_da_geometry), +				GFP_KERNEL | __GFP_RETRY_MAYFAIL); +	mp->m_attr_geo = kzalloc(sizeof(struct xfs_da_geometry), +				GFP_KERNEL | __GFP_RETRY_MAYFAIL);  	if (!mp->m_dir_geo || !mp->m_attr_geo) { -		kmem_free(mp->m_dir_geo); -		kmem_free(mp->m_attr_geo); +		kfree(mp->m_dir_geo); +		kfree(mp->m_attr_geo);  		return -ENOMEM;  	} @@ -178,8 +185,8 @@ void  xfs_da_unmount(  	struct xfs_mount	*mp)  { -	kmem_free(mp->m_dir_geo); -	kmem_free(mp->m_attr_geo); +	kfree(mp->m_dir_geo); +	kfree(mp->m_attr_geo);  }  /* @@ -236,7 +243,7 @@ xfs_dir_init(  	if (error)  		return error; -	args = kmem_zalloc(sizeof(*args), KM_NOFS); +	args = kzalloc(sizeof(*args), GFP_KERNEL | __GFP_NOFAIL);  	if (!args)  		return -ENOMEM; @@ -244,7 +251,7 @@ xfs_dir_init(  	args->dp = dp;  	args->trans = tp;  	error = xfs_dir2_sf_create(args, pdp->i_ino); -	kmem_free(args); +	kfree(args);  	return error;  } @@ -273,7 +280,7 @@ xfs_dir_createname(  		XFS_STATS_INC(dp->i_mount, xs_dir_create);  	} -	args = kmem_zalloc(sizeof(*args), KM_NOFS); +	args = kzalloc(sizeof(*args), GFP_KERNEL | __GFP_NOFAIL);  	if (!args)  		return -ENOMEM; @@ -313,7 +320,7 @@ xfs_dir_createname(  		rval = xfs_dir2_node_addname(args);  out_free: -	kmem_free(args); +	kfree(args);  	return rval;  } @@ -333,7 +340,8 @@ xfs_dir_cilookup_result(  					!(args->op_flags & XFS_DA_OP_CILOOKUP))  		return -EEXIST; -	args->value = kmem_alloc(len, KM_NOFS | KM_MAYFAIL); +	args->value = kmalloc(len, +			GFP_KERNEL | __GFP_NOLOCKDEP | __GFP_RETRY_MAYFAIL);  	if (!args->value)  		return -ENOMEM; @@ -364,15 +372,8 @@ xfs_dir_lookup(  	ASSERT(S_ISDIR(VFS_I(dp)->i_mode));  	XFS_STATS_INC(dp->i_mount, xs_dir_lookup); -	/* -	 * We need to use KM_NOFS here so that lockdep will not throw false -	 * positive deadlock warnings on a non-transactional lookup path. It is -	 * safe to recurse into inode recalim in that case, but lockdep can't -	 * easily be taught about it. Hence KM_NOFS avoids having to add more -	 * lockdep Doing this avoids having to add a bunch of lockdep class -	 * annotations into the reclaim path for the ilock. -	 */ -	args = kmem_zalloc(sizeof(*args), KM_NOFS); +	args = kzalloc(sizeof(*args), +			GFP_KERNEL | __GFP_NOLOCKDEP | __GFP_NOFAIL);  	args->geo = dp->i_mount->m_dir_geo;  	args->name = name->name;  	args->namelen = name->len; @@ -419,7 +420,7 @@ out_check_rval:  	}  out_free:  	xfs_iunlock(dp, lock_mode); -	kmem_free(args); +	kfree(args);  	return rval;  } @@ -441,7 +442,7 @@ xfs_dir_removename(  	ASSERT(S_ISDIR(VFS_I(dp)->i_mode));  	XFS_STATS_INC(dp->i_mount, xs_dir_remove); -	args = kmem_zalloc(sizeof(*args), KM_NOFS); +	args = kzalloc(sizeof(*args), GFP_KERNEL | __GFP_NOFAIL);  	if (!args)  		return -ENOMEM; @@ -477,7 +478,7 @@ xfs_dir_removename(  	else  		rval = xfs_dir2_node_removename(args);  out_free: -	kmem_free(args); +	kfree(args);  	return rval;  } @@ -502,7 +503,7 @@ xfs_dir_replace(  	if (rval)  		return rval; -	args = kmem_zalloc(sizeof(*args), KM_NOFS); +	args = kzalloc(sizeof(*args), GFP_KERNEL | __GFP_NOFAIL);  	if (!args)  		return -ENOMEM; @@ -538,7 +539,7 @@ xfs_dir_replace(  	else  		rval = xfs_dir2_node_replace(args);  out_free: -	kmem_free(args); +	kfree(args);  	return rval;  } @@ -626,8 +627,10 @@ xfs_dir2_isblock(  		return 0;  	*isblock = true; -	if (XFS_IS_CORRUPT(mp, args->dp->i_disk_size != args->geo->blksize)) +	if (XFS_IS_CORRUPT(mp, args->dp->i_disk_size != args->geo->blksize)) { +		xfs_da_mark_sick(args);  		return -EFSCORRUPTED; +	}  	return 0;  }  | 
