| // SPDX-License-Identifier: GPL-2.0 | 
 | /* | 
 |  * Copyright (c) 2000,2005 Silicon Graphics, Inc. | 
 |  * All Rights Reserved. | 
 |  */ | 
 | #include "xfs.h" | 
 | #include "xfs_fs.h" | 
 | #include "xfs_shared.h" | 
 | #include "xfs_format.h" | 
 | #include "xfs_da_format.h" | 
 | #include "xfs_log_format.h" | 
 | #include "xfs_trans_resv.h" | 
 | #include "xfs_mount.h" | 
 | #include "xfs_da_btree.h" | 
 | #include "xfs_bmap_btree.h" | 
 | #include "xfs_trans_space.h" | 
 |  | 
 | /* Calculate the disk space required to add a parent pointer. */ | 
 | unsigned int | 
 | xfs_parent_calc_space_res( | 
 | 	struct xfs_mount	*mp, | 
 | 	unsigned int		namelen) | 
 | { | 
 | 	/* | 
 | 	 * Parent pointers are always the first attr in an attr tree, and never | 
 | 	 * larger than a block | 
 | 	 */ | 
 | 	return XFS_DAENTER_SPACE_RES(mp, XFS_ATTR_FORK) + | 
 | 	       XFS_NEXTENTADD_SPACE_RES(mp, namelen, XFS_ATTR_FORK); | 
 | } | 
 |  | 
 | unsigned int | 
 | xfs_create_space_res( | 
 | 	struct xfs_mount	*mp, | 
 | 	unsigned int		namelen) | 
 | { | 
 | 	unsigned int		ret; | 
 |  | 
 | 	ret = XFS_IALLOC_SPACE_RES(mp) + XFS_DIRENTER_SPACE_RES(mp, namelen); | 
 | 	if (xfs_has_parent(mp)) | 
 | 		ret += xfs_parent_calc_space_res(mp, namelen); | 
 |  | 
 | 	return ret; | 
 | } | 
 |  | 
 | unsigned int | 
 | xfs_mkdir_space_res( | 
 | 	struct xfs_mount	*mp, | 
 | 	unsigned int		namelen) | 
 | { | 
 | 	return xfs_create_space_res(mp, namelen); | 
 | } | 
 |  | 
 | unsigned int | 
 | xfs_link_space_res( | 
 | 	struct xfs_mount	*mp, | 
 | 	unsigned int		namelen) | 
 | { | 
 | 	unsigned int		ret; | 
 |  | 
 | 	ret = XFS_DIRENTER_SPACE_RES(mp, namelen); | 
 | 	if (xfs_has_parent(mp)) | 
 | 		ret += xfs_parent_calc_space_res(mp, namelen); | 
 |  | 
 | 	return ret; | 
 | } | 
 |  | 
 | unsigned int | 
 | xfs_symlink_space_res( | 
 | 	struct xfs_mount	*mp, | 
 | 	unsigned int		namelen, | 
 | 	unsigned int		fsblocks) | 
 | { | 
 | 	unsigned int		ret; | 
 |  | 
 | 	ret = XFS_IALLOC_SPACE_RES(mp) + XFS_DIRENTER_SPACE_RES(mp, namelen) + | 
 | 			fsblocks; | 
 |  | 
 | 	if (xfs_has_parent(mp)) | 
 | 		ret += xfs_parent_calc_space_res(mp, namelen); | 
 |  | 
 | 	return ret; | 
 | } | 
 |  | 
 | unsigned int | 
 | xfs_remove_space_res( | 
 | 	struct xfs_mount	*mp, | 
 | 	unsigned int		namelen) | 
 | { | 
 | 	unsigned int		ret = XFS_DIRREMOVE_SPACE_RES(mp); | 
 |  | 
 | 	if (xfs_has_parent(mp)) | 
 | 		ret += xfs_parent_calc_space_res(mp, namelen); | 
 |  | 
 | 	return ret; | 
 | } | 
 |  | 
 | unsigned int | 
 | xfs_rename_space_res( | 
 | 	struct xfs_mount	*mp, | 
 | 	unsigned int		src_namelen, | 
 | 	bool			target_exists, | 
 | 	unsigned int		target_namelen, | 
 | 	bool			has_whiteout) | 
 | { | 
 | 	unsigned int		ret; | 
 |  | 
 | 	ret = XFS_DIRREMOVE_SPACE_RES(mp) + | 
 | 			XFS_DIRENTER_SPACE_RES(mp, target_namelen); | 
 |  | 
 | 	if (xfs_has_parent(mp)) { | 
 | 		if (has_whiteout) | 
 | 			ret += xfs_parent_calc_space_res(mp, src_namelen); | 
 | 		ret += 2 * xfs_parent_calc_space_res(mp, target_namelen); | 
 | 	} | 
 |  | 
 | 	if (target_exists) | 
 | 		ret += xfs_parent_calc_space_res(mp, target_namelen); | 
 |  | 
 | 	return ret; | 
 | } |