xfs_extfree_item.c 17.4 KB
Newer Older
D
Dave Chinner 已提交
1
// SPDX-License-Identifier: GPL-2.0
L
Linus Torvalds 已提交
2
/*
3 4
 * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc.
 * All Rights Reserved.
L
Linus Torvalds 已提交
5 6
 */
#include "xfs.h"
7
#include "xfs_fs.h"
8
#include "xfs_format.h"
9 10
#include "xfs_log_format.h"
#include "xfs_trans_resv.h"
11
#include "xfs_bit.h"
12
#include "xfs_shared.h"
L
Linus Torvalds 已提交
13
#include "xfs_mount.h"
14
#include "xfs_defer.h"
15
#include "xfs_trans.h"
L
Linus Torvalds 已提交
16 17
#include "xfs_trans_priv.h"
#include "xfs_extfree_item.h"
C
Christoph Hellwig 已提交
18
#include "xfs_log.h"
19 20
#include "xfs_btree.h"
#include "xfs_rmap.h"
21 22 23
#include "xfs_alloc.h"
#include "xfs_bmap.h"
#include "xfs_trace.h"
24
#include "xfs_error.h"
L
Linus Torvalds 已提交
25 26 27 28

kmem_zone_t	*xfs_efi_zone;
kmem_zone_t	*xfs_efd_zone;

29 30 31 32
static inline struct xfs_efi_log_item *EFI_ITEM(struct xfs_log_item *lip)
{
	return container_of(lip, struct xfs_efi_log_item, efi_item);
}
L
Linus Torvalds 已提交
33

34
void
35 36
xfs_efi_item_free(
	struct xfs_efi_log_item	*efip)
37
{
38
	kmem_free(efip->efi_item.li_lv_shadow);
39
	if (efip->efi_format.efi_nextents > XFS_EFI_MAX_FAST_EXTENTS)
40
		kmem_free(efip);
41
	else
42
		kmem_cache_free(xfs_efi_zone, efip);
43
}
L
Linus Torvalds 已提交
44

45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62
/*
 * Freeing the efi requires that we remove it from the AIL if it has already
 * been placed there. However, the EFI may not yet have been placed in the AIL
 * when called by xfs_efi_release() from EFD processing due to the ordering of
 * committed vs unpin operations in bulk insert operations. Hence the reference
 * count to ensure only the last caller frees the EFI.
 */
void
xfs_efi_release(
	struct xfs_efi_log_item	*efip)
{
	ASSERT(atomic_read(&efip->efi_refcount) > 0);
	if (atomic_dec_and_test(&efip->efi_refcount)) {
		xfs_trans_ail_remove(&efip->efi_item, SHUTDOWN_LOG_IO_ERROR);
		xfs_efi_item_free(efip);
	}
}

L
Linus Torvalds 已提交
63 64 65 66 67
/*
 * This returns the number of iovecs needed to log the given efi item.
 * We only need 1 iovec for an efi item.  It just logs the efi_log_format
 * structure.
 */
68 69 70 71 72 73 74 75 76
static inline int
xfs_efi_item_sizeof(
	struct xfs_efi_log_item *efip)
{
	return sizeof(struct xfs_efi_log_format) +
	       (efip->efi_format.efi_nextents - 1) * sizeof(xfs_extent_t);
}

STATIC void
77
xfs_efi_item_size(
78 79 80
	struct xfs_log_item	*lip,
	int			*nvecs,
	int			*nbytes)
L
Linus Torvalds 已提交
81
{
82 83
	*nvecs += 1;
	*nbytes += xfs_efi_item_sizeof(EFI_ITEM(lip));
L
Linus Torvalds 已提交
84 85 86 87 88 89 90 91 92 93
}

/*
 * This is called to fill in the vector of log iovecs for the
 * given efi log item. We use only 1 iovec, and we point that
 * at the efi_log_format structure embedded in the efi item.
 * It is at this point that we assert that all of the extent
 * slots in the efi item have been filled.
 */
