xfs_extfree_item.c 20.6 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"
25
#include "xfs_log_priv.h"
26
#include "xfs_log_recover.h"
L
Linus Torvalds 已提交
27 28 29 30

kmem_zone_t	*xfs_efi_zone;
kmem_zone_t	*xfs_efd_zone;

31 32
static const struct xfs_item_ops xfs_efi_item_ops;

33 34 35 36
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 已提交
37

38
STATIC void
39 40
xfs_efi_item_free(
	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_zone, efip);
47
}
L
Linus Torvalds 已提交
48

49 50 51 52 53 54 55
/*
 * 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.
 */
56
STATIC void
57 58 59 60 61
xfs_efi_release(
	struct xfs_efi_log_item	*efip)
{
	ASSERT(atomic_read(&efip->efi_refcount) > 0);
	if (atomic_dec_and_test(&efip->efi_refcount)) {
62
		xfs_trans_ail_delete(&efip->efi_item, SHUTDOWN_LOG_IO_ERROR);
63 64 65 66
		xfs_efi_item_free(efip);
	}
}

L
Linus Torvalds 已提交
67 68 69 70 71
/*
 * 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.
 */
72 73 74 75 76 77 78 79 80
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
81
xfs_efi_item_size(
82 83 84
	struct xfs_log_item	*lip,
	int			*nvecs,
	int			*nbytes)
L
Linus Torvalds 已提交
85
{
86 87
	*nvecs += 1;
	*nbytes += xfs_efi_item_sizeof(EFI_ITEM(lip));
L
Linus Torvalds 已提交
88 89 90 91 92 93 94 95 96 97
}

/*
 * 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
98 99
xfs_efi_item_format(
	struct xfs_log_item	*lip,
100
	struct xfs_log_vec	*lv)
L
Linus Torvalds 已提交
101
{
102
	struct xfs_efi_log_item	*efip = EFI_ITEM(lip);
103
	struct xfs_log_iovec	*vecp = NULL;
L
Linus Torvalds 已提交
104

105 106
	ASSERT(atomic_read(&efip->efi_next_extent) ==
				efip->efi_format.efi_nextents);
L
Linus Torvalds 已提交
107 108 109 110

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

111
	xlog_copy_iovec(lv, &vecp, XLOG_REG_TYPE_EFI_FORMAT,
C
Christoph Hellwig 已提交
112 113
			&efip->efi_format,
			xfs_efi_item_sizeof(efip));
L
Linus Torvalds 已提交
114 115 116 117
}


/*
118 119 120 121 122 123
 * 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 已提交
124 125
 */
STATIC void
126 127 128
xfs_efi_item_unpin(
	struct xfs_log_item	*lip,
	int			remove)
L
Linus Torvalds 已提交
129
{
130
	struct xfs_efi_log_item	*efip = EFI_ITEM(lip);
131
	xfs_efi_release(efip);
L
Linus Torvalds 已提交
132 133
}

134 135 136 137 138
/*
 * 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 已提交
139
STATIC void
C
Christoph Hellwig 已提交
140
xfs_efi_item_release(
141
	struct xfs_log_item	*lip)
L
Linus Torvalds 已提交
142
{
C
Christoph Hellwig 已提交
143
	xfs_efi_release(EFI_ITEM(lip));
L
Linus Torvalds 已提交
144 145 146 147 148
}

/*
 * Allocate and initialize an efi item with the given number of extents.
 */
149
STATIC struct xfs_efi_log_item *
150 151 152
xfs_efi_init(
	struct xfs_mount	*mp,
	uint			nextents)
L
Linus Torvalds 已提交
153 154

{
155
	struct xfs_efi_log_item	*efip;
L
Linus Torvalds 已提交
156 157 158 159
	uint			size;

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

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

173
	return efip;
L
Linus Torvalds 已提交
174 175
}

176 177 178 179 180 181 182
/*
 * 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.
 */
