1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Copyright (c) 2000,2005 Silicon Graphics, Inc. 4 * All Rights Reserved. 5 */ 6 #include "xfs.h" 7 #include "xfs_fs.h" 8 #include "xfs_shared.h" 9 #include "xfs_format.h" 10 #include "xfs_da_format.h" 11 #include "xfs_log_format.h" 12 #include "xfs_trans_resv.h" 13 #include "xfs_mount.h" 14 #include "xfs_da_btree.h" 15 #include "xfs_bmap_btree.h" 16 #include "xfs_trans_space.h" 17 18 /* Calculate the disk space required to add a parent pointer. */ 19 unsigned int 20 xfs_parent_calc_space_res( 21 struct xfs_mount *mp, 22 unsigned int namelen) 23 { 24 /* 25 * Parent pointers are always the first attr in an attr tree, and never 26 * larger than a block 27 */ 28 return XFS_DAENTER_SPACE_RES(mp, XFS_ATTR_FORK) + 29 XFS_NEXTENTADD_SPACE_RES(mp, namelen, XFS_ATTR_FORK); 30 } 31 32 unsigned int 33 xfs_create_space_res( 34 struct xfs_mount *mp, 35 unsigned int namelen) 36 { 37 unsigned int ret; 38 39 ret = XFS_IALLOC_SPACE_RES(mp) + XFS_DIRENTER_SPACE_RES(mp, namelen); 40 if (xfs_has_parent(mp)) 41 ret += xfs_parent_calc_space_res(mp, namelen); 42 43 return ret; 44 } 45 46 unsigned int 47 xfs_mkdir_space_res( 48 struct xfs_mount *mp, 49 unsigned int namelen) 50 { 51 return xfs_create_space_res(mp, namelen); 52 } 53 54 unsigned int 55 xfs_link_space_res( 56 struct xfs_mount *mp, 57 unsigned int namelen) 58 { 59 unsigned int ret; 60 61 ret = XFS_DIRENTER_SPACE_RES(mp, namelen); 62 if (xfs_has_parent(mp)) 63 ret += xfs_parent_calc_space_res(mp, namelen); 64 65 return ret; 66 } 67 68 unsigned int 69 xfs_symlink_space_res( 70 struct xfs_mount *mp, 71 unsigned int namelen, 72 unsigned int fsblocks) 73 { 74 unsigned int ret; 75 76 ret = XFS_IALLOC_SPACE_RES(mp) + XFS_DIRENTER_SPACE_RES(mp, namelen) + 77 fsblocks; 78 79 if (xfs_has_parent(mp)) 80 ret += xfs_parent_calc_space_res(mp, namelen); 81 82 return ret; 83 } 84 85 unsigned int 86 xfs_remove_space_res( 87 struct xfs_mount *mp, 88 unsigned int namelen) 89 { 90 unsigned int ret = XFS_DIRREMOVE_SPACE_RES(mp); 91 92 if (xfs_has_parent(mp)) 93 ret += xfs_parent_calc_space_res(mp, namelen); 94 95 return ret; 96 } 97 98 unsigned int 99 xfs_rename_space_res( 100 struct xfs_mount *mp, 101 unsigned int src_namelen, 102 bool target_exists, 103 unsigned int target_namelen, 104 bool has_whiteout) 105 { 106 unsigned int ret; 107 108 ret = XFS_DIRREMOVE_SPACE_RES(mp) + 109 XFS_DIRENTER_SPACE_RES(mp, target_namelen); 110 111 if (xfs_has_parent(mp)) { 112 if (has_whiteout) 113 ret += xfs_parent_calc_space_res(mp, src_namelen); 114 ret += 2 * xfs_parent_calc_space_res(mp, target_namelen); 115 } 116 117 if (target_exists) 118 ret += xfs_parent_calc_space_res(mp, target_namelen); 119 120 return ret; 121 } 122