STATIC void
94 95
xfs_efi_item_format(
	struct xfs_log_item	*lip,
96
	struct xfs_log_vec	*lv)
L
Linus Torvalds 已提交
97
{
98
	struct xfs_efi_log_item	*efip = EFI_ITEM(lip);
99
	struct xfs_log_iovec	*vecp = NULL;
L
Linus Torvalds 已提交
100

101 102
	ASSERT(atomic_read(&efip->efi_next_extent) ==
				efip->efi_format.efi_nextents);
L
Linus Torvalds 已提交
103 104 105 106

	efip->efi_format.efi_type = XFS_LI_EFI;
	efip->efi_format.efi_size = 1;

107
	xlog_copy_iovec(lv, &vecp, XLOG_REG_TYPE_EFI_FORMAT,
C
Christoph Hellwig 已提交
108 109
			&efip->efi_format,
			xfs_efi_item_sizeof(efip));
L
Linus Torvalds 已提交
110 111 112 113
}


/*
114 115 116 117 118 119
 * The unpin operation is the last place an EFI is manipulated in the log. It is
 * either inserted in the AIL or aborted in the event of a log I/O error. In
 * either case, the EFI transaction has been successfully committed to make it
 * this far. Therefore, we expect whoever committed the EFI to either construct
 * and commit the EFD or drop the EFD's reference in the event of error. Simply
 * drop the log's EFI reference now that the log is done with it.
L
Linus Torvalds 已提交
120 121
 */
STATIC void
122 123 124
xfs_efi_item_unpin(
	struct xfs_log_item	*lip,
	int			remove)
L
Linus Torvalds 已提交
125
{
126
	struct xfs_efi_log_item	*efip = EFI_ITEM(lip);
127
	xfs_efi_release(efip);
L
Linus Torvalds 已提交
128 129
}

130 131 132 133 134
/*
 * The EFI has been either committed or aborted if the transaction has been
 * cancelled. If the transaction was cancelled, an EFD isn't going to be
 * constructed and thus we free the EFI here directly.
 */
L
Linus Torvalds 已提交
135
STATIC void
C
Christoph Hellwig 已提交
136
xfs_efi_item_release(
137
	struct xfs_log_item	*lip)
L
Linus Torvalds 已提交
138
{
C
Christoph Hellwig 已提交
139
	xfs_efi_release(EFI_ITEM(lip));
L
Linus Torvalds 已提交
140 141
}

C
Christoph Hellwig 已提交
142
static const struct xfs_item_ops xfs_efi_item_ops = {
143 144 145
	.iop_size	= xfs_efi_item_size,
	.iop_format	= xfs_efi_item_format,
	.iop_unpin	= xfs_efi_item_unpin,
C
Christoph Hellwig 已提交
146
	.iop_release	= xfs_efi_item_release,
L
Linus Torvalds 已提交
147 148 149 150 151 152
};


/*
 * Allocate and initialize an efi item with the given number of extents.
 */
153 154 155 156
struct xfs_efi_log_item *
xfs_efi_init(
	struct xfs_mount	*mp,
	uint			nextents)
L
Linus Torvalds 已提交
157 158

{
159
	struct xfs_efi_log_item	*efip;
L
Linus Torvalds 已提交
160 161 162 163
	uint			size;

	ASSERT(nextents > 0);
	if (nextents > XFS_EFI_MAX_FAST_EXTENTS) {
164
		size = (uint)(sizeof(struct xfs_efi_log_item) +
L
Linus Torvalds 已提交
165
			((nextents - 1) * sizeof(xfs_extent_t)));
166
		efip = kmem_zalloc(size, 0);
L
Linus Torvalds 已提交
167
	} else {
168
		efip = kmem_zone_zalloc(xfs_efi_zone, 0);
L
Linus Torvalds 已提交
169 170
	}

171
	xfs_log_item_init(mp, &efip->efi_item, XFS_LI_EFI, &xfs_efi_item_ops);
L
Linus Torvalds 已提交
172
	efip->efi_format.efi_nextents = nextents;
173
	efip->efi_format.efi_id = (uintptr_t)(void *)efip;
174
	atomic_set(&efip->efi_next_extent, 0);
175
	atomic_set(&efip->efi_refcount, 2);
L
Linus Torvalds 已提交
176

177
	return efip;
L
Linus Torvalds 已提交
178 179
}