183
STATIC int
184 185
xfs_efi_copy_format(xfs_log_iovec_t *buf, xfs_efi_log_format_t *dst_efi_fmt)
{
186
	xfs_efi_log_format_t *src_efi_fmt = buf->i_addr;
187 188 189 190 191 192 193 194 195 196 197 198
	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) {
199
		xfs_efi_log_format_32_t *src_efi_fmt_32 = buf->i_addr;
200 201 202 203 204 205 206 207 208 209 210 211 212

		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) {
213
		xfs_efi_log_format_64_t *src_efi_fmt_64 = buf->i_addr;
214 215 216 217 218 219 220 221 222 223 224 225 226

		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;
	}
227
	XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_LOW, NULL);
D
Dave Chinner 已提交
228
	return -EFSCORRUPTED;
229 230
}

231
static inline struct xfs_efd_log_item *EFD_ITEM(struct xfs_log_item *lip)
232
{
233 234
	return container_of(lip, struct xfs_efd_log_item, efd_item);
}
L
Linus Torvalds 已提交
235

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

/*
 * 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.
 */
251 252 253 254 255 256 257 258 259
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
260
xfs_efd_item_size(
261 262 263
	struct xfs_log_item	*lip,
	int			*nvecs,
	int			*nbytes)
L
Linus Torvalds 已提交
264
{
265 266
	*nvecs += 1;
	*nbytes += xfs_efd_item_sizeof(EFD_ITEM(lip));
L
Linus Torvalds 已提交
267 268 269 270 271 272 273 274 275 276
}

/*
 * 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
277 278
xfs_efd_item_format(
	struct xfs_log_item	*lip,
279
	struct xfs_log_vec	*lv)
L
Linus Torvalds 已提交
280
{
281
	struct xfs_efd_log_item	*efdp = EFD_ITEM(lip);
282
	struct xfs_log_iovec	*vecp = NULL;
L
Linus Torvalds 已提交
283 284 285 286 287 288

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

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

289
	xlog_copy_iovec(lv, &vecp, XLOG_REG_TYPE_EFD_FORMAT,
C
Christoph Hellwig 已提交
290 291
			&efdp->efd_format,
			xfs_efd_item_sizeof(efdp));
L
Linus Torvalds 已提交
292 293
}

294 295 296 297
/*
 * 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 已提交
298
STATIC void
C
Christoph Hellwig 已提交
299
xfs_efd_item_release(
300
	struct xfs_log_item	*lip)
L
Linus Torvalds 已提交
301
{
302 303
	struct xfs_efd_log_item	*efdp = EFD_ITEM(lip);

C
Christoph Hellwig 已提交
304 305
	xfs_efi_release(efdp->efd_efip);
	xfs_efd_item_free(efdp);
L
Linus Torvalds 已提交
306 307
}

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

/*
316 317 318
 * 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 已提交
319
 */
320
static struct xfs_efd_log_item *
321 322 323 324
xfs_trans_get_efd(
	struct xfs_trans		*tp,
	struct xfs_efi_log_item		*efip,
	unsigned int			nextents)
L
Linus Torvalds 已提交
325
{
326
	struct xfs_efd_log_item		*efdp;
L
Linus Torvalds 已提交
327 328

	ASSERT(nextents > 0);
329

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

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

344
	xfs_trans_add_item(tp, &efdp->efd_item);
345
	return efdp;
L
Linus Torvalds 已提交
346
}
347

348 349 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
/*
 * 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,
415 416
	struct xfs_efi_log_item		*efip,
	struct xfs_extent_free_item	*free)
417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435
{
	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;
}

436
static struct xfs_log_item *
437 438 439
xfs_extent_free_create_intent(
	struct xfs_trans		*tp,
	struct list_head		*items,
440 441
	unsigned int			count,
	bool				sort)
442 443 444 445 446 447 448 449
{
	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);
450 451
	if (sort)
		list_sort(mp, items, xfs_extent_free_diff_items);
452 453
	list_for_each_entry(free, items, xefi_list)
		xfs_extent_free_log_item(tp, efip, free);
454
	return &efip->efi_item;
455 456
}

457
/* Get an EFD so we can process all the free extents. */
458
static struct xfs_log_item *
459 460
xfs_extent_free_create_done(
	struct xfs_trans		*tp,
461
	struct xfs_log_item		*intent,
462 463
	unsigned int			count)
{
464
	return &xfs_trans_get_efd(tp, EFI_ITEM(intent), count)->efd_item;
465 466 467 468 469 470
}

