cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

xfs_extfree_item.c (22252B)


      1// SPDX-License-Identifier: GPL-2.0
      2/*
      3 * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc.
      4 * All Rights Reserved.
      5 */
      6#include "xfs.h"
      7#include "xfs_fs.h"
      8#include "xfs_format.h"
      9#include "xfs_log_format.h"
     10#include "xfs_trans_resv.h"
     11#include "xfs_bit.h"
     12#include "xfs_shared.h"
     13#include "xfs_mount.h"
     14#include "xfs_defer.h"
     15#include "xfs_trans.h"
     16#include "xfs_trans_priv.h"
     17#include "xfs_extfree_item.h"
     18#include "xfs_log.h"
     19#include "xfs_btree.h"
     20#include "xfs_rmap.h"
     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"
     27
     28struct kmem_cache	*xfs_efi_cache;
     29struct kmem_cache	*xfs_efd_cache;
     30
     31static const struct xfs_item_ops xfs_efi_item_ops;
     32
     33static inline struct xfs_efi_log_item *EFI_ITEM(struct xfs_log_item *lip)
     34{
     35	return container_of(lip, struct xfs_efi_log_item, efi_item);
     36}
     37
     38STATIC void
     39xfs_efi_item_free(
     40	struct xfs_efi_log_item	*efip)
     41{
     42	kmem_free(efip->efi_item.li_lv_shadow);
     43	if (efip->efi_format.efi_nextents > XFS_EFI_MAX_FAST_EXTENTS)
     44		kmem_free(efip);
     45	else
     46		kmem_cache_free(xfs_efi_cache, efip);
     47}
     48
     49/*
     50 * Freeing the efi requires that we remove it from the AIL if it has already
     51 * been placed there. However, the EFI may not yet have been placed in the AIL
     52 * when called by xfs_efi_release() from EFD processing due to the ordering of
     53 * committed vs unpin operations in bulk insert operations. Hence the reference
     54 * count to ensure only the last caller frees the EFI.
     55 */
     56STATIC void
     57xfs_efi_release(
     58	struct xfs_efi_log_item	*efip)
     59{
     60	ASSERT(atomic_read(&efip->efi_refcount) > 0);
     61	if (!atomic_dec_and_test(&efip->efi_refcount))
     62		return;
     63
     64	xfs_trans_ail_delete(&efip->efi_item, 0);
     65	xfs_efi_item_free(efip);
     66}
     67
     68/*
     69 * This returns the number of iovecs needed to log the given efi item.
     70 * We only need 1 iovec for an efi item.  It just logs the efi_log_format
     71 * structure.
     72 */
     73static inline int
     74xfs_efi_item_sizeof(
     75	struct xfs_efi_log_item *efip)
     76{
     77	return sizeof(struct xfs_efi_log_format) +
     78	       (efip->efi_format.efi_nextents - 1) * sizeof(xfs_extent_t);
     79}
     80
     81STATIC void
     82xfs_efi_item_size(
     83	struct xfs_log_item	*lip,
     84	int			*nvecs,
     85	int			*nbytes)
     86{
     87	*nvecs += 1;
     88	*nbytes += xfs_efi_item_sizeof(EFI_ITEM(lip));
     89}
     90
     91/*
     92 * This is called to fill in the vector of log iovecs for the
     93 * given efi log item. We use only 1 iovec, and we point that
     94 * at the efi_log_format structure embedded in the efi item.
     95 * It is at this point that we assert that all of the extent
     96 * slots in the efi item have been filled.
     97 */
     98STATIC void
     99xfs_efi_item_format(
    100	struct xfs_log_item	*lip,
    101	struct xfs_log_vec	*lv)
    102{
    103	struct xfs_efi_log_item	*efip = EFI_ITEM(lip);
    104	struct xfs_log_iovec	*vecp = NULL;
    105
    106	ASSERT(atomic_read(&efip->efi_next_extent) ==
    107				efip->efi_format.efi_nextents);
    108
    109	efip->efi_format.efi_type = XFS_LI_EFI;
    110	efip->efi_format.efi_size = 1;
    111
    112	xlog_copy_iovec(lv, &vecp, XLOG_REG_TYPE_EFI_FORMAT,
    113			&efip->efi_format,
    114			xfs_efi_item_sizeof(efip));
    115}
    116
    117
    118/*
    119 * The unpin operation is the last place an EFI is manipulated in the log. It is
    120 * either inserted in the AIL or aborted in the event of a log I/O error. In
    121 * either case, the EFI transaction has been successfully committed to make it
    122 * this far. Therefore, we expect whoever committed the EFI to either construct
    123 * and commit the EFD or drop the EFD's reference in the event of error. Simply
    124 * drop the log's EFI reference now that the log is done with it.
    125 */
    126STATIC void
    127xfs_efi_item_unpin(
    128	struct xfs_log_item	*lip,
    129	int			remove)
    130{
    131	struct xfs_efi_log_item	*efip = EFI_ITEM(lip);
    132	xfs_efi_release(efip);
    133}
    134
    135/*
    136 * The EFI has been either committed or aborted if the transaction has been
    137 * cancelled. If the transaction was cancelled, an EFD isn't going to be
    138 * constructed and thus we free the EFI here directly.
    139 */
    140STATIC void
    141xfs_efi_item_release(
    142	struct xfs_log_item	*lip)
    143{
    144	xfs_efi_release(EFI_ITEM(lip));
    145}
    146
    147/*
    148 * Allocate and initialize an efi item with the given number of extents.
    149 */
    150STATIC struct xfs_efi_log_item *
    151xfs_efi_init(
    152	struct xfs_mount	*mp,
    153	uint			nextents)
    154
    155{
    156	struct xfs_efi_log_item	*efip;
    157	uint			size;
    158
    159	ASSERT(nextents > 0);
    160	if (nextents > XFS_EFI_MAX_FAST_EXTENTS) {
    161		size = (uint)(sizeof(struct xfs_efi_log_item) +
    162			((nextents - 1) * sizeof(xfs_extent_t)));
    163		efip = kmem_zalloc(size, 0);
    164	} else {
    165		efip = kmem_cache_zalloc(xfs_efi_cache,
    166					 GFP_KERNEL | __GFP_NOFAIL);
    167	}
    168
    169	xfs_log_item_init(mp, &efip->efi_item, XFS_LI_EFI, &xfs_efi_item_ops);
    170	efip->efi_format.efi_nextents = nextents;
    171	efip->efi_format.efi_id = (uintptr_t)(void *)efip;
    172	atomic_set(&efip->efi_next_extent, 0);
    173	atomic_set(&efip->efi_refcount, 2);
    174
    175	return efip;
    176}
    177
    178/*
    179 * Copy an EFI format buffer from the given buf, and into the destination
    180 * EFI format structure.
    181 * The given buffer can be in 32 bit or 64 bit form (which has different padding),
    182 * one of which will be the native format for this kernel.
    183 * It will handle the conversion of formats if necessary.
    184 */
    185STATIC int
    186xfs_efi_copy_format(xfs_log_iovec_t *buf, xfs_efi_log_format_t *dst_efi_fmt)
    187{
    188	xfs_efi_log_format_t *src_efi_fmt = buf->i_addr;
    189	uint i;
    190	uint len = sizeof(xfs_efi_log_format_t) + 
    191		(src_efi_fmt->efi_nextents - 1) * sizeof(xfs_extent_t);  
    192	uint len32 = sizeof(xfs_efi_log_format_32_t) + 
    193		(src_efi_fmt->efi_nextents - 1) * sizeof(xfs_extent_32_t);  
    194	uint len64 = sizeof(xfs_efi_log_format_64_t) + 
    195		(src_efi_fmt->efi_nextents - 1) * sizeof(xfs_extent_64_t);  
    196
    197	if (buf->i_len == len) {
    198		memcpy((char *)dst_efi_fmt, (char*)src_efi_fmt, len);
    199		return 0;
    200	} else if (buf->i_len == len32) {
    201		xfs_efi_log_format_32_t *src_efi_fmt_32 = buf->i_addr;
    202
    203		dst_efi_fmt->efi_type     = src_efi_fmt_32->efi_type;
    204		dst_efi_fmt->efi_size     = src_efi_fmt_32->efi_size;
    205		dst_efi_fmt->efi_nextents = src_efi_fmt_32->efi_nextents;
    206		dst_efi_fmt->efi_id       = src_efi_fmt_32->efi_id;
    207		for (i = 0; i < dst_efi_fmt->efi_nextents; i++) {
    208			dst_efi_fmt->efi_extents[i].ext_start =
    209				src_efi_fmt_32->efi_extents[i].ext_start;
    210			dst_efi_fmt->efi_extents[i].ext_len =
    211				src_efi_fmt_32->efi_extents[i].ext_len;
    212		}
    213		return 0;
    214	} else if (buf->i_len == len64) {
    215		xfs_efi_log_format_64_t *src_efi_fmt_64 = buf->i_addr;
    216
    217		dst_efi_fmt->efi_type     = src_efi_fmt_64->efi_type;
    218		dst_efi_fmt->efi_size     = src_efi_fmt_64->efi_size;
    219		dst_efi_fmt->efi_nextents = src_efi_fmt_64->efi_nextents;
    220		dst_efi_fmt->efi_id       = src_efi_fmt_64->efi_id;
    221		for (i = 0; i < dst_efi_fmt->efi_nextents; i++) {
    222			dst_efi_fmt->efi_extents[i].ext_start =
    223				src_efi_fmt_64->efi_extents[i].ext_start;
    224			dst_efi_fmt->efi_extents[i].ext_len =
    225				src_efi_fmt_64->efi_extents[i].ext_len;
    226		}
    227		return 0;
    228	}
    229	XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_LOW, NULL);
    230	return -EFSCORRUPTED;
    231}
    232
    233static inline struct xfs_efd_log_item *EFD_ITEM(struct xfs_log_item *lip)
    234{
    235	return container_of(lip, struct xfs_efd_log_item, efd_item);
    236}
    237
    238STATIC void
    239xfs_efd_item_free(struct xfs_efd_log_item *efdp)
    240{
    241	kmem_free(efdp->efd_item.li_lv_shadow);
    242	if (efdp->efd_format.efd_nextents > XFS_EFD_MAX_FAST_EXTENTS)
    243		kmem_free(efdp);
    244	else
    245		kmem_cache_free(xfs_efd_cache, efdp);
    246}
    247
    248/*
    249 * This returns the number of iovecs needed to log the given efd item.
    250 * We only need 1 iovec for an efd item.  It just logs the efd_log_format
    251 * structure.
    252 */
    253static inline int
    254xfs_efd_item_sizeof(
    255	struct xfs_efd_log_item *efdp)
    256{
    257	return sizeof(xfs_efd_log_format_t) +
    258	       (efdp->efd_format.efd_nextents - 1) * sizeof(xfs_extent_t);
    259}
    260
    261STATIC void
    262xfs_efd_item_size(
    263	struct xfs_log_item	*lip,
    264	int			*nvecs,
    265	int			*nbytes)
    266{
    267	*nvecs += 1;
    268	*nbytes += xfs_efd_item_sizeof(EFD_ITEM(lip));
    269}
    270
    271/*
    272 * This is called to fill in the vector of log iovecs for the
    273 * given efd log item. We use only 1 iovec, and we point that
    274 * at the efd_log_format structure embedded in the efd item.
    275 * It is at this point that we assert that all of the extent
    276 * slots in the efd item have been filled.
    277 */
    278STATIC void
    279xfs_efd_item_format(
    280	struct xfs_log_item	*lip,
    281	struct xfs_log_vec	*lv)
    282{
    283	struct xfs_efd_log_item	*efdp = EFD_ITEM(lip);
    284	struct xfs_log_iovec	*vecp = NULL;
    285
    286	ASSERT(efdp->efd_next_extent == efdp->efd_format.efd_nextents);
    287
    288	efdp->efd_format.efd_type = XFS_LI_EFD;
    289	efdp->efd_format.efd_size = 1;
    290
    291	xlog_copy_iovec(lv, &vecp, XLOG_REG_TYPE_EFD_FORMAT,
    292			&efdp->efd_format,
    293			xfs_efd_item_sizeof(efdp));
    294}
    295
    296/*
    297 * The EFD is either committed or aborted if the transaction is cancelled. If
    298 * the transaction is cancelled, drop our reference to the EFI and free the EFD.
    299 */
    300STATIC void
    301xfs_efd_item_release(
    302	struct xfs_log_item	*lip)
    303{
    304	struct xfs_efd_log_item	*efdp = EFD_ITEM(lip);
    305
    306	xfs_efi_release(efdp->efd_efip);
    307	xfs_efd_item_free(efdp);
    308}
    309
    310static struct xfs_log_item *
    311xfs_efd_item_intent(
    312	struct xfs_log_item	*lip)
    313{
    314	return &EFD_ITEM(lip)->efd_efip->efi_item;
    315}
    316
    317static const struct xfs_item_ops xfs_efd_item_ops = {
    318	.flags		= XFS_ITEM_RELEASE_WHEN_COMMITTED |
    319			  XFS_ITEM_INTENT_DONE,
    320	.iop_size	= xfs_efd_item_size,
    321	.iop_format	= xfs_efd_item_format,
    322	.iop_release	= xfs_efd_item_release,
    323	.iop_intent	= xfs_efd_item_intent,
    324};
    325
    326/*
    327 * Allocate an "extent free done" log item that will hold nextents worth of
    328 * extents.  The caller must use all nextents extents, because we are not
    329 * flexible about this at all.
    330 */
    331static struct xfs_efd_log_item *
    332xfs_trans_get_efd(
    333	struct xfs_trans		*tp,
    334	struct xfs_efi_log_item		*efip,
    335	unsigned int			nextents)
    336{
    337	struct xfs_efd_log_item		*efdp;
    338
    339	ASSERT(nextents > 0);
    340
    341	if (nextents > XFS_EFD_MAX_FAST_EXTENTS) {
    342		efdp = kmem_zalloc(sizeof(struct xfs_efd_log_item) +
    343				(nextents - 1) * sizeof(struct xfs_extent),
    344				0);
    345	} else {
    346		efdp = kmem_cache_zalloc(xfs_efd_cache,
    347					GFP_KERNEL | __GFP_NOFAIL);
    348	}
    349
    350	xfs_log_item_init(tp->t_mountp, &efdp->efd_item, XFS_LI_EFD,
    351			  &xfs_efd_item_ops);
    352	efdp->efd_efip = efip;
    353	efdp->efd_format.efd_nextents = nextents;
    354	efdp->efd_format.efd_efi_id = efip->efi_format.efi_id;
    355
    356	xfs_trans_add_item(tp, &efdp->efd_item);
    357	return efdp;
    358}
    359
    360/*
    361 * Free an extent and log it to the EFD. Note that the transaction is marked
    362 * dirty regardless of whether the extent free succeeds or fails to support the
    363 * EFI/EFD lifecycle rules.
    364 */
    365static int
    366xfs_trans_free_extent(
    367	struct xfs_trans		*tp,
    368	struct xfs_efd_log_item		*efdp,
    369	xfs_fsblock_t			start_block,
    370	xfs_extlen_t			ext_len,
    371	const struct xfs_owner_info	*oinfo,
    372	bool				skip_discard)
    373{
    374	struct xfs_mount		*mp = tp->t_mountp;
    375	struct xfs_extent		*extp;
    376	uint				next_extent;
    377	xfs_agnumber_t			agno = XFS_FSB_TO_AGNO(mp, start_block);
    378	xfs_agblock_t			agbno = XFS_FSB_TO_AGBNO(mp,
    379								start_block);
    380	int				error;
    381
    382	trace_xfs_bmap_free_deferred(tp->t_mountp, agno, 0, agbno, ext_len);
    383
    384	error = __xfs_free_extent(tp, start_block, ext_len,
    385				  oinfo, XFS_AG_RESV_NONE, skip_discard);
    386	/*
    387	 * Mark the transaction dirty, even on error. This ensures the
    388	 * transaction is aborted, which:
    389	 *
    390	 * 1.) releases the EFI and frees the EFD
    391	 * 2.) shuts down the filesystem
    392	 */
    393	tp->t_flags |= XFS_TRANS_DIRTY | XFS_TRANS_HAS_INTENT_DONE;
    394	set_bit(XFS_LI_DIRTY, &efdp->efd_item.li_flags);
    395
    396	next_extent = efdp->efd_next_extent;
    397	ASSERT(next_extent < efdp->efd_format.efd_nextents);
    398	extp = &(efdp->efd_format.efd_extents[next_extent]);
    399	extp->ext_start = start_block;
    400	extp->ext_len = ext_len;
    401	efdp->efd_next_extent++;
    402
    403	return error;
    404}
    405
    406/* Sort bmap items by AG. */
    407static int
    408xfs_extent_free_diff_items(
    409	void				*priv,
    410	const struct list_head		*a,
    411	const struct list_head		*b)
    412{
    413	struct xfs_mount		*mp = priv;
    414	struct xfs_extent_free_item	*ra;
    415	struct xfs_extent_free_item	*rb;
    416
    417	ra = container_of(a, struct xfs_extent_free_item, xefi_list);
    418	rb = container_of(b, struct xfs_extent_free_item, xefi_list);
    419	return  XFS_FSB_TO_AGNO(mp, ra->xefi_startblock) -
    420		XFS_FSB_TO_AGNO(mp, rb->xefi_startblock);
    421}
    422
    423/* Log a free extent to the intent item. */
    424STATIC void
    425xfs_extent_free_log_item(
    426	struct xfs_trans		*tp,
    427	struct xfs_efi_log_item		*efip,
    428	struct xfs_extent_free_item	*free)
    429{
    430	uint				next_extent;
    431	struct xfs_extent		*extp;
    432
    433	tp->t_flags |= XFS_TRANS_DIRTY;
    434	set_bit(XFS_LI_DIRTY, &efip->efi_item.li_flags);
    435
    436	/*
    437	 * atomic_inc_return gives us the value after the increment;
    438	 * we want to use it as an array index so we need to subtract 1 from
    439	 * it.
    440	 */
    441	next_extent = atomic_inc_return(&efip->efi_next_extent) - 1;
    442	ASSERT(next_extent < efip->efi_format.efi_nextents);
    443	extp = &efip->efi_format.efi_extents[next_extent];
    444	extp->ext_start = free->xefi_startblock;
    445	extp->ext_len = free->xefi_blockcount;
    446}
    447
    448static struct xfs_log_item *
    449xfs_extent_free_create_intent(
    450	struct xfs_trans		*tp,
    451	struct list_head		*items,
    452	unsigned int			count,
    453	bool				sort)
    454{
    455	struct xfs_mount		*mp = tp->t_mountp;
    456	struct xfs_efi_log_item		*efip = xfs_efi_init(mp, count);
    457	struct xfs_extent_free_item	*free;
    458
    459	ASSERT(count > 0);
    460
    461	xfs_trans_add_item(tp, &efip->efi_item);
    462	if (sort)
    463		list_sort(mp, items, xfs_extent_free_diff_items);
    464	list_for_each_entry(free, items, xefi_list)
    465		xfs_extent_free_log_item(tp, efip, free);
    466	return &efip->efi_item;
    467}
    468
    469/* Get an EFD so we can process all the free extents. */
    470static struct xfs_log_item *
    471xfs_extent_free_create_done(
    472	struct xfs_trans		*tp,
    473	struct xfs_log_item		*intent,
    474	unsigned int			count)
    475{
    476	return &xfs_trans_get_efd(tp, EFI_ITEM(intent), count)->efd_item;
    477}
    478
    479/* Process a free extent. */
    480STATIC int
    481xfs_extent_free_finish_item(
    482	struct xfs_trans		*tp,
    483	struct xfs_log_item		*done,
    484	struct list_head		*item,
    485	struct xfs_btree_cur		**state)
    486{
    487	struct xfs_owner_info		oinfo = { };
    488	struct xfs_extent_free_item	*free;
    489	int				error;
    490
    491	free = container_of(item, struct xfs_extent_free_item, xefi_list);
    492	oinfo.oi_owner = free->xefi_owner;
    493	if (free->xefi_flags & XFS_EFI_ATTR_FORK)
    494		oinfo.oi_flags |= XFS_OWNER_INFO_ATTR_FORK;
    495	if (free->xefi_flags & XFS_EFI_BMBT_BLOCK)
    496		oinfo.oi_flags |= XFS_OWNER_INFO_BMBT_BLOCK;
    497	error = xfs_trans_free_extent(tp, EFD_ITEM(done),
    498			free->xefi_startblock,
    499			free->xefi_blockcount,
    500			&oinfo, free->xefi_flags & XFS_EFI_SKIP_DISCARD);
    501	kmem_cache_free(xfs_extfree_item_cache, free);
    502	return error;
    503}
    504
    505/* Abort all pending EFIs. */
    506STATIC void
    507xfs_extent_free_abort_intent(
    508	struct xfs_log_item		*intent)
    509{
    510	xfs_efi_release(EFI_ITEM(intent));
    511}
    512
    513/* Cancel a free extent. */
    514STATIC void
    515xfs_extent_free_cancel_item(
    516	struct list_head		*item)
    517{
    518	struct xfs_extent_free_item	*free;
    519
    520	free = container_of(item, struct xfs_extent_free_item, xefi_list);
    521	kmem_cache_free(xfs_extfree_item_cache, free);
    522}
    523
    524const struct xfs_defer_op_type xfs_extent_free_defer_type = {
    525	.max_items	= XFS_EFI_MAX_FAST_EXTENTS,
    526	.create_intent	= xfs_extent_free_create_intent,
    527	.abort_intent	= xfs_extent_free_abort_intent,
    528	.create_done	= xfs_extent_free_create_done,
    529	.finish_item	= xfs_extent_free_finish_item,
    530	.cancel_item	= xfs_extent_free_cancel_item,
    531};
    532
    533/*
    534 * AGFL blocks are accounted differently in the reserve pools and are not
    535 * inserted into the busy extent list.
    536 */
    537STATIC int
    538xfs_agfl_free_finish_item(
    539	struct xfs_trans		*tp,
    540	struct xfs_log_item		*done,
    541	struct list_head		*item,
    542	struct xfs_btree_cur		**state)
    543{
    544	struct xfs_owner_info		oinfo = { };
    545	struct xfs_mount		*mp = tp->t_mountp;
    546	struct xfs_efd_log_item		*efdp = EFD_ITEM(done);
    547	struct xfs_extent_free_item	*free;
    548	struct xfs_extent		*extp;
    549	struct xfs_buf			*agbp;
    550	int				error;
    551	xfs_agnumber_t			agno;
    552	xfs_agblock_t			agbno;
    553	uint				next_extent;
    554
    555	free = container_of(item, struct xfs_extent_free_item, xefi_list);
    556	ASSERT(free->xefi_blockcount == 1);
    557	agno = XFS_FSB_TO_AGNO(mp, free->xefi_startblock);
    558	agbno = XFS_FSB_TO_AGBNO(mp, free->xefi_startblock);
    559	oinfo.oi_owner = free->xefi_owner;
    560
    561	trace_xfs_agfl_free_deferred(mp, agno, 0, agbno, free->xefi_blockcount);
    562
    563	error = xfs_alloc_read_agf(mp, tp, agno, 0, &agbp);
    564	if (!error)
    565		error = xfs_free_agfl_block(tp, agno, agbno, agbp, &oinfo);
    566
    567	/*
    568	 * Mark the transaction dirty, even on error. This ensures the
    569	 * transaction is aborted, which:
    570	 *
    571	 * 1.) releases the EFI and frees the EFD
    572	 * 2.) shuts down the filesystem
    573	 */
    574	tp->t_flags |= XFS_TRANS_DIRTY;
    575	set_bit(XFS_LI_DIRTY, &efdp->efd_item.li_flags);
    576
    577	next_extent = efdp->efd_next_extent;
    578	ASSERT(next_extent < efdp->efd_format.efd_nextents);
    579	extp = &(efdp->efd_format.efd_extents[next_extent]);
    580	extp->ext_start = free->xefi_startblock;
    581	extp->ext_len = free->xefi_blockcount;
    582	efdp->efd_next_extent++;
    583
    584	kmem_cache_free(xfs_extfree_item_cache, free);
    585	return error;
    586}
    587
    588/* sub-type with special handling for AGFL deferred frees */
    589const struct xfs_defer_op_type xfs_agfl_free_defer_type = {
    590	.max_items	= XFS_EFI_MAX_FAST_EXTENTS,
    591	.create_intent	= xfs_extent_free_create_intent,
    592	.abort_intent	= xfs_extent_free_abort_intent,
    593	.create_done	= xfs_extent_free_create_done,
    594	.finish_item	= xfs_agfl_free_finish_item,
    595	.cancel_item	= xfs_extent_free_cancel_item,
    596};
    597
    598/* Is this recovered EFI ok? */
    599static inline bool
    600xfs_efi_validate_ext(
    601	struct xfs_mount		*mp,
    602	struct xfs_extent		*extp)
    603{
    604	return xfs_verify_fsbext(mp, extp->ext_start, extp->ext_len);
    605}
    606
    607/*
    608 * Process an extent free intent item that was recovered from
    609 * the log.  We need to free the extents that it describes.
    610 */
    611STATIC int
    612xfs_efi_item_recover(
    613	struct xfs_log_item		*lip,
    614	struct list_head		*capture_list)
    615{
    616	struct xfs_efi_log_item		*efip = EFI_ITEM(lip);
    617	struct xfs_mount		*mp = lip->li_log->l_mp;
    618	struct xfs_efd_log_item		*efdp;
    619	struct xfs_trans		*tp;
    620	struct xfs_extent		*extp;
    621	int				i;
    622	int				error = 0;
    623
    624	/*
    625	 * First check the validity of the extents described by the
    626	 * EFI.  If any are bad, then assume that all are bad and
    627	 * just toss the EFI.
    628	 */
    629	for (i = 0; i < efip->efi_format.efi_nextents; i++) {
    630		if (!xfs_efi_validate_ext(mp,
    631					&efip->efi_format.efi_extents[i])) {
    632			XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp,
    633					&efip->efi_format,
    634					sizeof(efip->efi_format));
    635			return -EFSCORRUPTED;
    636		}
    637	}
    638
    639	error = xfs_trans_alloc(mp, &M_RES(mp)->tr_itruncate, 0, 0, 0, &tp);
    640	if (error)
    641		return error;
    642	efdp = xfs_trans_get_efd(tp, efip, efip->efi_format.efi_nextents);
    643
    644	for (i = 0; i < efip->efi_format.efi_nextents; i++) {
    645		extp = &efip->efi_format.efi_extents[i];
    646		error = xfs_trans_free_extent(tp, efdp, extp->ext_start,
    647					      extp->ext_len,
    648					      &XFS_RMAP_OINFO_ANY_OWNER, false);
    649		if (error == -EFSCORRUPTED)
    650			XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp,
    651					extp, sizeof(*extp));
    652		if (error)
    653			goto abort_error;
    654
    655	}
    656
    657	return xfs_defer_ops_capture_and_commit(tp, capture_list);
    658
    659abort_error:
    660	xfs_trans_cancel(tp);
    661	return error;
    662}
    663
    664STATIC bool
    665xfs_efi_item_match(
    666	struct xfs_log_item	*lip,
    667	uint64_t		intent_id)
    668{
    669	return EFI_ITEM(lip)->efi_format.efi_id == intent_id;
    670}
    671
    672/* Relog an intent item to push the log tail forward. */
    673static struct xfs_log_item *
    674xfs_efi_item_relog(
    675	struct xfs_log_item		*intent,
    676	struct xfs_trans		*tp)
    677{
    678	struct xfs_efd_log_item		*efdp;
    679	struct xfs_efi_log_item		*efip;
    680	struct xfs_extent		*extp;
    681	unsigned int			count;
    682
    683	count = EFI_ITEM(intent)->efi_format.efi_nextents;
    684	extp = EFI_ITEM(intent)->efi_format.efi_extents;
    685
    686	tp->t_flags |= XFS_TRANS_DIRTY;
    687	efdp = xfs_trans_get_efd(tp, EFI_ITEM(intent), count);
    688	efdp->efd_next_extent = count;
    689	memcpy(efdp->efd_format.efd_extents, extp, count * sizeof(*extp));
    690	set_bit(XFS_LI_DIRTY, &efdp->efd_item.li_flags);
    691
    692	efip = xfs_efi_init(tp->t_mountp, count);
    693	memcpy(efip->efi_format.efi_extents, extp, count * sizeof(*extp));
    694	atomic_set(&efip->efi_next_extent, count);
    695	xfs_trans_add_item(tp, &efip->efi_item);
    696	set_bit(XFS_LI_DIRTY, &efip->efi_item.li_flags);
    697	return &efip->efi_item;
    698}
    699
    700static const struct xfs_item_ops xfs_efi_item_ops = {
    701	.flags		= XFS_ITEM_INTENT,
    702	.iop_size	= xfs_efi_item_size,
    703	.iop_format	= xfs_efi_item_format,
    704	.iop_unpin	= xfs_efi_item_unpin,
    705	.iop_release	= xfs_efi_item_release,
    706	.iop_recover	= xfs_efi_item_recover,
    707	.iop_match	= xfs_efi_item_match,
    708	.iop_relog	= xfs_efi_item_relog,
    709};
    710
    711/*
    712 * This routine is called to create an in-core extent free intent
    713 * item from the efi format structure which was logged on disk.
    714 * It allocates an in-core efi, copies the extents from the format
    715 * structure into it, and adds the efi to the AIL with the given
    716 * LSN.
    717 */
    718STATIC int
    719xlog_recover_efi_commit_pass2(
    720	struct xlog			*log,
    721	struct list_head		*buffer_list,
    722	struct xlog_recover_item	*item,
    723	xfs_lsn_t			lsn)
    724{
    725	struct xfs_mount		*mp = log->l_mp;
    726	struct xfs_efi_log_item		*efip;
    727	struct xfs_efi_log_format	*efi_formatp;
    728	int				error;
    729
    730	efi_formatp = item->ri_buf[0].i_addr;
    731
    732	efip = xfs_efi_init(mp, efi_formatp->efi_nextents);
    733	error = xfs_efi_copy_format(&item->ri_buf[0], &efip->efi_format);
    734	if (error) {
    735		xfs_efi_item_free(efip);
    736		return error;
    737	}
    738	atomic_set(&efip->efi_next_extent, efi_formatp->efi_nextents);
    739	/*
    740	 * Insert the intent into the AIL directly and drop one reference so
    741	 * that finishing or canceling the work will drop the other.
    742	 */
    743	xfs_trans_ail_insert(log->l_ailp, &efip->efi_item, lsn);
    744	xfs_efi_release(efip);
    745	return 0;
    746}
    747
    748const struct xlog_recover_item_ops xlog_efi_item_ops = {
    749	.item_type		= XFS_LI_EFI,
    750	.commit_pass2		= xlog_recover_efi_commit_pass2,
    751};
    752
    753/*
    754 * This routine is called when an EFD format structure is found in a committed
    755 * transaction in the log. Its purpose is to cancel the corresponding EFI if it
    756 * was still in the log. To do this it searches the AIL for the EFI with an id
    757 * equal to that in the EFD format structure. If we find it we drop the EFD
    758 * reference, which removes the EFI from the AIL and frees it.
    759 */
    760STATIC int
    761xlog_recover_efd_commit_pass2(
    762	struct xlog			*log,
    763	struct list_head		*buffer_list,
    764	struct xlog_recover_item	*item,
    765	xfs_lsn_t			lsn)
    766{
    767	struct xfs_efd_log_format	*efd_formatp;
    768
    769	efd_formatp = item->ri_buf[0].i_addr;
    770	ASSERT((item->ri_buf[0].i_len == (sizeof(xfs_efd_log_format_32_t) +
    771		((efd_formatp->efd_nextents - 1) * sizeof(xfs_extent_32_t)))) ||
    772	       (item->ri_buf[0].i_len == (sizeof(xfs_efd_log_format_64_t) +
    773		((efd_formatp->efd_nextents - 1) * sizeof(xfs_extent_64_t)))));
    774
    775	xlog_recover_release_intent(log, XFS_LI_EFI, efd_formatp->efd_efi_id);
    776	return 0;
    777}
    778
    779const struct xlog_recover_item_ops xlog_efd_item_ops = {
    780	.item_type		= XFS_LI_EFD,
    781	.commit_pass2		= xlog_recover_efd_commit_pass2,
    782};