xref: /linux/fs/xfs/libxfs/xfs_trans_space.c (revision 5a558f369ef89c6fd8170ee1137274fcc08517ae)
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