/* Process a free extent. */
STATIC int
xfs_extent_free_finish_item(
	struct xfs_trans		*tp,
471
	struct xfs_log_item		*done,
472
	struct list_head		*item,
473
	struct xfs_btree_cur		**state)
474 475 476 477 478
{
	struct xfs_extent_free_item	*free;
	int				error;

	free = container_of(item, struct xfs_extent_free_item, xefi_list);
479
	error = xfs_trans_free_extent(tp, EFD_ITEM(done),
480 481 482 483 484 485 486 487 488 489
			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(
490
	struct xfs_log_item		*intent)
491
{
492
	xfs_efi_release(EFI_ITEM(intent));
493 494 495 496 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
}

/* 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,
522
	struct xfs_log_item		*done,
523
	struct list_head		*item,
524
	struct xfs_btree_cur		**state)
525 526
{
	struct xfs_mount		*mp = tp->t_mountp;
527
	struct xfs_efd_log_item		*efdp = EFD_ITEM(done);
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
	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,
};

579 580 581 582
/*
 * Process an extent free intent item that was recovered from
 * the log.  We need to free the extents that it describes.
 */
583
STATIC int
584 585 586 587 588 589 590 591 592 593 594
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;

595
	ASSERT(!test_bit(XFS_LI_RECOVERED, &efip->efi_item.li_flags));
596 597 598 599 600 601 602

	/*
	 * 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++) {
603
		extp = &efip->efi_format.efi_extents[i];
604 605
		startblock_fsb = XFS_BB_TO_FSB(mp,
				   XFS_FSB_TO_DADDR(mp, extp->ext_start));
606 607 608 609
		if (startblock_fsb == 0 ||
		    extp->ext_len == 0 ||
		    startblock_fsb >= mp->m_sb.sb_dblocks ||
		    extp->ext_len >= mp->m_sb.sb_agblocks) {
610 611 612 613
			/*
			 * This will pull the EFI from the AIL and
			 * free the memory associated with it.
			 */
614
			set_bit(XFS_LI_RECOVERED, &efip->efi_item.li_flags);
615
			xfs_efi_release(efip);
616
			return -EFSCORRUPTED;
617 618 619 620 621 622 623 624 625
		}
	}

	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++) {
626
		extp = &efip->efi_format.efi_extents[i];
627
		error = xfs_trans_free_extent(tp, efdp, extp->ext_start,
628 629
					      extp->ext_len,
					      &XFS_RMAP_OINFO_ANY_OWNER, false);
630 631 632 633 634
		if (error)
			goto abort_error;

	}

635
	set_bit(XFS_LI_RECOVERED, &efip->efi_item.li_flags);
636 637 638 639 640 641 642
	error = xfs_trans_commit(tp);
	return error;

abort_error:
	xfs_trans_cancel(tp);
	return error;
}
643

644 645 646 647 648 649 650 651 652 653 654 655 656 657
/* Recover the EFI if necessary. */
STATIC int
xfs_efi_item_recover(
	struct xfs_log_item		*lip,
	struct xfs_trans		*tp)
{
	struct xfs_ail			*ailp = lip->li_ailp;
	struct xfs_efi_log_item		*efip;
	int				error;

	/*
	 * Skip EFIs that we've already processed.
	 */
	efip = container_of(lip, struct xfs_efi_log_item, efi_item);
658
	if (test_bit(XFS_LI_RECOVERED, &efip->efi_item.li_flags))
659 660 661 662 663 664 665 666 667
		return 0;