180 181 182 183 184 185 186 187 188 189
/*
 * Copy an EFI format buffer from the given buf, and into the destination
 * EFI format structure.
 * The given buffer can be in 32 bit or 64 bit form (which has different padding),
 * one of which will be the native format for this kernel.
 * It will handle the conversion of formats if necessary.
 */
int
xfs_efi_copy_format(xfs_log_iovec_t *buf, xfs_efi_log_format_t *dst_efi_fmt)
{
190
	xfs_efi_log_format_t *src_efi_fmt = buf->i_addr;
191 192 193 194 195 196 197 198 199 200 201 202
	uint i;
	uint len = sizeof(xfs_efi_log_format_t) + 
		(src_efi_fmt->efi_nextents - 1) * sizeof(xfs_extent_t);  
	uint len32 = sizeof(xfs_efi_log_format_32_t) + 
		(src_efi_fmt->efi_nextents - 1) * sizeof(xfs_extent_32_t);  
	uint len64 = sizeof(xfs_efi_log_format_64_t) + 
		(src_efi_fmt->efi_nextents - 1) * sizeof(xfs_extent_64_t);  

	if (buf->i_len == len) {
		memcpy((char *)dst_efi_fmt, (char*)src_efi_fmt, len);
		return 0;
	} else if (buf->i_len == len32) {
203
		xfs_efi_log_format_32_t *src_efi_fmt_32 = buf->i_addr;
204 205 206 207 208 209 210 211 212 213 214 215 216

		dst_efi_fmt->efi_type     = src_efi_fmt_32->efi_type;
		dst_efi_fmt->efi_size     = src_efi_fmt_32->efi_size;
		dst_efi_fmt->efi_nextents = src_efi_fmt_32->efi_nextents;
		dst_efi_fmt->efi_id       = src_efi_fmt_32->efi_id;
		for (i = 0; i < dst_efi_fmt->efi_nextents; i++) {
			dst_efi_fmt->efi_extents[i].ext_start =
				src_efi_fmt_32->efi_extents[i].ext_start;
			dst_efi_fmt->efi_extents[i].ext_len =
				src_efi_fmt_32->efi_extents[i].ext_len;
		}
		return 0;
	} else if (buf->i_len == len64) {
217
		xfs_efi_log_format_64_t *src_efi_fmt_64 = buf->i_addr;
218 219 220 221 222 223 224 225 226 227 228 229 230

		dst_efi_fmt->efi_type     = src_efi_fmt_64->efi_type;
		dst_efi_fmt->efi_size     = src_efi_fmt_64->efi_size;
		dst_efi_fmt->efi_nextents = src_efi_fmt_64->efi_nextents;
		dst_efi_fmt->efi_id       = src_efi_fmt_64->efi_id;
		for (i = 0; i < dst_efi_fmt->efi_nextents; i++) {
			dst_efi_fmt->efi_extents[i].ext_start =
				src_efi_fmt_64->efi_extents[i].ext_start;
			dst_efi_fmt->efi_extents[i].ext_len =
				src_efi_fmt_64->efi_extents[i].ext_len;
		}
		return 0;
	}
231
	XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_LOW, NULL);
D
Dave Chinner 已提交
232
	return -EFSCORRUPTED;
233 234
}

235
static inline struct xfs_efd_log_item *EFD_ITEM(struct xfs_log_item *lip)
236
{
237 238
	return container_of(lip, struct xfs_efd_log_item, efd_item);
}
L
Linus Torvalds 已提交
239

240 241 242
STATIC void
xfs_efd_item_free(struct xfs_efd_log_item *efdp)
{
243
	kmem_free(efdp->efd_item.li_lv_shadow);
244
	if (efdp->efd_format.efd_nextents > XFS_EFD_MAX_FAST_EXTENTS)
245
		kmem_free(efdp);
246
	else
247
		kmem_cache_free(xfs_efd_zone, efdp);
248
}
L
Linus Torvalds 已提交
249 250 251 252 253 254

