hc
2024-05-14 bedbef8ad3e75a304af6361af235302bcc61d06b
kernel/fs/xfs/xfs_extfree_item.c
....@@ -9,25 +9,33 @@
99 #include "xfs_log_format.h"
1010 #include "xfs_trans_resv.h"
1111 #include "xfs_bit.h"
12
+#include "xfs_shared.h"
1213 #include "xfs_mount.h"
14
+#include "xfs_defer.h"
1315 #include "xfs_trans.h"
1416 #include "xfs_trans_priv.h"
15
-#include "xfs_buf_item.h"
1617 #include "xfs_extfree_item.h"
1718 #include "xfs_log.h"
1819 #include "xfs_btree.h"
1920 #include "xfs_rmap.h"
20
-
21
+#include "xfs_alloc.h"
22
+#include "xfs_bmap.h"
23
+#include "xfs_trace.h"
24
+#include "xfs_error.h"
25
+#include "xfs_log_priv.h"
26
+#include "xfs_log_recover.h"
2127
2228 kmem_zone_t *xfs_efi_zone;
2329 kmem_zone_t *xfs_efd_zone;
30
+
31
+static const struct xfs_item_ops xfs_efi_item_ops;
2432
2533 static inline struct xfs_efi_log_item *EFI_ITEM(struct xfs_log_item *lip)
2634 {
2735 return container_of(lip, struct xfs_efi_log_item, efi_item);
2836 }
2937
30
-void
38
+STATIC void
3139 xfs_efi_item_free(
3240 struct xfs_efi_log_item *efip)
3341 {
....@@ -35,7 +43,7 @@
3543 if (efip->efi_format.efi_nextents > XFS_EFI_MAX_FAST_EXTENTS)
3644 kmem_free(efip);
3745 else
38
- kmem_zone_free(xfs_efi_zone, efip);
46
+ kmem_cache_free(xfs_efi_zone, efip);
3947 }
4048
4149 /*
....@@ -45,13 +53,13 @@
4553 * committed vs unpin operations in bulk insert operations. Hence the reference
4654 * count to ensure only the last caller frees the EFI.
4755 */
48
-void
56
+STATIC void
4957 xfs_efi_release(
5058 struct xfs_efi_log_item *efip)
5159 {
5260 ASSERT(atomic_read(&efip->efi_refcount) > 0);
5361 if (atomic_dec_and_test(&efip->efi_refcount)) {
54
- xfs_trans_ail_remove(&efip->efi_item, SHUTDOWN_LOG_IO_ERROR);
62
+ xfs_trans_ail_delete(&efip->efi_item, SHUTDOWN_LOG_IO_ERROR);
5563 xfs_efi_item_free(efip);
5664 }
5765 }
....@@ -107,15 +115,6 @@
107115
108116
109117 /*
110
- * Pinning has no meaning for an efi item, so just return.
111
- */
112
-STATIC void
113
-xfs_efi_item_pin(
114
- struct xfs_log_item *lip)
115
-{
116
-}
117
-
118
-/*
119118 * The unpin operation is the last place an EFI is manipulated in the log. It is
120119 * either inserted in the AIL or aborted in the event of a log I/O error. In
121120 * either case, the EFI transaction has been successfully committed to make it
....@@ -133,78 +132,21 @@
133132 }
134133
135134 /*
136
- * Efi items have no locking or pushing. However, since EFIs are pulled from
137
- * the AIL when their corresponding EFDs are committed to disk, their situation
138
- * is very similar to being pinned. Return XFS_ITEM_PINNED so that the caller
139
- * will eventually flush the log. This should help in getting the EFI out of
140
- * the AIL.
141
- */
142
-STATIC uint
143
-xfs_efi_item_push(
144
- struct xfs_log_item *lip,
145
- struct list_head *buffer_list)
146
-{
147
- return XFS_ITEM_PINNED;
148
-}
149
-
150
-/*
151135 * The EFI has been either committed or aborted if the transaction has been
152136 * cancelled. If the transaction was cancelled, an EFD isn't going to be
153137 * constructed and thus we free the EFI here directly.
154138 */
155139 STATIC void
156
-xfs_efi_item_unlock(
140
+xfs_efi_item_release(
157141 struct xfs_log_item *lip)
158142 {
159
- if (test_bit(XFS_LI_ABORTED, &lip->li_flags))
160
- xfs_efi_release(EFI_ITEM(lip));
143
+ xfs_efi_release(EFI_ITEM(lip));
161144 }
162
-
163
-/*
164
- * The EFI is logged only once and cannot be moved in the log, so simply return
165
- * the lsn at which it's been logged.
166
- */
167
-STATIC xfs_lsn_t
168
-xfs_efi_item_committed(
169
- struct xfs_log_item *lip,
170
- xfs_lsn_t lsn)
171
-{
172
- return lsn;
173
-}
174
-
175
-/*
176
- * The EFI dependency tracking op doesn't do squat. It can't because
177
- * it doesn't know where the free extent is coming from. The dependency
178
- * tracking has to be handled by the "enclosing" metadata object. For
179
- * example, for inodes, the inode is locked throughout the extent freeing
180
- * so the dependency should be recorded there.
181
- */
182
-STATIC void
183
-xfs_efi_item_committing(
184
- struct xfs_log_item *lip,
185
- xfs_lsn_t lsn)
186
-{
187
-}
188
-
189
-/*
190
- * This is the ops vector shared by all efi log items.
191
- */
192
-static const struct xfs_item_ops xfs_efi_item_ops = {
193
- .iop_size = xfs_efi_item_size,
194
- .iop_format = xfs_efi_item_format,
195
- .iop_pin = xfs_efi_item_pin,
196
- .iop_unpin = xfs_efi_item_unpin,
197
- .iop_unlock = xfs_efi_item_unlock,
198
- .iop_committed = xfs_efi_item_committed,
199
- .iop_push = xfs_efi_item_push,
200
- .iop_committing = xfs_efi_item_committing
201
-};
202
-
203145
204146 /*
205147 * Allocate and initialize an efi item with the given number of extents.
206148 */
207
-struct xfs_efi_log_item *
149
+STATIC struct xfs_efi_log_item *
208150 xfs_efi_init(
209151 struct xfs_mount *mp,
210152 uint nextents)
....@@ -215,11 +157,12 @@
215157
216158 ASSERT(nextents > 0);
217159 if (nextents > XFS_EFI_MAX_FAST_EXTENTS) {
218
- size = (uint)(sizeof(xfs_efi_log_item_t) +
160
+ size = (uint)(sizeof(struct xfs_efi_log_item) +
219161 ((nextents - 1) * sizeof(xfs_extent_t)));
220
- efip = kmem_zalloc(size, KM_SLEEP);
162
+ efip = kmem_zalloc(size, 0);
221163 } else {
222
- efip = kmem_zone_zalloc(xfs_efi_zone, KM_SLEEP);
164
+ efip = kmem_cache_zalloc(xfs_efi_zone,
165
+ GFP_KERNEL | __GFP_NOFAIL);
223166 }
224167
225168 xfs_log_item_init(mp, &efip->efi_item, XFS_LI_EFI, &xfs_efi_item_ops);
....@@ -238,7 +181,7 @@
238181 * one of which will be the native format for this kernel.
239182 * It will handle the conversion of formats if necessary.
240183 */
241
-int
184
+STATIC int
242185 xfs_efi_copy_format(xfs_log_iovec_t *buf, xfs_efi_log_format_t *dst_efi_fmt)
243186 {
244187 xfs_efi_log_format_t *src_efi_fmt = buf->i_addr;
....@@ -282,6 +225,7 @@
282225 }
283226 return 0;
284227 }
228
+ XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_LOW, NULL);
285229 return -EFSCORRUPTED;
286230 }
287231
....@@ -297,7 +241,7 @@
297241 if (efdp->efd_format.efd_nextents > XFS_EFD_MAX_FAST_EXTENTS)
298242 kmem_free(efdp);
299243 else
300
- kmem_zone_free(xfs_efd_zone, efdp);
244
+ kmem_cache_free(xfs_efd_zone, efdp);
301245 }
302246
303247 /*
....@@ -349,154 +293,308 @@
349293 }
350294
351295 /*
352
- * Pinning has no meaning for an efd item, so just return.
353
- */
354
-STATIC void
355
-xfs_efd_item_pin(
356
- struct xfs_log_item *lip)
357
-{
358
-}
359
-
360
-/*
361
- * Since pinning has no meaning for an efd item, unpinning does
362
- * not either.
363
- */
364
-STATIC void
365
-xfs_efd_item_unpin(
366
- struct xfs_log_item *lip,
367
- int remove)
368
-{
369
-}
370
-
371
-/*
372
- * There isn't much you can do to push on an efd item. It is simply stuck
373
- * waiting for the log to be flushed to disk.
374
- */
375
-STATIC uint
376
-xfs_efd_item_push(
377
- struct xfs_log_item *lip,
378
- struct list_head *buffer_list)
379
-{
380
- return XFS_ITEM_PINNED;
381
-}
382
-
383
-/*
384296 * The EFD is either committed or aborted if the transaction is cancelled. If
385297 * the transaction is cancelled, drop our reference to the EFI and free the EFD.
386298 */
387299 STATIC void
388
-xfs_efd_item_unlock(
300
+xfs_efd_item_release(
389301 struct xfs_log_item *lip)
390302 {
391303 struct xfs_efd_log_item *efdp = EFD_ITEM(lip);
392304
393
- if (test_bit(XFS_LI_ABORTED, &lip->li_flags)) {
394
- xfs_efi_release(efdp->efd_efip);
395
- xfs_efd_item_free(efdp);
396
- }
397
-}
398
-
399
-/*
400
- * When the efd item is committed to disk, all we need to do is delete our
401
- * reference to our partner efi item and then free ourselves. Since we're
402
- * freeing ourselves we must return -1 to keep the transaction code from further
403
- * referencing this item.
404
- */
405
-STATIC xfs_lsn_t
406
-xfs_efd_item_committed(
407
- struct xfs_log_item *lip,
408
- xfs_lsn_t lsn)
409
-{
410
- struct xfs_efd_log_item *efdp = EFD_ITEM(lip);
411
-
412
- /*
413
- * Drop the EFI reference regardless of whether the EFD has been
414
- * aborted. Once the EFD transaction is constructed, it is the sole
415
- * responsibility of the EFD to release the EFI (even if the EFI is
416
- * aborted due to log I/O error).
417
- */
418305 xfs_efi_release(efdp->efd_efip);
419306 xfs_efd_item_free(efdp);
420
-
421
- return (xfs_lsn_t)-1;
422307 }
423308
424
-/*
425
- * The EFD dependency tracking op doesn't do squat. It can't because
426
- * it doesn't know where the free extent is coming from. The dependency
427
- * tracking has to be handled by the "enclosing" metadata object. For
428
- * example, for inodes, the inode is locked throughout the extent freeing
429
- * so the dependency should be recorded there.
430
- */
431
-STATIC void
432
-xfs_efd_item_committing(
433
- struct xfs_log_item *lip,
434
- xfs_lsn_t lsn)
435
-{
436
-}
437
-
438
-/*
439
- * This is the ops vector shared by all efd log items.
440
- */
441309 static const struct xfs_item_ops xfs_efd_item_ops = {
310
+ .flags = XFS_ITEM_RELEASE_WHEN_COMMITTED,
442311 .iop_size = xfs_efd_item_size,
443312 .iop_format = xfs_efd_item_format,
444
- .iop_pin = xfs_efd_item_pin,
445
- .iop_unpin = xfs_efd_item_unpin,
446
- .iop_unlock = xfs_efd_item_unlock,
447
- .iop_committed = xfs_efd_item_committed,
448
- .iop_push = xfs_efd_item_push,
449
- .iop_committing = xfs_efd_item_committing
313
+ .iop_release = xfs_efd_item_release,
450314 };
451315
452316 /*
453
- * Allocate and initialize an efd item with the given number of extents.
317
+ * Allocate an "extent free done" log item that will hold nextents worth of
318
+ * extents. The caller must use all nextents extents, because we are not
319
+ * flexible about this at all.
454320 */
455
-struct xfs_efd_log_item *
456
-xfs_efd_init(
457
- struct xfs_mount *mp,
458
- struct xfs_efi_log_item *efip,
459
- uint nextents)
460
-
321
+static struct xfs_efd_log_item *
322
+xfs_trans_get_efd(
323
+ struct xfs_trans *tp,
324
+ struct xfs_efi_log_item *efip,
325
+ unsigned int nextents)
461326 {
462
- struct xfs_efd_log_item *efdp;
463
- uint size;
327
+ struct xfs_efd_log_item *efdp;
464328
465329 ASSERT(nextents > 0);
330
+
466331 if (nextents > XFS_EFD_MAX_FAST_EXTENTS) {
467
- size = (uint)(sizeof(xfs_efd_log_item_t) +
468
- ((nextents - 1) * sizeof(xfs_extent_t)));
469
- efdp = kmem_zalloc(size, KM_SLEEP);
332
+ efdp = kmem_zalloc(sizeof(struct xfs_efd_log_item) +
333
+ (nextents - 1) * sizeof(struct xfs_extent),
334
+ 0);
470335 } else {
471
- efdp = kmem_zone_zalloc(xfs_efd_zone, KM_SLEEP);
336
+ efdp = kmem_cache_zalloc(xfs_efd_zone,
337
+ GFP_KERNEL | __GFP_NOFAIL);
472338 }
473339
474
- xfs_log_item_init(mp, &efdp->efd_item, XFS_LI_EFD, &xfs_efd_item_ops);
340
+ xfs_log_item_init(tp->t_mountp, &efdp->efd_item, XFS_LI_EFD,
341
+ &xfs_efd_item_ops);
475342 efdp->efd_efip = efip;
476343 efdp->efd_format.efd_nextents = nextents;
477344 efdp->efd_format.efd_efi_id = efip->efi_format.efi_id;
478345
346
+ xfs_trans_add_item(tp, &efdp->efd_item);
479347 return efdp;
480348 }
349
+
350
+/*
351
+ * Free an extent and log it to the EFD. Note that the transaction is marked
352
+ * dirty regardless of whether the extent free succeeds or fails to support the
353
+ * EFI/EFD lifecycle rules.
354
+ */
355
+static int
356
+xfs_trans_free_extent(
357
+ struct xfs_trans *tp,
358
+ struct xfs_efd_log_item *efdp,
359
+ xfs_fsblock_t start_block,
360
+ xfs_extlen_t ext_len,
361
+ const struct xfs_owner_info *oinfo,
362
+ bool skip_discard)
363
+{
364
+ struct xfs_mount *mp = tp->t_mountp;
365
+ struct xfs_extent *extp;
366
+ uint next_extent;
367
+ xfs_agnumber_t agno = XFS_FSB_TO_AGNO(mp, start_block);
368
+ xfs_agblock_t agbno = XFS_FSB_TO_AGBNO(mp,
369
+ start_block);
370
+ int error;
371
+
372
+ trace_xfs_bmap_free_deferred(tp->t_mountp, agno, 0, agbno, ext_len);
373
+
374
+ error = __xfs_free_extent(tp, start_block, ext_len,
375
+ oinfo, XFS_AG_RESV_NONE, skip_discard);
376
+ /*
377
+ * Mark the transaction dirty, even on error. This ensures the
378
+ * transaction is aborted, which:
379
+ *
380
+ * 1.) releases the EFI and frees the EFD
381
+ * 2.) shuts down the filesystem
382
+ */
383
+ tp->t_flags |= XFS_TRANS_DIRTY;
384
+ set_bit(XFS_LI_DIRTY, &efdp->efd_item.li_flags);
385
+
386
+ next_extent = efdp->efd_next_extent;
387
+ ASSERT(next_extent < efdp->efd_format.efd_nextents);
388
+ extp = &(efdp->efd_format.efd_extents[next_extent]);
389
+ extp->ext_start = start_block;
390
+ extp->ext_len = ext_len;
391
+ efdp->efd_next_extent++;
392
+
393
+ return error;
394
+}
395
+
396
+/* Sort bmap items by AG. */
397
+static int
398
+xfs_extent_free_diff_items(
399
+ void *priv,
400
+ struct list_head *a,
401
+ struct list_head *b)
402
+{
403
+ struct xfs_mount *mp = priv;
404
+ struct xfs_extent_free_item *ra;
405
+ struct xfs_extent_free_item *rb;
406
+
407
+ ra = container_of(a, struct xfs_extent_free_item, xefi_list);
408
+ rb = container_of(b, struct xfs_extent_free_item, xefi_list);
409
+ return XFS_FSB_TO_AGNO(mp, ra->xefi_startblock) -
410
+ XFS_FSB_TO_AGNO(mp, rb->xefi_startblock);
411
+}
412
+
413
+/* Log a free extent to the intent item. */
414
+STATIC void
415
+xfs_extent_free_log_item(
416
+ struct xfs_trans *tp,
417
+ struct xfs_efi_log_item *efip,
418
+ struct xfs_extent_free_item *free)
419
+{
420
+ uint next_extent;
421
+ struct xfs_extent *extp;
422
+
423
+ tp->t_flags |= XFS_TRANS_DIRTY;
424
+ set_bit(XFS_LI_DIRTY, &efip->efi_item.li_flags);
425
+
426
+ /*
427
+ * atomic_inc_return gives us the value after the increment;
428
+ * we want to use it as an array index so we need to subtract 1 from
429
+ * it.
430
+ */
431
+ next_extent = atomic_inc_return(&efip->efi_next_extent) - 1;
432
+ ASSERT(next_extent < efip->efi_format.efi_nextents);
433
+ extp = &efip->efi_format.efi_extents[next_extent];
434
+ extp->ext_start = free->xefi_startblock;
435
+ extp->ext_len = free->xefi_blockcount;
436
+}
437
+
438
+static struct xfs_log_item *
439
+xfs_extent_free_create_intent(
440
+ struct xfs_trans *tp,
441
+ struct list_head *items,
442
+ unsigned int count,
443
+ bool sort)
444
+{
445
+ struct xfs_mount *mp = tp->t_mountp;
446
+ struct xfs_efi_log_item *efip = xfs_efi_init(mp, count);
447
+ struct xfs_extent_free_item *free;
448
+
449
+ ASSERT(count > 0);
450
+
451
+ xfs_trans_add_item(tp, &efip->efi_item);
452
+ if (sort)
453
+ list_sort(mp, items, xfs_extent_free_diff_items);
454
+ list_for_each_entry(free, items, xefi_list)
455
+ xfs_extent_free_log_item(tp, efip, free);
456
+ return &efip->efi_item;
457
+}
458
+
459
+/* Get an EFD so we can process all the free extents. */
460
+static struct xfs_log_item *
461
+xfs_extent_free_create_done(
462
+ struct xfs_trans *tp,
463
+ struct xfs_log_item *intent,
464
+ unsigned int count)
465
+{
466
+ return &xfs_trans_get_efd(tp, EFI_ITEM(intent), count)->efd_item;
467
+}
468
+
469
+/* Process a free extent. */
470
+STATIC int
471
+xfs_extent_free_finish_item(
472
+ struct xfs_trans *tp,
473
+ struct xfs_log_item *done,
474
+ struct list_head *item,
475
+ struct xfs_btree_cur **state)
476
+{
477
+ struct xfs_extent_free_item *free;
478
+ int error;
479
+
480
+ free = container_of(item, struct xfs_extent_free_item, xefi_list);
481
+ error = xfs_trans_free_extent(tp, EFD_ITEM(done),
482
+ free->xefi_startblock,
483
+ free->xefi_blockcount,
484
+ &free->xefi_oinfo, free->xefi_skip_discard);
485
+ kmem_cache_free(xfs_bmap_free_item_zone, free);
486
+ return error;
487
+}
488
+
489
+/* Abort all pending EFIs. */
490
+STATIC void
491
+xfs_extent_free_abort_intent(
492
+ struct xfs_log_item *intent)
493
+{
494
+ xfs_efi_release(EFI_ITEM(intent));
495
+}
496
+
497
+/* Cancel a free extent. */
498
+STATIC void
499
+xfs_extent_free_cancel_item(
500
+ struct list_head *item)
501
+{
502
+ struct xfs_extent_free_item *free;
503
+
504
+ free = container_of(item, struct xfs_extent_free_item, xefi_list);
505
+ kmem_cache_free(xfs_bmap_free_item_zone, free);
506
+}
507
+
508
+const struct xfs_defer_op_type xfs_extent_free_defer_type = {
509
+ .max_items = XFS_EFI_MAX_FAST_EXTENTS,
510
+ .create_intent = xfs_extent_free_create_intent,
511
+ .abort_intent = xfs_extent_free_abort_intent,
512
+ .create_done = xfs_extent_free_create_done,
513
+ .finish_item = xfs_extent_free_finish_item,
514
+ .cancel_item = xfs_extent_free_cancel_item,
515
+};
516
+
517
+/*
518
+ * AGFL blocks are accounted differently in the reserve pools and are not
519
+ * inserted into the busy extent list.
520
+ */
521
+STATIC int
522
+xfs_agfl_free_finish_item(
523
+ struct xfs_trans *tp,
524
+ struct xfs_log_item *done,
525
+ struct list_head *item,
526
+ struct xfs_btree_cur **state)
527
+{
528
+ struct xfs_mount *mp = tp->t_mountp;
529
+ struct xfs_efd_log_item *efdp = EFD_ITEM(done);
530
+ struct xfs_extent_free_item *free;
531
+ struct xfs_extent *extp;
532
+ struct xfs_buf *agbp;
533
+ int error;
534
+ xfs_agnumber_t agno;
535
+ xfs_agblock_t agbno;
536
+ uint next_extent;
537
+
538
+ free = container_of(item, struct xfs_extent_free_item, xefi_list);
539
+ ASSERT(free->xefi_blockcount == 1);
540
+ agno = XFS_FSB_TO_AGNO(mp, free->xefi_startblock);
541
+ agbno = XFS_FSB_TO_AGBNO(mp, free->xefi_startblock);
542
+
543
+ trace_xfs_agfl_free_deferred(mp, agno, 0, agbno, free->xefi_blockcount);
544
+
545
+ error = xfs_alloc_read_agf(mp, tp, agno, 0, &agbp);
546
+ if (!error)
547
+ error = xfs_free_agfl_block(tp, agno, agbno, agbp,
548
+ &free->xefi_oinfo);
549
+
550
+ /*
551
+ * Mark the transaction dirty, even on error. This ensures the
552
+ * transaction is aborted, which:
553
+ *
554
+ * 1.) releases the EFI and frees the EFD
555
+ * 2.) shuts down the filesystem
556
+ */
557
+ tp->t_flags |= XFS_TRANS_DIRTY;
558
+ set_bit(XFS_LI_DIRTY, &efdp->efd_item.li_flags);
559
+
560
+ next_extent = efdp->efd_next_extent;
561
+ ASSERT(next_extent < efdp->efd_format.efd_nextents);
562
+ extp = &(efdp->efd_format.efd_extents[next_extent]);
563
+ extp->ext_start = free->xefi_startblock;
564
+ extp->ext_len = free->xefi_blockcount;
565
+ efdp->efd_next_extent++;
566
+
567
+ kmem_cache_free(xfs_bmap_free_item_zone, free);
568
+ return error;
569
+}
570
+
571
+/* sub-type with special handling for AGFL deferred frees */
572
+const struct xfs_defer_op_type xfs_agfl_free_defer_type = {
573
+ .max_items = XFS_EFI_MAX_FAST_EXTENTS,
574
+ .create_intent = xfs_extent_free_create_intent,
575
+ .abort_intent = xfs_extent_free_abort_intent,
576
+ .create_done = xfs_extent_free_create_done,
577
+ .finish_item = xfs_agfl_free_finish_item,
578
+ .cancel_item = xfs_extent_free_cancel_item,
579
+};
481580
482581 /*
483582 * Process an extent free intent item that was recovered from
484583 * the log. We need to free the extents that it describes.
485584 */
486
-int
487
-xfs_efi_recover(
488
- struct xfs_mount *mp,
489
- struct xfs_efi_log_item *efip)
585
+STATIC int
586
+xfs_efi_item_recover(
587
+ struct xfs_log_item *lip,
588
+ struct list_head *capture_list)
490589 {
491
- struct xfs_efd_log_item *efdp;
492
- struct xfs_trans *tp;
493
- int i;
494
- int error = 0;
495
- xfs_extent_t *extp;
496
- xfs_fsblock_t startblock_fsb;
497
- struct xfs_owner_info oinfo;
498
-
499
- ASSERT(!test_bit(XFS_EFI_RECOVERED, &efip->efi_flags));
590
+ struct xfs_efi_log_item *efip = EFI_ITEM(lip);
591
+ struct xfs_mount *mp = lip->li_mountp;
592
+ struct xfs_efd_log_item *efdp;
593
+ struct xfs_trans *tp;
594
+ struct xfs_extent *extp;
595
+ xfs_fsblock_t startblock_fsb;
596
+ int i;
597
+ int error = 0;
500598
501599 /*
502600 * First check the validity of the extents described by the
....@@ -510,15 +608,8 @@
510608 if (startblock_fsb == 0 ||
511609 extp->ext_len == 0 ||
512610 startblock_fsb >= mp->m_sb.sb_dblocks ||
513
- extp->ext_len >= mp->m_sb.sb_agblocks) {
514
- /*
515
- * This will pull the EFI from the AIL and
516
- * free the memory associated with it.
517
- */
518
- set_bit(XFS_EFI_RECOVERED, &efip->efi_flags);
519
- xfs_efi_release(efip);
520
- return -EIO;
521
- }
611
+ extp->ext_len >= mp->m_sb.sb_agblocks)
612
+ return -EFSCORRUPTED;
522613 }
523614
524615 error = xfs_trans_alloc(mp, &M_RES(mp)->tr_itruncate, 0, 0, 0, &tp);
....@@ -526,21 +617,138 @@
526617 return error;
527618 efdp = xfs_trans_get_efd(tp, efip, efip->efi_format.efi_nextents);
528619
529
- xfs_rmap_any_owner_update(&oinfo);
530620 for (i = 0; i < efip->efi_format.efi_nextents; i++) {
531621 extp = &efip->efi_format.efi_extents[i];
532622 error = xfs_trans_free_extent(tp, efdp, extp->ext_start,
533
- extp->ext_len, &oinfo, false);
623
+ extp->ext_len,
624
+ &XFS_RMAP_OINFO_ANY_OWNER, false);
534625 if (error)
535626 goto abort_error;
536627
537628 }
538629
539
- set_bit(XFS_EFI_RECOVERED, &efip->efi_flags);
540
- error = xfs_trans_commit(tp);
541
- return error;
630
+ return xfs_defer_ops_capture_and_commit(tp, NULL, capture_list);
542631
543632 abort_error:
544633 xfs_trans_cancel(tp);
545634 return error;
546635 }
636
+
637
+STATIC bool
638
+xfs_efi_item_match(
639
+ struct xfs_log_item *lip,
640
+ uint64_t intent_id)
641
+{
642
+ return EFI_ITEM(lip)->efi_format.efi_id == intent_id;
643
+}
644
+
645
+/* Relog an intent item to push the log tail forward. */
646
+static struct xfs_log_item *
647
+xfs_efi_item_relog(
648
+ struct xfs_log_item *intent,
649
+ struct xfs_trans *tp)
650
+{
651
+ struct xfs_efd_log_item *efdp;
652
+ struct xfs_efi_log_item *efip;
653
+ struct xfs_extent *extp;
654
+ unsigned int count;
655
+
656
+ count = EFI_ITEM(intent)->efi_format.efi_nextents;
657
+ extp = EFI_ITEM(intent)->efi_format.efi_extents;
658
+
659
+ tp->t_flags |= XFS_TRANS_DIRTY;
660
+ efdp = xfs_trans_get_efd(tp, EFI_ITEM(intent), count);
661
+ efdp->efd_next_extent = count;
662
+ memcpy(efdp->efd_format.efd_extents, extp, count * sizeof(*extp));
663
+ set_bit(XFS_LI_DIRTY, &efdp->efd_item.li_flags);
664
+
665
+ efip = xfs_efi_init(tp->t_mountp, count);
666
+ memcpy(efip->efi_format.efi_extents, extp, count * sizeof(*extp));
667
+ atomic_set(&efip->efi_next_extent, count);
668
+ xfs_trans_add_item(tp, &efip->efi_item);
669
+ set_bit(XFS_LI_DIRTY, &efip->efi_item.li_flags);
670
+ return &efip->efi_item;
671
+}
672
+
673
+static const struct xfs_item_ops xfs_efi_item_ops = {
674
+ .iop_size = xfs_efi_item_size,
675
+ .iop_format = xfs_efi_item_format,
676
+ .iop_unpin = xfs_efi_item_unpin,
677
+ .iop_release = xfs_efi_item_release,
678
+ .iop_recover = xfs_efi_item_recover,
679
+ .iop_match = xfs_efi_item_match,
680
+ .iop_relog = xfs_efi_item_relog,
681
+};
682
+
683
+/*
684
+ * This routine is called to create an in-core extent free intent
685
+ * item from the efi format structure which was logged on disk.
686
+ * It allocates an in-core efi, copies the extents from the format
687
+ * structure into it, and adds the efi to the AIL with the given
688
+ * LSN.
689
+ */
690
+STATIC int
691
+xlog_recover_efi_commit_pass2(
692
+ struct xlog *log,
693
+ struct list_head *buffer_list,
694
+ struct xlog_recover_item *item,
695
+ xfs_lsn_t lsn)
696
+{
697
+ struct xfs_mount *mp = log->l_mp;
698
+ struct xfs_efi_log_item *efip;
699
+ struct xfs_efi_log_format *efi_formatp;
700
+ int error;
701
+
702
+ efi_formatp = item->ri_buf[0].i_addr;
703
+
704
+ efip = xfs_efi_init(mp, efi_formatp->efi_nextents);
705
+ error = xfs_efi_copy_format(&item->ri_buf[0], &efip->efi_format);
706
+ if (error) {
707
+ xfs_efi_item_free(efip);
708
+ return error;
709
+ }
710
+ atomic_set(&efip->efi_next_extent, efi_formatp->efi_nextents);
711
+ /*
712
+ * Insert the intent into the AIL directly and drop one reference so
713
+ * that finishing or canceling the work will drop the other.
714
+ */
715
+ xfs_trans_ail_insert(log->l_ailp, &efip->efi_item, lsn);
716
+ xfs_efi_release(efip);
717
+ return 0;
718
+}
719
+
720
+const struct xlog_recover_item_ops xlog_efi_item_ops = {
721
+ .item_type = XFS_LI_EFI,
722
+ .commit_pass2 = xlog_recover_efi_commit_pass2,
723
+};
724
+
725
+/*
726
+ * This routine is called when an EFD format structure is found in a committed
727
+ * transaction in the log. Its purpose is to cancel the corresponding EFI if it
728
+ * was still in the log. To do this it searches the AIL for the EFI with an id
729
+ * equal to that in the EFD format structure. If we find it we drop the EFD
730
+ * reference, which removes the EFI from the AIL and frees it.
731
+ */
732
+STATIC int
733
+xlog_recover_efd_commit_pass2(
734
+ struct xlog *log,
735
+ struct list_head *buffer_list,
736
+ struct xlog_recover_item *item,
737
+ xfs_lsn_t lsn)
738
+{
739
+ struct xfs_efd_log_format *efd_formatp;
740
+
741
+ efd_formatp = item->ri_buf[0].i_addr;
742
+ ASSERT((item->ri_buf[0].i_len == (sizeof(xfs_efd_log_format_32_t) +
743
+ ((efd_formatp->efd_nextents - 1) * sizeof(xfs_extent_32_t)))) ||
744
+ (item->ri_buf[0].i_len == (sizeof(xfs_efd_log_format_64_t) +
745
+ ((efd_formatp->efd_nextents - 1) * sizeof(xfs_extent_64_t)))));
746
+
747
+ xlog_recover_release_intent(log, XFS_LI_EFI, efd_formatp->efd_efi_id);
748
+ return 0;
749
+}
750
+
751
+const struct xlog_recover_item_ops xlog_efd_item_ops = {
752
+ .item_type = XFS_LI_EFD,
753
+ .commit_pass2 = xlog_recover_efd_commit_pass2,
754
+};