	spin_unlock(&ailp->ail_lock);
	error = xfs_efi_recover(tp->t_mountp, efip);
	spin_lock(&ailp->ail_lock);

	return error;
}

668 669 670 671 672 673 674 675
STATIC bool
xfs_efi_item_match(
	struct xfs_log_item	*lip,
	uint64_t		intent_id)
{
	return EFI_ITEM(lip)->efi_format.efi_id == intent_id;
}

676 677 678 679 680 681
static const struct xfs_item_ops xfs_efi_item_ops = {
	.iop_size	= xfs_efi_item_size,
	.iop_format	= xfs_efi_item_format,
	.iop_unpin	= xfs_efi_item_unpin,
	.iop_release	= xfs_efi_item_release,
	.iop_recover	= xfs_efi_item_recover,
682
	.iop_match	= xfs_efi_item_match,
683 684
};

685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713
/*
 * This routine is called to create an in-core extent free intent
 * item from the efi format structure which was logged on disk.
 * It allocates an in-core efi, copies the extents from the format
 * structure into it, and adds the efi to the AIL with the given
 * LSN.
 */
STATIC int
xlog_recover_efi_commit_pass2(
	struct xlog			*log,
	struct list_head		*buffer_list,
	struct xlog_recover_item	*item,
	xfs_lsn_t			lsn)
{
	struct xfs_mount		*mp = log->l_mp;
	struct xfs_efi_log_item		*efip;
	struct xfs_efi_log_format	*efi_formatp;
	int				error;

	efi_formatp = item->ri_buf[0].i_addr;

	efip = xfs_efi_init(mp, efi_formatp->efi_nextents);
	error = xfs_efi_copy_format(&item->ri_buf[0], &efip->efi_format);
	if (error) {
		xfs_efi_item_free(efip);
		return error;
	}
	atomic_set(&efip->efi_next_extent, efi_formatp->efi_nextents);
	/*
714 715
	 * Insert the intent into the AIL directly and drop one reference so
	 * that finishing or canceling the work will drop the other.
716
	 */
717
	xfs_trans_ail_insert(log->l_ailp, &efip->efi_item, lsn);
718 719 720 721
	xfs_efi_release(efip);
	return 0;
}

722 723
const struct xlog_recover_item_ops xlog_efi_item_ops = {
	.item_type		= XFS_LI_EFI,
724
	.commit_pass2		= xlog_recover_efi_commit_pass2,
725 726
};

727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748
/*
 * This routine is called when an EFD format structure is found in a committed
 * transaction in the log. Its purpose is to cancel the corresponding EFI if it
 * was still in the log. To do this it searches the AIL for the EFI with an id
 * equal to that in the EFD format structure. If we find it we drop the EFD
 * reference, which removes the EFI from the AIL and frees it.
 */
STATIC int
xlog_recover_efd_commit_pass2(
	struct xlog			*log,
	struct list_head		*buffer_list,
	struct xlog_recover_item	*item,
	xfs_lsn_t			lsn)
{
	struct xfs_efd_log_format	*efd_formatp;

	efd_formatp = item->ri_buf[0].i_addr;
	ASSERT((item->ri_buf[0].i_len == (sizeof(xfs_efd_log_format_32_t) +
		((efd_formatp->efd_nextents - 1) * sizeof(xfs_extent_32_t)))) ||
	       (item->ri_buf[0].i_len == (sizeof(xfs_efd_log_format_64_t) +
		((efd_formatp->efd_nextents - 1) * sizeof(xfs_extent_64_t)))));

749
	xlog_recover_release_intent(log, XFS_LI_EFI, efd_formatp->efd_efi_id);
750 751 752
	return 0;
}

753 754
const struct xlog_recover_item_ops xlog_efd_item_ops = {
	.item_type		= XFS_LI_EFD,
755
	.commit_pass2		= xlog_recover_efd_commit_pass2,
756
};