/*
 * This returns the number of iovecs needed to log the given efd item.
 * We only need 1 iovec for an efd item.  It just logs the efd_log_format
 * structure.
 */
255 256 257 258 259 260 261 262 263
static inline int
xfs_efd_item_sizeof(
	struct xfs_efd_log_item *efdp)
{
	return sizeof(xfs_efd_log_format_t) +
	       (efdp->efd_format.efd_nextents - 1) * sizeof(xfs_extent_t);
}

STATIC void
264
xfs_efd_item_size(
265 266 267
	struct xfs_log_item	*lip,
	int			*nvecs,
	int			*nbytes)
L
Linus Torvalds 已提交
268
{
269 270
	*nvecs += 1;
	*nbytes += xfs_efd_item_sizeof(EFD_ITEM(lip));
L
Linus Torvalds 已提交
271 272 273 274 275 276 277 278 279 280
}

/*
 * This is called to fill in the vector of log iovecs for the
 * given efd log item. We use only 1 iovec, and we point that
 * at the efd_log_format structure embedded in the efd item.
 * It is at this point that we assert that all of the extent
 * slots in the efd item have been filled.
 */
STATIC void
281 282
xfs_efd_item_format(
	struct xfs_log_item	*lip,
283
	struct xfs_log_vec	*lv)
L
Linus Torvalds 已提交
284
{
285
	struct xfs_efd_log_item	*efdp = EFD_ITEM(lip);
286
	struct xfs_log_iovec	*vecp = NULL;
L
Linus Torvalds 已提交
287 288 289 290 291 292

	ASSERT(efdp->efd_next_extent == efdp->efd_format.efd_nextents);

	efdp->efd_format.efd_type = XFS_LI_EFD;
	efdp->efd_format.efd_size = 1;

293
	xlog_copy_iovec(lv, &vecp, XLOG_REG_TYPE_EFD_FORMAT,
C
Christoph Hellwig 已提交
294 295
			&efdp->efd_format,
			xfs_efd_item_sizeof(efdp));
L
Linus Torvalds 已提交
296 297
}

298 299 300 301
/*
 * The EFD is either committed or aborted if the transaction is cancelled. If
 * the transaction is cancelled, drop our reference to the EFI and free the EFD.
 */
L
Linus Torvalds 已提交
302
STATIC void
C
Christoph Hellwig 已提交
303
xfs_efd_item_release(
304
	struct xfs_log_item	*lip)
L
Linus Torvalds 已提交
305
{
306 307
	struct xfs_efd_log_item	*efdp = EFD_ITEM(lip);

C
Christoph Hellwig 已提交
308 309
	xfs_efi_release(efdp->efd_efip);
	xfs_efd_item_free(efdp);
L
Linus Torvalds 已提交
310 311
}

C
Christoph Hellwig 已提交
312
static const struct xfs_item_ops xfs_efd_item_ops = {
313
	.flags		= XFS_ITEM_RELEASE_WHEN_COMMITTED,
314 315
	.iop_size	= xfs_efd_item_size,
	.iop_format	= xfs_efd_item_format,
C
Christoph Hellwig 已提交
316
	.iop_release	= xfs_efd_item_release,
L
Linus Torvalds 已提交
317 318 319
};

/*
320 321 322
 * Allocate an "extent free done" log item that will hold nextents worth of
 * extents.  The caller must use all nextents extents, because we are not
 * flexible about this at all.
L
Linus Torvalds 已提交
323
 */
324
static struct xfs_efd_log_item *
325 326 327 328
xfs_trans_get_efd(
	struct xfs_trans		*tp,
	struct xfs_efi_log_item		*efip,
	unsigned int			nextents)
