Commit 5e116e99 authored by Dave Chinner's avatar Dave Chinner
Browse files

Merge branch 'guilt/xlog-intent-whiteouts' into xfs-5.19-for-next

parents 9cf4f616 0d227466
Loading
Loading
Loading
Loading
+18 −12
Original line number Diff line number Diff line
@@ -186,7 +186,7 @@ static const struct xfs_defer_op_type *defer_op_types[] = {
	[XFS_DEFER_OPS_TYPE_AGFL_FREE]	= &xfs_agfl_free_defer_type,
};

static void
static bool
xfs_defer_create_intent(
	struct xfs_trans		*tp,
	struct xfs_defer_pending	*dfp,
@@ -197,6 +197,7 @@ xfs_defer_create_intent(
	if (!dfp->dfp_intent)
		dfp->dfp_intent = ops->create_intent(tp, &dfp->dfp_work,
						     dfp->dfp_count, sort);
	return dfp->dfp_intent != NULL;
}

/*
@@ -204,16 +205,18 @@ xfs_defer_create_intent(
 * associated extents, then add the entire intake list to the end of
 * the pending list.
 */
STATIC void
static bool
xfs_defer_create_intents(
	struct xfs_trans		*tp)
{
	struct xfs_defer_pending	*dfp;
	bool				ret = false;

	list_for_each_entry(dfp, &tp->t_dfops, dfp_list) {
		trace_xfs_defer_create_intent(tp->t_mountp, dfp);
		xfs_defer_create_intent(tp, dfp, true);
		ret |= xfs_defer_create_intent(tp, dfp, true);
	}
	return ret;
}

/* Abort all the intents that were committed. */
@@ -487,7 +490,7 @@ int
xfs_defer_finish_noroll(
	struct xfs_trans		**tp)
{
	struct xfs_defer_pending	*dfp;
	struct xfs_defer_pending	*dfp = NULL;
	int				error = 0;
	LIST_HEAD(dop_pending);

@@ -506,17 +509,20 @@ xfs_defer_finish_noroll(
		 * of time that any one intent item can stick around in memory,
		 * pinning the log tail.
		 */
		xfs_defer_create_intents(*tp);
		bool has_intents = xfs_defer_create_intents(*tp);

		list_splice_init(&(*tp)->t_dfops, &dop_pending);

		if (has_intents || dfp) {
			error = xfs_defer_trans_roll(tp);
			if (error)
				goto out_shutdown;

		/* Possibly relog intent items to keep the log moving. */
			/* Relog intent items to keep the log moving. */
			error = xfs_defer_relog(tp, &dop_pending);
			if (error)
				goto out_shutdown;
		}

		dfp = list_first_entry(&dop_pending, struct xfs_defer_pending,
				       dfp_list);
+3 −9
Original line number Diff line number Diff line
@@ -36,7 +36,7 @@ xfs_init_local_fork(
	int64_t			size)
{
	struct xfs_ifork	*ifp = XFS_IFORK_PTR(ip, whichfork);
	int			mem_size = size, real_size = 0;
	int			mem_size = size;
	bool			zero_terminate;

	/*
@@ -50,8 +50,7 @@ xfs_init_local_fork(
		mem_size++;

	if (size) {
		real_size = roundup(mem_size, 4);
		ifp->if_u1.if_data = kmem_alloc(real_size, KM_NOFS);
		ifp->if_u1.if_data = kmem_alloc(mem_size, KM_NOFS);
		memcpy(ifp->if_u1.if_data, data, size);
		if (zero_terminate)
			ifp->if_u1.if_data[size] = '\0';
@@ -497,12 +496,7 @@ xfs_idata_realloc(
		return;
	}

	/*
	 * For inline data, the underlying buffer must be a multiple of 4 bytes
	 * in size so that it can be logged and stay on word boundaries.
	 * We enforce that here.
	 */
	ifp->if_u1.if_data = krealloc(ifp->if_u1.if_data, roundup(new_size, 4),
	ifp->if_u1.if_data = krealloc(ifp->if_u1.if_data, new_size,
				      GFP_NOFS | __GFP_NOFAIL);
	ifp->if_bytes = new_size;
}
+17 −7
Original line number Diff line number Diff line
@@ -54,13 +54,23 @@ void xfs_log_get_max_trans_res(struct xfs_mount *mp,
/*
 * Values for t_flags.
 */
#define	XFS_TRANS_DIRTY		0x01	/* something needs to be logged */
#define	XFS_TRANS_SB_DIRTY	0x02	/* superblock is modified */
#define	XFS_TRANS_PERM_LOG_RES	0x04	/* xact took a permanent log res */
#define	XFS_TRANS_SYNC		0x08	/* make commit synchronous */
#define XFS_TRANS_RESERVE	0x20    /* OK to use reserved data blocks */
#define XFS_TRANS_NO_WRITECOUNT 0x40	/* do not elevate SB writecount */
#define XFS_TRANS_RES_FDBLKS	0x80	/* reserve newly freed blocks */
/* Transaction needs to be logged */
#define XFS_TRANS_DIRTY			(1u << 0)
/* Superblock is dirty and needs to be logged */
#define XFS_TRANS_SB_DIRTY		(1u << 1)
/* Transaction took a permanent log reservation */
#define XFS_TRANS_PERM_LOG_RES		(1u << 2)
/* Synchronous transaction commit needed */
#define XFS_TRANS_SYNC			(1u << 3)
/* Transaction can use reserve block pool */
#define XFS_TRANS_RESERVE		(1u << 4)
/* Transaction should avoid VFS level superblock write accounting */
#define XFS_TRANS_NO_WRITECOUNT		(1u << 5)
/* Transaction has freed blocks returned to it's reservation */
#define XFS_TRANS_RES_FDBLKS		(1u << 6)
/* Transaction contains an intent done log item */
#define XFS_TRANS_HAS_INTENT_DONE	(1u << 7)

/*
 * LOWMODE is used by the allocator to activate the lowspace algorithm - when
 * free space is running low the extent allocator may choose to allocate an
+19 −6
Original line number Diff line number Diff line
@@ -39,6 +39,7 @@ STATIC void
xfs_bui_item_free(
	struct xfs_bui_log_item	*buip)
{
	kmem_free(buip->bui_item.li_lv_shadow);
	kmem_cache_free(xfs_bui_cache, buip);
}

@@ -54,11 +55,12 @@ xfs_bui_release(
	struct xfs_bui_log_item	*buip)
{
	ASSERT(atomic_read(&buip->bui_refcount) > 0);
	if (atomic_dec_and_test(&buip->bui_refcount)) {
		xfs_trans_ail_delete(&buip->bui_item, SHUTDOWN_LOG_IO_ERROR);
	if (!atomic_dec_and_test(&buip->bui_refcount))
		return;

	xfs_trans_ail_delete(&buip->bui_item, 0);
	xfs_bui_item_free(buip);
}
}


STATIC void
@@ -198,14 +200,24 @@ xfs_bud_item_release(
	struct xfs_bud_log_item	*budp = BUD_ITEM(lip);

	xfs_bui_release(budp->bud_buip);
	kmem_free(budp->bud_item.li_lv_shadow);
	kmem_cache_free(xfs_bud_cache, budp);
}

static struct xfs_log_item *
xfs_bud_item_intent(
	struct xfs_log_item	*lip)
{
	return &BUD_ITEM(lip)->bud_buip->bui_item;
}

static const struct xfs_item_ops xfs_bud_item_ops = {
	.flags		= XFS_ITEM_RELEASE_WHEN_COMMITTED,
	.flags		= XFS_ITEM_RELEASE_WHEN_COMMITTED |
			  XFS_ITEM_INTENT_DONE,
	.iop_size	= xfs_bud_item_size,
	.iop_format	= xfs_bud_item_format,
	.iop_release	= xfs_bud_item_release,
	.iop_intent	= xfs_bud_item_intent,
};

static struct xfs_bud_log_item *
@@ -254,7 +266,7 @@ xfs_trans_log_finish_bmap_update(
	 * 1.) releases the BUI and frees the BUD
	 * 2.) shuts down the filesystem
	 */
	tp->t_flags |= XFS_TRANS_DIRTY;
	tp->t_flags |= XFS_TRANS_DIRTY | XFS_TRANS_HAS_INTENT_DONE;
	set_bit(XFS_LI_DIRTY, &budp->bud_item.li_flags);

	return error;
@@ -586,6 +598,7 @@ xfs_bui_item_relog(
}

static const struct xfs_item_ops xfs_bui_item_ops = {
	.flags		= XFS_ITEM_INTENT,
	.iop_size	= xfs_bui_item_size,
	.iop_format	= xfs_bui_item_format,
	.iop_unpin	= xfs_bui_item_unpin,
+17 −6
Original line number Diff line number Diff line
@@ -58,11 +58,12 @@ 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_delete(&efip->efi_item, SHUTDOWN_LOG_IO_ERROR);
	if (!atomic_dec_and_test(&efip->efi_refcount))
		return;

	xfs_trans_ail_delete(&efip->efi_item, 0);
	xfs_efi_item_free(efip);
}
}

/*
 * This returns the number of iovecs needed to log the given efi item.
@@ -306,11 +307,20 @@ xfs_efd_item_release(
	xfs_efd_item_free(efdp);
}

static struct xfs_log_item *
xfs_efd_item_intent(
	struct xfs_log_item	*lip)
{
	return &EFD_ITEM(lip)->efd_efip->efi_item;
}

static const struct xfs_item_ops xfs_efd_item_ops = {
	.flags		= XFS_ITEM_RELEASE_WHEN_COMMITTED,
	.flags		= XFS_ITEM_RELEASE_WHEN_COMMITTED |
			  XFS_ITEM_INTENT_DONE,
	.iop_size	= xfs_efd_item_size,
	.iop_format	= xfs_efd_item_format,
	.iop_release	= xfs_efd_item_release,
	.iop_intent	= xfs_efd_item_intent,
};

/*
@@ -380,7 +390,7 @@ xfs_trans_free_extent(
	 * 1.) releases the EFI and frees the EFD
	 * 2.) shuts down the filesystem
	 */
	tp->t_flags |= XFS_TRANS_DIRTY;
	tp->t_flags |= XFS_TRANS_DIRTY | XFS_TRANS_HAS_INTENT_DONE;
	set_bit(XFS_LI_DIRTY, &efdp->efd_item.li_flags);

	next_extent = efdp->efd_next_extent;
@@ -688,6 +698,7 @@ xfs_efi_item_relog(
}

static const struct xfs_item_ops xfs_efi_item_ops = {
	.flags		= XFS_ITEM_INTENT,
	.iop_size	= xfs_efi_item_size,
	.iop_format	= xfs_efi_item_format,
	.iop_unpin	= xfs_efi_item_unpin,
Loading