0001
0002
0003
0004
0005
0006 #include "xfs.h"
0007 #include "xfs_fs.h"
0008 #include "xfs_format.h"
0009 #include "xfs_log_format.h"
0010 #include "xfs_trans_resv.h"
0011 #include "xfs_bit.h"
0012 #include "xfs_shared.h"
0013 #include "xfs_mount.h"
0014 #include "xfs_ag.h"
0015 #include "xfs_defer.h"
0016 #include "xfs_trans.h"
0017 #include "xfs_trans_priv.h"
0018 #include "xfs_extfree_item.h"
0019 #include "xfs_log.h"
0020 #include "xfs_btree.h"
0021 #include "xfs_rmap.h"
0022 #include "xfs_alloc.h"
0023 #include "xfs_bmap.h"
0024 #include "xfs_trace.h"
0025 #include "xfs_error.h"
0026 #include "xfs_log_priv.h"
0027 #include "xfs_log_recover.h"
0028
0029 struct kmem_cache *xfs_efi_cache;
0030 struct kmem_cache *xfs_efd_cache;
0031
0032 static const struct xfs_item_ops xfs_efi_item_ops;
0033
0034 static inline struct xfs_efi_log_item *EFI_ITEM(struct xfs_log_item *lip)
0035 {
0036 return container_of(lip, struct xfs_efi_log_item, efi_item);
0037 }
0038
0039 STATIC void
0040 xfs_efi_item_free(
0041 struct xfs_efi_log_item *efip)
0042 {
0043 kmem_free(efip->efi_item.li_lv_shadow);
0044 if (efip->efi_format.efi_nextents > XFS_EFI_MAX_FAST_EXTENTS)
0045 kmem_free(efip);
0046 else
0047 kmem_cache_free(xfs_efi_cache, efip);
0048 }
0049
0050
0051
0052
0053
0054
0055
0056
0057 STATIC void
0058 xfs_efi_release(
0059 struct xfs_efi_log_item *efip)
0060 {
0061 ASSERT(atomic_read(&efip->efi_refcount) > 0);
0062 if (!atomic_dec_and_test(&efip->efi_refcount))
0063 return;
0064
0065 xfs_trans_ail_delete(&efip->efi_item, 0);
0066 xfs_efi_item_free(efip);
0067 }
0068
0069
0070
0071
0072
0073
0074 static inline int
0075 xfs_efi_item_sizeof(
0076 struct xfs_efi_log_item *efip)
0077 {
0078 return sizeof(struct xfs_efi_log_format) +
0079 (efip->efi_format.efi_nextents - 1) * sizeof(xfs_extent_t);
0080 }
0081
0082 STATIC void
0083 xfs_efi_item_size(
0084 struct xfs_log_item *lip,
0085 int *nvecs,
0086 int *nbytes)
0087 {
0088 *nvecs += 1;
0089 *nbytes += xfs_efi_item_sizeof(EFI_ITEM(lip));
0090 }
0091
0092
0093
0094
0095
0096
0097
0098
0099 STATIC void
0100 xfs_efi_item_format(
0101 struct xfs_log_item *lip,
0102 struct xfs_log_vec *lv)
0103 {
0104 struct xfs_efi_log_item *efip = EFI_ITEM(lip);
0105 struct xfs_log_iovec *vecp = NULL;
0106
0107 ASSERT(atomic_read(&efip->efi_next_extent) ==
0108 efip->efi_format.efi_nextents);
0109
0110 efip->efi_format.efi_type = XFS_LI_EFI;
0111 efip->efi_format.efi_size = 1;
0112
0113 xlog_copy_iovec(lv, &vecp, XLOG_REG_TYPE_EFI_FORMAT,
0114 &efip->efi_format,
0115 xfs_efi_item_sizeof(efip));
0116 }
0117
0118
0119
0120
0121
0122
0123
0124
0125
0126
0127 STATIC void
0128 xfs_efi_item_unpin(
0129 struct xfs_log_item *lip,
0130 int remove)
0131 {
0132 struct xfs_efi_log_item *efip = EFI_ITEM(lip);
0133 xfs_efi_release(efip);
0134 }
0135
0136
0137
0138
0139
0140
0141 STATIC void
0142 xfs_efi_item_release(
0143 struct xfs_log_item *lip)
0144 {
0145 xfs_efi_release(EFI_ITEM(lip));
0146 }
0147
0148
0149
0150
0151 STATIC struct xfs_efi_log_item *
0152 xfs_efi_init(
0153 struct xfs_mount *mp,
0154 uint nextents)
0155
0156 {
0157 struct xfs_efi_log_item *efip;
0158 uint size;
0159
0160 ASSERT(nextents > 0);
0161 if (nextents > XFS_EFI_MAX_FAST_EXTENTS) {
0162 size = (uint)(sizeof(struct xfs_efi_log_item) +
0163 ((nextents - 1) * sizeof(xfs_extent_t)));
0164 efip = kmem_zalloc(size, 0);
0165 } else {
0166 efip = kmem_cache_zalloc(xfs_efi_cache,
0167 GFP_KERNEL | __GFP_NOFAIL);
0168 }
0169
0170 xfs_log_item_init(mp, &efip->efi_item, XFS_LI_EFI, &xfs_efi_item_ops);
0171 efip->efi_format.efi_nextents = nextents;
0172 efip->efi_format.efi_id = (uintptr_t)(void *)efip;
0173 atomic_set(&efip->efi_next_extent, 0);
0174 atomic_set(&efip->efi_refcount, 2);
0175
0176 return efip;
0177 }
0178
0179
0180
0181
0182
0183
0184
0185
0186 STATIC int
0187 xfs_efi_copy_format(xfs_log_iovec_t *buf, xfs_efi_log_format_t *dst_efi_fmt)
0188 {
0189 xfs_efi_log_format_t *src_efi_fmt = buf->i_addr;
0190 uint i;
0191 uint len = sizeof(xfs_efi_log_format_t) +
0192 (src_efi_fmt->efi_nextents - 1) * sizeof(xfs_extent_t);
0193 uint len32 = sizeof(xfs_efi_log_format_32_t) +
0194 (src_efi_fmt->efi_nextents - 1) * sizeof(xfs_extent_32_t);
0195 uint len64 = sizeof(xfs_efi_log_format_64_t) +
0196 (src_efi_fmt->efi_nextents - 1) * sizeof(xfs_extent_64_t);
0197
0198 if (buf->i_len == len) {
0199 memcpy((char *)dst_efi_fmt, (char*)src_efi_fmt, len);
0200 return 0;
0201 } else if (buf->i_len == len32) {
0202 xfs_efi_log_format_32_t *src_efi_fmt_32 = buf->i_addr;
0203
0204 dst_efi_fmt->efi_type = src_efi_fmt_32->efi_type;
0205 dst_efi_fmt->efi_size = src_efi_fmt_32->efi_size;
0206 dst_efi_fmt->efi_nextents = src_efi_fmt_32->efi_nextents;
0207 dst_efi_fmt->efi_id = src_efi_fmt_32->efi_id;
0208 for (i = 0; i < dst_efi_fmt->efi_nextents; i++) {
0209 dst_efi_fmt->efi_extents[i].ext_start =
0210 src_efi_fmt_32->efi_extents[i].ext_start;
0211 dst_efi_fmt->efi_extents[i].ext_len =
0212 src_efi_fmt_32->efi_extents[i].ext_len;
0213 }
0214 return 0;
0215 } else if (buf->i_len == len64) {
0216 xfs_efi_log_format_64_t *src_efi_fmt_64 = buf->i_addr;
0217
0218 dst_efi_fmt->efi_type = src_efi_fmt_64->efi_type;
0219 dst_efi_fmt->efi_size = src_efi_fmt_64->efi_size;
0220 dst_efi_fmt->efi_nextents = src_efi_fmt_64->efi_nextents;
0221 dst_efi_fmt->efi_id = src_efi_fmt_64->efi_id;
0222 for (i = 0; i < dst_efi_fmt->efi_nextents; i++) {
0223 dst_efi_fmt->efi_extents[i].ext_start =
0224 src_efi_fmt_64->efi_extents[i].ext_start;
0225 dst_efi_fmt->efi_extents[i].ext_len =
0226 src_efi_fmt_64->efi_extents[i].ext_len;
0227 }
0228 return 0;
0229 }
0230 XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_LOW, NULL);
0231 return -EFSCORRUPTED;
0232 }
0233
0234 static inline struct xfs_efd_log_item *EFD_ITEM(struct xfs_log_item *lip)
0235 {
0236 return container_of(lip, struct xfs_efd_log_item, efd_item);
0237 }
0238
0239 STATIC void
0240 xfs_efd_item_free(struct xfs_efd_log_item *efdp)
0241 {
0242 kmem_free(efdp->efd_item.li_lv_shadow);
0243 if (efdp->efd_format.efd_nextents > XFS_EFD_MAX_FAST_EXTENTS)
0244 kmem_free(efdp);
0245 else
0246 kmem_cache_free(xfs_efd_cache, efdp);
0247 }
0248
0249
0250
0251
0252
0253
0254 static inline int
0255 xfs_efd_item_sizeof(
0256 struct xfs_efd_log_item *efdp)
0257 {
0258 return sizeof(xfs_efd_log_format_t) +
0259 (efdp->efd_format.efd_nextents - 1) * sizeof(xfs_extent_t);
0260 }
0261
0262 STATIC void
0263 xfs_efd_item_size(
0264 struct xfs_log_item *lip,
0265 int *nvecs,
0266 int *nbytes)
0267 {
0268 *nvecs += 1;
0269 *nbytes += xfs_efd_item_sizeof(EFD_ITEM(lip));
0270 }
0271
0272
0273
0274
0275
0276
0277
0278
0279 STATIC void
0280 xfs_efd_item_format(
0281 struct xfs_log_item *lip,
0282 struct xfs_log_vec *lv)
0283 {
0284 struct xfs_efd_log_item *efdp = EFD_ITEM(lip);
0285 struct xfs_log_iovec *vecp = NULL;
0286
0287 ASSERT(efdp->efd_next_extent == efdp->efd_format.efd_nextents);
0288
0289 efdp->efd_format.efd_type = XFS_LI_EFD;
0290 efdp->efd_format.efd_size = 1;
0291
0292 xlog_copy_iovec(lv, &vecp, XLOG_REG_TYPE_EFD_FORMAT,
0293 &efdp->efd_format,
0294 xfs_efd_item_sizeof(efdp));
0295 }
0296
0297
0298
0299
0300
0301 STATIC void
0302 xfs_efd_item_release(
0303 struct xfs_log_item *lip)
0304 {
0305 struct xfs_efd_log_item *efdp = EFD_ITEM(lip);
0306
0307 xfs_efi_release(efdp->efd_efip);
0308 xfs_efd_item_free(efdp);
0309 }
0310
0311 static struct xfs_log_item *
0312 xfs_efd_item_intent(
0313 struct xfs_log_item *lip)
0314 {
0315 return &EFD_ITEM(lip)->efd_efip->efi_item;
0316 }
0317
0318 static const struct xfs_item_ops xfs_efd_item_ops = {
0319 .flags = XFS_ITEM_RELEASE_WHEN_COMMITTED |
0320 XFS_ITEM_INTENT_DONE,
0321 .iop_size = xfs_efd_item_size,
0322 .iop_format = xfs_efd_item_format,
0323 .iop_release = xfs_efd_item_release,
0324 .iop_intent = xfs_efd_item_intent,
0325 };
0326
0327
0328
0329
0330
0331
0332 static struct xfs_efd_log_item *
0333 xfs_trans_get_efd(
0334 struct xfs_trans *tp,
0335 struct xfs_efi_log_item *efip,
0336 unsigned int nextents)
0337 {
0338 struct xfs_efd_log_item *efdp;
0339
0340 ASSERT(nextents > 0);
0341
0342 if (nextents > XFS_EFD_MAX_FAST_EXTENTS) {
0343 efdp = kmem_zalloc(sizeof(struct xfs_efd_log_item) +
0344 (nextents - 1) * sizeof(struct xfs_extent),
0345 0);
0346 } else {
0347 efdp = kmem_cache_zalloc(xfs_efd_cache,
0348 GFP_KERNEL | __GFP_NOFAIL);
0349 }
0350
0351 xfs_log_item_init(tp->t_mountp, &efdp->efd_item, XFS_LI_EFD,
0352 &xfs_efd_item_ops);
0353 efdp->efd_efip = efip;
0354 efdp->efd_format.efd_nextents = nextents;
0355 efdp->efd_format.efd_efi_id = efip->efi_format.efi_id;
0356
0357 xfs_trans_add_item(tp, &efdp->efd_item);
0358 return efdp;
0359 }
0360
0361
0362
0363
0364
0365
0366 static int
0367 xfs_trans_free_extent(
0368 struct xfs_trans *tp,
0369 struct xfs_efd_log_item *efdp,
0370 xfs_fsblock_t start_block,
0371 xfs_extlen_t ext_len,
0372 const struct xfs_owner_info *oinfo,
0373 bool skip_discard)
0374 {
0375 struct xfs_mount *mp = tp->t_mountp;
0376 struct xfs_extent *extp;
0377 uint next_extent;
0378 xfs_agnumber_t agno = XFS_FSB_TO_AGNO(mp, start_block);
0379 xfs_agblock_t agbno = XFS_FSB_TO_AGBNO(mp,
0380 start_block);
0381 int error;
0382
0383 trace_xfs_bmap_free_deferred(tp->t_mountp, agno, 0, agbno, ext_len);
0384
0385 error = __xfs_free_extent(tp, start_block, ext_len,
0386 oinfo, XFS_AG_RESV_NONE, skip_discard);
0387
0388
0389
0390
0391
0392
0393
0394 tp->t_flags |= XFS_TRANS_DIRTY | XFS_TRANS_HAS_INTENT_DONE;
0395 set_bit(XFS_LI_DIRTY, &efdp->efd_item.li_flags);
0396
0397 next_extent = efdp->efd_next_extent;
0398 ASSERT(next_extent < efdp->efd_format.efd_nextents);
0399 extp = &(efdp->efd_format.efd_extents[next_extent]);
0400 extp->ext_start = start_block;
0401 extp->ext_len = ext_len;
0402 efdp->efd_next_extent++;
0403
0404 return error;
0405 }
0406
0407
0408 static int
0409 xfs_extent_free_diff_items(
0410 void *priv,
0411 const struct list_head *a,
0412 const struct list_head *b)
0413 {
0414 struct xfs_mount *mp = priv;
0415 struct xfs_extent_free_item *ra;
0416 struct xfs_extent_free_item *rb;
0417
0418 ra = container_of(a, struct xfs_extent_free_item, xefi_list);
0419 rb = container_of(b, struct xfs_extent_free_item, xefi_list);
0420 return XFS_FSB_TO_AGNO(mp, ra->xefi_startblock) -
0421 XFS_FSB_TO_AGNO(mp, rb->xefi_startblock);
0422 }
0423
0424
0425 STATIC void
0426 xfs_extent_free_log_item(
0427 struct xfs_trans *tp,
0428 struct xfs_efi_log_item *efip,
0429 struct xfs_extent_free_item *free)
0430 {
0431 uint next_extent;
0432 struct xfs_extent *extp;
0433
0434 tp->t_flags |= XFS_TRANS_DIRTY;
0435 set_bit(XFS_LI_DIRTY, &efip->efi_item.li_flags);
0436
0437
0438
0439
0440
0441
0442 next_extent = atomic_inc_return(&efip->efi_next_extent) - 1;
0443 ASSERT(next_extent < efip->efi_format.efi_nextents);
0444 extp = &efip->efi_format.efi_extents[next_extent];
0445 extp->ext_start = free->xefi_startblock;
0446 extp->ext_len = free->xefi_blockcount;
0447 }
0448
0449 static struct xfs_log_item *
0450 xfs_extent_free_create_intent(
0451 struct xfs_trans *tp,
0452 struct list_head *items,
0453 unsigned int count,
0454 bool sort)
0455 {
0456 struct xfs_mount *mp = tp->t_mountp;
0457 struct xfs_efi_log_item *efip = xfs_efi_init(mp, count);
0458 struct xfs_extent_free_item *free;
0459
0460 ASSERT(count > 0);
0461
0462 xfs_trans_add_item(tp, &efip->efi_item);
0463 if (sort)
0464 list_sort(mp, items, xfs_extent_free_diff_items);
0465 list_for_each_entry(free, items, xefi_list)
0466 xfs_extent_free_log_item(tp, efip, free);
0467 return &efip->efi_item;
0468 }
0469
0470
0471 static struct xfs_log_item *
0472 xfs_extent_free_create_done(
0473 struct xfs_trans *tp,
0474 struct xfs_log_item *intent,
0475 unsigned int count)
0476 {
0477 return &xfs_trans_get_efd(tp, EFI_ITEM(intent), count)->efd_item;
0478 }
0479
0480
0481 STATIC int
0482 xfs_extent_free_finish_item(
0483 struct xfs_trans *tp,
0484 struct xfs_log_item *done,
0485 struct list_head *item,
0486 struct xfs_btree_cur **state)
0487 {
0488 struct xfs_owner_info oinfo = { };
0489 struct xfs_extent_free_item *free;
0490 int error;
0491
0492 free = container_of(item, struct xfs_extent_free_item, xefi_list);
0493 oinfo.oi_owner = free->xefi_owner;
0494 if (free->xefi_flags & XFS_EFI_ATTR_FORK)
0495 oinfo.oi_flags |= XFS_OWNER_INFO_ATTR_FORK;
0496 if (free->xefi_flags & XFS_EFI_BMBT_BLOCK)
0497 oinfo.oi_flags |= XFS_OWNER_INFO_BMBT_BLOCK;
0498 error = xfs_trans_free_extent(tp, EFD_ITEM(done),
0499 free->xefi_startblock,
0500 free->xefi_blockcount,
0501 &oinfo, free->xefi_flags & XFS_EFI_SKIP_DISCARD);
0502 kmem_cache_free(xfs_extfree_item_cache, free);
0503 return error;
0504 }
0505
0506
0507 STATIC void
0508 xfs_extent_free_abort_intent(
0509 struct xfs_log_item *intent)
0510 {
0511 xfs_efi_release(EFI_ITEM(intent));
0512 }
0513
0514
0515 STATIC void
0516 xfs_extent_free_cancel_item(
0517 struct list_head *item)
0518 {
0519 struct xfs_extent_free_item *free;
0520
0521 free = container_of(item, struct xfs_extent_free_item, xefi_list);
0522 kmem_cache_free(xfs_extfree_item_cache, free);
0523 }
0524
0525 const struct xfs_defer_op_type xfs_extent_free_defer_type = {
0526 .max_items = XFS_EFI_MAX_FAST_EXTENTS,
0527 .create_intent = xfs_extent_free_create_intent,
0528 .abort_intent = xfs_extent_free_abort_intent,
0529 .create_done = xfs_extent_free_create_done,
0530 .finish_item = xfs_extent_free_finish_item,
0531 .cancel_item = xfs_extent_free_cancel_item,
0532 };
0533
0534
0535
0536
0537
0538 STATIC int
0539 xfs_agfl_free_finish_item(
0540 struct xfs_trans *tp,
0541 struct xfs_log_item *done,
0542 struct list_head *item,
0543 struct xfs_btree_cur **state)
0544 {
0545 struct xfs_owner_info oinfo = { };
0546 struct xfs_mount *mp = tp->t_mountp;
0547 struct xfs_efd_log_item *efdp = EFD_ITEM(done);
0548 struct xfs_extent_free_item *free;
0549 struct xfs_extent *extp;
0550 struct xfs_buf *agbp;
0551 int error;
0552 xfs_agnumber_t agno;
0553 xfs_agblock_t agbno;
0554 uint next_extent;
0555 struct xfs_perag *pag;
0556
0557 free = container_of(item, struct xfs_extent_free_item, xefi_list);
0558 ASSERT(free->xefi_blockcount == 1);
0559 agno = XFS_FSB_TO_AGNO(mp, free->xefi_startblock);
0560 agbno = XFS_FSB_TO_AGBNO(mp, free->xefi_startblock);
0561 oinfo.oi_owner = free->xefi_owner;
0562
0563 trace_xfs_agfl_free_deferred(mp, agno, 0, agbno, free->xefi_blockcount);
0564
0565 pag = xfs_perag_get(mp, agno);
0566 error = xfs_alloc_read_agf(pag, tp, 0, &agbp);
0567 if (!error)
0568 error = xfs_free_agfl_block(tp, agno, agbno, agbp, &oinfo);
0569 xfs_perag_put(pag);
0570
0571
0572
0573
0574
0575
0576
0577
0578 tp->t_flags |= XFS_TRANS_DIRTY;
0579 set_bit(XFS_LI_DIRTY, &efdp->efd_item.li_flags);
0580
0581 next_extent = efdp->efd_next_extent;
0582 ASSERT(next_extent < efdp->efd_format.efd_nextents);
0583 extp = &(efdp->efd_format.efd_extents[next_extent]);
0584 extp->ext_start = free->xefi_startblock;
0585 extp->ext_len = free->xefi_blockcount;
0586 efdp->efd_next_extent++;
0587
0588 kmem_cache_free(xfs_extfree_item_cache, free);
0589 return error;
0590 }
0591
0592
0593 const struct xfs_defer_op_type xfs_agfl_free_defer_type = {
0594 .max_items = XFS_EFI_MAX_FAST_EXTENTS,
0595 .create_intent = xfs_extent_free_create_intent,
0596 .abort_intent = xfs_extent_free_abort_intent,
0597 .create_done = xfs_extent_free_create_done,
0598 .finish_item = xfs_agfl_free_finish_item,
0599 .cancel_item = xfs_extent_free_cancel_item,
0600 };
0601
0602
0603 static inline bool
0604 xfs_efi_validate_ext(
0605 struct xfs_mount *mp,
0606 struct xfs_extent *extp)
0607 {
0608 return xfs_verify_fsbext(mp, extp->ext_start, extp->ext_len);
0609 }
0610
0611
0612
0613
0614
0615 STATIC int
0616 xfs_efi_item_recover(
0617 struct xfs_log_item *lip,
0618 struct list_head *capture_list)
0619 {
0620 struct xfs_efi_log_item *efip = EFI_ITEM(lip);
0621 struct xfs_mount *mp = lip->li_log->l_mp;
0622 struct xfs_efd_log_item *efdp;
0623 struct xfs_trans *tp;
0624 struct xfs_extent *extp;
0625 int i;
0626 int error = 0;
0627
0628
0629
0630
0631
0632
0633 for (i = 0; i < efip->efi_format.efi_nextents; i++) {
0634 if (!xfs_efi_validate_ext(mp,
0635 &efip->efi_format.efi_extents[i])) {
0636 XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp,
0637 &efip->efi_format,
0638 sizeof(efip->efi_format));
0639 return -EFSCORRUPTED;
0640 }
0641 }
0642
0643 error = xfs_trans_alloc(mp, &M_RES(mp)->tr_itruncate, 0, 0, 0, &tp);
0644 if (error)
0645 return error;
0646 efdp = xfs_trans_get_efd(tp, efip, efip->efi_format.efi_nextents);
0647
0648 for (i = 0; i < efip->efi_format.efi_nextents; i++) {
0649 extp = &efip->efi_format.efi_extents[i];
0650 error = xfs_trans_free_extent(tp, efdp, extp->ext_start,
0651 extp->ext_len,
0652 &XFS_RMAP_OINFO_ANY_OWNER, false);
0653 if (error == -EFSCORRUPTED)
0654 XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp,
0655 extp, sizeof(*extp));
0656 if (error)
0657 goto abort_error;
0658
0659 }
0660
0661 return xfs_defer_ops_capture_and_commit(tp, capture_list);
0662
0663 abort_error:
0664 xfs_trans_cancel(tp);
0665 return error;
0666 }
0667
0668 STATIC bool
0669 xfs_efi_item_match(
0670 struct xfs_log_item *lip,
0671 uint64_t intent_id)
0672 {
0673 return EFI_ITEM(lip)->efi_format.efi_id == intent_id;
0674 }
0675
0676
0677 static struct xfs_log_item *
0678 xfs_efi_item_relog(
0679 struct xfs_log_item *intent,
0680 struct xfs_trans *tp)
0681 {
0682 struct xfs_efd_log_item *efdp;
0683 struct xfs_efi_log_item *efip;
0684 struct xfs_extent *extp;
0685 unsigned int count;
0686
0687 count = EFI_ITEM(intent)->efi_format.efi_nextents;
0688 extp = EFI_ITEM(intent)->efi_format.efi_extents;
0689
0690 tp->t_flags |= XFS_TRANS_DIRTY;
0691 efdp = xfs_trans_get_efd(tp, EFI_ITEM(intent), count);
0692 efdp->efd_next_extent = count;
0693 memcpy(efdp->efd_format.efd_extents, extp, count * sizeof(*extp));
0694 set_bit(XFS_LI_DIRTY, &efdp->efd_item.li_flags);
0695
0696 efip = xfs_efi_init(tp->t_mountp, count);
0697 memcpy(efip->efi_format.efi_extents, extp, count * sizeof(*extp));
0698 atomic_set(&efip->efi_next_extent, count);
0699 xfs_trans_add_item(tp, &efip->efi_item);
0700 set_bit(XFS_LI_DIRTY, &efip->efi_item.li_flags);
0701 return &efip->efi_item;
0702 }
0703
0704 static const struct xfs_item_ops xfs_efi_item_ops = {
0705 .flags = XFS_ITEM_INTENT,
0706 .iop_size = xfs_efi_item_size,
0707 .iop_format = xfs_efi_item_format,
0708 .iop_unpin = xfs_efi_item_unpin,
0709 .iop_release = xfs_efi_item_release,
0710 .iop_recover = xfs_efi_item_recover,
0711 .iop_match = xfs_efi_item_match,
0712 .iop_relog = xfs_efi_item_relog,
0713 };
0714
0715
0716
0717
0718
0719
0720
0721
0722 STATIC int
0723 xlog_recover_efi_commit_pass2(
0724 struct xlog *log,
0725 struct list_head *buffer_list,
0726 struct xlog_recover_item *item,
0727 xfs_lsn_t lsn)
0728 {
0729 struct xfs_mount *mp = log->l_mp;
0730 struct xfs_efi_log_item *efip;
0731 struct xfs_efi_log_format *efi_formatp;
0732 int error;
0733
0734 efi_formatp = item->ri_buf[0].i_addr;
0735
0736 efip = xfs_efi_init(mp, efi_formatp->efi_nextents);
0737 error = xfs_efi_copy_format(&item->ri_buf[0], &efip->efi_format);
0738 if (error) {
0739 xfs_efi_item_free(efip);
0740 return error;
0741 }
0742 atomic_set(&efip->efi_next_extent, efi_formatp->efi_nextents);
0743
0744
0745
0746
0747 xfs_trans_ail_insert(log->l_ailp, &efip->efi_item, lsn);
0748 xfs_efi_release(efip);
0749 return 0;
0750 }
0751
0752 const struct xlog_recover_item_ops xlog_efi_item_ops = {
0753 .item_type = XFS_LI_EFI,
0754 .commit_pass2 = xlog_recover_efi_commit_pass2,
0755 };
0756
0757
0758
0759
0760
0761
0762
0763
0764 STATIC int
0765 xlog_recover_efd_commit_pass2(
0766 struct xlog *log,
0767 struct list_head *buffer_list,
0768 struct xlog_recover_item *item,
0769 xfs_lsn_t lsn)
0770 {
0771 struct xfs_efd_log_format *efd_formatp;
0772
0773 efd_formatp = item->ri_buf[0].i_addr;
0774 ASSERT((item->ri_buf[0].i_len == (sizeof(xfs_efd_log_format_32_t) +
0775 ((efd_formatp->efd_nextents - 1) * sizeof(xfs_extent_32_t)))) ||
0776 (item->ri_buf[0].i_len == (sizeof(xfs_efd_log_format_64_t) +
0777 ((efd_formatp->efd_nextents - 1) * sizeof(xfs_extent_64_t)))));
0778
0779 xlog_recover_release_intent(log, XFS_LI_EFI, efd_formatp->efd_efi_id);
0780 return 0;
0781 }
0782
0783 const struct xlog_recover_item_ops xlog_efd_item_ops = {
0784 .item_type = XFS_LI_EFD,
0785 .commit_pass2 = xlog_recover_efd_commit_pass2,
0786 };