@@ -196,6 +196,24 @@ xfs_calc_inode_chunk_res(
196
196
return res ;
197
197
}
198
198
199
+ /*
200
+ * Per-extent log reservation for the btree changes involved in freeing or
201
+ * allocating a realtime extent. We have to be able to log as many rtbitmap
202
+ * blocks as needed to mark inuse MAXEXTLEN blocks' worth of realtime extents,
203
+ * as well as the realtime summary block.
204
+ */
205
+ unsigned int
206
+ xfs_rtalloc_log_count (
207
+ struct xfs_mount * mp ,
208
+ unsigned int num_ops )
209
+ {
210
+ unsigned int blksz = XFS_FSB_TO_B (mp , 1 );
211
+ unsigned int rtbmp_bytes ;
212
+
213
+ rtbmp_bytes = (MAXEXTLEN / mp -> m_sb .sb_rextsize ) / NBBY ;
214
+ return (howmany (rtbmp_bytes , blksz ) + 1 ) * num_ops ;
215
+ }
216
+
199
217
/*
200
218
* Various log reservation values.
201
219
*
@@ -218,13 +236,21 @@ xfs_calc_inode_chunk_res(
218
236
219
237
/*
220
238
* In a write transaction we can allocate a maximum of 2
221
- * extents. This gives:
239
+ * extents. This gives (t1) :
222
240
* the inode getting the new extents: inode size
223
241
* the inode's bmap btree: max depth * block size
224
242
* the agfs of the ags from which the extents are allocated: 2 * sector
225
243
* the superblock free block counter: sector size
226
244
* the allocation btrees: 2 exts * 2 trees * (2 * max depth - 1) * block size
227
- * And the bmap_finish transaction can free bmap blocks in a join:
245
+ * Or, if we're writing to a realtime file (t2):
246
+ * the inode getting the new extents: inode size
247
+ * the inode's bmap btree: max depth * block size
248
+ * the agfs of the ags from which the extents are allocated: 2 * sector
249
+ * the superblock free block counter: sector size
250
+ * the realtime bitmap: ((MAXEXTLEN / rtextsize) / NBBY) bytes
251
+ * the realtime summary: 1 block
252
+ * the allocation btrees: 2 trees * (2 * max depth - 1) * block size
253
+ * And the bmap_finish transaction can free bmap blocks in a join (t3):
228
254
* the agfs of the ags containing the blocks: 2 * sector size
229
255
* the agfls of the ags containing the blocks: 2 * sector size
230
256
* the super block free block counter: sector size
@@ -234,40 +260,72 @@ STATIC uint
234
260
xfs_calc_write_reservation (
235
261
struct xfs_mount * mp )
236
262
{
237
- return XFS_DQUOT_LOGRES (mp ) +
238
- max ((xfs_calc_inode_res (mp , 1 ) +
263
+ unsigned int t1 , t2 , t3 ;
264
+ unsigned int blksz = XFS_FSB_TO_B (mp , 1 );
265
+
266
+ t1 = xfs_calc_inode_res (mp , 1 ) +
267
+ xfs_calc_buf_res (XFS_BM_MAXLEVELS (mp , XFS_DATA_FORK ), blksz ) +
268
+ xfs_calc_buf_res (3 , mp -> m_sb .sb_sectsize ) +
269
+ xfs_calc_buf_res (xfs_allocfree_log_count (mp , 2 ), blksz );
270
+
271
+ if (xfs_sb_version_hasrealtime (& mp -> m_sb )) {
272
+ t2 = xfs_calc_inode_res (mp , 1 ) +
239
273
xfs_calc_buf_res (XFS_BM_MAXLEVELS (mp , XFS_DATA_FORK ),
240
- XFS_FSB_TO_B ( mp , 1 ) ) +
274
+ blksz ) +
241
275
xfs_calc_buf_res (3 , mp -> m_sb .sb_sectsize ) +
242
- xfs_calc_buf_res (xfs_allocfree_log_count (mp , 2 ),
243
- XFS_FSB_TO_B (mp , 1 ))),
244
- (xfs_calc_buf_res (5 , mp -> m_sb .sb_sectsize ) +
245
- xfs_calc_buf_res (xfs_allocfree_log_count (mp , 2 ),
246
- XFS_FSB_TO_B (mp , 1 ))));
276
+ xfs_calc_buf_res (xfs_rtalloc_log_count (mp , 1 ), blksz ) +
277
+ xfs_calc_buf_res (xfs_allocfree_log_count (mp , 1 ), blksz );
278
+ } else {
279
+ t2 = 0 ;
280
+ }
281
+
282
+ t3 = xfs_calc_buf_res (5 , mp -> m_sb .sb_sectsize ) +
283
+ xfs_calc_buf_res (xfs_allocfree_log_count (mp , 2 ), blksz );
284
+
285
+ return XFS_DQUOT_LOGRES (mp ) + max3 (t1 , t2 , t3 );
247
286
}
248
287
249
288
/*
250
- * In truncating a file we free up to two extents at once. We can modify:
289
+ * In truncating a file we free up to two extents at once. We can modify (t1) :
251
290
* the inode being truncated: inode size
252
291
* the inode's bmap btree: (max depth + 1) * block size
253
- * And the bmap_finish transaction can free the blocks and bmap blocks:
292
+ * And the bmap_finish transaction can free the blocks and bmap blocks (t2) :
254
293
* the agf for each of the ags: 4 * sector size
255
294
* the agfl for each of the ags: 4 * sector size
256
295
* the super block to reflect the freed blocks: sector size
257
296
* worst case split in allocation btrees per extent assuming 4 extents:
258
297
* 4 exts * 2 trees * (2 * max depth - 1) * block size
298
+ * Or, if it's a realtime file (t3):
299
+ * the agf for each of the ags: 2 * sector size
300
+ * the agfl for each of the ags: 2 * sector size
301
+ * the super block to reflect the freed blocks: sector size
302
+ * the realtime bitmap: 2 exts * ((MAXEXTLEN / rtextsize) / NBBY) bytes
303
+ * the realtime summary: 2 exts * 1 block
304
+ * worst case split in allocation btrees per extent assuming 2 extents:
305
+ * 2 exts * 2 trees * (2 * max depth - 1) * block size
259
306
*/
260
307
STATIC uint
261
308
xfs_calc_itruncate_reservation (
262
309
struct xfs_mount * mp )
263
310
{
264
- return XFS_DQUOT_LOGRES (mp ) +
265
- max ((xfs_calc_inode_res (mp , 1 ) +
266
- xfs_calc_buf_res (XFS_BM_MAXLEVELS (mp , XFS_DATA_FORK ) + 1 ,
267
- XFS_FSB_TO_B (mp , 1 ))),
268
- (xfs_calc_buf_res (9 , mp -> m_sb .sb_sectsize ) +
269
- xfs_calc_buf_res (xfs_allocfree_log_count (mp , 4 ),
270
- XFS_FSB_TO_B (mp , 1 ))));
311
+ unsigned int t1 , t2 , t3 ;
312
+ unsigned int blksz = XFS_FSB_TO_B (mp , 1 );
313
+
314
+ t1 = xfs_calc_inode_res (mp , 1 ) +
315
+ xfs_calc_buf_res (XFS_BM_MAXLEVELS (mp , XFS_DATA_FORK ) + 1 , blksz );
316
+
317
+ t2 = xfs_calc_buf_res (9 , mp -> m_sb .sb_sectsize ) +
318
+ xfs_calc_buf_res (xfs_allocfree_log_count (mp , 4 ), blksz );
319
+
320
+ if (xfs_sb_version_hasrealtime (& mp -> m_sb )) {
321
+ t3 = xfs_calc_buf_res (5 , mp -> m_sb .sb_sectsize ) +
322
+ xfs_calc_buf_res (xfs_rtalloc_log_count (mp , 2 ), blksz ) +
323
+ xfs_calc_buf_res (xfs_allocfree_log_count (mp , 2 ), blksz );
324
+ } else {
325
+ t3 = 0 ;
326
+ }
327
+
328
+ return XFS_DQUOT_LOGRES (mp ) + max3 (t1 , t2 , t3 );
271
329
}
272
330
273
331
/*
0 commit comments