Line data Source code
1 : // SPDX-License-Identifier: GPL-2.0
2 : /*
3 : * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc.
4 : * Copyright (C) 2010 Red Hat, Inc.
5 : * All Rights Reserved.
6 : */
7 : #include "xfs.h"
8 : #include "xfs_fs.h"
9 : #include "xfs_shared.h"
10 : #include "xfs_format.h"
11 : #include "xfs_log_format.h"
12 : #include "xfs_trans_resv.h"
13 : #include "xfs_mount.h"
14 : #include "xfs_da_format.h"
15 : #include "xfs_da_btree.h"
16 : #include "xfs_inode.h"
17 : #include "xfs_bmap_btree.h"
18 : #include "xfs_quota.h"
19 : #include "xfs_trans.h"
20 : #include "xfs_qm.h"
21 : #include "xfs_trans_space.h"
22 : #include "xfs_attr_item.h"
23 : #include "xfs_log.h"
24 : #include "xfs_da_format.h"
25 : #include "xfs_rtbitmap.h"
26 :
27 : #define _ALLOC true
28 : #define _FREE false
29 :
30 : /*
31 : * A buffer has a format structure overhead in the log in addition
32 : * to the data, so we need to take this into account when reserving
33 : * space in a transaction for a buffer. Round the space required up
34 : * to a multiple of 128 bytes so that we don't change the historical
35 : * reservation that has been used for this overhead.
36 : */
37 : STATIC uint
38 5336769 : xfs_buf_log_overhead(void)
39 : {
40 5336769 : return round_up(sizeof(struct xlog_op_header) +
41 : sizeof(struct xfs_buf_log_format), 128);
42 : }
43 :
44 : /*
45 : * Calculate out transaction log reservation per item in bytes.
46 : *
47 : * The nbufs argument is used to indicate the number of items that
48 : * will be changed in a transaction. size is used to tell how many
49 : * bytes should be reserved per item.
50 : */
51 : STATIC uint
52 5336769 : xfs_calc_buf_res(
53 : uint nbufs,
54 : uint size)
55 : {
56 5336769 : return nbufs * (size + xfs_buf_log_overhead());
57 : }
58 :
59 : /*
60 : * Per-extent log reservation for the btree changes involved in freeing or
61 : * allocating an extent. In classic XFS there were two trees that will be
62 : * modified (bnobt + cntbt). With rmap enabled, there are three trees
63 : * (rmapbt). The number of blocks reserved is based on the formula:
64 : *
65 : * num trees * ((2 blocks/level * max depth) - 1)
66 : *
67 : * Keep in mind that max depth is calculated separately for each type of tree.
68 : */
69 : uint
70 160502895 : xfs_allocfree_block_count(
71 : struct xfs_mount *mp,
72 : uint num_ops)
73 : {
74 160502895 : uint blocks;
75 :
76 160502895 : blocks = num_ops * 2 * (2 * mp->m_alloc_maxlevels - 1);
77 160502895 : if (xfs_has_rmapbt(mp))
78 160498577 : blocks += num_ops * (2 * mp->m_rmap_maxlevels - 1);
79 :
80 160502895 : return blocks;
81 : }
82 :
83 : /*
84 : * Per-extent log reservation for refcount btree changes. These are never done
85 : * in the same transaction as an allocation or a free, so we compute them
86 : * separately.
87 : */
88 : static unsigned int
89 : xfs_refcountbt_block_count(
90 : struct xfs_mount *mp,
91 : unsigned int num_ops)
92 : {
93 148956 : return num_ops * (2 * mp->m_refc_maxlevels - 1);
94 : }
95 :
96 : static unsigned int
97 : xfs_rtrefcountbt_block_count(
98 : struct xfs_mount *mp,
99 : unsigned int num_ops)
100 : {
101 1446 : return num_ops * (2 * mp->m_rtrefc_maxlevels - 1);
102 : }
103 :
104 : /*
105 : * Logging inodes is really tricksy. They are logged in memory format,
106 : * which means that what we write into the log doesn't directly translate into
107 : * the amount of space they use on disk.
108 : *
109 : * Case in point - btree format forks in memory format use more space than the
110 : * on-disk format. In memory, the buffer contains a normal btree block header so
111 : * the btree code can treat it as though it is just another generic buffer.
112 : * However, when we write it to the inode fork, we don't write all of this
113 : * header as it isn't needed. e.g. the root is only ever in the inode, so
114 : * there's no need for sibling pointers which would waste 16 bytes of space.
115 : *
116 : * Hence when we have an inode with a maximally sized btree format fork, then
117 : * amount of information we actually log is greater than the size of the inode
118 : * on disk. Hence we need an inode reservation function that calculates all this
119 : * correctly. So, we log:
120 : *
121 : * - 4 log op headers for object
122 : * - for the ilf, the inode core and 2 forks
123 : * - inode log format object
124 : * - the inode core
125 : * - two inode forks containing bmap btree root blocks.
126 : * - the btree data contained by both forks will fit into the inode size,
127 : * hence when combined with the inode core above, we have a total of the
128 : * actual inode size.
129 : * - the BMBT headers need to be accounted separately, as they are
130 : * additional to the records and pointers that fit inside the inode
131 : * forks.
132 : */
133 : STATIC uint
134 940599 : xfs_calc_inode_res(
135 : struct xfs_mount *mp,
136 : uint ninodes)
137 : {
138 1881198 : return ninodes *
139 : (4 * sizeof(struct xlog_op_header) +
140 : sizeof(struct xfs_inode_log_format) +
141 940599 : mp->m_sb.sb_inodesize +
142 940599 : 2 * xfs_bmbt_block_len(mp));
143 : }
144 :
145 : /*
146 : * Inode btree record insertion/removal modifies the inode btree and free space
147 : * btrees (since the inobt does not use the agfl). This requires the following
148 : * reservation:
149 : *
150 : * the inode btree: max depth * blocksize
151 : * the allocation btrees: 2 trees * (max depth - 1) * block size
152 : *
153 : * The caller must account for SB and AG header modifications, etc.
154 : */
155 : STATIC uint
156 640640 : xfs_calc_inobt_res(
157 : struct xfs_mount *mp)
158 : {
159 640640 : return xfs_calc_buf_res(M_IGEO(mp)->inobt_maxlevels,
160 640640 : XFS_FSB_TO_B(mp, 1)) +
161 640640 : xfs_calc_buf_res(xfs_allocfree_block_count(mp, 1),
162 : XFS_FSB_TO_B(mp, 1));
163 : }
164 :
165 : /*
166 : * The free inode btree is a conditional feature. The behavior differs slightly
167 : * from that of the traditional inode btree in that the finobt tracks records
168 : * for inode chunks with at least one free inode. A record can be removed from
169 : * the tree during individual inode allocation. Therefore the finobt
170 : * reservation is unconditional for both the inode chunk allocation and
171 : * individual inode allocation (modify) cases.
172 : *
173 : * Behavior aside, the reservation for finobt modification is equivalent to the
174 : * traditional inobt: cover a full finobt shape change plus block allocation.
175 : */
176 : STATIC uint
177 394752 : xfs_calc_finobt_res(
178 : struct xfs_mount *mp)
179 : {
180 394752 : if (!xfs_has_finobt(mp))
181 : return 0;
182 :
183 393920 : return xfs_calc_inobt_res(mp);
184 : }
185 :
186 : /*
187 : * Calculate the reservation required to allocate or free an inode chunk. This
188 : * includes:
189 : *
190 : * the allocation btrees: 2 trees * (max depth - 1) * block size
191 : * the inode chunk: m_ino_geo.ialloc_blks * N
192 : *
193 : * The size N of the inode chunk reservation depends on whether it is for
194 : * allocation or free and which type of create transaction is in use. An inode
195 : * chunk free always invalidates the buffers and only requires reservation for
196 : * headers (N == 0). An inode chunk allocation requires a chunk sized
197 : * reservation on v4 and older superblocks to initialize the chunk. No chunk
198 : * reservation is required for allocation on v5 supers, which use ordered
199 : * buffers to initialize.
200 : */
201 : STATIC uint
202 246720 : xfs_calc_inode_chunk_res(
203 : struct xfs_mount *mp,
204 : bool alloc)
205 : {
206 246720 : uint res, size = 0;
207 :
208 246720 : res = xfs_calc_buf_res(xfs_allocfree_block_count(mp, 1),
209 246720 : XFS_FSB_TO_B(mp, 1));
210 246720 : if (alloc) {
211 : /* icreate tx uses ordered buffers */
212 197376 : if (xfs_has_v3inodes(mp))
213 : return res;
214 : size = XFS_FSB_TO_B(mp, 1);
215 : }
216 :
217 49712 : res += xfs_calc_buf_res(M_IGEO(mp)->ialloc_blks, size);
218 49712 : return res;
219 : }
220 :
221 : /*
222 : * Per-extent log reservation for the btree changes involved in freeing or
223 : * allocating a realtime extent. We have to be able to log as many rtbitmap
224 : * blocks as needed to mark inuse XFS_BMBT_MAX_EXTLEN blocks' worth of realtime
225 : * extents, as well as the realtime summary block (t1). Realtime rmap btree
226 : * operations happen in a second transaction, so factor in a couple of rtrmapbt
227 : * splits (t2).
228 : */
229 : static unsigned int
230 1473 : xfs_rtalloc_block_count(
231 : struct xfs_mount *mp,
232 : unsigned int num_ops)
233 : {
234 1473 : unsigned int rtbmp_blocks;
235 1473 : xfs_rtxlen_t rtxlen;
236 1473 : unsigned int t1, t2 = 0;
237 :
238 1473 : rtxlen = xfs_extlen_to_rtxlen(mp, XFS_MAX_BMBT_EXTLEN);
239 1473 : rtbmp_blocks = xfs_rtbitmap_blockcount(mp, rtxlen);
240 1473 : t1 = (rtbmp_blocks + 1) * num_ops;
241 :
242 1473 : if (xfs_has_rmapbt(mp))
243 1446 : t2 = num_ops * (2 * mp->m_rtrmap_maxlevels - 1);
244 :
245 1473 : return max(t1, t2);
246 : }
247 :
248 : /*
249 : * Various log reservation values.
250 : *
251 : * These are based on the size of the file system block because that is what
252 : * most transactions manipulate. Each adds in an additional 128 bytes per
253 : * item logged to try to account for the overhead of the transaction mechanism.
254 : *
255 : * Note: Most of the reservations underestimate the number of allocation
256 : * groups into which they could free extents in the xfs_defer_finish() call.
257 : * This is because the number in the worst case is quite high and quite
258 : * unusual. In order to fix this we need to change xfs_defer_finish() to free
259 : * extents in only a single AG at a time. This will require changes to the
260 : * EFI code as well, however, so that the EFI for the extents not freed is
261 : * logged again in each transaction. See SGI PV #261917.
262 : *
263 : * Reservation functions here avoid a huge stack in xfs_trans_init due to
264 : * register overflow from temporaries in the calculations.
265 : */
266 :
267 : /*
268 : * Compute the log reservation required to handle the refcount update
269 : * transaction. Refcount updates are always done via deferred log items.
270 : *
271 : * This is calculated as the max of:
272 : * Data device refcount updates (t1):
273 : * the agfs of the ags containing the blocks: nr_ops * sector size
274 : * the refcount btrees: nr_ops * 1 trees * (2 * max depth - 1) * block size
275 : * Realtime refcount updates (t2);
276 : * the rt refcount inode
277 : * the rtrefcount btrees: nr_ops * 1 trees * (2 * max depth - 1) * block size
278 : */
279 : static unsigned int
280 148032 : xfs_calc_refcountbt_reservation(
281 : struct xfs_mount *mp,
282 : unsigned int nr_ops)
283 : {
284 148032 : unsigned int blksz = XFS_FSB_TO_B(mp, 1);
285 148032 : unsigned int t1, t2 = 0;
286 :
287 148032 : if (!xfs_has_reflink(mp))
288 : return 0;
289 :
290 147540 : t1 = xfs_calc_buf_res(nr_ops, mp->m_sb.sb_sectsize) +
291 147540 : xfs_calc_buf_res(xfs_refcountbt_block_count(mp, nr_ops), blksz);
292 :
293 147540 : if (xfs_has_realtime(mp))
294 1446 : t2 = xfs_calc_inode_res(mp, 1) +
295 1446 : xfs_calc_buf_res(xfs_rtrefcountbt_block_count(mp, nr_ops),
296 : blksz);
297 :
298 147540 : return max(t1, t2);
299 : }
300 :
301 : /*
302 : * In a write transaction we can allocate a maximum of 2
303 : * extents. This gives (t1):
304 : * the inode getting the new extents: inode size
305 : * the inode's bmap btree: max depth * block size
306 : * the agfs of the ags from which the extents are allocated: 2 * sector
307 : * the superblock free block counter: sector size
308 : * the allocation btrees: 2 exts * 2 trees * (2 * max depth - 1) * block size
309 : * Or, if we're writing to a realtime file (t2):
310 : * the inode getting the new extents: inode size
311 : * the inode's bmap btree: max depth * block size
312 : * the agfs of the ags from which the extents are allocated: 2 * sector
313 : * the superblock free block counter: sector size
314 : * the realtime bitmap: ((XFS_BMBT_MAX_EXTLEN / rtextsize) / NBBY) bytes
315 : * the realtime summary: 1 block
316 : * the allocation btrees: 2 trees * (2 * max depth - 1) * block size
317 : * And the bmap_finish transaction can free bmap blocks in a join (t3):
318 : * the agfs of the ags containing the blocks: 2 * sector size
319 : * the agfls of the ags containing the blocks: 2 * sector size
320 : * the super block free block counter: sector size
321 : * the allocation btrees: 2 exts * 2 trees * (2 * max depth - 1) * block size
322 : * And any refcount updates that happen in a separate transaction (t4).
323 : */
324 : STATIC uint
325 99766 : xfs_calc_write_reservation(
326 : struct xfs_mount *mp,
327 : bool for_minlogsize)
328 : {
329 99766 : unsigned int t1, t2, t3, t4;
330 99766 : unsigned int blksz = XFS_FSB_TO_B(mp, 1);
331 :
332 99766 : t1 = xfs_calc_inode_res(mp, 1) +
333 99766 : xfs_calc_buf_res(XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK), blksz) +
334 99766 : xfs_calc_buf_res(3, mp->m_sb.sb_sectsize) +
335 99766 : xfs_calc_buf_res(xfs_allocfree_block_count(mp, 2), blksz);
336 :
337 99766 : if (xfs_has_realtime(mp)) {
338 1964 : t2 = xfs_calc_inode_res(mp, 1) +
339 : xfs_calc_buf_res(XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK),
340 : blksz) +
341 982 : xfs_calc_buf_res(3, mp->m_sb.sb_sectsize) +
342 982 : xfs_calc_buf_res(xfs_rtalloc_block_count(mp, 1), blksz) +
343 982 : xfs_calc_buf_res(xfs_allocfree_block_count(mp, 1), blksz);
344 : } else {
345 : t2 = 0;
346 : }
347 :
348 99766 : t3 = xfs_calc_buf_res(5, mp->m_sb.sb_sectsize) +
349 99766 : xfs_calc_buf_res(xfs_allocfree_block_count(mp, 2), blksz);
350 :
351 : /*
352 : * In the early days of reflink, we included enough reservation to log
353 : * two refcountbt splits for each transaction. The codebase runs
354 : * refcountbt updates in separate transactions now, so to compute the
355 : * minimum log size, add the refcountbtree splits back to t1 and t3 and
356 : * do not account them separately as t4. Reflink did not support
357 : * realtime when the reservations were established, so no adjustment to
358 : * t2 is needed.
359 : */
360 99766 : if (for_minlogsize) {
361 1078 : unsigned int adj = 0;
362 :
363 1078 : if (xfs_has_reflink(mp))
364 944 : adj = xfs_calc_buf_res(
365 : xfs_refcountbt_block_count(mp, 2),
366 : blksz);
367 1078 : t1 += adj;
368 1078 : t3 += adj;
369 1078 : return XFS_DQUOT_LOGRES(mp) + max3(t1, t2, t3);
370 : }
371 :
372 98688 : t4 = xfs_calc_refcountbt_reservation(mp, 1);
373 98688 : return XFS_DQUOT_LOGRES(mp) + max(t4, max3(t1, t2, t3));
374 : }
375 :
376 : unsigned int
377 539 : xfs_calc_write_reservation_minlogsize(
378 : struct xfs_mount *mp)
379 : {
380 539 : return xfs_calc_write_reservation(mp, true);
381 : }
382 :
383 : /*
384 : * In truncating a file we free up to two extents at once. We can modify (t1):
385 : * the inode being truncated: inode size
386 : * the inode's bmap btree: (max depth + 1) * block size
387 : * And the bmap_finish transaction can free the blocks and bmap blocks (t2):
388 : * the agf for each of the ags: 4 * sector size
389 : * the agfl for each of the ags: 4 * sector size
390 : * the super block to reflect the freed blocks: sector size
391 : * worst case split in allocation btrees per extent assuming 4 extents:
392 : * 4 exts * 2 trees * (2 * max depth - 1) * block size
393 : * Or, if it's a realtime file (t3):
394 : * the agf for each of the ags: 2 * sector size
395 : * the agfl for each of the ags: 2 * sector size
396 : * the super block to reflect the freed blocks: sector size
397 : * the realtime bitmap:
398 : * 2 exts * ((XFS_BMBT_MAX_EXTLEN / rtextsize) / NBBY) bytes
399 : * the realtime summary: 2 exts * 1 block
400 : * worst case split in allocation btrees per extent assuming 2 extents:
401 : * 2 exts * 2 trees * (2 * max depth - 1) * block size
402 : * And any refcount updates that happen in a separate transaction (t4).
403 : */
404 : STATIC uint
405 49883 : xfs_calc_itruncate_reservation(
406 : struct xfs_mount *mp,
407 : bool for_minlogsize)
408 : {
409 49883 : unsigned int t1, t2, t3, t4;
410 49883 : unsigned int blksz = XFS_FSB_TO_B(mp, 1);
411 :
412 49883 : t1 = xfs_calc_inode_res(mp, 1) +
413 49883 : xfs_calc_buf_res(XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK) + 1, blksz);
414 :
415 49883 : t2 = xfs_calc_buf_res(9, mp->m_sb.sb_sectsize) +
416 49883 : xfs_calc_buf_res(xfs_allocfree_block_count(mp, 4), blksz);
417 :
418 49883 : if (xfs_has_realtime(mp)) {
419 982 : t3 = xfs_calc_buf_res(5, mp->m_sb.sb_sectsize) +
420 491 : xfs_calc_buf_res(xfs_rtalloc_block_count(mp, 2), blksz) +
421 491 : xfs_calc_buf_res(xfs_allocfree_block_count(mp, 2), blksz);
422 : } else {
423 : t3 = 0;
424 : }
425 :
426 : /*
427 : * In the early days of reflink, we included enough reservation to log
428 : * four refcountbt splits in the same transaction as bnobt/cntbt
429 : * updates. The codebase runs refcountbt updates in separate
430 : * transactions now, so to compute the minimum log size, add the
431 : * refcount btree splits back here and do not compute them separately
432 : * as t4. Reflink did not support realtime when the reservations were
433 : * established, so do not adjust t3.
434 : */
435 49883 : if (for_minlogsize) {
436 539 : if (xfs_has_reflink(mp))
437 472 : t2 += xfs_calc_buf_res(
438 : xfs_refcountbt_block_count(mp, 4),
439 : blksz);
440 :
441 539 : return XFS_DQUOT_LOGRES(mp) + max3(t1, t2, t3);
442 : }
443 :
444 49344 : t4 = xfs_calc_refcountbt_reservation(mp, 2);
445 49344 : return XFS_DQUOT_LOGRES(mp) + max(t4, max3(t1, t2, t3));
446 : }
447 :
448 : unsigned int
449 539 : xfs_calc_itruncate_reservation_minlogsize(
450 : struct xfs_mount *mp)
451 : {
452 539 : return xfs_calc_itruncate_reservation(mp, true);
453 : }
454 :
455 : static inline unsigned int xfs_calc_pptr_link_overhead(void)
456 : {
457 : return sizeof(struct xfs_attri_log_format) +
458 : xlog_calc_iovec_len(sizeof(struct xfs_parent_name_rec)) +
459 : xlog_calc_iovec_len(XFS_PARENT_DIRENT_NAME_MAX_SIZE);
460 : }
461 : static inline unsigned int xfs_calc_pptr_unlink_overhead(void)
462 : {
463 : return sizeof(struct xfs_attri_log_format) +
464 : xlog_calc_iovec_len(sizeof(struct xfs_parent_name_rec)) +
465 : xlog_calc_iovec_len(XFS_PARENT_DIRENT_NAME_MAX_SIZE);
466 : }
467 : static inline unsigned int xfs_calc_pptr_replace_overhead(void)
468 : {
469 : return sizeof(struct xfs_attri_log_format) +
470 : xlog_calc_iovec_len(sizeof(struct xfs_parent_name_rec)) +
471 : xlog_calc_iovec_len(XFS_PARENT_DIRENT_NAME_MAX_SIZE) +
472 : xlog_calc_iovec_len(sizeof(struct xfs_parent_name_rec)) +
473 : xlog_calc_iovec_len(XFS_PARENT_DIRENT_NAME_MAX_SIZE);
474 : }
475 :
476 : /*
477 : * In renaming a files we can modify:
478 : * the five inodes involved: 5 * inode size
479 : * the two directory btrees: 2 * (max depth + v2) * dir block size
480 : * the two directory bmap btrees: 2 * max depth * block size
481 : * And the bmap_finish transaction can free dir and bmap blocks (two sets
482 : * of bmap blocks) giving (t2):
483 : * the agf for the ags in which the blocks live: 3 * sector size
484 : * the agfl for the ags in which the blocks live: 3 * sector size
485 : * the superblock for the free block count: sector size
486 : * the allocation btrees: 3 exts * 2 trees * (2 * max depth - 1) * block size
487 : * If parent pointers are enabled (t3), then each transaction in the chain
488 : * must be capable of setting or removing the extended attribute
489 : * containing the parent information. It must also be able to handle
490 : * the three xattr intent items that track the progress of the parent
491 : * pointer update.
492 : */
493 : STATIC uint
494 49344 : xfs_calc_rename_reservation(
495 : struct xfs_mount *mp)
496 : {
497 49344 : unsigned int overhead = XFS_DQUOT_LOGRES(mp);
498 49344 : struct xfs_trans_resv *resp = M_RES(mp);
499 49344 : unsigned int t1, t2, t3 = 0;
500 :
501 49344 : t1 = xfs_calc_inode_res(mp, 5) +
502 49344 : xfs_calc_buf_res(2 * XFS_DIROP_LOG_COUNT(mp),
503 49344 : XFS_FSB_TO_B(mp, 1));
504 :
505 49344 : t2 = xfs_calc_buf_res(7, mp->m_sb.sb_sectsize) +
506 49344 : xfs_calc_buf_res(xfs_allocfree_block_count(mp, 3),
507 : XFS_FSB_TO_B(mp, 1));
508 :
509 49344 : if (xfs_has_parent(mp)) {
510 48126 : unsigned int rename_overhead, exchange_overhead;
511 :
512 48126 : t3 = max(resp->tr_attrsetm.tr_logres,
513 : resp->tr_attrrm.tr_logres);
514 :
515 : /*
516 : * For a standard rename, the three xattr intent log items
517 : * are (1) replacing the pptr for the source file; (2)
518 : * removing the pptr on the dest file; and (3) adding a
519 : * pptr for the whiteout file in the src dir.
520 : *
521 : * For an RENAME_EXCHANGE, there are two xattr intent
522 : * items to replace the pptr for both src and dest
523 : * files. Link counts don't change and there is no
524 : * whiteout.
525 : *
526 : * In the worst case we can end up relogging all log
527 : * intent items to allow the log tail to move ahead, so
528 : * they become overhead added to each transaction in a
529 : * processing chain.
530 : */
531 48126 : rename_overhead = xfs_calc_pptr_replace_overhead() +
532 : xfs_calc_pptr_unlink_overhead() +
533 : xfs_calc_pptr_link_overhead();
534 48126 : exchange_overhead = 2 * xfs_calc_pptr_replace_overhead();
535 :
536 48126 : overhead += max(rename_overhead, exchange_overhead);
537 : }
538 :
539 49344 : return overhead + max3(t1, t2, t3);
540 : }
541 :
542 : static inline unsigned int
543 : xfs_rename_log_count(
544 : struct xfs_mount *mp,
545 : struct xfs_trans_resv *resp)
546 : {
547 : /* One for the rename, one more for freeing blocks */
548 49344 : unsigned int ret = XFS_RENAME_LOG_COUNT;
549 :
550 : /*
551 : * Pre-reserve enough log reservation to handle the transaction
552 : * rolling needed to remove or add one parent pointer.
553 : */
554 49344 : if (xfs_has_parent(mp))
555 48126 : ret += max(resp->tr_attrsetm.tr_logcount,
556 : resp->tr_attrrm.tr_logcount);
557 :
558 49344 : return ret;
559 : }
560 :
561 : /*
562 : * For removing an inode from unlinked list at first, we can modify:
563 : * the agi hash list and counters: sector size
564 : * the on disk inode before ours in the agi hash list: inode cluster size
565 : * the on disk inode in the agi hash list: inode cluster size
566 : */
567 : STATIC uint
568 98688 : xfs_calc_iunlink_remove_reservation(
569 : struct xfs_mount *mp)
570 : {
571 98688 : return xfs_calc_buf_res(1, mp->m_sb.sb_sectsize) +
572 98688 : 2 * M_IGEO(mp)->inode_cluster_size;
573 : }
574 :
575 : static inline unsigned int
576 : xfs_link_log_count(
577 : struct xfs_mount *mp,
578 : struct xfs_trans_resv *resp)
579 : {
580 49344 : unsigned int ret = XFS_LINK_LOG_COUNT;
581 :
582 : /*
583 : * Pre-reserve enough log reservation to handle the transaction
584 : * rolling needed to add one parent pointer.
585 : */
586 49344 : if (xfs_has_parent(mp))
587 48126 : ret += resp->tr_attrsetm.tr_logcount;
588 :
589 49344 : return ret;
590 : }
591 :
592 : /*
593 : * For creating a link to an inode:
594 : * the parent directory inode: inode size
595 : * the linked inode: inode size
596 : * the directory btree could split: (max depth + v2) * dir block size
597 : * the directory bmap btree could join or split: (max depth + v2) * blocksize
598 : * And the bmap_finish transaction can free some bmap blocks giving:
599 : * the agf for the ag in which the blocks live: sector size
600 : * the agfl for the ag in which the blocks live: sector size
601 : * the superblock for the free block count: sector size
602 : * the allocation btrees: 2 trees * (2 * max depth - 1) * block size
603 : */
604 : STATIC uint
605 49344 : xfs_calc_link_reservation(
606 : struct xfs_mount *mp)
607 : {
608 49344 : unsigned int overhead = XFS_DQUOT_LOGRES(mp);
609 49344 : struct xfs_trans_resv *resp = M_RES(mp);
610 49344 : unsigned int t1, t2, t3 = 0;
611 :
612 49344 : overhead += xfs_calc_iunlink_remove_reservation(mp);
613 49344 : t1 = xfs_calc_inode_res(mp, 2) +
614 49344 : xfs_calc_buf_res(XFS_DIROP_LOG_COUNT(mp), XFS_FSB_TO_B(mp, 1));
615 49344 : t2 = xfs_calc_buf_res(3, mp->m_sb.sb_sectsize) +
616 49344 : xfs_calc_buf_res(xfs_allocfree_block_count(mp, 1),
617 : XFS_FSB_TO_B(mp, 1));
618 :
619 49344 : if (xfs_has_parent(mp)) {
620 48126 : t3 = resp->tr_attrsetm.tr_logres;
621 48126 : overhead += xfs_calc_pptr_link_overhead();
622 : }
623 :
624 49344 : return overhead + max3(t1, t2, t3);
625 : }
626 :
627 : /*
628 : * For adding an inode to unlinked list we can modify:
629 : * the agi hash list: sector size
630 : * the on disk inode: inode cluster size
631 : */
632 : STATIC uint
633 98688 : xfs_calc_iunlink_add_reservation(xfs_mount_t *mp)
634 : {
635 98688 : return xfs_calc_buf_res(1, mp->m_sb.sb_sectsize) +
636 98688 : M_IGEO(mp)->inode_cluster_size;
637 : }
638 :
639 : static inline unsigned int
640 : xfs_remove_log_count(
641 : struct xfs_mount *mp,
642 : struct xfs_trans_resv *resp)
643 : {
644 49344 : unsigned int ret = XFS_REMOVE_LOG_COUNT;
645 :
646 : /*
647 : * Pre-reserve enough log reservation to handle the transaction
648 : * rolling needed to add one parent pointer.
649 : */
650 49344 : if (xfs_has_parent(mp))
651 48126 : ret += resp->tr_attrrm.tr_logcount;
652 :
653 49344 : return ret;
654 : }
655 :
656 : /*
657 : * For removing a directory entry we can modify:
658 : * the parent directory inode: inode size
659 : * the removed inode: inode size
660 : * the directory btree could join: (max depth + v2) * dir block size
661 : * the directory bmap btree could join or split: (max depth + v2) * blocksize
662 : * And the bmap_finish transaction can free the dir and bmap blocks giving:
663 : * the agf for the ag in which the blocks live: 2 * sector size
664 : * the agfl for the ag in which the blocks live: 2 * sector size
665 : * the superblock for the free block count: sector size
666 : * the allocation btrees: 2 exts * 2 trees * (2 * max depth - 1) * block size
667 : */
668 : STATIC uint
669 49344 : xfs_calc_remove_reservation(
670 : struct xfs_mount *mp)
671 : {
672 49344 : unsigned int overhead = XFS_DQUOT_LOGRES(mp);
673 49344 : struct xfs_trans_resv *resp = M_RES(mp);
674 49344 : unsigned int t1, t2, t3 = 0;
675 :
676 49344 : overhead += xfs_calc_iunlink_add_reservation(mp);
677 :
678 49344 : t1 = xfs_calc_inode_res(mp, 2) +
679 49344 : xfs_calc_buf_res(XFS_DIROP_LOG_COUNT(mp), XFS_FSB_TO_B(mp, 1));
680 49344 : t2 = xfs_calc_buf_res(4, mp->m_sb.sb_sectsize) +
681 49344 : xfs_calc_buf_res(xfs_allocfree_block_count(mp, 2),
682 : XFS_FSB_TO_B(mp, 1));
683 :
684 49344 : if (xfs_has_parent(mp)) {
685 48126 : t3 = resp->tr_attrrm.tr_logres;
686 48126 : overhead += xfs_calc_pptr_unlink_overhead();
687 : }
688 :
689 49344 : return overhead + max3(t1, t2, t3);
690 : }
691 :
692 : /*
693 : * For create, break it in to the two cases that the transaction
694 : * covers. We start with the modify case - allocation done by modification
695 : * of the state of existing inodes - and the allocation case.
696 : */
697 :
698 : /*
699 : * For create we can modify:
700 : * the parent directory inode: inode size
701 : * the new inode: inode size
702 : * the inode btree entry: block size
703 : * the superblock for the nlink flag: sector size
704 : * the directory btree: (max depth + v2) * dir block size
705 : * the directory inode's bmap btree: (max depth + v2) * block size
706 : * the finobt (record modification and allocation btrees)
707 : */
708 : STATIC uint
709 148032 : xfs_calc_create_resv_modify(
710 : struct xfs_mount *mp)
711 : {
712 148032 : return xfs_calc_inode_res(mp, 2) +
713 148032 : xfs_calc_buf_res(1, mp->m_sb.sb_sectsize) +
714 148032 : (uint)XFS_FSB_TO_B(mp, 1) +
715 148032 : xfs_calc_buf_res(XFS_DIROP_LOG_COUNT(mp), XFS_FSB_TO_B(mp, 1)) +
716 148032 : xfs_calc_finobt_res(mp);
717 : }
718 :
719 : /*
720 : * For icreate we can allocate some inodes giving:
721 : * the agi and agf of the ag getting the new inodes: 2 * sectorsize
722 : * the superblock for the nlink flag: sector size
723 : * the inode chunk (allocation, optional init)
724 : * the inobt (record insertion)
725 : * the finobt (optional, record insertion)
726 : */
727 : STATIC uint
728 197376 : xfs_calc_icreate_resv_alloc(
729 : struct xfs_mount *mp)
730 : {
731 197376 : return xfs_calc_buf_res(2, mp->m_sb.sb_sectsize) +
732 197376 : mp->m_sb.sb_sectsize +
733 197376 : xfs_calc_inode_chunk_res(mp, _ALLOC) +
734 197376 : xfs_calc_inobt_res(mp) +
735 197376 : xfs_calc_finobt_res(mp);
736 : }
737 :
738 : static inline unsigned int
739 : xfs_icreate_log_count(
740 : struct xfs_mount *mp,
741 : struct xfs_trans_resv *resp)
742 : {
743 49344 : unsigned int ret = XFS_CREATE_LOG_COUNT;
744 :
745 : /*
746 : * Pre-reserve enough log reservation to handle the transaction
747 : * rolling needed to add one parent pointer.
748 : */
749 49344 : if (xfs_has_parent(mp))
750 48126 : ret += resp->tr_attrsetm.tr_logcount;
751 :
752 49344 : return ret;
753 : }
754 :
755 : STATIC uint
756 148032 : xfs_calc_icreate_reservation(
757 : struct xfs_mount *mp)
758 : {
759 148032 : struct xfs_trans_resv *resp = M_RES(mp);
760 148032 : unsigned int overhead = XFS_DQUOT_LOGRES(mp);
761 148032 : unsigned int t1, t2, t3 = 0;
762 :
763 148032 : t1 = xfs_calc_icreate_resv_alloc(mp);
764 148032 : t2 = xfs_calc_create_resv_modify(mp);
765 :
766 148032 : if (xfs_has_parent(mp)) {
767 144378 : t3 = resp->tr_attrsetm.tr_logres;
768 144378 : overhead += xfs_calc_pptr_link_overhead();
769 : }
770 :
771 148032 : return overhead + max3(t1, t2, t3);
772 : }
773 :
774 : STATIC uint
775 49344 : xfs_calc_create_tmpfile_reservation(
776 : struct xfs_mount *mp)
777 : {
778 49344 : uint res = XFS_DQUOT_LOGRES(mp);
779 :
780 49344 : res += xfs_calc_icreate_resv_alloc(mp);
781 49344 : return res + xfs_calc_iunlink_add_reservation(mp);
782 : }
783 :
784 : static inline unsigned int
785 : xfs_mkdir_log_count(
786 : struct xfs_mount *mp,
787 : struct xfs_trans_resv *resp)
788 : {
789 49344 : unsigned int ret = XFS_MKDIR_LOG_COUNT;
790 :
791 : /*
792 : * Pre-reserve enough log reservation to handle the transaction
793 : * rolling needed to add one parent pointer.
794 : */
795 49344 : if (xfs_has_parent(mp))
796 48126 : ret += resp->tr_attrsetm.tr_logcount;
797 :
798 49344 : return ret;
799 : }
800 :
801 : /*
802 : * Making a new directory is the same as creating a new file.
803 : */
804 : STATIC uint
805 49344 : xfs_calc_mkdir_reservation(
806 : struct xfs_mount *mp)
807 : {
808 49344 : return xfs_calc_icreate_reservation(mp);
809 : }
810 :
811 : static inline unsigned int
812 : xfs_symlink_log_count(
813 : struct xfs_mount *mp,
814 : struct xfs_trans_resv *resp)
815 : {
816 49344 : unsigned int ret = XFS_SYMLINK_LOG_COUNT;
817 :
818 : /*
819 : * Pre-reserve enough log reservation to handle the transaction
820 : * rolling needed to add one parent pointer.
821 : */
822 49344 : if (xfs_has_parent(mp))
823 48126 : ret += resp->tr_attrsetm.tr_logcount;
824 :
825 49344 : return ret;
826 : }
827 :
828 : /*
829 : * Making a new symplink is the same as creating a new file, but
830 : * with the added blocks for remote symlink data which can be up to 1kB in
831 : * length (XFS_SYMLINK_MAXLEN).
832 : */
833 : STATIC uint
834 49344 : xfs_calc_symlink_reservation(
835 : struct xfs_mount *mp)
836 : {
837 49344 : return xfs_calc_icreate_reservation(mp) +
838 49344 : xfs_calc_buf_res(1, XFS_SYMLINK_MAXLEN);
839 : }
840 :
841 : /*
842 : * In freeing an inode we can modify:
843 : * the inode being freed: inode size
844 : * the super block free inode counter, AGF and AGFL: sector size
845 : * the on disk inode (agi unlinked list removal)
846 : * the inode chunk (invalidated, headers only)
847 : * the inode btree
848 : * the finobt (record insertion, removal or modification)
849 : *
850 : * Note that the inode chunk res. includes an allocfree res. for freeing of the
851 : * inode chunk. This is technically extraneous because the inode chunk free is
852 : * deferred (it occurs after a transaction roll). Include the extra reservation
853 : * anyways since we've had reports of ifree transaction overruns due to too many
854 : * agfl fixups during inode chunk frees.
855 : */
856 : STATIC uint
857 49344 : xfs_calc_ifree_reservation(
858 : struct xfs_mount *mp)
859 : {
860 49344 : return XFS_DQUOT_LOGRES(mp) +
861 49344 : xfs_calc_inode_res(mp, 1) +
862 49344 : xfs_calc_buf_res(3, mp->m_sb.sb_sectsize) +
863 49344 : xfs_calc_iunlink_remove_reservation(mp) +
864 49344 : xfs_calc_inode_chunk_res(mp, _FREE) +
865 49344 : xfs_calc_inobt_res(mp) +
866 49344 : xfs_calc_finobt_res(mp);
867 : }
868 :
869 : /*
870 : * When only changing the inode we log the inode and possibly the superblock
871 : * We also add a bit of slop for the transaction stuff.
872 : */
873 : STATIC uint
874 49344 : xfs_calc_ichange_reservation(
875 : struct xfs_mount *mp)
876 : {
877 49344 : return XFS_DQUOT_LOGRES(mp) +
878 49344 : xfs_calc_inode_res(mp, 1) +
879 49344 : xfs_calc_buf_res(1, mp->m_sb.sb_sectsize);
880 :
881 : }
882 :
883 : /*
884 : * Growing the data section of the filesystem.
885 : * superblock
886 : * agi and agf
887 : * allocation btrees
888 : */
889 : STATIC uint
890 49344 : xfs_calc_growdata_reservation(
891 : struct xfs_mount *mp)
892 : {
893 49344 : return xfs_calc_buf_res(3, mp->m_sb.sb_sectsize) +
894 49344 : xfs_calc_buf_res(xfs_allocfree_block_count(mp, 1),
895 49344 : XFS_FSB_TO_B(mp, 1));
896 : }
897 :
898 : /*
899 : * Growing the rt section of the filesystem.
900 : * In the first set of transactions (ALLOC) we allocate space to the
901 : * bitmap or summary files.
902 : * superblock: sector size
903 : * agf of the ag from which the extent is allocated: sector size
904 : * bmap btree for bitmap/summary inode: max depth * blocksize
905 : * bitmap/summary inode: inode size
906 : * allocation btrees for 1 block alloc: 2 * (2 * maxdepth - 1) * blocksize
907 : */
908 : STATIC uint
909 49344 : xfs_calc_growrtalloc_reservation(
910 : struct xfs_mount *mp)
911 : {
912 49344 : return xfs_calc_buf_res(2, mp->m_sb.sb_sectsize) +
913 49344 : xfs_calc_buf_res(XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK),
914 49344 : XFS_FSB_TO_B(mp, 1)) +
915 49344 : xfs_calc_inode_res(mp, 1) +
916 49344 : xfs_calc_buf_res(xfs_allocfree_block_count(mp, 1),
917 : XFS_FSB_TO_B(mp, 1));
918 : }
919 :
920 : /*
921 : * Growing the rt section of the filesystem.
922 : * In the second set of transactions (ZERO) we zero the new metadata blocks.
923 : * one bitmap/summary block: blocksize
924 : */
925 : STATIC uint
926 49344 : xfs_calc_growrtzero_reservation(
927 : struct xfs_mount *mp)
928 : {
929 49344 : return xfs_calc_buf_res(1, mp->m_sb.sb_blocksize);
930 : }
931 :
932 : /*
933 : * Growing the rt section of the filesystem.
934 : * In the third set of transactions (FREE) we update metadata without
935 : * allocating any new blocks.
936 : * superblock: sector size
937 : * bitmap inode: inode size
938 : * summary inode: inode size
939 : * one bitmap block: blocksize
940 : * summary blocks: new summary size
941 : */
942 : STATIC uint
943 49344 : xfs_calc_growrtfree_reservation(
944 : struct xfs_mount *mp)
945 : {
946 49344 : return xfs_calc_buf_res(1, mp->m_sb.sb_sectsize) +
947 49344 : xfs_calc_inode_res(mp, 2) +
948 49344 : xfs_calc_buf_res(1, mp->m_sb.sb_blocksize) +
949 49344 : xfs_calc_buf_res(1, mp->m_rsumsize);
950 : }
951 :
952 : /*
953 : * Logging the inode modification timestamp on a synchronous write.
954 : * inode
955 : */
956 : STATIC uint
957 49344 : xfs_calc_swrite_reservation(
958 : struct xfs_mount *mp)
959 : {
960 49344 : return xfs_calc_inode_res(mp, 1);
961 : }
962 :
963 : /*
964 : * Logging the inode mode bits when writing a setuid/setgid file
965 : * inode
966 : */
967 : STATIC uint
968 49344 : xfs_calc_writeid_reservation(
969 : struct xfs_mount *mp)
970 : {
971 49344 : return xfs_calc_inode_res(mp, 1);
972 : }
973 :
974 : /*
975 : * Converting the inode from non-attributed to attributed.
976 : * the inode being converted: inode size
977 : * agf block and superblock (for block allocation)
978 : * the new block (directory sized)
979 : * bmap blocks for the new directory block
980 : * allocation btrees
981 : */
982 : STATIC uint
983 49344 : xfs_calc_addafork_reservation(
984 : struct xfs_mount *mp)
985 : {
986 49344 : return XFS_DQUOT_LOGRES(mp) +
987 49344 : xfs_calc_inode_res(mp, 1) +
988 49344 : xfs_calc_buf_res(2, mp->m_sb.sb_sectsize) +
989 49344 : xfs_calc_buf_res(1, mp->m_dir_geo->blksize) +
990 49344 : xfs_calc_buf_res(XFS_DAENTER_BMAP1B(mp, XFS_DATA_FORK) + 1,
991 49344 : XFS_FSB_TO_B(mp, 1)) +
992 49344 : xfs_calc_buf_res(xfs_allocfree_block_count(mp, 1),
993 : XFS_FSB_TO_B(mp, 1));
994 : }
995 :
996 : /*
997 : * Removing the attribute fork of a file
998 : * the inode being truncated: inode size
999 : * the inode's bmap btree: max depth * block size
1000 : * And the bmap_finish transaction can free the blocks and bmap blocks:
1001 : * the agf for each of the ags: 4 * sector size
1002 : * the agfl for each of the ags: 4 * sector size
1003 : * the super block to reflect the freed blocks: sector size
1004 : * worst case split in allocation btrees per extent assuming 4 extents:
1005 : * 4 exts * 2 trees * (2 * max depth - 1) * block size
1006 : */
1007 : STATIC uint
1008 49344 : xfs_calc_attrinval_reservation(
1009 : struct xfs_mount *mp)
1010 : {
1011 49344 : return max((xfs_calc_inode_res(mp, 1) +
1012 : xfs_calc_buf_res(XFS_BM_MAXLEVELS(mp, XFS_ATTR_FORK),
1013 : XFS_FSB_TO_B(mp, 1))),
1014 : (xfs_calc_buf_res(9, mp->m_sb.sb_sectsize) +
1015 : xfs_calc_buf_res(xfs_allocfree_block_count(mp, 4),
1016 : XFS_FSB_TO_B(mp, 1))));
1017 : }
1018 :
1019 : /*
1020 : * Setting an attribute at mount time.
1021 : * the inode getting the attribute
1022 : * the superblock for allocations
1023 : * the agfs extents are allocated from
1024 : * the attribute btree * max depth
1025 : * the inode allocation btree
1026 : * Since attribute transaction space is dependent on the size of the attribute,
1027 : * the calculation is done partially at mount time and partially at runtime(see
1028 : * below).
1029 : */
1030 : STATIC uint
1031 49344 : xfs_calc_attrsetm_reservation(
1032 : struct xfs_mount *mp)
1033 : {
1034 49344 : return XFS_DQUOT_LOGRES(mp) +
1035 49344 : xfs_calc_inode_res(mp, 1) +
1036 49344 : xfs_calc_buf_res(1, mp->m_sb.sb_sectsize) +
1037 49344 : xfs_calc_buf_res(XFS_DA_NODE_MAXDEPTH, XFS_FSB_TO_B(mp, 1));
1038 : }
1039 :
1040 : /*
1041 : * Setting an attribute at runtime, transaction space unit per block.
1042 : * the superblock for allocations: sector size
1043 : * the inode bmap btree could join or split: max depth * block size
1044 : * Since the runtime attribute transaction space is dependent on the total
1045 : * blocks needed for the 1st bmap, here we calculate out the space unit for
1046 : * one block so that the caller could figure out the total space according
1047 : * to the attibute extent length in blocks by:
1048 : * ext * M_RES(mp)->tr_attrsetrt.tr_logres
1049 : */
1050 : STATIC uint
1051 49344 : xfs_calc_attrsetrt_reservation(
1052 : struct xfs_mount *mp)
1053 : {
1054 49344 : return xfs_calc_buf_res(1, mp->m_sb.sb_sectsize) +
1055 49344 : xfs_calc_buf_res(XFS_BM_MAXLEVELS(mp, XFS_ATTR_FORK),
1056 49344 : XFS_FSB_TO_B(mp, 1));
1057 : }
1058 :
1059 : /*
1060 : * Removing an attribute.
1061 : * the inode: inode size
1062 : * the attribute btree could join: max depth * block size
1063 : * the inode bmap btree could join or split: max depth * block size
1064 : * And the bmap_finish transaction can free the attr blocks freed giving:
1065 : * the agf for the ag in which the blocks live: 2 * sector size
1066 : * the agfl for the ag in which the blocks live: 2 * sector size
1067 : * the superblock for the free block count: sector size
1068 : * the allocation btrees: 2 exts * 2 trees * (2 * max depth - 1) * block size
1069 : */
1070 : STATIC uint
1071 49344 : xfs_calc_attrrm_reservation(
1072 : struct xfs_mount *mp)
1073 : {
1074 49344 : return XFS_DQUOT_LOGRES(mp) +
1075 49344 : max((xfs_calc_inode_res(mp, 1) +
1076 : xfs_calc_buf_res(XFS_DA_NODE_MAXDEPTH,
1077 : XFS_FSB_TO_B(mp, 1)) +
1078 : (uint)XFS_FSB_TO_B(mp,
1079 : XFS_BM_MAXLEVELS(mp, XFS_ATTR_FORK)) +
1080 : xfs_calc_buf_res(XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK), 0)),
1081 : (xfs_calc_buf_res(5, mp->m_sb.sb_sectsize) +
1082 : xfs_calc_buf_res(xfs_allocfree_block_count(mp, 2),
1083 : XFS_FSB_TO_B(mp, 1))));
1084 : }
1085 :
1086 : /*
1087 : * Clearing a bad agino number in an agi hash bucket.
1088 : */
1089 : STATIC uint
1090 49344 : xfs_calc_clear_agi_bucket_reservation(
1091 : struct xfs_mount *mp)
1092 : {
1093 49344 : return xfs_calc_buf_res(1, mp->m_sb.sb_sectsize);
1094 : }
1095 :
1096 : /*
1097 : * Adjusting quota limits.
1098 : * the disk quota buffer: sizeof(struct xfs_disk_dquot)
1099 : */
1100 : STATIC uint
1101 49344 : xfs_calc_qm_setqlim_reservation(void)
1102 : {
1103 49344 : return xfs_calc_buf_res(1, sizeof(struct xfs_disk_dquot));
1104 : }
1105 :
1106 : /*
1107 : * Allocating quota on disk if needed.
1108 : * the write transaction log space for quota file extent allocation
1109 : * the unit of quota allocation: one system block size
1110 : */
1111 : STATIC uint
1112 49883 : xfs_calc_qm_dqalloc_reservation(
1113 : struct xfs_mount *mp,
1114 : bool for_minlogsize)
1115 : {
1116 49883 : return xfs_calc_write_reservation(mp, for_minlogsize) +
1117 49883 : xfs_calc_buf_res(1,
1118 49883 : XFS_FSB_TO_B(mp, XFS_DQUOT_CLUSTER_SIZE_FSB) - 1);
1119 : }
1120 :
1121 : unsigned int
1122 539 : xfs_calc_qm_dqalloc_reservation_minlogsize(
1123 : struct xfs_mount *mp)
1124 : {
1125 539 : return xfs_calc_qm_dqalloc_reservation(mp, true);
1126 : }
1127 :
1128 : /*
1129 : * Syncing the incore super block changes to disk.
1130 : * the super block to reflect the changes: sector size
1131 : */
1132 : STATIC uint
1133 49344 : xfs_calc_sb_reservation(
1134 : struct xfs_mount *mp)
1135 : {
1136 49344 : return xfs_calc_buf_res(1, mp->m_sb.sb_sectsize);
1137 : }
1138 :
1139 : /*
1140 : * Metadata inode creation needs enough space to create or mkdir a directory,
1141 : * plus logging the superblock.
1142 : */
1143 : static unsigned int
1144 48028 : xfs_calc_imeta_create_resv(
1145 : struct xfs_mount *mp,
1146 : struct xfs_trans_resv *resp)
1147 : {
1148 48028 : unsigned int ret;
1149 :
1150 48028 : ret = xfs_calc_buf_res(1, mp->m_sb.sb_sectsize);
1151 48028 : if (xfs_has_metadir(mp))
1152 48028 : ret += max(resp->tr_create.tr_logres, resp->tr_mkdir.tr_logres);
1153 : else
1154 0 : ret += resp->tr_create.tr_logres;
1155 48028 : return ret;
1156 : }
1157 :
1158 : /* Metadata inode creation needs enough rounds to create or mkdir a directory */
1159 : static int
1160 : xfs_calc_imeta_create_count(
1161 : struct xfs_mount *mp,
1162 : struct xfs_trans_resv *resp)
1163 : {
1164 48028 : if (xfs_has_metadir(mp))
1165 48028 : return max(resp->tr_create.tr_logcount,
1166 : resp->tr_mkdir.tr_logcount);
1167 0 : return resp->tr_create.tr_logcount;
1168 : }
1169 :
1170 : /*
1171 : * Metadata inode link needs enough space to add a file plus logging the
1172 : * superblock.
1173 : */
1174 : static unsigned int
1175 : xfs_calc_imeta_link_resv(
1176 : struct xfs_mount *mp,
1177 : struct xfs_trans_resv *resp)
1178 : {
1179 48028 : unsigned int ret;
1180 :
1181 48028 : ret = xfs_calc_buf_res(1, mp->m_sb.sb_sectsize);
1182 48028 : ret += resp->tr_link.tr_logres;
1183 48028 : return ret;
1184 : }
1185 :
1186 : /* Metadata inode linking needs enough rounds to remove a file. */
1187 : static int
1188 : xfs_calc_imeta_link_count(
1189 : struct xfs_mount *mp,
1190 : struct xfs_trans_resv *resp)
1191 : {
1192 48028 : return resp->tr_link.tr_logcount;
1193 : }
1194 :
1195 : /*
1196 : * Metadata inode unlink needs enough space to remove a file plus logging the
1197 : * superblock.
1198 : */
1199 : static unsigned int
1200 : xfs_calc_imeta_unlink_resv(
1201 : struct xfs_mount *mp,
1202 : struct xfs_trans_resv *resp)
1203 : {
1204 48028 : unsigned int ret;
1205 :
1206 48028 : ret = xfs_calc_buf_res(1, mp->m_sb.sb_sectsize);
1207 48028 : ret += resp->tr_remove.tr_logres;
1208 48028 : return ret;
1209 : }
1210 :
1211 : /* Metadata inode unlinking needs enough rounds to remove a file. */
1212 : static int
1213 : xfs_calc_imeta_unlink_count(
1214 : struct xfs_mount *mp,
1215 : struct xfs_trans_resv *resp)
1216 : {
1217 48028 : return resp->tr_remove.tr_logcount;
1218 : }
1219 :
1220 : /*
1221 : * Namespace reservations.
1222 : *
1223 : * These get tricky when parent pointers are enabled as we have attribute
1224 : * modifications occurring from within these transactions. Rather than confuse
1225 : * each of these reservation calculations with the conditional attribute
1226 : * reservations, add them here in a clear and concise manner. This requires that
1227 : * the attribute reservations have already been calculated.
1228 : *
1229 : * Note that we only include the static attribute reservation here; the runtime
1230 : * reservation will have to be modified by the size of the attributes being
1231 : * added/removed/modified. See the comments on the attribute reservation
1232 : * calculations for more details.
1233 : */
1234 : STATIC void
1235 49344 : xfs_calc_namespace_reservations(
1236 : struct xfs_mount *mp,
1237 : struct xfs_trans_resv *resp)
1238 : {
1239 49344 : ASSERT(resp->tr_attrsetm.tr_logres > 0);
1240 :
1241 49344 : resp->tr_rename.tr_logres = xfs_calc_rename_reservation(mp);
1242 49344 : resp->tr_rename.tr_logcount = xfs_rename_log_count(mp, resp);
1243 49344 : resp->tr_rename.tr_logflags |= XFS_TRANS_PERM_LOG_RES;
1244 :
1245 49344 : resp->tr_link.tr_logres = xfs_calc_link_reservation(mp);
1246 49344 : resp->tr_link.tr_logcount = xfs_link_log_count(mp, resp);
1247 49344 : resp->tr_link.tr_logflags |= XFS_TRANS_PERM_LOG_RES;
1248 :
1249 49344 : resp->tr_remove.tr_logres = xfs_calc_remove_reservation(mp);
1250 49344 : resp->tr_remove.tr_logcount = xfs_remove_log_count(mp, resp);
1251 49344 : resp->tr_remove.tr_logflags |= XFS_TRANS_PERM_LOG_RES;
1252 :
1253 49344 : resp->tr_symlink.tr_logres = xfs_calc_symlink_reservation(mp);
1254 49344 : resp->tr_symlink.tr_logcount = xfs_symlink_log_count(mp, resp);
1255 49344 : resp->tr_symlink.tr_logflags |= XFS_TRANS_PERM_LOG_RES;
1256 :
1257 49344 : resp->tr_create.tr_logres = xfs_calc_icreate_reservation(mp);
1258 49344 : resp->tr_create.tr_logcount = xfs_icreate_log_count(mp, resp);
1259 49344 : resp->tr_create.tr_logflags |= XFS_TRANS_PERM_LOG_RES;
1260 :
1261 49344 : resp->tr_mkdir.tr_logres = xfs_calc_mkdir_reservation(mp);
1262 49344 : resp->tr_mkdir.tr_logcount = xfs_mkdir_log_count(mp, resp);
1263 49344 : resp->tr_mkdir.tr_logflags |= XFS_TRANS_PERM_LOG_RES;
1264 49344 : }
1265 :
1266 : void
1267 49344 : xfs_trans_resv_calc(
1268 : struct xfs_mount *mp,
1269 : struct xfs_trans_resv *resp)
1270 : {
1271 49344 : int logcount_adj = 0;
1272 :
1273 : /*
1274 : * The following transactions are logged in physical format and
1275 : * require a permanent reservation on space.
1276 : */
1277 49344 : resp->tr_write.tr_logres = xfs_calc_write_reservation(mp, false);
1278 49344 : resp->tr_write.tr_logcount = XFS_WRITE_LOG_COUNT;
1279 49344 : resp->tr_write.tr_logflags |= XFS_TRANS_PERM_LOG_RES;
1280 :
1281 49344 : resp->tr_itruncate.tr_logres = xfs_calc_itruncate_reservation(mp, false);
1282 49344 : resp->tr_itruncate.tr_logcount = XFS_ITRUNCATE_LOG_COUNT;
1283 49344 : resp->tr_itruncate.tr_logflags |= XFS_TRANS_PERM_LOG_RES;
1284 :
1285 49344 : resp->tr_create_tmpfile.tr_logres =
1286 49344 : xfs_calc_create_tmpfile_reservation(mp);
1287 49344 : resp->tr_create_tmpfile.tr_logcount = XFS_CREATE_TMPFILE_LOG_COUNT;
1288 49344 : resp->tr_create_tmpfile.tr_logflags |= XFS_TRANS_PERM_LOG_RES;
1289 :
1290 49344 : resp->tr_ifree.tr_logres = xfs_calc_ifree_reservation(mp);
1291 49344 : resp->tr_ifree.tr_logcount = XFS_INACTIVE_LOG_COUNT;
1292 49344 : resp->tr_ifree.tr_logflags |= XFS_TRANS_PERM_LOG_RES;
1293 :
1294 49344 : resp->tr_addafork.tr_logres = xfs_calc_addafork_reservation(mp);
1295 49344 : resp->tr_addafork.tr_logcount = XFS_ADDAFORK_LOG_COUNT;
1296 49344 : resp->tr_addafork.tr_logflags |= XFS_TRANS_PERM_LOG_RES;
1297 :
1298 49344 : resp->tr_attrinval.tr_logres = xfs_calc_attrinval_reservation(mp);
1299 49344 : resp->tr_attrinval.tr_logcount = XFS_ATTRINVAL_LOG_COUNT;
1300 49344 : resp->tr_attrinval.tr_logflags |= XFS_TRANS_PERM_LOG_RES;
1301 :
1302 49344 : resp->tr_attrsetm.tr_logres = xfs_calc_attrsetm_reservation(mp);
1303 49344 : resp->tr_attrsetm.tr_logcount = XFS_ATTRSET_LOG_COUNT;
1304 49344 : resp->tr_attrsetm.tr_logflags |= XFS_TRANS_PERM_LOG_RES;
1305 :
1306 49344 : resp->tr_attrrm.tr_logres = xfs_calc_attrrm_reservation(mp);
1307 49344 : resp->tr_attrrm.tr_logcount = XFS_ATTRRM_LOG_COUNT;
1308 49344 : resp->tr_attrrm.tr_logflags |= XFS_TRANS_PERM_LOG_RES;
1309 :
1310 49344 : resp->tr_growrtalloc.tr_logres = xfs_calc_growrtalloc_reservation(mp);
1311 49344 : resp->tr_growrtalloc.tr_logcount = XFS_DEFAULT_PERM_LOG_COUNT;
1312 49344 : resp->tr_growrtalloc.tr_logflags |= XFS_TRANS_PERM_LOG_RES;
1313 :
1314 49344 : resp->tr_qm_dqalloc.tr_logres = xfs_calc_qm_dqalloc_reservation(mp,
1315 : false);
1316 49344 : resp->tr_qm_dqalloc.tr_logcount = XFS_WRITE_LOG_COUNT;
1317 49344 : resp->tr_qm_dqalloc.tr_logflags |= XFS_TRANS_PERM_LOG_RES;
1318 :
1319 49344 : xfs_calc_namespace_reservations(mp, resp);
1320 :
1321 : /*
1322 : * The following transactions are logged in logical format with
1323 : * a default log count.
1324 : */
1325 49344 : resp->tr_qm_setqlim.tr_logres = xfs_calc_qm_setqlim_reservation();
1326 49344 : resp->tr_qm_setqlim.tr_logcount = XFS_DEFAULT_LOG_COUNT;
1327 :
1328 49344 : resp->tr_sb.tr_logres = xfs_calc_sb_reservation(mp);
1329 49344 : resp->tr_sb.tr_logcount = XFS_DEFAULT_LOG_COUNT;
1330 :
1331 : /* growdata requires permanent res; it can free space to the last AG */
1332 49344 : resp->tr_growdata.tr_logres = xfs_calc_growdata_reservation(mp);
1333 49344 : resp->tr_growdata.tr_logcount = XFS_DEFAULT_PERM_LOG_COUNT;
1334 49344 : resp->tr_growdata.tr_logflags |= XFS_TRANS_PERM_LOG_RES;
1335 :
1336 : /* The following transaction are logged in logical format */
1337 49344 : resp->tr_ichange.tr_logres = xfs_calc_ichange_reservation(mp);
1338 49344 : resp->tr_fsyncts.tr_logres = xfs_calc_swrite_reservation(mp);
1339 49344 : resp->tr_writeid.tr_logres = xfs_calc_writeid_reservation(mp);
1340 49344 : resp->tr_attrsetrt.tr_logres = xfs_calc_attrsetrt_reservation(mp);
1341 49344 : resp->tr_clearagi.tr_logres = xfs_calc_clear_agi_bucket_reservation(mp);
1342 49344 : resp->tr_growrtzero.tr_logres = xfs_calc_growrtzero_reservation(mp);
1343 49344 : resp->tr_growrtfree.tr_logres = xfs_calc_growrtfree_reservation(mp);
1344 :
1345 : /*
1346 : * Add one logcount for BUI items that appear with rmap or reflink,
1347 : * one logcount for refcount intent items, and one logcount for rmap
1348 : * intent items.
1349 : */
1350 49344 : if (xfs_has_reflink(mp) || xfs_has_rmapbt(mp))
1351 : logcount_adj++;
1352 49344 : if (xfs_has_reflink(mp))
1353 49180 : logcount_adj++;
1354 49344 : if (xfs_has_rmapbt(mp))
1355 49190 : logcount_adj++;
1356 :
1357 49344 : resp->tr_itruncate.tr_logcount += logcount_adj;
1358 49344 : resp->tr_write.tr_logcount += logcount_adj;
1359 49344 : resp->tr_qm_dqalloc.tr_logcount += logcount_adj;
1360 :
1361 : /* metadata inode creation and unlink */
1362 49344 : if (xfs_has_metadir(mp)) {
1363 48028 : resp->tr_imeta_create.tr_logres =
1364 48028 : xfs_calc_imeta_create_resv(mp, resp);
1365 48028 : resp->tr_imeta_create.tr_logcount =
1366 : xfs_calc_imeta_create_count(mp, resp);
1367 48028 : resp->tr_imeta_create.tr_logflags |= XFS_TRANS_PERM_LOG_RES;
1368 :
1369 48028 : resp->tr_imeta_link.tr_logres =
1370 : xfs_calc_imeta_link_resv(mp, resp);
1371 48028 : resp->tr_imeta_link.tr_logcount =
1372 : xfs_calc_imeta_link_count(mp, resp);
1373 48028 : resp->tr_imeta_link.tr_logflags |= XFS_TRANS_PERM_LOG_RES;
1374 :
1375 48028 : resp->tr_imeta_unlink.tr_logres =
1376 : xfs_calc_imeta_unlink_resv(mp, resp);
1377 48028 : resp->tr_imeta_unlink.tr_logcount =
1378 : xfs_calc_imeta_unlink_count(mp, resp);
1379 48028 : resp->tr_imeta_unlink.tr_logflags |= XFS_TRANS_PERM_LOG_RES;
1380 : } else {
1381 1316 : resp->tr_imeta_create = resp->tr_create;
1382 1316 : resp->tr_imeta_link = resp->tr_link;
1383 1316 : resp->tr_imeta_unlink = resp->tr_remove;
1384 : }
1385 49344 : }
|