L
Linus Torvalds 已提交
329
{
330
	struct xfs_efd_log_item		*efdp;
L
Linus Torvalds 已提交
331 332

	ASSERT(nextents > 0);
333

L
Linus Torvalds 已提交
334
	if (nextents > XFS_EFD_MAX_FAST_EXTENTS) {
335 336
		efdp = kmem_zalloc(sizeof(struct xfs_efd_log_item) +
				(nextents - 1) * sizeof(struct xfs_extent),
337
				0);
L
Linus Torvalds 已提交
338
	} else {
339
		efdp = kmem_zone_zalloc(xfs_efd_zone, 0);
L
Linus Torvalds 已提交
340 341
	}

342 343
	xfs_log_item_init(tp->t_mountp, &efdp->efd_item, XFS_LI_EFD,
			  &xfs_efd_item_ops);
L
Linus Torvalds 已提交
344 345 346 347
	efdp->efd_efip = efip;
	efdp->efd_format.efd_nextents = nextents;
	efdp->efd_format.efd_efi_id = efip->efi_format.efi_id;

348
	xfs_trans_add_item(tp, &efdp->efd_item);
349
	return efdp;
L
Linus Torvalds 已提交
350
}
351

352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418
/*
 * Free an extent and log it to the EFD. Note that the transaction is marked
 * dirty regardless of whether the extent free succeeds or fails to support the
 * EFI/EFD lifecycle rules.
 */
static int
xfs_trans_free_extent(
	struct xfs_trans		*tp,
	struct xfs_efd_log_item		*efdp,
	xfs_fsblock_t			start_block,
	xfs_extlen_t			ext_len,
	const struct xfs_owner_info	*oinfo,
	bool				skip_discard)
{
	struct xfs_mount		*mp = tp->t_mountp;
	struct xfs_extent		*extp;
	uint				next_extent;
	xfs_agnumber_t			agno = XFS_FSB_TO_AGNO(mp, start_block);
	xfs_agblock_t			agbno = XFS_FSB_TO_AGBNO(mp,
								start_block);
	int				error;

	trace_xfs_bmap_free_deferred(tp->t_mountp, agno, 0, agbno, ext_len);

	error = __xfs_free_extent(tp, start_block, ext_len,
				  oinfo, XFS_AG_RESV_NONE, skip_discard);
	/*
	 * Mark the transaction dirty, even on error. This ensures the
	 * transaction is aborted, which:
	 *
	 * 1.) releases the EFI and frees the EFD
	 * 2.) shuts down the filesystem
	 */
	tp->t_flags |= XFS_TRANS_DIRTY;
	set_bit(XFS_LI_DIRTY, &efdp->efd_item.li_flags);

	next_extent = efdp->efd_next_extent;
	ASSERT(next_extent < efdp->efd_format.efd_nextents);
	extp = &(efdp->efd_format.efd_extents[next_extent]);
	extp->ext_start = start_block;
	extp->ext_len = ext_len;
	efdp->efd_next_extent++;

	return error;
}

/* Sort bmap items by AG. */
static int
xfs_extent_free_diff_items(
	void				*priv,
	struct list_head		*a,
	struct list_head		*b)
{
	struct xfs_mount		*mp = priv;
	struct xfs_extent_free_item	*ra;
	struct xfs_extent_free_item	*rb;

	ra = container_of(a, struct xfs_extent_free_item, xefi_list);
	rb = container_of(b, struct xfs_extent_free_item, xefi_list);
	return  XFS_FSB_TO_AGNO(mp, ra->xefi_startblock) -
		XFS_FSB_TO_AGNO(mp, rb->xefi_startblock);
}

/* Log a free extent to the intent item. */
STATIC void
xfs_extent_free_log_item(
	struct xfs_trans		*tp,
419 420
	struct xfs_efi_log_item		*efip,
	struct xfs_extent_free_item	*free)
