aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@infradead.org>2010-05-04 09:53:48 -0400
committerAlex Elder <aelder@sgi.com>2010-05-28 15:58:30 -0400
commit025101dca4480eff9da948405e872d5115030850 (patch)
treea35460cf1a1cce94bb19249328761551c8f1b6b1
parent32891b292d6262d1db8e553cf3f4b38a91247b5a (diff)
xfs: cleanup log reservation calculactions
Instead of having small helper functions calling big macros do the calculations for the log reservations directly in the functions. These are mostly 1:1 from the macros execept that the macros kept the quota calculations in their callers. Signed-off-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Alex Elder <aelder@sgi.com>
-rw-r--r--fs/xfs/xfs_trans.c446
-rw-r--r--fs/xfs/xfs_trans.h411
2 files changed, 400 insertions, 457 deletions
diff --git a/fs/xfs/xfs_trans.c b/fs/xfs/xfs_trans.c
index ce558efa2ea0..28547dfce037 100644
--- a/fs/xfs/xfs_trans.c
+++ b/fs/xfs/xfs_trans.c
@@ -48,134 +48,489 @@
48 48
49kmem_zone_t *xfs_trans_zone; 49kmem_zone_t *xfs_trans_zone;
50 50
51
51/* 52/*
52 * Reservation functions here avoid a huge stack in xfs_trans_init 53 * Various log reservation values.
53 * due to register overflow from temporaries in the calculations. 54 *
55 * These are based on the size of the file system block because that is what
56 * most transactions manipulate. Each adds in an additional 128 bytes per
57 * item logged to try to account for the overhead of the transaction mechanism.
58 *
59 * Note: Most of the reservations underestimate the number of allocation
60 * groups into which they could free extents in the xfs_bmap_finish() call.
61 * This is because the number in the worst case is quite high and quite
62 * unusual. In order to fix this we need to change xfs_bmap_finish() to free
63 * extents in only a single AG at a time. This will require changes to the
64 * EFI code as well, however, so that the EFI for the extents not freed is
65 * logged again in each transaction. See SGI PV #261917.
66 *
67 * Reservation functions here avoid a huge stack in xfs_trans_init due to
68 * register overflow from temporaries in the calculations.
69 */
70
71
72/*
73 * In a write transaction we can allocate a maximum of 2
74 * extents. This gives:
75 * the inode getting the new extents: inode size
76 * the inode's bmap btree: max depth * block size
77 * the agfs of the ags from which the extents are allocated: 2 * sector
78 * the superblock free block counter: sector size
79 * the allocation btrees: 2 exts * 2 trees * (2 * max depth - 1) * block size
80 * And the bmap_finish transaction can free bmap blocks in a join:
81 * the agfs of the ags containing the blocks: 2 * sector size
82 * the agfls of the ags containing the blocks: 2 * sector size
83 * the super block free block counter: sector size
84 * the allocation btrees: 2 exts * 2 trees * (2 * max depth - 1) * block size
54 */ 85 */
55STATIC uint 86STATIC uint
56xfs_calc_write_reservation(xfs_mount_t *mp) 87xfs_calc_write_reservation(
88 struct xfs_mount *mp)
57{ 89{
58 return XFS_CALC_WRITE_LOG_RES(mp) + XFS_DQUOT_LOGRES(mp); 90 return XFS_DQUOT_LOGRES(mp) +
91 MAX((mp->m_sb.sb_inodesize +
92 XFS_FSB_TO_B(mp, XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK)) +
93 2 * mp->m_sb.sb_sectsize +
94 mp->m_sb.sb_sectsize +
95 XFS_ALLOCFREE_LOG_RES(mp, 2) +
96 128 * (4 + XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK) +
97 XFS_ALLOCFREE_LOG_COUNT(mp, 2))),
98 (2 * mp->m_sb.sb_sectsize +
99 2 * mp->m_sb.sb_sectsize +
100 mp->m_sb.sb_sectsize +
101 XFS_ALLOCFREE_LOG_RES(mp, 2) +
102 128 * (5 + XFS_ALLOCFREE_LOG_COUNT(mp, 2))));
59} 103}
60 104
105/*
106 * In truncating a file we free up to two extents at once. We can modify:
107 * the inode being truncated: inode size
108 * the inode's bmap btree: (max depth + 1) * block size
109 * And the bmap_finish transaction can free the blocks and bmap blocks:
110 * the agf for each of the ags: 4 * sector size
111 * the agfl for each of the ags: 4 * sector size
112 * the super block to reflect the freed blocks: sector size
113 * worst case split in allocation btrees per extent assuming 4 extents:
114 * 4 exts * 2 trees * (2 * max depth - 1) * block size
115 * the inode btree: max depth * blocksize
116 * the allocation btrees: 2 trees * (max depth - 1) * block size
117 */
61STATIC uint 118STATIC uint
62xfs_calc_itruncate_reservation(xfs_mount_t *mp) 119xfs_calc_itruncate_reservation(
120 struct xfs_mount *mp)
63{ 121{
64 return XFS_CALC_ITRUNCATE_LOG_RES(mp) + XFS_DQUOT_LOGRES(mp); 122 return XFS_DQUOT_LOGRES(mp) +
123 MAX((mp->m_sb.sb_inodesize +
124 XFS_FSB_TO_B(mp, XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK) + 1) +
125 128 * (2 + XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK))),
126 (4 * mp->m_sb.sb_sectsize +
127 4 * mp->m_sb.sb_sectsize +
128 mp->m_sb.sb_sectsize +
129 XFS_ALLOCFREE_LOG_RES(mp, 4) +
130 128 * (9 + XFS_ALLOCFREE_LOG_COUNT(mp, 4)) +
131 128 * 5 +
132 XFS_ALLOCFREE_LOG_RES(mp, 1) +
133 128 * (2 + XFS_IALLOC_BLOCKS(mp) + mp->m_in_maxlevels +
134 XFS_ALLOCFREE_LOG_COUNT(mp, 1))));
65} 135}
66 136
137/*
138 * In renaming a files we can modify:
139 * the four inodes involved: 4 * inode size
140 * the two directory btrees: 2 * (max depth + v2) * dir block size
141 * the two directory bmap btrees: 2 * max depth * block size
142 * And the bmap_finish transaction can free dir and bmap blocks (two sets
143 * of bmap blocks) giving:
144 * the agf for the ags in which the blocks live: 3 * sector size
145 * the agfl for the ags in which the blocks live: 3 * sector size
146 * the superblock for the free block count: sector size
147 * the allocation btrees: 3 exts * 2 trees * (2 * max depth - 1) * block size
148 */
67STATIC uint 149STATIC uint
68xfs_calc_rename_reservation(xfs_mount_t *mp) 150xfs_calc_rename_reservation(
151 struct xfs_mount *mp)
69{ 152{
70 return XFS_CALC_RENAME_LOG_RES(mp) + XFS_DQUOT_LOGRES(mp); 153 return XFS_DQUOT_LOGRES(mp) +
154 MAX((4 * mp->m_sb.sb_inodesize +
155 2 * XFS_DIROP_LOG_RES(mp) +
156 128 * (4 + 2 * XFS_DIROP_LOG_COUNT(mp))),
157 (3 * mp->m_sb.sb_sectsize +
158 3 * mp->m_sb.sb_sectsize +
159 mp->m_sb.sb_sectsize +
160 XFS_ALLOCFREE_LOG_RES(mp, 3) +
161 128 * (7 + XFS_ALLOCFREE_LOG_COUNT(mp, 3))));
71} 162}
72 163
164/*
165 * For creating a link to an inode:
166 * the parent directory inode: inode size
167 * the linked inode: inode size
168 * the directory btree could split: (max depth + v2) * dir block size
169 * the directory bmap btree could join or split: (max depth + v2) * blocksize
170 * And the bmap_finish transaction can free some bmap blocks giving:
171 * the agf for the ag in which the blocks live: sector size
172 * the agfl for the ag in which the blocks live: sector size
173 * the superblock for the free block count: sector size
174 * the allocation btrees: 2 trees * (2 * max depth - 1) * block size
175 */
73STATIC uint 176STATIC uint
74xfs_calc_link_reservation(xfs_mount_t *mp) 177xfs_calc_link_reservation(
178 struct xfs_mount *mp)
75{ 179{
76 return XFS_CALC_LINK_LOG_RES(mp) + XFS_DQUOT_LOGRES(mp); 180 return XFS_DQUOT_LOGRES(mp) +
181 MAX((mp->m_sb.sb_inodesize +
182 mp->m_sb.sb_inodesize +
183 XFS_DIROP_LOG_RES(mp) +
184 128 * (2 + XFS_DIROP_LOG_COUNT(mp))),
185 (mp->m_sb.sb_sectsize +
186 mp->m_sb.sb_sectsize +
187 mp->m_sb.sb_sectsize +
188 XFS_ALLOCFREE_LOG_RES(mp, 1) +
189 128 * (3 + XFS_ALLOCFREE_LOG_COUNT(mp, 1))));
77} 190}
78 191
192/*
193 * For removing a directory entry we can modify:
194 * the parent directory inode: inode size
195 * the removed inode: inode size
196 * the directory btree could join: (max depth + v2) * dir block size
197 * the directory bmap btree could join or split: (max depth + v2) * blocksize
198 * And the bmap_finish transaction can free the dir and bmap blocks giving:
199 * the agf for the ag in which the blocks live: 2 * sector size
200 * the agfl for the ag in which the blocks live: 2 * sector size
201 * the superblock for the free block count: sector size
202 * the allocation btrees: 2 exts * 2 trees * (2 * max depth - 1) * block size
203 */
79STATIC uint 204STATIC uint
80xfs_calc_remove_reservation(xfs_mount_t *mp) 205xfs_calc_remove_reservation(
206 struct xfs_mount *mp)
81{ 207{
82 return XFS_CALC_REMOVE_LOG_RES(mp) + XFS_DQUOT_LOGRES(mp); 208 return XFS_DQUOT_LOGRES(mp) +
209 MAX((mp->m_sb.sb_inodesize +
210 mp->m_sb.sb_inodesize +
211 XFS_DIROP_LOG_RES(mp) +
212 128 * (2 + XFS_DIROP_LOG_COUNT(mp))),
213 (2 * mp->m_sb.sb_sectsize +
214 2 * mp->m_sb.sb_sectsize +
215 mp->m_sb.sb_sectsize +
216 XFS_ALLOCFREE_LOG_RES(mp, 2) +
217 128 * (5 + XFS_ALLOCFREE_LOG_COUNT(mp, 2))));
83} 218}
84 219
220/*
221 * For symlink we can modify:
222 * the parent directory inode: inode size
223 * the new inode: inode size
224 * the inode btree entry: 1 block
225 * the directory btree: (max depth + v2) * dir block size
226 * the directory inode's bmap btree: (max depth + v2) * block size
227 * the blocks for the symlink: 1 kB
228 * Or in the first xact we allocate some inodes giving:
229 * the agi and agf of the ag getting the new inodes: 2 * sectorsize
230 * the inode blocks allocated: XFS_IALLOC_BLOCKS * blocksize
231 * the inode btree: max depth * blocksize
232 * the allocation btrees: 2 trees * (2 * max depth - 1) * block size
233 */
85STATIC uint 234STATIC uint
86xfs_calc_symlink_reservation(xfs_mount_t *mp) 235xfs_calc_symlink_reservation(
236 struct xfs_mount *mp)
87{ 237{
88 return XFS_CALC_SYMLINK_LOG_RES(mp) + XFS_DQUOT_LOGRES(mp); 238 return XFS_DQUOT_LOGRES(mp) +
239 MAX((mp->m_sb.sb_inodesize +
240 mp->m_sb.sb_inodesize +
241 XFS_FSB_TO_B(mp, 1) +
242 XFS_DIROP_LOG_RES(mp) +
243 1024 +
244 128 * (4 + XFS_DIROP_LOG_COUNT(mp))),
245 (2 * mp->m_sb.sb_sectsize +
246 XFS_FSB_TO_B(mp, XFS_IALLOC_BLOCKS(mp)) +
247 XFS_FSB_TO_B(mp, mp->m_in_maxlevels) +
248 XFS_ALLOCFREE_LOG_RES(mp, 1) +
249 128 * (2 + XFS_IALLOC_BLOCKS(mp) + mp->m_in_maxlevels +
250 XFS_ALLOCFREE_LOG_COUNT(mp, 1))));
89} 251}
90 252
253/*
254 * For create we can modify:
255 * the parent directory inode: inode size
256 * the new inode: inode size
257 * the inode btree entry: block size
258 * the superblock for the nlink flag: sector size
259 * the directory btree: (max depth + v2) * dir block size
260 * the directory inode's bmap btree: (max depth + v2) * block size
261 * Or in the first xact we allocate some inodes giving:
262 * the agi and agf of the ag getting the new inodes: 2 * sectorsize
263 * the superblock for the nlink flag: sector size
264 * the inode blocks allocated: XFS_IALLOC_BLOCKS * blocksize
265 * the inode btree: max depth * blocksize
266 * the allocation btrees: 2 trees * (max depth - 1) * block size
267 */
91STATIC uint 268STATIC uint
92xfs_calc_create_reservation(xfs_mount_t *mp) 269xfs_calc_create_reservation(
270 struct xfs_mount *mp)
93{ 271{
94 return XFS_CALC_CREATE_LOG_RES(mp) + XFS_DQUOT_LOGRES(mp); 272 return XFS_DQUOT_LOGRES(mp) +
273 MAX((mp->m_sb.sb_inodesize +
274 mp->m_sb.sb_inodesize +
275 mp->m_sb.sb_sectsize +
276 XFS_FSB_TO_B(mp, 1) +
277 XFS_DIROP_LOG_RES(mp) +
278 128 * (3 + XFS_DIROP_LOG_COUNT(mp))),
279 (3 * mp->m_sb.sb_sectsize +
280 XFS_FSB_TO_B(mp, XFS_IALLOC_BLOCKS(mp)) +
281 XFS_FSB_TO_B(mp, mp->m_in_maxlevels) +
282 XFS_ALLOCFREE_LOG_RES(mp, 1) +
283 128 * (2 + XFS_IALLOC_BLOCKS(mp) + mp->m_in_maxlevels +
284 XFS_ALLOCFREE_LOG_COUNT(mp, 1))));
95} 285}
96 286
287/*
288 * Making a new directory is the same as creating a new file.
289 */
97STATIC uint 290STATIC uint
98xfs_calc_mkdir_reservation(xfs_mount_t *mp) 291xfs_calc_mkdir_reservation(
292 struct xfs_mount *mp)
99{ 293{
100 return XFS_CALC_MKDIR_LOG_RES(mp) + XFS_DQUOT_LOGRES(mp); 294 return xfs_calc_create_reservation(mp);
101} 295}
102 296
297/*
298 * In freeing an inode we can modify:
299 * the inode being freed: inode size
300 * the super block free inode counter: sector size
301 * the agi hash list and counters: sector size
302 * the inode btree entry: block size
303 * the on disk inode before ours in the agi hash list: inode cluster size
304 * the inode btree: max depth * blocksize
305 * the allocation btrees: 2 trees * (max depth - 1) * block size
306 */
103STATIC uint 307STATIC uint
104xfs_calc_ifree_reservation(xfs_mount_t *mp) 308xfs_calc_ifree_reservation(
309 struct xfs_mount *mp)
105{ 310{
106 return XFS_CALC_IFREE_LOG_RES(mp) + XFS_DQUOT_LOGRES(mp); 311 return XFS_DQUOT_LOGRES(mp) +
312 mp->m_sb.sb_inodesize +
313 mp->m_sb.sb_sectsize +
314 mp->m_sb.sb_sectsize +
315 XFS_FSB_TO_B(mp, 1) +
316 MAX((__uint16_t)XFS_FSB_TO_B(mp, 1),
317 XFS_INODE_CLUSTER_SIZE(mp)) +
318 128 * 5 +
319 XFS_ALLOCFREE_LOG_RES(mp, 1) +
320 128 * (2 + XFS_IALLOC_BLOCKS(mp) + mp->m_in_maxlevels +
321 XFS_ALLOCFREE_LOG_COUNT(mp, 1));
107} 322}
108 323
324/*
325 * When only changing the inode we log the inode and possibly the superblock
326 * We also add a bit of slop for the transaction stuff.
327 */
109STATIC uint 328STATIC uint
110xfs_calc_ichange_reservation(xfs_mount_t *mp) 329xfs_calc_ichange_reservation(
330 struct xfs_mount *mp)
111{ 331{
112 return XFS_CALC_ICHANGE_LOG_RES(mp) + XFS_DQUOT_LOGRES(mp); 332 return XFS_DQUOT_LOGRES(mp) +
333 mp->m_sb.sb_inodesize +
334 mp->m_sb.sb_sectsize +
335 512;
336
113} 337}
114 338
339/*
340 * Growing the data section of the filesystem.
341 * superblock
342 * agi and agf
343 * allocation btrees
344 */
115STATIC uint 345STATIC uint
116xfs_calc_growdata_reservation(xfs_mount_t *mp) 346xfs_calc_growdata_reservation(
347 struct xfs_mount *mp)
117{ 348{
118 return XFS_CALC_GROWDATA_LOG_RES(mp); 349 return mp->m_sb.sb_sectsize * 3 +
350 XFS_ALLOCFREE_LOG_RES(mp, 1) +
351 128 * (3 + XFS_ALLOCFREE_LOG_COUNT(mp, 1));
119} 352}
120 353
354/*
355 * Growing the rt section of the filesystem.
356 * In the first set of transactions (ALLOC) we allocate space to the
357 * bitmap or summary files.
358 * superblock: sector size
359 * agf of the ag from which the extent is allocated: sector size
360 * bmap btree for bitmap/summary inode: max depth * blocksize
361 * bitmap/summary inode: inode size
362 * allocation btrees for 1 block alloc: 2 * (2 * maxdepth - 1) * blocksize
363 */
121STATIC uint 364STATIC uint
122xfs_calc_growrtalloc_reservation(xfs_mount_t *mp) 365xfs_calc_growrtalloc_reservation(
366 struct xfs_mount *mp)
123{ 367{
124 return XFS_CALC_GROWRTALLOC_LOG_RES(mp); 368 return 2 * mp->m_sb.sb_sectsize +
369 XFS_FSB_TO_B(mp, XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK)) +
370 mp->m_sb.sb_inodesize +
371 XFS_ALLOCFREE_LOG_RES(mp, 1) +
372 128 * (3 + XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK) +
373 XFS_ALLOCFREE_LOG_COUNT(mp, 1));
125} 374}
126 375
376/*
377 * Growing the rt section of the filesystem.
378 * In the second set of transactions (ZERO) we zero the new metadata blocks.
379 * one bitmap/summary block: blocksize
380 */
127STATIC uint 381STATIC uint
128xfs_calc_growrtzero_reservation(xfs_mount_t *mp) 382xfs_calc_growrtzero_reservation(
383 struct xfs_mount *mp)
129{ 384{
130 return XFS_CALC_GROWRTZERO_LOG_RES(mp); 385 return mp->m_sb.sb_blocksize + 128;
131} 386}
132 387
388/*
389 * Growing the rt section of the filesystem.
390 * In the third set of transactions (FREE) we update metadata without
391 * allocating any new blocks.
392 * superblock: sector size
393 * bitmap inode: inode size
394 * summary inode: inode size
395 * one bitmap block: blocksize
396 * summary blocks: new summary size
397 */
133STATIC uint 398STATIC uint
134xfs_calc_growrtfree_reservation(xfs_mount_t *mp) 399xfs_calc_growrtfree_reservation(
400 struct xfs_mount *mp)
135{ 401{
136 return XFS_CALC_GROWRTFREE_LOG_RES(mp); 402 return mp->m_sb.sb_sectsize +
403 2 * mp->m_sb.sb_inodesize +
404 mp->m_sb.sb_blocksize +
405 mp->m_rsumsize +
406 128 * 5;
137} 407}
138 408
409/*
410 * Logging the inode modification timestamp on a synchronous write.
411 * inode
412 */
139STATIC uint 413STATIC uint
140xfs_calc_swrite_reservation(xfs_mount_t *mp) 414xfs_calc_swrite_reservation(
415 struct xfs_mount *mp)
141{ 416{
142 return XFS_CALC_SWRITE_LOG_RES(mp); 417 return mp->m_sb.sb_inodesize + 128;
143} 418}
144 419
420/*
421 * Logging the inode mode bits when writing a setuid/setgid file
422 * inode
423 */
145STATIC uint 424STATIC uint
146xfs_calc_writeid_reservation(xfs_mount_t *mp) 425xfs_calc_writeid_reservation(xfs_mount_t *mp)
147{ 426{
148 return XFS_CALC_WRITEID_LOG_RES(mp); 427 return mp->m_sb.sb_inodesize + 128;
149} 428}
150 429
430/*
431 * Converting the inode from non-attributed to attributed.
432 * the inode being converted: inode size
433 * agf block and superblock (for block allocation)
434 * the new block (directory sized)
435 * bmap blocks for the new directory block
436 * allocation btrees
437 */
151STATIC uint 438STATIC uint
152xfs_calc_addafork_reservation(xfs_mount_t *mp) 439xfs_calc_addafork_reservation(
440 struct xfs_mount *mp)
153{ 441{
154 return XFS_CALC_ADDAFORK_LOG_RES(mp) + XFS_DQUOT_LOGRES(mp); 442 return XFS_DQUOT_LOGRES(mp) +
443 mp->m_sb.sb_inodesize +
444 mp->m_sb.sb_sectsize * 2 +
445 mp->m_dirblksize +
446 XFS_FSB_TO_B(mp, XFS_DAENTER_BMAP1B(mp, XFS_DATA_FORK) + 1) +
447 XFS_ALLOCFREE_LOG_RES(mp, 1) +
448 128 * (4 + XFS_DAENTER_BMAP1B(mp, XFS_DATA_FORK) + 1 +
449 XFS_ALLOCFREE_LOG_COUNT(mp, 1));
155} 450}
156 451
452/*
453 * Removing the attribute fork of a file
454 * the inode being truncated: inode size
455 * the inode's bmap btree: max depth * block size
456 * And the bmap_finish transaction can free the blocks and bmap blocks:
457 * the agf for each of the ags: 4 * sector size
458 * the agfl for each of the ags: 4 * sector size
459 * the super block to reflect the freed blocks: sector size
460 * worst case split in allocation btrees per extent assuming 4 extents:
461 * 4 exts * 2 trees * (2 * max depth - 1) * block size
462 */
157STATIC uint 463STATIC uint
158xfs_calc_attrinval_reservation(xfs_mount_t *mp) 464xfs_calc_attrinval_reservation(
465 struct xfs_mount *mp)
159{ 466{
160 return XFS_CALC_ATTRINVAL_LOG_RES(mp); 467 return MAX((mp->m_sb.sb_inodesize +
468 XFS_FSB_TO_B(mp, XFS_BM_MAXLEVELS(mp, XFS_ATTR_FORK)) +
469 128 * (1 + XFS_BM_MAXLEVELS(mp, XFS_ATTR_FORK))),
470 (4 * mp->m_sb.sb_sectsize +
471 4 * mp->m_sb.sb_sectsize +
472 mp->m_sb.sb_sectsize +
473 XFS_ALLOCFREE_LOG_RES(mp, 4) +
474 128 * (9 + XFS_ALLOCFREE_LOG_COUNT(mp, 4))));
161} 475}
162 476
477/*
478 * Setting an attribute.
479 * the inode getting the attribute
480 * the superblock for allocations
481 * the agfs extents are allocated from
482 * the attribute btree * max depth
483 * the inode allocation btree
484 * Since attribute transaction space is dependent on the size of the attribute,
485 * the calculation is done partially at mount time and partially at runtime.
486 */
163STATIC uint 487STATIC uint
164xfs_calc_attrset_reservation(xfs_mount_t *mp) 488xfs_calc_attrset_reservation(
489 struct xfs_mount *mp)
165{ 490{
166 return XFS_CALC_ATTRSET_LOG_RES(mp) + XFS_DQUOT_LOGRES(mp); 491 return XFS_DQUOT_LOGRES(mp) +
492 mp->m_sb.sb_inodesize +
493 mp->m_sb.sb_sectsize +
494 XFS_FSB_TO_B(mp, XFS_DA_NODE_MAXDEPTH) +
495 128 * (2 + XFS_DA_NODE_MAXDEPTH);
167} 496}
168 497
498/*
499 * Removing an attribute.
500 * the inode: inode size
501 * the attribute btree could join: max depth * block size
502 * the inode bmap btree could join or split: max depth * block size
503 * And the bmap_finish transaction can free the attr blocks freed giving:
504 * the agf for the ag in which the blocks live: 2 * sector size
505 * the agfl for the ag in which the blocks live: 2 * sector size
506 * the superblock for the free block count: sector size
507 * the allocation btrees: 2 exts * 2 trees * (2 * max depth - 1) * block size
508 */
169STATIC uint 509STATIC uint
170xfs_calc_attrrm_reservation(xfs_mount_t *mp) 510xfs_calc_attrrm_reservation(
511 struct xfs_mount *mp)
171{ 512{
172 return XFS_CALC_ATTRRM_LOG_RES(mp) + XFS_DQUOT_LOGRES(mp); 513 return XFS_DQUOT_LOGRES(mp) +
514 MAX((mp->m_sb.sb_inodesize +
515 XFS_FSB_TO_B(mp, XFS_DA_NODE_MAXDEPTH) +
516 XFS_FSB_TO_B(mp, XFS_BM_MAXLEVELS(mp, XFS_ATTR_FORK)) +
517 128 * (1 + XFS_DA_NODE_MAXDEPTH +
518 XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK))),
519 (2 * mp->m_sb.sb_sectsize +
520 2 * mp->m_sb.sb_sectsize +
521 mp->m_sb.sb_sectsize +
522 XFS_ALLOCFREE_LOG_RES(mp, 2) +
523 128 * (5 + XFS_ALLOCFREE_LOG_COUNT(mp, 2))));
173} 524}
174 525
526/*
527 * Clearing a bad agino number in an agi hash bucket.
528 */
175STATIC uint 529STATIC uint
176xfs_calc_clear_agi_bucket_reservation(xfs_mount_t *mp) 530xfs_calc_clear_agi_bucket_reservation(
531 struct xfs_mount *mp)
177{ 532{
178 return XFS_CALC_CLEAR_AGI_BUCKET_LOG_RES(mp); 533 return mp->m_sb.sb_sectsize + 128;
179} 534}
180 535
181/* 536/*
@@ -184,11 +539,10 @@ xfs_calc_clear_agi_bucket_reservation(xfs_mount_t *mp)
184 */ 539 */
185void 540void
186xfs_trans_init( 541xfs_trans_init(
187 xfs_mount_t *mp) 542 struct xfs_mount *mp)
188{ 543{
189 xfs_trans_reservations_t *resp; 544 struct xfs_trans_reservations *resp = &mp->m_reservations;
190 545
191 resp = &(mp->m_reservations);
192 resp->tr_write = xfs_calc_write_reservation(mp); 546 resp->tr_write = xfs_calc_write_reservation(mp);
193 resp->tr_itruncate = xfs_calc_itruncate_reservation(mp); 547 resp->tr_itruncate = xfs_calc_itruncate_reservation(mp);
194 resp->tr_rename = xfs_calc_rename_reservation(mp); 548 resp->tr_rename = xfs_calc_rename_reservation(mp);
diff --git a/fs/xfs/xfs_trans.h b/fs/xfs/xfs_trans.h
index 8c69e7824f68..e639e8e9a2a9 100644
--- a/fs/xfs/xfs_trans.h
+++ b/fs/xfs/xfs_trans.h
@@ -300,24 +300,6 @@ xfs_lic_desc_to_chunk(xfs_log_item_desc_t *dp)
300 300
301 301
302/* 302/*
303 * Various log reservation values.
304 * These are based on the size of the file system block
305 * because that is what most transactions manipulate.
306 * Each adds in an additional 128 bytes per item logged to
307 * try to account for the overhead of the transaction mechanism.
308 *
309 * Note:
310 * Most of the reservations underestimate the number of allocation
311 * groups into which they could free extents in the xfs_bmap_finish()
312 * call. This is because the number in the worst case is quite high
313 * and quite unusual. In order to fix this we need to change
314 * xfs_bmap_finish() to free extents in only a single AG at a time.
315 * This will require changes to the EFI code as well, however, so that
316 * the EFI for the extents not freed is logged again in each transaction.
317 * See bug 261917.
318 */
319
320/*
321 * Per-extent log reservation for the allocation btree changes 303 * Per-extent log reservation for the allocation btree changes
322 * involved in freeing or allocating an extent. 304 * involved in freeing or allocating an extent.
323 * 2 trees * (2 blocks/level * max depth - 1) * block size 305 * 2 trees * (2 blocks/level * max depth - 1) * block size
@@ -341,429 +323,36 @@ xfs_lic_desc_to_chunk(xfs_log_item_desc_t *dp)
341 (XFS_DAENTER_BLOCKS(mp, XFS_DATA_FORK) + \ 323 (XFS_DAENTER_BLOCKS(mp, XFS_DATA_FORK) + \
342 XFS_DAENTER_BMAPS(mp, XFS_DATA_FORK) + 1) 324 XFS_DAENTER_BMAPS(mp, XFS_DATA_FORK) + 1)
343 325
344/*
345 * In a write transaction we can allocate a maximum of 2
346 * extents. This gives:
347 * the inode getting the new extents: inode size
348 * the inode's bmap btree: max depth * block size
349 * the agfs of the ags from which the extents are allocated: 2 * sector
350 * the superblock free block counter: sector size
351 * the allocation btrees: 2 exts * 2 trees * (2 * max depth - 1) * block size
352 * And the bmap_finish transaction can free bmap blocks in a join:
353 * the agfs of the ags containing the blocks: 2 * sector size
354 * the agfls of the ags containing the blocks: 2 * sector size
355 * the super block free block counter: sector size
356 * the allocation btrees: 2 exts * 2 trees * (2 * max depth - 1) * block size
357 */
358#define XFS_CALC_WRITE_LOG_RES(mp) \
359 (MAX( \
360 ((mp)->m_sb.sb_inodesize + \
361 XFS_FSB_TO_B((mp), XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK)) + \
362 (2 * (mp)->m_sb.sb_sectsize) + \
363 (mp)->m_sb.sb_sectsize + \
364 XFS_ALLOCFREE_LOG_RES(mp, 2) + \
365 (128 * (4 + XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK) + XFS_ALLOCFREE_LOG_COUNT(mp, 2)))),\
366 ((2 * (mp)->m_sb.sb_sectsize) + \
367 (2 * (mp)->m_sb.sb_sectsize) + \
368 (mp)->m_sb.sb_sectsize + \
369 XFS_ALLOCFREE_LOG_RES(mp, 2) + \
370 (128 * (5 + XFS_ALLOCFREE_LOG_COUNT(mp, 2))))))
371 326
372#define XFS_WRITE_LOG_RES(mp) ((mp)->m_reservations.tr_write) 327#define XFS_WRITE_LOG_RES(mp) ((mp)->m_reservations.tr_write)
373
374/*
375 * In truncating a file we free up to two extents at once. We can modify:
376 * the inode being truncated: inode size
377 * the inode's bmap btree: (max depth + 1) * block size
378 * And the bmap_finish transaction can free the blocks and bmap blocks:
379 * the agf for each of the ags: 4 * sector size
380 * the agfl for each of the ags: 4 * sector size
381 * the super block to reflect the freed blocks: sector size
382 * worst case split in allocation btrees per extent assuming 4 extents:
383 * 4 exts * 2 trees * (2 * max depth - 1) * block size
384 * the inode btree: max depth * blocksize
385 * the allocation btrees: 2 trees * (max depth - 1) * block size
386 */
387#define XFS_CALC_ITRUNCATE_LOG_RES(mp) \
388 (MAX( \
389 ((mp)->m_sb.sb_inodesize + \
390 XFS_FSB_TO_B((mp), XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK) + 1) + \
391 (128 * (2 + XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK)))), \
392 ((4 * (mp)->m_sb.sb_sectsize) + \
393 (4 * (mp)->m_sb.sb_sectsize) + \
394 (mp)->m_sb.sb_sectsize + \
395 XFS_ALLOCFREE_LOG_RES(mp, 4) + \
396 (128 * (9 + XFS_ALLOCFREE_LOG_COUNT(mp, 4))) + \
397 (128 * 5) + \
398 XFS_ALLOCFREE_LOG_RES(mp, 1) + \
399 (128 * (2 + XFS_IALLOC_BLOCKS(mp) + (mp)->m_in_maxlevels + \
400 XFS_ALLOCFREE_LOG_COUNT(mp, 1))))))
401
402#define XFS_ITRUNCATE_LOG_RES(mp) ((mp)->m_reservations.tr_itruncate) 328#define XFS_ITRUNCATE_LOG_RES(mp) ((mp)->m_reservations.tr_itruncate)
403
404/*
405 * In renaming a files we can modify:
406 * the four inodes involved: 4 * inode size
407 * the two directory btrees: 2 * (max depth + v2) * dir block size
408 * the two directory bmap btrees: 2 * max depth * block size
409 * And the bmap_finish transaction can free dir and bmap blocks (two sets
410 * of bmap blocks) giving:
411 * the agf for the ags in which the blocks live: 3 * sector size
412 * the agfl for the ags in which the blocks live: 3 * sector size
413 * the superblock for the free block count: sector size
414 * the allocation btrees: 3 exts * 2 trees * (2 * max depth - 1) * block size
415 */
416#define XFS_CALC_RENAME_LOG_RES(mp) \
417 (MAX( \
418 ((4 * (mp)->m_sb.sb_inodesize) + \
419 (2 * XFS_DIROP_LOG_RES(mp)) + \
420 (128 * (4 + 2 * XFS_DIROP_LOG_COUNT(mp)))), \
421 ((3 * (mp)->m_sb.sb_sectsize) + \
422 (3 * (mp)->m_sb.sb_sectsize) + \
423 (mp)->m_sb.sb_sectsize + \
424 XFS_ALLOCFREE_LOG_RES(mp, 3) + \
425 (128 * (7 + XFS_ALLOCFREE_LOG_COUNT(mp, 3))))))
426
427#define XFS_RENAME_LOG_RES(mp) ((mp)->m_reservations.tr_rename) 329#define XFS_RENAME_LOG_RES(mp) ((mp)->m_reservations.tr_rename)
428
429/*
430 * For creating a link to an inode:
431 * the parent directory inode: inode size
432 * the linked inode: inode size
433 * the directory btree could split: (max depth + v2) * dir block size
434 * the directory bmap btree could join or split: (max depth + v2) * blocksize
435 * And the bmap_finish transaction can free some bmap blocks giving:
436 * the agf for the ag in which the blocks live: sector size
437 * the agfl for the ag in which the blocks live: sector size
438 * the superblock for the free block count: sector size
439 * the allocation btrees: 2 trees * (2 * max depth - 1) * block size
440 */
441#define XFS_CALC_LINK_LOG_RES(mp) \
442 (MAX( \
443 ((mp)->m_sb.sb_inodesize + \
444 (mp)->m_sb.sb_inodesize + \
445 XFS_DIROP_LOG_RES(mp) + \
446 (128 * (2 + XFS_DIROP_LOG_COUNT(mp)))), \
447 ((mp)->m_sb.sb_sectsize + \
448 (mp)->m_sb.sb_sectsize + \
449 (mp)->m_sb.sb_sectsize + \
450 XFS_ALLOCFREE_LOG_RES(mp, 1) + \
451 (128 * (3 + XFS_ALLOCFREE_LOG_COUNT(mp, 1))))))
452
453#define XFS_LINK_LOG_RES(mp) ((mp)->m_reservations.tr_link) 330#define XFS_LINK_LOG_RES(mp) ((mp)->m_reservations.tr_link)
454
455/*
456 * For removing a directory entry we can modify:
457 * the parent directory inode: inode size
458 * the removed inode: inode size
459 * the directory btree could join: (max depth + v2) * dir block size
460 * the directory bmap btree could join or split: (max depth + v2) * blocksize
461 * And the bmap_finish transaction can free the dir and bmap blocks giving:
462 * the agf for the ag in which the blocks live: 2 * sector size
463 * the agfl for the ag in which the blocks live: 2 * sector size
464 * the superblock for the free block count: sector size
465 * the allocation btrees: 2 exts * 2 trees * (2 * max depth - 1) * block size
466 */
467#define XFS_CALC_REMOVE_LOG_RES(mp) \
468 (MAX( \
469 ((mp)->m_sb.sb_inodesize + \
470 (mp)->m_sb.sb_inodesize + \
471 XFS_DIROP_LOG_RES(mp) + \
472 (128 * (2 + XFS_DIROP_LOG_COUNT(mp)))), \
473 ((2 * (mp)->m_sb.sb_sectsize) + \
474 (2 * (mp)->m_sb.sb_sectsize) + \
475 (mp)->m_sb.sb_sectsize + \
476 XFS_ALLOCFREE_LOG_RES(mp, 2) + \
477 (128 * (5 + XFS_ALLOCFREE_LOG_COUNT(mp, 2))))))
478
479#define XFS_REMOVE_LOG_RES(mp) ((mp)->m_reservations.tr_remove) 331#define XFS_REMOVE_LOG_RES(mp) ((mp)->m_reservations.tr_remove)
480
481/*
482 * For symlink we can modify:
483 * the parent directory inode: inode size
484 * the new inode: inode size
485 * the inode btree entry: 1 block
486 * the directory btree: (max depth + v2) * dir block size
487 * the directory inode's bmap btree: (max depth + v2) * block size
488 * the blocks for the symlink: 1 kB
489 * Or in the first xact we allocate some inodes giving:
490 * the agi and agf of the ag getting the new inodes: 2 * sectorsize
491 * the inode blocks allocated: XFS_IALLOC_BLOCKS * blocksize
492 * the inode btree: max depth * blocksize
493 * the allocation btrees: 2 trees * (2 * max depth - 1) * block size
494 */
495#define XFS_CALC_SYMLINK_LOG_RES(mp) \
496 (MAX( \
497 ((mp)->m_sb.sb_inodesize + \
498 (mp)->m_sb.sb_inodesize + \
499 XFS_FSB_TO_B(mp, 1) + \
500 XFS_DIROP_LOG_RES(mp) + \
501 1024 + \
502 (128 * (4 + XFS_DIROP_LOG_COUNT(mp)))), \
503 (2 * (mp)->m_sb.sb_sectsize + \
504 XFS_FSB_TO_B((mp), XFS_IALLOC_BLOCKS((mp))) + \
505 XFS_FSB_TO_B((mp), (mp)->m_in_maxlevels) + \
506 XFS_ALLOCFREE_LOG_RES(mp, 1) + \
507 (128 * (2 + XFS_IALLOC_BLOCKS(mp) + (mp)->m_in_maxlevels + \
508 XFS_ALLOCFREE_LOG_COUNT(mp, 1))))))
509
510#define XFS_SYMLINK_LOG_RES(mp) ((mp)->m_reservations.tr_symlink) 332#define XFS_SYMLINK_LOG_RES(mp) ((mp)->m_reservations.tr_symlink)
511
512/*
513 * For create we can modify:
514 * the parent directory inode: inode size
515 * the new inode: inode size
516 * the inode btree entry: block size
517 * the superblock for the nlink flag: sector size
518 * the directory btree: (max depth + v2) * dir block size
519 * the directory inode's bmap btree: (max depth + v2) * block size
520 * Or in the first xact we allocate some inodes giving:
521 * the agi and agf of the ag getting the new inodes: 2 * sectorsize
522 * the superblock for the nlink flag: sector size
523 * the inode blocks allocated: XFS_IALLOC_BLOCKS * blocksize
524 * the inode btree: max depth * blocksize
525 * the allocation btrees: 2 trees * (max depth - 1) * block size
526 */
527#define XFS_CALC_CREATE_LOG_RES(mp) \
528 (MAX( \
529 ((mp)->m_sb.sb_inodesize + \
530 (mp)->m_sb.sb_inodesize + \
531 (mp)->m_sb.sb_sectsize + \
532 XFS_FSB_TO_B(mp, 1) + \
533 XFS_DIROP_LOG_RES(mp) + \
534 (128 * (3 + XFS_DIROP_LOG_COUNT(mp)))), \
535 (3 * (mp)->m_sb.sb_sectsize + \
536 XFS_FSB_TO_B((mp), XFS_IALLOC_BLOCKS((mp))) + \
537 XFS_FSB_TO_B((mp), (mp)->m_in_maxlevels) + \
538 XFS_ALLOCFREE_LOG_RES(mp, 1) + \
539 (128 * (2 + XFS_IALLOC_BLOCKS(mp) + (mp)->m_in_maxlevels + \
540 XFS_ALLOCFREE_LOG_COUNT(mp, 1))))))
541
542#define XFS_CREATE_LOG_RES(mp) ((mp)->m_reservations.tr_create) 333#define XFS_CREATE_LOG_RES(mp) ((mp)->m_reservations.tr_create)
543
544/*
545 * Making a new directory is the same as creating a new file.
546 */
547#define XFS_CALC_MKDIR_LOG_RES(mp) XFS_CALC_CREATE_LOG_RES(mp)
548
549#define XFS_MKDIR_LOG_RES(mp) ((mp)->m_reservations.tr_mkdir) 334#define XFS_MKDIR_LOG_RES(mp) ((mp)->m_reservations.tr_mkdir)
550
551/*
552 * In freeing an inode we can modify:
553 * the inode being freed: inode size
554 * the super block free inode counter: sector size
555 * the agi hash list and counters: sector size
556 * the inode btree entry: block size
557 * the on disk inode before ours in the agi hash list: inode cluster size
558 * the inode btree: max depth * blocksize
559 * the allocation btrees: 2 trees * (max depth - 1) * block size
560 */
561#define XFS_CALC_IFREE_LOG_RES(mp) \
562 ((mp)->m_sb.sb_inodesize + \
563 (mp)->m_sb.sb_sectsize + \
564 (mp)->m_sb.sb_sectsize + \
565 XFS_FSB_TO_B((mp), 1) + \
566 MAX((__uint16_t)XFS_FSB_TO_B((mp), 1), XFS_INODE_CLUSTER_SIZE(mp)) + \
567 (128 * 5) + \
568 XFS_ALLOCFREE_LOG_RES(mp, 1) + \
569 (128 * (2 + XFS_IALLOC_BLOCKS(mp) + (mp)->m_in_maxlevels + \
570 XFS_ALLOCFREE_LOG_COUNT(mp, 1))))
571
572
573#define XFS_IFREE_LOG_RES(mp) ((mp)->m_reservations.tr_ifree) 335#define XFS_IFREE_LOG_RES(mp) ((mp)->m_reservations.tr_ifree)
574
575/*
576 * When only changing the inode we log the inode and possibly the superblock
577 * We also add a bit of slop for the transaction stuff.
578 */
579#define XFS_CALC_ICHANGE_LOG_RES(mp) ((mp)->m_sb.sb_inodesize + \
580 (mp)->m_sb.sb_sectsize + 512)
581
582#define XFS_ICHANGE_LOG_RES(mp) ((mp)->m_reservations.tr_ichange) 336#define XFS_ICHANGE_LOG_RES(mp) ((mp)->m_reservations.tr_ichange)
583
584/*
585 * Growing the data section of the filesystem.
586 * superblock
587 * agi and agf
588 * allocation btrees
589 */
590#define XFS_CALC_GROWDATA_LOG_RES(mp) \
591 ((mp)->m_sb.sb_sectsize * 3 + \
592 XFS_ALLOCFREE_LOG_RES(mp, 1) + \
593 (128 * (3 + XFS_ALLOCFREE_LOG_COUNT(mp, 1))))
594
595#define XFS_GROWDATA_LOG_RES(mp) ((mp)->m_reservations.tr_growdata) 337#define XFS_GROWDATA_LOG_RES(mp) ((mp)->m_reservations.tr_growdata)
596
597/*
598 * Growing the rt section of the filesystem.
599 * In the first set of transactions (ALLOC) we allocate space to the
600 * bitmap or summary files.
601 * superblock: sector size
602 * agf of the ag from which the extent is allocated: sector size
603 * bmap btree for bitmap/summary inode: max depth * blocksize
604 * bitmap/summary inode: inode size
605 * allocation btrees for 1 block alloc: 2 * (2 * maxdepth - 1) * blocksize
606 */
607#define XFS_CALC_GROWRTALLOC_LOG_RES(mp) \
608 (2 * (mp)->m_sb.sb_sectsize + \
609 XFS_FSB_TO_B((mp), XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK)) + \
610 (mp)->m_sb.sb_inodesize + \
611 XFS_ALLOCFREE_LOG_RES(mp, 1) + \
612 (128 * \
613 (3 + XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK) + \
614 XFS_ALLOCFREE_LOG_COUNT(mp, 1))))
615
616#define XFS_GROWRTALLOC_LOG_RES(mp) ((mp)->m_reservations.tr_growrtalloc) 338#define XFS_GROWRTALLOC_LOG_RES(mp) ((mp)->m_reservations.tr_growrtalloc)
617
618/*
619 * Growing the rt section of the filesystem.
620 * In the second set of transactions (ZERO) we zero the new metadata blocks.
621 * one bitmap/summary block: blocksize
622 */
623#define XFS_CALC_GROWRTZERO_LOG_RES(mp) \
624 ((mp)->m_sb.sb_blocksize + 128)
625
626#define XFS_GROWRTZERO_LOG_RES(mp) ((mp)->m_reservations.tr_growrtzero) 339#define XFS_GROWRTZERO_LOG_RES(mp) ((mp)->m_reservations.tr_growrtzero)
627
628/*
629 * Growing the rt section of the filesystem.
630 * In the third set of transactions (FREE) we update metadata without
631 * allocating any new blocks.
632 * superblock: sector size
633 * bitmap inode: inode size
634 * summary inode: inode size
635 * one bitmap block: blocksize
636 * summary blocks: new summary size
637 */
638#define XFS_CALC_GROWRTFREE_LOG_RES(mp) \
639 ((mp)->m_sb.sb_sectsize + \
640 2 * (mp)->m_sb.sb_inodesize + \
641 (mp)->m_sb.sb_blocksize + \
642 (mp)->m_rsumsize + \
643 (128 * 5))
644
645#define XFS_GROWRTFREE_LOG_RES(mp) ((mp)->m_reservations.tr_growrtfree) 340#define XFS_GROWRTFREE_LOG_RES(mp) ((mp)->m_reservations.tr_growrtfree)
646
647/*
648 * Logging the inode modification timestamp on a synchronous write.
649 * inode
650 */
651#define XFS_CALC_SWRITE_LOG_RES(mp) \
652 ((mp)->m_sb.sb_inodesize + 128)
653
654#define XFS_SWRITE_LOG_RES(mp) ((mp)->m_reservations.tr_swrite) 341#define XFS_SWRITE_LOG_RES(mp) ((mp)->m_reservations.tr_swrite)
655
656/* 342/*
657 * Logging the inode timestamps on an fsync -- same as SWRITE 343 * Logging the inode timestamps on an fsync -- same as SWRITE
658 * as long as SWRITE logs the entire inode core 344 * as long as SWRITE logs the entire inode core
659 */ 345 */
660#define XFS_FSYNC_TS_LOG_RES(mp) ((mp)->m_reservations.tr_swrite) 346#define XFS_FSYNC_TS_LOG_RES(mp) ((mp)->m_reservations.tr_swrite)
661
662/*
663 * Logging the inode mode bits when writing a setuid/setgid file
664 * inode
665 */
666#define XFS_CALC_WRITEID_LOG_RES(mp) \
667 ((mp)->m_sb.sb_inodesize + 128)
668
669#define XFS_WRITEID_LOG_RES(mp) ((mp)->m_reservations.tr_swrite) 347#define XFS_WRITEID_LOG_RES(mp) ((mp)->m_reservations.tr_swrite)
670
671/*
672 * Converting the inode from non-attributed to attributed.
673 * the inode being converted: inode size
674 * agf block and superblock (for block allocation)
675 * the new block (directory sized)
676 * bmap blocks for the new directory block
677 * allocation btrees
678 */
679#define XFS_CALC_ADDAFORK_LOG_RES(mp) \
680 ((mp)->m_sb.sb_inodesize + \
681 (mp)->m_sb.sb_sectsize * 2 + \
682 (mp)->m_dirblksize + \
683 XFS_FSB_TO_B(mp, (XFS_DAENTER_BMAP1B(mp, XFS_DATA_FORK) + 1)) + \
684 XFS_ALLOCFREE_LOG_RES(mp, 1) + \
685 (128 * (4 + (XFS_DAENTER_BMAP1B(mp, XFS_DATA_FORK) + 1) + \
686 XFS_ALLOCFREE_LOG_COUNT(mp, 1))))
687
688#define XFS_ADDAFORK_LOG_RES(mp) ((mp)->m_reservations.tr_addafork) 348#define XFS_ADDAFORK_LOG_RES(mp) ((mp)->m_reservations.tr_addafork)
689
690/*
691 * Removing the attribute fork of a file
692 * the inode being truncated: inode size
693 * the inode's bmap btree: max depth * block size
694 * And the bmap_finish transaction can free the blocks and bmap blocks:
695 * the agf for each of the ags: 4 * sector size
696 * the agfl for each of the ags: 4 * sector size
697 * the super block to reflect the freed blocks: sector size
698 * worst case split in allocation btrees per extent assuming 4 extents:
699 * 4 exts * 2 trees * (2 * max depth - 1) * block size
700 */
701#define XFS_CALC_ATTRINVAL_LOG_RES(mp) \
702 (MAX( \
703 ((mp)->m_sb.sb_inodesize + \
704 XFS_FSB_TO_B((mp), XFS_BM_MAXLEVELS(mp, XFS_ATTR_FORK)) + \
705 (128 * (1 + XFS_BM_MAXLEVELS(mp, XFS_ATTR_FORK)))), \
706 ((4 * (mp)->m_sb.sb_sectsize) + \
707 (4 * (mp)->m_sb.sb_sectsize) + \
708 (mp)->m_sb.sb_sectsize + \
709 XFS_ALLOCFREE_LOG_RES(mp, 4) + \
710 (128 * (9 + XFS_ALLOCFREE_LOG_COUNT(mp, 4))))))
711
712#define XFS_ATTRINVAL_LOG_RES(mp) ((mp)->m_reservations.tr_attrinval) 349#define XFS_ATTRINVAL_LOG_RES(mp) ((mp)->m_reservations.tr_attrinval)
713
714/*
715 * Setting an attribute.
716 * the inode getting the attribute
717 * the superblock for allocations
718 * the agfs extents are allocated from
719 * the attribute btree * max depth
720 * the inode allocation btree
721 * Since attribute transaction space is dependent on the size of the attribute,
722 * the calculation is done partially at mount time and partially at runtime.
723 */
724#define XFS_CALC_ATTRSET_LOG_RES(mp) \
725 ((mp)->m_sb.sb_inodesize + \
726 (mp)->m_sb.sb_sectsize + \
727 XFS_FSB_TO_B((mp), XFS_DA_NODE_MAXDEPTH) + \
728 (128 * (2 + XFS_DA_NODE_MAXDEPTH)))
729
730#define XFS_ATTRSET_LOG_RES(mp, ext) \ 350#define XFS_ATTRSET_LOG_RES(mp, ext) \
731 ((mp)->m_reservations.tr_attrset + \ 351 ((mp)->m_reservations.tr_attrset + \
732 (ext * (mp)->m_sb.sb_sectsize) + \ 352 (ext * (mp)->m_sb.sb_sectsize) + \
733 (ext * XFS_FSB_TO_B((mp), XFS_BM_MAXLEVELS(mp, XFS_ATTR_FORK))) + \ 353 (ext * XFS_FSB_TO_B((mp), XFS_BM_MAXLEVELS(mp, XFS_ATTR_FORK))) + \
734 (128 * (ext + (ext * XFS_BM_MAXLEVELS(mp, XFS_ATTR_FORK))))) 354 (128 * (ext + (ext * XFS_BM_MAXLEVELS(mp, XFS_ATTR_FORK)))))
735
736/*
737 * Removing an attribute.
738 * the inode: inode size
739 * the attribute btree could join: max depth * block size
740 * the inode bmap btree could join or split: max depth * block size
741 * And the bmap_finish transaction can free the attr blocks freed giving:
742 * the agf for the ag in which the blocks live: 2 * sector size
743 * the agfl for the ag in which the blocks live: 2 * sector size
744 * the superblock for the free block count: sector size
745 * the allocation btrees: 2 exts * 2 trees * (2 * max depth - 1) * block size
746 */
747#define XFS_CALC_ATTRRM_LOG_RES(mp) \
748 (MAX( \
749 ((mp)->m_sb.sb_inodesize + \
750 XFS_FSB_TO_B((mp), XFS_DA_NODE_MAXDEPTH) + \
751 XFS_FSB_TO_B((mp), XFS_BM_MAXLEVELS(mp, XFS_ATTR_FORK)) + \
752 (128 * (1 + XFS_DA_NODE_MAXDEPTH + XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK)))), \
753 ((2 * (mp)->m_sb.sb_sectsize) + \
754 (2 * (mp)->m_sb.sb_sectsize) + \
755 (mp)->m_sb.sb_sectsize + \
756 XFS_ALLOCFREE_LOG_RES(mp, 2) + \
757 (128 * (5 + XFS_ALLOCFREE_LOG_COUNT(mp, 2))))))
758
759#define XFS_ATTRRM_LOG_RES(mp) ((mp)->m_reservations.tr_attrrm) 355#define XFS_ATTRRM_LOG_RES(mp) ((mp)->m_reservations.tr_attrrm)
760
761/*
762 * Clearing a bad agino number in an agi hash bucket.
763 */
764#define XFS_CALC_CLEAR_AGI_BUCKET_LOG_RES(mp) \
765 ((mp)->m_sb.sb_sectsize + 128)
766
767#define XFS_CLEAR_AGI_BUCKET_LOG_RES(mp) ((mp)->m_reservations.tr_clearagi) 356#define XFS_CLEAR_AGI_BUCKET_LOG_RES(mp) ((mp)->m_reservations.tr_clearagi)
768 357
769 358