File Index
Files and directories
Sign in
FILE

xfs_extfree_item.c

File preview with syntax highlighting.

linux-6.19.14/fs/xfs/xfs_extfree_item.c C
   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_ag.h"
  15#include "xfs_defer.h"
  16#include "xfs_trans.h"
  17#include "xfs_trans_priv.h"
  18#include "xfs_extfree_item.h"
  19#include "xfs_log.h"
  20#include "xfs_btree.h"
  21#include "xfs_rmap.h"
  22#include "xfs_alloc.h"
  23#include "xfs_bmap.h"
  24#include "xfs_trace.h"
  25#include "xfs_error.h"
  26#include "xfs_log_priv.h"
  27#include "xfs_log_recover.h"
  28#include "xfs_rtalloc.h"
  29#include "xfs_inode.h"
  30#include "xfs_rtbitmap.h"
  31#include "xfs_rtgroup.h"
  32#include "xfs_zone_alloc.h"
  33
  34struct kmem_cache	*xfs_efi_cache;
  35struct kmem_cache	*xfs_efd_cache;
  36
  37static const struct xfs_item_ops xfs_efi_item_ops;
  38
  39static inline struct xfs_efi_log_item *EFI_ITEM(struct xfs_log_item *lip)
  40{
  41	return container_of(lip, struct xfs_efi_log_item, efi_item);
  42}
  43
  44STATIC void
  45xfs_efi_item_free(
  46	struct xfs_efi_log_item	*efip)
  47{
  48	kvfree(efip->efi_item.li_lv_shadow);
  49	if (efip->efi_format.efi_nextents > XFS_EFI_MAX_FAST_EXTENTS)
  50		kfree(efip);
  51	else
  52		kmem_cache_free(xfs_efi_cache, efip);
  53}
  54
  55/*
  56 * Freeing the efi requires that we remove it from the AIL if it has already
  57 * been placed there. However, the EFI may not yet have been placed in the AIL
  58 * when called by xfs_efi_release() from EFD processing due to the ordering of
  59 * committed vs unpin operations in bulk insert operations. Hence the reference
  60 * count to ensure only the last caller frees the EFI.
  61 */
  62STATIC void
  63xfs_efi_release(
  64	struct xfs_efi_log_item	*efip)
  65{
  66	ASSERT(atomic_read(&efip->efi_refcount) > 0);
  67	if (!atomic_dec_and_test(&efip->efi_refcount))
  68		return;
  69
  70	xfs_trans_ail_delete(&efip->efi_item, 0);
  71	xfs_efi_item_free(efip);
  72}
  73
  74STATIC void
  75xfs_efi_item_size(
  76	struct xfs_log_item	*lip,
  77	int			*nvecs,
  78	int			*nbytes)
  79{
  80	struct xfs_efi_log_item	*efip = EFI_ITEM(lip);
  81
  82	*nvecs += 1;
  83	*nbytes += xfs_efi_log_format_sizeof(efip->efi_format.efi_nextents);
  84}
  85
  86unsigned int xfs_efi_log_space(unsigned int nr)
  87{
  88	return xlog_item_space(1, xfs_efi_log_format_sizeof(nr));
  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	ASSERT(lip->li_type == XFS_LI_EFI || lip->li_type == XFS_LI_EFI_RT);
 109
 110	efip->efi_format.efi_type = lip->li_type;
 111	efip->efi_format.efi_size = 1;
 112
 113	xlog_copy_iovec(lv, &vecp, XLOG_REG_TYPE_EFI_FORMAT, &efip->efi_format,
 114			xfs_efi_log_format_sizeof(efip->efi_format.efi_nextents));
 115}
 116
 117/*
 118 * The unpin operation is the last place an EFI is manipulated in the log. It is
 119 * either inserted in the AIL or aborted in the event of a log I/O error. In
 120 * either case, the EFI transaction has been successfully committed to make it
 121 * this far. Therefore, we expect whoever committed the EFI to either construct
 122 * and commit the EFD or drop the EFD's reference in the event of error. Simply
 123 * drop the log's EFI reference now that the log is done with it.
 124 */
 125STATIC void
 126xfs_efi_item_unpin(
 127	struct xfs_log_item	*lip,
 128	int			remove)
 129{
 130	struct xfs_efi_log_item	*efip = EFI_ITEM(lip);
 131	xfs_efi_release(efip);
 132}
 133
 134/*
 135 * The EFI has been either committed or aborted if the transaction has been
 136 * cancelled. If the transaction was cancelled, an EFD isn't going to be
 137 * constructed and thus we free the EFI here directly.
 138 */
 139STATIC void
 140xfs_efi_item_release(
 141	struct xfs_log_item	*lip)
 142{
 143	xfs_efi_release(EFI_ITEM(lip));
 144}
 145
 146/*
 147 * Allocate and initialize an efi item with the given number of extents.
 148 */
 149STATIC struct xfs_efi_log_item *
 150xfs_efi_init(
 151	struct xfs_mount	*mp,
 152	unsigned short		item_type,
 153	uint			nextents)
 154{
 155	struct xfs_efi_log_item	*efip;
 156
 157	ASSERT(item_type == XFS_LI_EFI || item_type == XFS_LI_EFI_RT);
 158	ASSERT(nextents > 0);
 159
 160	if (nextents > XFS_EFI_MAX_FAST_EXTENTS) {
 161		efip = kzalloc(xfs_efi_log_item_sizeof(nextents),
 162				GFP_KERNEL | __GFP_NOFAIL);
 163	} else {
 164		efip = kmem_cache_zalloc(xfs_efi_cache,
 165					 GFP_KERNEL | __GFP_NOFAIL);
 166	}
 167
 168	xfs_log_item_init(mp, &efip->efi_item, item_type, &xfs_efi_item_ops);
 169	efip->efi_format.efi_nextents = nextents;
 170	efip->efi_format.efi_id = (uintptr_t)(void *)efip;
 171	atomic_set(&efip->efi_next_extent, 0);
 172	atomic_set(&efip->efi_refcount, 2);
 173
 174	return efip;
 175}
 176
 177/*
 178 * Copy an EFI format buffer from the given buf, and into the destination
 179 * EFI format structure.
 180 * The given buffer can be in 32 bit or 64 bit form (which has different padding),
 181 * one of which will be the native format for this kernel.
 182 * It will handle the conversion of formats if necessary.
 183 */
 184STATIC int
 185xfs_efi_copy_format(
 186	struct kvec			*buf,
 187	struct xfs_efi_log_format	*dst_efi_fmt)
 188{
 189	struct xfs_efi_log_format	*src_efi_fmt = buf->iov_base;
 190	uint				len, len32, len64, i;
 191
 192	len = xfs_efi_log_format_sizeof(src_efi_fmt->efi_nextents);
 193	len32 = xfs_efi_log_format32_sizeof(src_efi_fmt->efi_nextents);
 194	len64 = xfs_efi_log_format64_sizeof(src_efi_fmt->efi_nextents);
 195
 196	if (buf->iov_len == len) {
 197		memcpy(dst_efi_fmt, src_efi_fmt,
 198		       offsetof(struct xfs_efi_log_format, efi_extents));
 199		for (i = 0; i < src_efi_fmt->efi_nextents; i++)
 200			memcpy(&dst_efi_fmt->efi_extents[i],
 201			       &src_efi_fmt->efi_extents[i],
 202			       sizeof(struct xfs_extent));
 203		return 0;
 204	} else if (buf->iov_len == len32) {
 205		struct xfs_efi_log_format_32 *src_efi_fmt_32 = buf->iov_base;
 206
 207		dst_efi_fmt->efi_type     = src_efi_fmt_32->efi_type;
 208		dst_efi_fmt->efi_size     = src_efi_fmt_32->efi_size;
 209		dst_efi_fmt->efi_nextents = src_efi_fmt_32->efi_nextents;
 210		dst_efi_fmt->efi_id       = src_efi_fmt_32->efi_id;
 211		for (i = 0; i < dst_efi_fmt->efi_nextents; i++) {
 212			dst_efi_fmt->efi_extents[i].ext_start =
 213				src_efi_fmt_32->efi_extents[i].ext_start;
 214			dst_efi_fmt->efi_extents[i].ext_len =
 215				src_efi_fmt_32->efi_extents[i].ext_len;
 216		}
 217		return 0;
 218	} else if (buf->iov_len == len64) {
 219		struct xfs_efi_log_format_64 *src_efi_fmt_64 = buf->iov_base;
 220
 221		dst_efi_fmt->efi_type     = src_efi_fmt_64->efi_type;
 222		dst_efi_fmt->efi_size     = src_efi_fmt_64->efi_size;
 223		dst_efi_fmt->efi_nextents = src_efi_fmt_64->efi_nextents;
 224		dst_efi_fmt->efi_id       = src_efi_fmt_64->efi_id;
 225		for (i = 0; i < dst_efi_fmt->efi_nextents; i++) {
 226			dst_efi_fmt->efi_extents[i].ext_start =
 227				src_efi_fmt_64->efi_extents[i].ext_start;
 228			dst_efi_fmt->efi_extents[i].ext_len =
 229				src_efi_fmt_64->efi_extents[i].ext_len;
 230		}
 231		return 0;
 232	}
 233	XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, NULL, buf->iov_base,
 234			buf->iov_len);
 235	return -EFSCORRUPTED;
 236}
 237
 238static inline struct xfs_efd_log_item *EFD_ITEM(struct xfs_log_item *lip)
 239{
 240	return container_of(lip, struct xfs_efd_log_item, efd_item);
 241}
 242
 243STATIC void
 244xfs_efd_item_free(struct xfs_efd_log_item *efdp)
 245{
 246	kvfree(efdp->efd_item.li_lv_shadow);
 247	if (efdp->efd_format.efd_nextents > XFS_EFD_MAX_FAST_EXTENTS)
 248		kfree(efdp);
 249	else
 250		kmem_cache_free(xfs_efd_cache, efdp);
 251}
 252
 253STATIC void
 254xfs_efd_item_size(
 255	struct xfs_log_item	*lip,
 256	int			*nvecs,
 257	int			*nbytes)
 258{
 259	struct xfs_efd_log_item	*efdp = EFD_ITEM(lip);
 260
 261	*nvecs += 1;
 262	*nbytes += xfs_efd_log_format_sizeof(efdp->efd_format.efd_nextents);
 263}
 264
 265unsigned int xfs_efd_log_space(unsigned int nr)
 266{
 267	return xlog_item_space(1, xfs_efd_log_format_sizeof(nr));
 268}
 269
 270/*
 271 * This is called to fill in the vector of log iovecs for the
 272 * given efd log item. We use only 1 iovec, and we point that
 273 * at the efd_log_format structure embedded in the efd item.
 274 * It is at this point that we assert that all of the extent
 275 * slots in the efd item have been filled.
 276 */
 277STATIC void
 278xfs_efd_item_format(
 279	struct xfs_log_item	*lip,
 280	struct xfs_log_vec	*lv)
 281{
 282	struct xfs_efd_log_item	*efdp = EFD_ITEM(lip);
 283	struct xfs_log_iovec	*vecp = NULL;
 284
 285	ASSERT(efdp->efd_next_extent == efdp->efd_format.efd_nextents);
 286	ASSERT(lip->li_type == XFS_LI_EFD || lip->li_type == XFS_LI_EFD_RT);
 287
 288	efdp->efd_format.efd_type = lip->li_type;
 289	efdp->efd_format.efd_size = 1;
 290
 291	xlog_copy_iovec(lv, &vecp, XLOG_REG_TYPE_EFD_FORMAT, &efdp->efd_format,
 292			xfs_efd_log_format_sizeof(efdp->efd_format.efd_nextents));
 293}
 294
 295/*
 296 * The EFD is either committed or aborted if the transaction is cancelled. If
 297 * the transaction is cancelled, drop our reference to the EFI and free the EFD.
 298 */
 299STATIC void
 300xfs_efd_item_release(
 301	struct xfs_log_item	*lip)
 302{
 303	struct xfs_efd_log_item	*efdp = EFD_ITEM(lip);
 304
 305	xfs_efi_release(efdp->efd_efip);
 306	xfs_efd_item_free(efdp);
 307}
 308
 309static struct xfs_log_item *
 310xfs_efd_item_intent(
 311	struct xfs_log_item	*lip)
 312{
 313	return &EFD_ITEM(lip)->efd_efip->efi_item;
 314}
 315
 316static const struct xfs_item_ops xfs_efd_item_ops = {
 317	.flags		= XFS_ITEM_RELEASE_WHEN_COMMITTED |
 318			  XFS_ITEM_INTENT_DONE,
 319	.iop_size	= xfs_efd_item_size,
 320	.iop_format	= xfs_efd_item_format,
 321	.iop_release	= xfs_efd_item_release,
 322	.iop_intent	= xfs_efd_item_intent,
 323};
 324
 325static inline struct xfs_extent_free_item *xefi_entry(const struct list_head *e)
 326{
 327	return list_entry(e, struct xfs_extent_free_item, xefi_list);
 328}
 329
 330static inline bool
 331xfs_efi_item_isrt(const struct xfs_log_item *lip)
 332{
 333	ASSERT(lip->li_type == XFS_LI_EFI || lip->li_type == XFS_LI_EFI_RT);
 334
 335	return lip->li_type == XFS_LI_EFI_RT;
 336}
 337
 338/*
 339 * Fill the EFD with all extents from the EFI when we need to roll the
 340 * transaction and continue with a new EFI.
 341 *
 342 * This simply copies all the extents in the EFI to the EFD rather than make
 343 * assumptions about which extents in the EFI have already been processed. We
 344 * currently keep the xefi list in the same order as the EFI extent list, but
 345 * that may not always be the case. Copying everything avoids leaving a landmine
 346 * were we fail to cancel all the extents in an EFI if the xefi list is
 347 * processed in a different order to the extents in the EFI.
 348 */
 349static void
 350xfs_efd_from_efi(
 351	struct xfs_efd_log_item	*efdp)
 352{
 353	struct xfs_efi_log_item *efip = efdp->efd_efip;
 354	uint                    i;
 355
 356	ASSERT(efip->efi_format.efi_nextents > 0);
 357	ASSERT(efdp->efd_next_extent < efip->efi_format.efi_nextents);
 358
 359	for (i = 0; i < efip->efi_format.efi_nextents; i++) {
 360	       efdp->efd_format.efd_extents[i] =
 361		       efip->efi_format.efi_extents[i];
 362	}
 363	efdp->efd_next_extent = efip->efi_format.efi_nextents;
 364}
 365
 366static void
 367xfs_efd_add_extent(
 368	struct xfs_efd_log_item		*efdp,
 369	struct xfs_extent_free_item	*xefi)
 370{
 371	struct xfs_extent		*extp;
 372
 373	ASSERT(efdp->efd_next_extent < efdp->efd_format.efd_nextents);
 374
 375	extp = &efdp->efd_format.efd_extents[efdp->efd_next_extent];
 376	extp->ext_start = xefi->xefi_startblock;
 377	extp->ext_len = xefi->xefi_blockcount;
 378
 379	efdp->efd_next_extent++;
 380}
 381
 382/* Sort bmap items by AG. */
 383static int
 384xfs_extent_free_diff_items(
 385	void				*priv,
 386	const struct list_head		*a,
 387	const struct list_head		*b)
 388{
 389	struct xfs_extent_free_item	*ra = xefi_entry(a);
 390	struct xfs_extent_free_item	*rb = xefi_entry(b);
 391
 392	return ra->xefi_group->xg_gno - rb->xefi_group->xg_gno;
 393}
 394
 395/* Log a free extent to the intent item. */
 396STATIC void
 397xfs_extent_free_log_item(
 398	struct xfs_trans		*tp,
 399	struct xfs_efi_log_item		*efip,
 400	struct xfs_extent_free_item	*xefi)
 401{
 402	uint				next_extent;
 403	struct xfs_extent		*extp;
 404
 405	/*
 406	 * atomic_inc_return gives us the value after the increment;
 407	 * we want to use it as an array index so we need to subtract 1 from
 408	 * it.
 409	 */
 410	next_extent = atomic_inc_return(&efip->efi_next_extent) - 1;
 411	ASSERT(next_extent < efip->efi_format.efi_nextents);
 412	extp = &efip->efi_format.efi_extents[next_extent];
 413	extp->ext_start = xefi->xefi_startblock;
 414	extp->ext_len = xefi->xefi_blockcount;
 415}
 416
 417static struct xfs_log_item *
 418__xfs_extent_free_create_intent(
 419	struct xfs_trans		*tp,
 420	struct list_head		*items,
 421	unsigned int			count,
 422	bool				sort,
 423	unsigned short			item_type)
 424{
 425	struct xfs_mount		*mp = tp->t_mountp;
 426	struct xfs_efi_log_item		*efip;
 427	struct xfs_extent_free_item	*xefi;
 428
 429	ASSERT(count > 0);
 430
 431	efip = xfs_efi_init(mp, item_type, count);
 432	if (sort)
 433		list_sort(mp, items, xfs_extent_free_diff_items);
 434	list_for_each_entry(xefi, items, xefi_list)
 435		xfs_extent_free_log_item(tp, efip, xefi);
 436	return &efip->efi_item;
 437}
 438
 439static struct xfs_log_item *
 440xfs_extent_free_create_intent(
 441	struct xfs_trans		*tp,
 442	struct list_head		*items,
 443	unsigned int			count,
 444	bool				sort)
 445{
 446	return __xfs_extent_free_create_intent(tp, items, count, sort,
 447			XFS_LI_EFI);
 448}
 449
 450static inline unsigned short
 451xfs_efd_type_from_efi(const struct xfs_efi_log_item *efip)
 452{
 453	return xfs_efi_item_isrt(&efip->efi_item) ?  XFS_LI_EFD_RT : XFS_LI_EFD;
 454}
 455
 456/* Get an EFD so we can process all the free extents. */
 457static struct xfs_log_item *
 458xfs_extent_free_create_done(
 459	struct xfs_trans		*tp,
 460	struct xfs_log_item		*intent,
 461	unsigned int			count)
 462{
 463	struct xfs_efi_log_item		*efip = EFI_ITEM(intent);
 464	struct xfs_efd_log_item		*efdp;
 465
 466	ASSERT(count > 0);
 467
 468	if (count > XFS_EFD_MAX_FAST_EXTENTS) {
 469		efdp = kzalloc(xfs_efd_log_item_sizeof(count),
 470				GFP_KERNEL | __GFP_NOFAIL);
 471	} else {
 472		efdp = kmem_cache_zalloc(xfs_efd_cache,
 473					GFP_KERNEL | __GFP_NOFAIL);
 474	}
 475
 476	xfs_log_item_init(tp->t_mountp, &efdp->efd_item,
 477			xfs_efd_type_from_efi(efip), &xfs_efd_item_ops);
 478	efdp->efd_efip = efip;
 479	efdp->efd_format.efd_nextents = count;
 480	efdp->efd_format.efd_efi_id = efip->efi_format.efi_id;
 481
 482	return &efdp->efd_item;
 483}
 484
 485static inline const struct xfs_defer_op_type *
 486xefi_ops(
 487	struct xfs_extent_free_item	*xefi)
 488{
 489	if (xfs_efi_is_realtime(xefi))
 490		return &xfs_rtextent_free_defer_type;
 491	if (xefi->xefi_agresv == XFS_AG_RESV_AGFL)
 492		return &xfs_agfl_free_defer_type;
 493	return &xfs_extent_free_defer_type;
 494}
 495
 496/* Add this deferred EFI to the transaction. */
 497void
 498xfs_extent_free_defer_add(
 499	struct xfs_trans		*tp,
 500	struct xfs_extent_free_item	*xefi,
 501	struct xfs_defer_pending	**dfpp)
 502{
 503	struct xfs_mount		*mp = tp->t_mountp;
 504
 505	xefi->xefi_group = xfs_group_intent_get(mp, xefi->xefi_startblock,
 506			xfs_efi_is_realtime(xefi) ? XG_TYPE_RTG : XG_TYPE_AG);
 507
 508	trace_xfs_extent_free_defer(mp, xefi);
 509	*dfpp = xfs_defer_add(tp, &xefi->xefi_list, xefi_ops(xefi));
 510}
 511
 512/* Cancel a free extent. */
 513STATIC void
 514xfs_extent_free_cancel_item(
 515	struct list_head		*item)
 516{
 517	struct xfs_extent_free_item	*xefi = xefi_entry(item);
 518
 519	xfs_group_intent_put(xefi->xefi_group);
 520	kmem_cache_free(xfs_extfree_item_cache, xefi);
 521}
 522
 523/* Process a free extent. */
 524STATIC int
 525xfs_extent_free_finish_item(
 526	struct xfs_trans		*tp,
 527	struct xfs_log_item		*done,
 528	struct list_head		*item,
 529	struct xfs_btree_cur		**state)
 530{
 531	struct xfs_owner_info		oinfo = { };
 532	struct xfs_extent_free_item	*xefi = xefi_entry(item);
 533	struct xfs_efd_log_item		*efdp = EFD_ITEM(done);
 534	struct xfs_mount		*mp = tp->t_mountp;
 535	xfs_agblock_t			agbno;
 536	int				error = 0;
 537
 538	agbno = XFS_FSB_TO_AGBNO(mp, xefi->xefi_startblock);
 539
 540	oinfo.oi_owner = xefi->xefi_owner;
 541	if (xefi->xefi_flags & XFS_EFI_ATTR_FORK)
 542		oinfo.oi_flags |= XFS_OWNER_INFO_ATTR_FORK;
 543	if (xefi->xefi_flags & XFS_EFI_BMBT_BLOCK)
 544		oinfo.oi_flags |= XFS_OWNER_INFO_BMBT_BLOCK;
 545
 546	trace_xfs_extent_free_deferred(mp, xefi);
 547
 548	/*
 549	 * If we need a new transaction to make progress, the caller will log a
 550	 * new EFI with the current contents. It will also log an EFD to cancel
 551	 * the existing EFI, and so we need to copy all the unprocessed extents
 552	 * in this EFI to the EFD so this works correctly.
 553	 */
 554	if (!(xefi->xefi_flags & XFS_EFI_CANCELLED))
 555		error = __xfs_free_extent(tp, to_perag(xefi->xefi_group), agbno,
 556				xefi->xefi_blockcount, &oinfo, xefi->xefi_agresv,
 557				xefi->xefi_flags & XFS_EFI_SKIP_DISCARD);
 558	if (error == -EAGAIN) {
 559		xfs_efd_from_efi(efdp);
 560		return error;
 561	}
 562
 563	xfs_efd_add_extent(efdp, xefi);
 564	xfs_extent_free_cancel_item(item);
 565	return error;
 566}
 567
 568/* Abort all pending EFIs. */
 569STATIC void
 570xfs_extent_free_abort_intent(
 571	struct xfs_log_item		*intent)
 572{
 573	xfs_efi_release(EFI_ITEM(intent));
 574}
 575
 576/*
 577 * AGFL blocks are accounted differently in the reserve pools and are not
 578 * inserted into the busy extent list.
 579 */
 580STATIC int
 581xfs_agfl_free_finish_item(
 582	struct xfs_trans		*tp,
 583	struct xfs_log_item		*done,
 584	struct list_head		*item,
 585	struct xfs_btree_cur		**state)
 586{
 587	struct xfs_owner_info		oinfo = { };
 588	struct xfs_mount		*mp = tp->t_mountp;
 589	struct xfs_efd_log_item		*efdp = EFD_ITEM(done);
 590	struct xfs_extent_free_item	*xefi = xefi_entry(item);
 591	struct xfs_buf			*agbp;
 592	int				error;
 593	xfs_agblock_t			agbno;
 594
 595	ASSERT(xefi->xefi_blockcount == 1);
 596	agbno = XFS_FSB_TO_AGBNO(mp, xefi->xefi_startblock);
 597	oinfo.oi_owner = xefi->xefi_owner;
 598
 599	trace_xfs_agfl_free_deferred(mp, xefi);
 600
 601	error = xfs_alloc_read_agf(to_perag(xefi->xefi_group), tp, 0, &agbp);
 602	if (!error)
 603		error = xfs_free_ag_extent(tp, agbp, agbno, 1, &oinfo,
 604				XFS_AG_RESV_AGFL);
 605
 606	xfs_efd_add_extent(efdp, xefi);
 607	xfs_extent_free_cancel_item(&xefi->xefi_list);
 608	return error;
 609}
 610
 611/* Is this recovered EFI ok? */
 612static inline bool
 613xfs_efi_validate_ext(
 614	struct xfs_mount		*mp,
 615	bool				isrt,
 616	struct xfs_extent		*extp)
 617{
 618	if (isrt)
 619		return xfs_verify_rtbext(mp, extp->ext_start, extp->ext_len);
 620
 621	return xfs_verify_fsbext(mp, extp->ext_start, extp->ext_len);
 622}
 623
 624static inline void
 625xfs_efi_recover_work(
 626	struct xfs_mount		*mp,
 627	struct xfs_defer_pending	*dfp,
 628	bool				isrt,
 629	struct xfs_extent		*extp)
 630{
 631	struct xfs_extent_free_item	*xefi;
 632
 633	xefi = kmem_cache_zalloc(xfs_extfree_item_cache,
 634			       GFP_KERNEL | __GFP_NOFAIL);
 635	xefi->xefi_startblock = extp->ext_start;
 636	xefi->xefi_blockcount = extp->ext_len;
 637	xefi->xefi_agresv = XFS_AG_RESV_NONE;
 638	xefi->xefi_owner = XFS_RMAP_OWN_UNKNOWN;
 639	xefi->xefi_group = xfs_group_intent_get(mp, extp->ext_start,
 640			isrt ? XG_TYPE_RTG : XG_TYPE_AG);
 641	if (isrt)
 642		xefi->xefi_flags |= XFS_EFI_REALTIME;
 643
 644	xfs_defer_add_item(dfp, &xefi->xefi_list);
 645}
 646
 647/*
 648 * Process an extent free intent item that was recovered from
 649 * the log.  We need to free the extents that it describes.
 650 */
 651STATIC int
 652xfs_extent_free_recover_work(
 653	struct xfs_defer_pending	*dfp,
 654	struct list_head		*capture_list)
 655{
 656	struct xfs_trans_res		resv;
 657	struct xfs_log_item		*lip = dfp->dfp_intent;
 658	struct xfs_efi_log_item		*efip = EFI_ITEM(lip);
 659	struct xfs_mount		*mp = lip->li_log->l_mp;
 660	struct xfs_trans		*tp;
 661	int				i;
 662	int				error = 0;
 663	bool				isrt = xfs_efi_item_isrt(lip);
 664
 665	/*
 666	 * First check the validity of the extents described by the EFI.  If
 667	 * any are bad, then assume that all are bad and just toss the EFI.
 668	 * Mixing RT and non-RT extents in the same EFI item is not allowed.
 669	 */
 670	for (i = 0; i < efip->efi_format.efi_nextents; i++) {
 671		if (!xfs_efi_validate_ext(mp, isrt,
 672					&efip->efi_format.efi_extents[i])) {
 673			XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp,
 674					&efip->efi_format,
 675					sizeof(efip->efi_format));
 676			return -EFSCORRUPTED;
 677		}
 678
 679		xfs_efi_recover_work(mp, dfp, isrt,
 680				&efip->efi_format.efi_extents[i]);
 681	}
 682
 683	resv = xlog_recover_resv(&M_RES(mp)->tr_itruncate);
 684	error = xfs_trans_alloc(mp, &resv, 0, 0, 0, &tp);
 685	if (error)
 686		return error;
 687
 688	error = xlog_recover_finish_intent(tp, dfp);
 689	if (error == -EFSCORRUPTED)
 690		XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp,
 691				&efip->efi_format,
 692				sizeof(efip->efi_format));
 693	if (error)
 694		goto abort_error;
 695
 696	return xfs_defer_ops_capture_and_commit(tp, capture_list);
 697
 698abort_error:
 699	xfs_trans_cancel(tp);
 700	return error;
 701}
 702
 703/* Relog an intent item to push the log tail forward. */
 704static struct xfs_log_item *
 705xfs_extent_free_relog_intent(
 706	struct xfs_trans		*tp,
 707	struct xfs_log_item		*intent,
 708	struct xfs_log_item		*done_item)
 709{
 710	struct xfs_efd_log_item		*efdp = EFD_ITEM(done_item);
 711	struct xfs_efi_log_item		*efip;
 712	struct xfs_extent		*extp;
 713	unsigned int			count;
 714
 715	count = EFI_ITEM(intent)->efi_format.efi_nextents;
 716	extp = EFI_ITEM(intent)->efi_format.efi_extents;
 717
 718	ASSERT(intent->li_type == XFS_LI_EFI || intent->li_type == XFS_LI_EFI_RT);
 719
 720	efdp->efd_next_extent = count;
 721	memcpy(efdp->efd_format.efd_extents, extp, count * sizeof(*extp));
 722
 723	efip = xfs_efi_init(tp->t_mountp, intent->li_type, count);
 724	memcpy(efip->efi_format.efi_extents, extp, count * sizeof(*extp));
 725	atomic_set(&efip->efi_next_extent, count);
 726
 727	return &efip->efi_item;
 728}
 729
 730const struct xfs_defer_op_type xfs_extent_free_defer_type = {
 731	.name		= "extent_free",
 732	.max_items	= XFS_EFI_MAX_FAST_EXTENTS,
 733	.create_intent	= xfs_extent_free_create_intent,
 734	.abort_intent	= xfs_extent_free_abort_intent,
 735	.create_done	= xfs_extent_free_create_done,
 736	.finish_item	= xfs_extent_free_finish_item,
 737	.cancel_item	= xfs_extent_free_cancel_item,
 738	.recover_work	= xfs_extent_free_recover_work,
 739	.relog_intent	= xfs_extent_free_relog_intent,
 740};
 741
 742/* sub-type with special handling for AGFL deferred frees */
 743const struct xfs_defer_op_type xfs_agfl_free_defer_type = {
 744	.name		= "agfl_free",
 745	.max_items	= XFS_EFI_MAX_FAST_EXTENTS,
 746	.create_intent	= xfs_extent_free_create_intent,
 747	.abort_intent	= xfs_extent_free_abort_intent,
 748	.create_done	= xfs_extent_free_create_done,
 749	.finish_item	= xfs_agfl_free_finish_item,
 750	.cancel_item	= xfs_extent_free_cancel_item,
 751	.recover_work	= xfs_extent_free_recover_work,
 752	.relog_intent	= xfs_extent_free_relog_intent,
 753};
 754
 755#ifdef CONFIG_XFS_RT
 756/* Create a realtime extent freeing */
 757static struct xfs_log_item *
 758xfs_rtextent_free_create_intent(
 759	struct xfs_trans		*tp,
 760	struct list_head		*items,
 761	unsigned int			count,
 762	bool				sort)
 763{
 764	return __xfs_extent_free_create_intent(tp, items, count, sort,
 765			XFS_LI_EFI_RT);
 766}
 767
 768/* Process a free realtime extent. */
 769STATIC int
 770xfs_rtextent_free_finish_item(
 771	struct xfs_trans		*tp,
 772	struct xfs_log_item		*done,
 773	struct list_head		*item,
 774	struct xfs_btree_cur		**state)
 775{
 776	struct xfs_mount		*mp = tp->t_mountp;
 777	struct xfs_extent_free_item	*xefi = xefi_entry(item);
 778	struct xfs_efd_log_item		*efdp = EFD_ITEM(done);
 779	struct xfs_rtgroup		**rtgp = (struct xfs_rtgroup **)state;
 780	int				error = 0;
 781
 782	trace_xfs_extent_free_deferred(mp, xefi);
 783
 784	if (xefi->xefi_flags & XFS_EFI_CANCELLED)
 785		goto done;
 786
 787	if (*rtgp != to_rtg(xefi->xefi_group)) {
 788		unsigned int		lock_flags;
 789
 790		if (xfs_has_zoned(mp))
 791			lock_flags = XFS_RTGLOCK_RMAP;
 792		else
 793			lock_flags = XFS_RTGLOCK_BITMAP;
 794
 795		*rtgp = to_rtg(xefi->xefi_group);
 796		xfs_rtgroup_lock(*rtgp, lock_flags);
 797		xfs_rtgroup_trans_join(tp, *rtgp, lock_flags);
 798	}
 799
 800	if (xfs_has_zoned(mp)) {
 801		error = xfs_zone_free_blocks(tp, *rtgp, xefi->xefi_startblock,
 802				xefi->xefi_blockcount);
 803	} else {
 804		error = xfs_rtfree_blocks(tp, *rtgp, xefi->xefi_startblock,
 805				xefi->xefi_blockcount);
 806	}
 807
 808	if (error == -EAGAIN) {
 809		xfs_efd_from_efi(efdp);
 810		return error;
 811	}
 812done:
 813	xfs_efd_add_extent(efdp, xefi);
 814	xfs_extent_free_cancel_item(item);
 815	return error;
 816}
 817
 818const struct xfs_defer_op_type xfs_rtextent_free_defer_type = {
 819	.name		= "rtextent_free",
 820	.max_items	= XFS_EFI_MAX_FAST_EXTENTS,
 821	.create_intent	= xfs_rtextent_free_create_intent,
 822	.abort_intent	= xfs_extent_free_abort_intent,
 823	.create_done	= xfs_extent_free_create_done,
 824	.finish_item	= xfs_rtextent_free_finish_item,
 825	.cancel_item	= xfs_extent_free_cancel_item,
 826	.recover_work	= xfs_extent_free_recover_work,
 827	.relog_intent	= xfs_extent_free_relog_intent,
 828};
 829#else
 830const struct xfs_defer_op_type xfs_rtextent_free_defer_type = {
 831	.name		= "rtextent_free",
 832};
 833#endif /* CONFIG_XFS_RT */
 834
 835STATIC bool
 836xfs_efi_item_match(
 837	struct xfs_log_item	*lip,
 838	uint64_t		intent_id)
 839{
 840	return EFI_ITEM(lip)->efi_format.efi_id == intent_id;
 841}
 842
 843static const struct xfs_item_ops xfs_efi_item_ops = {
 844	.flags		= XFS_ITEM_INTENT,
 845	.iop_size	= xfs_efi_item_size,
 846	.iop_format	= xfs_efi_item_format,
 847	.iop_unpin	= xfs_efi_item_unpin,
 848	.iop_release	= xfs_efi_item_release,
 849	.iop_match	= xfs_efi_item_match,
 850};
 851
 852/*
 853 * This routine is called to create an in-core extent free intent
 854 * item from the efi format structure which was logged on disk.
 855 * It allocates an in-core efi, copies the extents from the format
 856 * structure into it, and adds the efi to the AIL with the given
 857 * LSN.
 858 */
 859STATIC int
 860xlog_recover_efi_commit_pass2(
 861	struct xlog			*log,
 862	struct list_head		*buffer_list,
 863	struct xlog_recover_item	*item,
 864	xfs_lsn_t			lsn)
 865{
 866	struct xfs_mount		*mp = log->l_mp;
 867	struct xfs_efi_log_item		*efip;
 868	struct xfs_efi_log_format	*efi_formatp;
 869	int				error;
 870
 871	efi_formatp = item->ri_buf[0].iov_base;
 872
 873	if (item->ri_buf[0].iov_len < xfs_efi_log_format_sizeof(0)) {
 874		XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp,
 875				item->ri_buf[0].iov_base, item->ri_buf[0].iov_len);
 876		return -EFSCORRUPTED;
 877	}
 878
 879	efip = xfs_efi_init(mp, ITEM_TYPE(item), efi_formatp->efi_nextents);
 880	error = xfs_efi_copy_format(&item->ri_buf[0], &efip->efi_format);
 881	if (error) {
 882		xfs_efi_item_free(efip);
 883		return error;
 884	}
 885	atomic_set(&efip->efi_next_extent, efi_formatp->efi_nextents);
 886
 887	xlog_recover_intent_item(log, &efip->efi_item, lsn,
 888			&xfs_extent_free_defer_type);
 889	return 0;
 890}
 891
 892const struct xlog_recover_item_ops xlog_efi_item_ops = {
 893	.item_type		= XFS_LI_EFI,
 894	.commit_pass2		= xlog_recover_efi_commit_pass2,
 895};
 896
 897#ifdef CONFIG_XFS_RT
 898STATIC int
 899xlog_recover_rtefi_commit_pass2(
 900	struct xlog			*log,
 901	struct list_head		*buffer_list,
 902	struct xlog_recover_item	*item,
 903	xfs_lsn_t			lsn)
 904{
 905	struct xfs_mount		*mp = log->l_mp;
 906	struct xfs_efi_log_item		*efip;
 907	struct xfs_efi_log_format	*efi_formatp;
 908	int				error;
 909
 910	efi_formatp = item->ri_buf[0].iov_base;
 911
 912	if (item->ri_buf[0].iov_len < xfs_efi_log_format_sizeof(0)) {
 913		XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp,
 914				item->ri_buf[0].iov_base, item->ri_buf[0].iov_len);
 915		return -EFSCORRUPTED;
 916	}
 917
 918	efip = xfs_efi_init(mp, ITEM_TYPE(item), efi_formatp->efi_nextents);
 919	error = xfs_efi_copy_format(&item->ri_buf[0], &efip->efi_format);
 920	if (error) {
 921		xfs_efi_item_free(efip);
 922		return error;
 923	}
 924	atomic_set(&efip->efi_next_extent, efi_formatp->efi_nextents);
 925
 926	xlog_recover_intent_item(log, &efip->efi_item, lsn,
 927			&xfs_rtextent_free_defer_type);
 928	return 0;
 929}
 930#else
 931STATIC int
 932xlog_recover_rtefi_commit_pass2(
 933	struct xlog			*log,
 934	struct list_head		*buffer_list,
 935	struct xlog_recover_item	*item,
 936	xfs_lsn_t			lsn)
 937{
 938	XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, log->l_mp,
 939			item->ri_buf[0].iov_base, item->ri_buf[0].iov_len);
 940	return -EFSCORRUPTED;
 941}
 942#endif
 943
 944const struct xlog_recover_item_ops xlog_rtefi_item_ops = {
 945	.item_type		= XFS_LI_EFI_RT,
 946	.commit_pass2		= xlog_recover_rtefi_commit_pass2,
 947};
 948
 949/*
 950 * This routine is called when an EFD format structure is found in a committed
 951 * transaction in the log. Its purpose is to cancel the corresponding EFI if it
 952 * was still in the log. To do this it searches the AIL for the EFI with an id
 953 * equal to that in the EFD format structure. If we find it we drop the EFD
 954 * reference, which removes the EFI from the AIL and frees it.
 955 */
 956STATIC int
 957xlog_recover_efd_commit_pass2(
 958	struct xlog			*log,
 959	struct list_head		*buffer_list,
 960	struct xlog_recover_item	*item,
 961	xfs_lsn_t			lsn)
 962{
 963	struct xfs_efd_log_format	*efd_formatp;
 964	int				buflen = item->ri_buf[0].iov_len;
 965
 966	efd_formatp = item->ri_buf[0].iov_base;
 967
 968	if (buflen < sizeof(struct xfs_efd_log_format)) {
 969		XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, log->l_mp,
 970				efd_formatp, buflen);
 971		return -EFSCORRUPTED;
 972	}
 973
 974	if (item->ri_buf[0].iov_len != xfs_efd_log_format32_sizeof(
 975						efd_formatp->efd_nextents) &&
 976	    item->ri_buf[0].iov_len != xfs_efd_log_format64_sizeof(
 977						efd_formatp->efd_nextents)) {
 978		XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, log->l_mp,
 979				efd_formatp, buflen);
 980		return -EFSCORRUPTED;
 981	}
 982
 983	xlog_recover_release_intent(log, XFS_LI_EFI, efd_formatp->efd_efi_id);
 984	return 0;
 985}
 986
 987const struct xlog_recover_item_ops xlog_efd_item_ops = {
 988	.item_type		= XFS_LI_EFD,
 989	.commit_pass2		= xlog_recover_efd_commit_pass2,
 990};
 991
 992#ifdef CONFIG_XFS_RT
 993STATIC int
 994xlog_recover_rtefd_commit_pass2(
 995	struct xlog			*log,
 996	struct list_head		*buffer_list,
 997	struct xlog_recover_item	*item,
 998	xfs_lsn_t			lsn)
 999{
1000	struct xfs_efd_log_format	*efd_formatp;
1001	int				buflen = item->ri_buf[0].iov_len;
1002
1003	efd_formatp = item->ri_buf[0].iov_base;
1004
1005	if (buflen < sizeof(struct xfs_efd_log_format)) {
1006		XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, log->l_mp,
1007				efd_formatp, buflen);
1008		return -EFSCORRUPTED;
1009	}
1010
1011	if (item->ri_buf[0].iov_len != xfs_efd_log_format32_sizeof(
1012						efd_formatp->efd_nextents) &&
1013	    item->ri_buf[0].iov_len != xfs_efd_log_format64_sizeof(
1014						efd_formatp->efd_nextents)) {
1015		XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, log->l_mp,
1016				efd_formatp, buflen);
1017		return -EFSCORRUPTED;
1018	}
1019
1020	xlog_recover_release_intent(log, XFS_LI_EFI_RT,
1021			efd_formatp->efd_efi_id);
1022	return 0;
1023}
1024#else
1025# define xlog_recover_rtefd_commit_pass2	xlog_recover_rtefi_commit_pass2
1026#endif
1027
1028const struct xlog_recover_item_ops xlog_rtefd_item_ops = {
1029	.item_type		= XFS_LI_EFD_RT,
1030	.commit_pass2		= xlog_recover_rtefd_commit_pass2,
1031};
~/ Read-only file preview.