421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439
{
	uint				next_extent;
	struct xfs_extent		*extp;

	tp->t_flags |= XFS_TRANS_DIRTY;
	set_bit(XFS_LI_DIRTY, &efip->efi_item.li_flags);

	/*
	 * atomic_inc_return gives us the value after the increment;
	 * we want to use it as an array index so we need to subtract 1 from
	 * it.
	 */
	next_extent = atomic_inc_return(&efip->efi_next_extent) - 1;
	ASSERT(next_extent < efip->efi_format.efi_nextents);
	extp = &efip->efi_format.efi_extents[next_extent];
	extp->ext_start = free->xefi_startblock;
	extp->ext_len = free->xefi_blockcount;
}

440
static struct xfs_log_item *
441 442 443
xfs_extent_free_create_intent(
	struct xfs_trans		*tp,
	struct list_head		*items,
444 445
	unsigned int			count,
	bool				sort)
446 447 448 449 450 451 452 453
{
	struct xfs_mount		*mp = tp->t_mountp;
	struct xfs_efi_log_item		*efip = xfs_efi_init(mp, count);
	struct xfs_extent_free_item	*free;

	ASSERT(count > 0);

	xfs_trans_add_item(tp, &efip->efi_item);
454 455
	if (sort)
		list_sort(mp, items, xfs_extent_free_diff_items);
456 457
	list_for_each_entry(free, items, xefi_list)
		xfs_extent_free_log_item(tp, efip, free);
458
	return &efip->efi_item;
459 460
}

461 462 463 464
/* Get an EFD so we can process all the free extents. */
STATIC void *
xfs_extent_free_create_done(
	struct xfs_trans		*tp,
465
	struct xfs_log_item		*intent,
466 467
	unsigned int			count)
{
468
	return xfs_trans_get_efd(tp, EFI_ITEM(intent), count);
469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493
}

/* Process a free extent. */
STATIC int
xfs_extent_free_finish_item(
	struct xfs_trans		*tp,
	struct list_head		*item,
	void				*done_item,
	void				**state)
{
	struct xfs_extent_free_item	*free;
	int				error;

	free = container_of(item, struct xfs_extent_free_item, xefi_list);
	error = xfs_trans_free_extent(tp, done_item,
			free->xefi_startblock,
			free->xefi_blockcount,
			&free->xefi_oinfo, free->xefi_skip_discard);
	kmem_free(free);
	return error;
}

/* Abort all pending EFIs. */
STATIC void
xfs_extent_free_abort_intent(
494
	struct xfs_log_item		*intent)
495
{
496
	xfs_efi_release(EFI_ITEM(intent));
497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582
}

/* Cancel a free extent. */
STATIC void
xfs_extent_free_cancel_item(
	struct list_head		*item)
{
	struct xfs_extent_free_item	*free;

	free = container_of(item, struct xfs_extent_free_item, xefi_list);
	kmem_free(free);
}

const struct xfs_defer_op_type xfs_extent_free_defer_type = {
	.max_items	= XFS_EFI_MAX_FAST_EXTENTS,
	.create_intent	= xfs_extent_free_create_intent,
	.abort_intent	= xfs_extent_free_abort_intent,
	.create_done	= xfs_extent_free_create_done,
	.finish_item	= xfs_extent_free_finish_item,
	.cancel_item	= xfs_extent_free_cancel_item,
};

/*
 * AGFL blocks are accounted differently in the reserve pools and are not
 * inserted into the busy extent list.
 */
STATIC int
xfs_agfl_free_finish_item(
	struct xfs_trans		*tp,
	struct list_head		*item,
	void				*done_item,
	void				**state)
{
	struct xfs_mount		*mp = tp->t_mountp;
	struct xfs_efd_log_item		*efdp = done_item;
	struct xfs_extent_free_item	*free;
	struct xfs_extent		*extp;
	struct xfs_buf			*agbp;
	int				error;
	xfs_agnumber_t			agno;
	xfs_agblock_t			agbno;
	uint				next_extent;

	free = container_of(item, struct xfs_extent_free_item, xefi_list);
	ASSERT(free->xefi_blockcount == 1);
	agno = XFS_FSB_TO_AGNO(mp, free->xefi_startblock);
	agbno = XFS_FSB_TO_AGBNO(mp, free->xefi_startblock);

	trace_xfs_agfl_free_deferred(mp, agno, 0, agbno, free->xefi_blockcount);

	error = xfs_alloc_read_agf(mp, tp, agno, 0, &agbp);
	if (!error)
		error = xfs_free_agfl_block(tp, agno, agbno, agbp,
					    &free->xefi_oinfo);

	/*
	 * Mark the transaction dirty, even on error. This ensures the
	 * transaction is aborted, which:
	 *
	 * 1.) releases the EFI and frees the EFD
	 * 2.) shuts down the filesystem
	 */
	tp->t_flags |= XFS_TRANS_DIRTY;
	set_bit(XFS_LI_DIRTY, &efdp->efd_item.li_flags);

	next_extent = efdp->efd_next_extent;
	ASSERT(next_extent < efdp->efd_format.efd_nextents);
	extp = &(efdp->efd_format.efd_extents[next_extent]);
	extp->ext_start = free->xefi_startblock;
	extp->ext_len = free->xefi_blockcount;
	efdp->efd_next_extent++;

	kmem_free(free);
	return error;
}

/* sub-type with special handling for AGFL deferred frees */
const struct xfs_defer_op_type xfs_agfl_free_defer_type = {
	.max_items	= XFS_EFI_MAX_FAST_EXTENTS,
	.create_intent	= xfs_extent_free_create_intent,
	.abort_intent	= xfs_extent_free_abort_intent,
	.create_done	= xfs_extent_free_create_done,
	.finish_item	= xfs_agfl_free_finish_item,
	.cancel_item	= xfs_extent_free_cancel_item,
};

583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606
/*
 * Process an extent free intent item that was recovered from
 * the log.  We need to free the extents that it describes.
 */
int
xfs_efi_recover(
	struct xfs_mount	*mp,
	struct xfs_efi_log_item	*efip)
{
	struct xfs_efd_log_item	*efdp;
	struct xfs_trans	*tp;
	int			i;
	int			error = 0;
	xfs_extent_t		*extp;
	xfs_fsblock_t		startblock_fsb;

	ASSERT(!test_bit(XFS_EFI_RECOVERED, &efip->efi_flags));

	/*
	 * First check the validity of the extents described by the
	 * EFI.  If any are bad, then assume that all are bad and
	 * just toss the EFI.
	 */
	for (i = 0; i < efip->efi_format.efi_nextents; i++) {
607
		extp = &efip->efi_format.efi_extents[i];
608 609
		startblock_fsb = XFS_BB_TO_FSB(mp,
				   XFS_FSB_TO_DADDR(mp, extp->ext_start));
610 611 612 613
		if (startblock_fsb == 0 ||
		    extp->ext_len == 0 ||
		    startblock_fsb >= mp->m_sb.sb_dblocks ||
		    extp->ext_len >= mp->m_sb.sb_agblocks) {
614 615 616 617 618 619
			/*
			 * This will pull the EFI from the AIL and
			 * free the memory associated with it.
			 */
			set_bit(XFS_EFI_RECOVERED, &efip->efi_flags);
			xfs_efi_release(efip);
620
			return -EFSCORRUPTED;
621 622 623 624 625 626 627 628 629
		}
	}

	error = xfs_trans_alloc(mp, &M_RES(mp)->tr_itruncate, 0, 0, 0, &tp);
	if (error)
		return error;
	efdp = xfs_trans_get_efd(tp, efip, efip->efi_format.efi_nextents);

	for (i = 0; i < efip->efi_format.efi_nextents; i++) {
630
		extp = &efip->efi_format.efi_extents[i];
631
		error = xfs_trans_free_extent(tp, efdp, extp->ext_start,
632 633
					      extp->ext_len,
					      &XFS_RMAP_OINFO_ANY_OWNER, false);
634 635 636 637 638 639 640 641 642 643 644 645 646
		if (error)
			goto abort_error;

	}

	set_bit(XFS_EFI_RECOVERED, &efip->efi_flags);
	error = xfs_trans_commit(tp);
	return error;

abort_error:
	xfs_trans_cancel(tp);
	return error;
}