brintos

brintos / linux-shallow public Read only

0
0
Text · 18.0 KiB · 88b5580 Raw
701 lines · c
1// SPDX-License-Identifier: GPL-2.0+2/*3 * Copyright (C) 2016 Oracle.  All Rights Reserved.4 * Author: Darrick J. Wong <darrick.wong@oracle.com>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_rmap_item.h"18#include "xfs_log.h"19#include "xfs_rmap.h"20#include "xfs_error.h"21#include "xfs_log_priv.h"22#include "xfs_log_recover.h"23#include "xfs_ag.h"24#include "xfs_btree.h"25#include "xfs_trace.h"26 27struct kmem_cache	*xfs_rui_cache;28struct kmem_cache	*xfs_rud_cache;29 30static const struct xfs_item_ops xfs_rui_item_ops;31 32static inline struct xfs_rui_log_item *RUI_ITEM(struct xfs_log_item *lip)33{34	return container_of(lip, struct xfs_rui_log_item, rui_item);35}36 37STATIC void38xfs_rui_item_free(39	struct xfs_rui_log_item	*ruip)40{41	kvfree(ruip->rui_item.li_lv_shadow);42	if (ruip->rui_format.rui_nextents > XFS_RUI_MAX_FAST_EXTENTS)43		kfree(ruip);44	else45		kmem_cache_free(xfs_rui_cache, ruip);46}47 48/*49 * Freeing the RUI requires that we remove it from the AIL if it has already50 * been placed there. However, the RUI may not yet have been placed in the AIL51 * when called by xfs_rui_release() from RUD processing due to the ordering of52 * committed vs unpin operations in bulk insert operations. Hence the reference53 * count to ensure only the last caller frees the RUI.54 */55STATIC void56xfs_rui_release(57	struct xfs_rui_log_item	*ruip)58{59	ASSERT(atomic_read(&ruip->rui_refcount) > 0);60	if (!atomic_dec_and_test(&ruip->rui_refcount))61		return;62 63	xfs_trans_ail_delete(&ruip->rui_item, 0);64	xfs_rui_item_free(ruip);65}66 67STATIC void68xfs_rui_item_size(69	struct xfs_log_item	*lip,70	int			*nvecs,71	int			*nbytes)72{73	struct xfs_rui_log_item	*ruip = RUI_ITEM(lip);74 75	*nvecs += 1;76	*nbytes += xfs_rui_log_format_sizeof(ruip->rui_format.rui_nextents);77}78 79/*80 * This is called to fill in the vector of log iovecs for the81 * given rui log item. We use only 1 iovec, and we point that82 * at the rui_log_format structure embedded in the rui item.83 * It is at this point that we assert that all of the extent84 * slots in the rui item have been filled.85 */86STATIC void87xfs_rui_item_format(88	struct xfs_log_item	*lip,89	struct xfs_log_vec	*lv)90{91	struct xfs_rui_log_item	*ruip = RUI_ITEM(lip);92	struct xfs_log_iovec	*vecp = NULL;93 94	ASSERT(atomic_read(&ruip->rui_next_extent) ==95			ruip->rui_format.rui_nextents);96 97	ruip->rui_format.rui_type = XFS_LI_RUI;98	ruip->rui_format.rui_size = 1;99 100	xlog_copy_iovec(lv, &vecp, XLOG_REG_TYPE_RUI_FORMAT, &ruip->rui_format,101			xfs_rui_log_format_sizeof(ruip->rui_format.rui_nextents));102}103 104/*105 * The unpin operation is the last place an RUI is manipulated in the log. It is106 * either inserted in the AIL or aborted in the event of a log I/O error. In107 * either case, the RUI transaction has been successfully committed to make it108 * this far. Therefore, we expect whoever committed the RUI to either construct109 * and commit the RUD or drop the RUD's reference in the event of error. Simply110 * drop the log's RUI reference now that the log is done with it.111 */112STATIC void113xfs_rui_item_unpin(114	struct xfs_log_item	*lip,115	int			remove)116{117	struct xfs_rui_log_item	*ruip = RUI_ITEM(lip);118 119	xfs_rui_release(ruip);120}121 122/*123 * The RUI has been either committed or aborted if the transaction has been124 * cancelled. If the transaction was cancelled, an RUD isn't going to be125 * constructed and thus we free the RUI here directly.126 */127STATIC void128xfs_rui_item_release(129	struct xfs_log_item	*lip)130{131	xfs_rui_release(RUI_ITEM(lip));132}133 134/*135 * Allocate and initialize an rui item with the given number of extents.136 */137STATIC struct xfs_rui_log_item *138xfs_rui_init(139	struct xfs_mount		*mp,140	uint				nextents)141 142{143	struct xfs_rui_log_item		*ruip;144 145	ASSERT(nextents > 0);146	if (nextents > XFS_RUI_MAX_FAST_EXTENTS)147		ruip = kzalloc(xfs_rui_log_item_sizeof(nextents),148				GFP_KERNEL | __GFP_NOFAIL);149	else150		ruip = kmem_cache_zalloc(xfs_rui_cache,151					 GFP_KERNEL | __GFP_NOFAIL);152 153	xfs_log_item_init(mp, &ruip->rui_item, XFS_LI_RUI, &xfs_rui_item_ops);154	ruip->rui_format.rui_nextents = nextents;155	ruip->rui_format.rui_id = (uintptr_t)(void *)ruip;156	atomic_set(&ruip->rui_next_extent, 0);157	atomic_set(&ruip->rui_refcount, 2);158 159	return ruip;160}161 162static inline struct xfs_rud_log_item *RUD_ITEM(struct xfs_log_item *lip)163{164	return container_of(lip, struct xfs_rud_log_item, rud_item);165}166 167STATIC void168xfs_rud_item_size(169	struct xfs_log_item	*lip,170	int			*nvecs,171	int			*nbytes)172{173	*nvecs += 1;174	*nbytes += sizeof(struct xfs_rud_log_format);175}176 177/*178 * This is called to fill in the vector of log iovecs for the179 * given rud log item. We use only 1 iovec, and we point that180 * at the rud_log_format structure embedded in the rud item.181 * It is at this point that we assert that all of the extent182 * slots in the rud item have been filled.183 */184STATIC void185xfs_rud_item_format(186	struct xfs_log_item	*lip,187	struct xfs_log_vec	*lv)188{189	struct xfs_rud_log_item	*rudp = RUD_ITEM(lip);190	struct xfs_log_iovec	*vecp = NULL;191 192	rudp->rud_format.rud_type = XFS_LI_RUD;193	rudp->rud_format.rud_size = 1;194 195	xlog_copy_iovec(lv, &vecp, XLOG_REG_TYPE_RUD_FORMAT, &rudp->rud_format,196			sizeof(struct xfs_rud_log_format));197}198 199/*200 * The RUD is either committed or aborted if the transaction is cancelled. If201 * the transaction is cancelled, drop our reference to the RUI and free the202 * RUD.203 */204STATIC void205xfs_rud_item_release(206	struct xfs_log_item	*lip)207{208	struct xfs_rud_log_item	*rudp = RUD_ITEM(lip);209 210	xfs_rui_release(rudp->rud_ruip);211	kvfree(rudp->rud_item.li_lv_shadow);212	kmem_cache_free(xfs_rud_cache, rudp);213}214 215static struct xfs_log_item *216xfs_rud_item_intent(217	struct xfs_log_item	*lip)218{219	return &RUD_ITEM(lip)->rud_ruip->rui_item;220}221 222static const struct xfs_item_ops xfs_rud_item_ops = {223	.flags		= XFS_ITEM_RELEASE_WHEN_COMMITTED |224			  XFS_ITEM_INTENT_DONE,225	.iop_size	= xfs_rud_item_size,226	.iop_format	= xfs_rud_item_format,227	.iop_release	= xfs_rud_item_release,228	.iop_intent	= xfs_rud_item_intent,229};230 231static inline struct xfs_rmap_intent *ri_entry(const struct list_head *e)232{233	return list_entry(e, struct xfs_rmap_intent, ri_list);234}235 236/* Sort rmap intents by AG. */237static int238xfs_rmap_update_diff_items(239	void				*priv,240	const struct list_head		*a,241	const struct list_head		*b)242{243	struct xfs_rmap_intent		*ra = ri_entry(a);244	struct xfs_rmap_intent		*rb = ri_entry(b);245 246	return ra->ri_pag->pag_agno - rb->ri_pag->pag_agno;247}248 249/* Log rmap updates in the intent item. */250STATIC void251xfs_rmap_update_log_item(252	struct xfs_trans		*tp,253	struct xfs_rui_log_item		*ruip,254	struct xfs_rmap_intent		*ri)255{256	uint				next_extent;257	struct xfs_map_extent		*map;258 259	/*260	 * atomic_inc_return gives us the value after the increment;261	 * we want to use it as an array index so we need to subtract 1 from262	 * it.263	 */264	next_extent = atomic_inc_return(&ruip->rui_next_extent) - 1;265	ASSERT(next_extent < ruip->rui_format.rui_nextents);266	map = &ruip->rui_format.rui_extents[next_extent];267	map->me_owner = ri->ri_owner;268	map->me_startblock = ri->ri_bmap.br_startblock;269	map->me_startoff = ri->ri_bmap.br_startoff;270	map->me_len = ri->ri_bmap.br_blockcount;271 272	map->me_flags = 0;273	if (ri->ri_bmap.br_state == XFS_EXT_UNWRITTEN)274		map->me_flags |= XFS_RMAP_EXTENT_UNWRITTEN;275	if (ri->ri_whichfork == XFS_ATTR_FORK)276		map->me_flags |= XFS_RMAP_EXTENT_ATTR_FORK;277	switch (ri->ri_type) {278	case XFS_RMAP_MAP:279		map->me_flags |= XFS_RMAP_EXTENT_MAP;280		break;281	case XFS_RMAP_MAP_SHARED:282		map->me_flags |= XFS_RMAP_EXTENT_MAP_SHARED;283		break;284	case XFS_RMAP_UNMAP:285		map->me_flags |= XFS_RMAP_EXTENT_UNMAP;286		break;287	case XFS_RMAP_UNMAP_SHARED:288		map->me_flags |= XFS_RMAP_EXTENT_UNMAP_SHARED;289		break;290	case XFS_RMAP_CONVERT:291		map->me_flags |= XFS_RMAP_EXTENT_CONVERT;292		break;293	case XFS_RMAP_CONVERT_SHARED:294		map->me_flags |= XFS_RMAP_EXTENT_CONVERT_SHARED;295		break;296	case XFS_RMAP_ALLOC:297		map->me_flags |= XFS_RMAP_EXTENT_ALLOC;298		break;299	case XFS_RMAP_FREE:300		map->me_flags |= XFS_RMAP_EXTENT_FREE;301		break;302	default:303		ASSERT(0);304	}305}306 307static struct xfs_log_item *308xfs_rmap_update_create_intent(309	struct xfs_trans		*tp,310	struct list_head		*items,311	unsigned int			count,312	bool				sort)313{314	struct xfs_mount		*mp = tp->t_mountp;315	struct xfs_rui_log_item		*ruip = xfs_rui_init(mp, count);316	struct xfs_rmap_intent		*ri;317 318	ASSERT(count > 0);319 320	if (sort)321		list_sort(mp, items, xfs_rmap_update_diff_items);322	list_for_each_entry(ri, items, ri_list)323		xfs_rmap_update_log_item(tp, ruip, ri);324	return &ruip->rui_item;325}326 327/* Get an RUD so we can process all the deferred rmap updates. */328static struct xfs_log_item *329xfs_rmap_update_create_done(330	struct xfs_trans		*tp,331	struct xfs_log_item		*intent,332	unsigned int			count)333{334	struct xfs_rui_log_item		*ruip = RUI_ITEM(intent);335	struct xfs_rud_log_item		*rudp;336 337	rudp = kmem_cache_zalloc(xfs_rud_cache, GFP_KERNEL | __GFP_NOFAIL);338	xfs_log_item_init(tp->t_mountp, &rudp->rud_item, XFS_LI_RUD,339			  &xfs_rud_item_ops);340	rudp->rud_ruip = ruip;341	rudp->rud_format.rud_rui_id = ruip->rui_format.rui_id;342 343	return &rudp->rud_item;344}345 346/* Add this deferred RUI to the transaction. */347void348xfs_rmap_defer_add(349	struct xfs_trans	*tp,350	struct xfs_rmap_intent	*ri)351{352	struct xfs_mount	*mp = tp->t_mountp;353 354	trace_xfs_rmap_defer(mp, ri);355 356	ri->ri_pag = xfs_perag_intent_get(mp, ri->ri_bmap.br_startblock);357	xfs_defer_add(tp, &ri->ri_list, &xfs_rmap_update_defer_type);358}359 360/* Cancel a deferred rmap update. */361STATIC void362xfs_rmap_update_cancel_item(363	struct list_head		*item)364{365	struct xfs_rmap_intent		*ri = ri_entry(item);366 367	xfs_perag_intent_put(ri->ri_pag);368	kmem_cache_free(xfs_rmap_intent_cache, ri);369}370 371/* Process a deferred rmap update. */372STATIC int373xfs_rmap_update_finish_item(374	struct xfs_trans		*tp,375	struct xfs_log_item		*done,376	struct list_head		*item,377	struct xfs_btree_cur		**state)378{379	struct xfs_rmap_intent		*ri = ri_entry(item);380	int				error;381 382	error = xfs_rmap_finish_one(tp, ri, state);383 384	xfs_rmap_update_cancel_item(item);385	return error;386}387 388/* Clean up after calling xfs_rmap_finish_one. */389STATIC void390xfs_rmap_finish_one_cleanup(391	struct xfs_trans	*tp,392	struct xfs_btree_cur	*rcur,393	int			error)394{395	struct xfs_buf		*agbp = NULL;396 397	if (rcur == NULL)398		return;399	agbp = rcur->bc_ag.agbp;400	xfs_btree_del_cursor(rcur, error);401	if (error && agbp)402		xfs_trans_brelse(tp, agbp);403}404 405/* Abort all pending RUIs. */406STATIC void407xfs_rmap_update_abort_intent(408	struct xfs_log_item	*intent)409{410	xfs_rui_release(RUI_ITEM(intent));411}412 413/* Is this recovered RUI ok? */414static inline bool415xfs_rui_validate_map(416	struct xfs_mount		*mp,417	struct xfs_map_extent		*map)418{419	if (!xfs_has_rmapbt(mp))420		return false;421 422	if (map->me_flags & ~XFS_RMAP_EXTENT_FLAGS)423		return false;424 425	switch (map->me_flags & XFS_RMAP_EXTENT_TYPE_MASK) {426	case XFS_RMAP_EXTENT_MAP:427	case XFS_RMAP_EXTENT_MAP_SHARED:428	case XFS_RMAP_EXTENT_UNMAP:429	case XFS_RMAP_EXTENT_UNMAP_SHARED:430	case XFS_RMAP_EXTENT_CONVERT:431	case XFS_RMAP_EXTENT_CONVERT_SHARED:432	case XFS_RMAP_EXTENT_ALLOC:433	case XFS_RMAP_EXTENT_FREE:434		break;435	default:436		return false;437	}438 439	if (!XFS_RMAP_NON_INODE_OWNER(map->me_owner) &&440	    !xfs_verify_ino(mp, map->me_owner))441		return false;442 443	if (!xfs_verify_fileext(mp, map->me_startoff, map->me_len))444		return false;445 446	return xfs_verify_fsbext(mp, map->me_startblock, map->me_len);447}448 449static inline void450xfs_rui_recover_work(451	struct xfs_mount		*mp,452	struct xfs_defer_pending	*dfp,453	const struct xfs_map_extent	*map)454{455	struct xfs_rmap_intent		*ri;456 457	ri = kmem_cache_alloc(xfs_rmap_intent_cache, GFP_KERNEL | __GFP_NOFAIL);458 459	switch (map->me_flags & XFS_RMAP_EXTENT_TYPE_MASK) {460	case XFS_RMAP_EXTENT_MAP:461		ri->ri_type = XFS_RMAP_MAP;462		break;463	case XFS_RMAP_EXTENT_MAP_SHARED:464		ri->ri_type = XFS_RMAP_MAP_SHARED;465		break;466	case XFS_RMAP_EXTENT_UNMAP:467		ri->ri_type = XFS_RMAP_UNMAP;468		break;469	case XFS_RMAP_EXTENT_UNMAP_SHARED:470		ri->ri_type = XFS_RMAP_UNMAP_SHARED;471		break;472	case XFS_RMAP_EXTENT_CONVERT:473		ri->ri_type = XFS_RMAP_CONVERT;474		break;475	case XFS_RMAP_EXTENT_CONVERT_SHARED:476		ri->ri_type = XFS_RMAP_CONVERT_SHARED;477		break;478	case XFS_RMAP_EXTENT_ALLOC:479		ri->ri_type = XFS_RMAP_ALLOC;480		break;481	case XFS_RMAP_EXTENT_FREE:482		ri->ri_type = XFS_RMAP_FREE;483		break;484	default:485		ASSERT(0);486		return;487	}488 489	ri->ri_owner = map->me_owner;490	ri->ri_whichfork = (map->me_flags & XFS_RMAP_EXTENT_ATTR_FORK) ?491			XFS_ATTR_FORK : XFS_DATA_FORK;492	ri->ri_bmap.br_startblock = map->me_startblock;493	ri->ri_bmap.br_startoff = map->me_startoff;494	ri->ri_bmap.br_blockcount = map->me_len;495	ri->ri_bmap.br_state = (map->me_flags & XFS_RMAP_EXTENT_UNWRITTEN) ?496			XFS_EXT_UNWRITTEN : XFS_EXT_NORM;497	ri->ri_pag = xfs_perag_intent_get(mp, map->me_startblock);498 499	xfs_defer_add_item(dfp, &ri->ri_list);500}501 502/*503 * Process an rmap update intent item that was recovered from the log.504 * We need to update the rmapbt.505 */506STATIC int507xfs_rmap_recover_work(508	struct xfs_defer_pending	*dfp,509	struct list_head		*capture_list)510{511	struct xfs_trans_res		resv;512	struct xfs_log_item		*lip = dfp->dfp_intent;513	struct xfs_rui_log_item		*ruip = RUI_ITEM(lip);514	struct xfs_trans		*tp;515	struct xfs_mount		*mp = lip->li_log->l_mp;516	int				i;517	int				error = 0;518 519	/*520	 * First check the validity of the extents described by the521	 * RUI.  If any are bad, then assume that all are bad and522	 * just toss the RUI.523	 */524	for (i = 0; i < ruip->rui_format.rui_nextents; i++) {525		if (!xfs_rui_validate_map(mp,526					&ruip->rui_format.rui_extents[i])) {527			XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp,528					&ruip->rui_format,529					sizeof(ruip->rui_format));530			return -EFSCORRUPTED;531		}532 533		xfs_rui_recover_work(mp, dfp, &ruip->rui_format.rui_extents[i]);534	}535 536	resv = xlog_recover_resv(&M_RES(mp)->tr_itruncate);537	error = xfs_trans_alloc(mp, &resv, mp->m_rmap_maxlevels, 0,538			XFS_TRANS_RESERVE, &tp);539	if (error)540		return error;541 542	error = xlog_recover_finish_intent(tp, dfp);543	if (error == -EFSCORRUPTED)544		XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp,545				&ruip->rui_format,546				sizeof(ruip->rui_format));547	if (error)548		goto abort_error;549 550	return xfs_defer_ops_capture_and_commit(tp, capture_list);551 552abort_error:553	xfs_trans_cancel(tp);554	return error;555}556 557/* Relog an intent item to push the log tail forward. */558static struct xfs_log_item *559xfs_rmap_relog_intent(560	struct xfs_trans		*tp,561	struct xfs_log_item		*intent,562	struct xfs_log_item		*done_item)563{564	struct xfs_rui_log_item		*ruip;565	struct xfs_map_extent		*map;566	unsigned int			count;567 568	count = RUI_ITEM(intent)->rui_format.rui_nextents;569	map = RUI_ITEM(intent)->rui_format.rui_extents;570 571	ruip = xfs_rui_init(tp->t_mountp, count);572	memcpy(ruip->rui_format.rui_extents, map, count * sizeof(*map));573	atomic_set(&ruip->rui_next_extent, count);574 575	return &ruip->rui_item;576}577 578const struct xfs_defer_op_type xfs_rmap_update_defer_type = {579	.name		= "rmap",580	.max_items	= XFS_RUI_MAX_FAST_EXTENTS,581	.create_intent	= xfs_rmap_update_create_intent,582	.abort_intent	= xfs_rmap_update_abort_intent,583	.create_done	= xfs_rmap_update_create_done,584	.finish_item	= xfs_rmap_update_finish_item,585	.finish_cleanup = xfs_rmap_finish_one_cleanup,586	.cancel_item	= xfs_rmap_update_cancel_item,587	.recover_work	= xfs_rmap_recover_work,588	.relog_intent	= xfs_rmap_relog_intent,589};590 591STATIC bool592xfs_rui_item_match(593	struct xfs_log_item	*lip,594	uint64_t		intent_id)595{596	return RUI_ITEM(lip)->rui_format.rui_id == intent_id;597}598 599static const struct xfs_item_ops xfs_rui_item_ops = {600	.flags		= XFS_ITEM_INTENT,601	.iop_size	= xfs_rui_item_size,602	.iop_format	= xfs_rui_item_format,603	.iop_unpin	= xfs_rui_item_unpin,604	.iop_release	= xfs_rui_item_release,605	.iop_match	= xfs_rui_item_match,606};607 608static inline void609xfs_rui_copy_format(610	struct xfs_rui_log_format	*dst,611	const struct xfs_rui_log_format	*src)612{613	unsigned int			i;614 615	memcpy(dst, src, offsetof(struct xfs_rui_log_format, rui_extents));616 617	for (i = 0; i < src->rui_nextents; i++)618		memcpy(&dst->rui_extents[i], &src->rui_extents[i],619				sizeof(struct xfs_map_extent));620}621 622/*623 * This routine is called to create an in-core extent rmap update624 * item from the rui format structure which was logged on disk.625 * It allocates an in-core rui, copies the extents from the format626 * structure into it, and adds the rui to the AIL with the given627 * LSN.628 */629STATIC int630xlog_recover_rui_commit_pass2(631	struct xlog			*log,632	struct list_head		*buffer_list,633	struct xlog_recover_item	*item,634	xfs_lsn_t			lsn)635{636	struct xfs_mount		*mp = log->l_mp;637	struct xfs_rui_log_item		*ruip;638	struct xfs_rui_log_format	*rui_formatp;639	size_t				len;640 641	rui_formatp = item->ri_buf[0].i_addr;642 643	if (item->ri_buf[0].i_len < xfs_rui_log_format_sizeof(0)) {644		XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp,645				item->ri_buf[0].i_addr, item->ri_buf[0].i_len);646		return -EFSCORRUPTED;647	}648 649	len = xfs_rui_log_format_sizeof(rui_formatp->rui_nextents);650	if (item->ri_buf[0].i_len != len) {651		XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp,652				item->ri_buf[0].i_addr, item->ri_buf[0].i_len);653		return -EFSCORRUPTED;654	}655 656	ruip = xfs_rui_init(mp, rui_formatp->rui_nextents);657	xfs_rui_copy_format(&ruip->rui_format, rui_formatp);658	atomic_set(&ruip->rui_next_extent, rui_formatp->rui_nextents);659 660	xlog_recover_intent_item(log, &ruip->rui_item, lsn,661			&xfs_rmap_update_defer_type);662	return 0;663}664 665const struct xlog_recover_item_ops xlog_rui_item_ops = {666	.item_type		= XFS_LI_RUI,667	.commit_pass2		= xlog_recover_rui_commit_pass2,668};669 670/*671 * This routine is called when an RUD format structure is found in a committed672 * transaction in the log. Its purpose is to cancel the corresponding RUI if it673 * was still in the log. To do this it searches the AIL for the RUI with an id674 * equal to that in the RUD format structure. If we find it we drop the RUD675 * reference, which removes the RUI from the AIL and frees it.676 */677STATIC int678xlog_recover_rud_commit_pass2(679	struct xlog			*log,680	struct list_head		*buffer_list,681	struct xlog_recover_item	*item,682	xfs_lsn_t			lsn)683{684	struct xfs_rud_log_format	*rud_formatp;685 686	rud_formatp = item->ri_buf[0].i_addr;687	if (item->ri_buf[0].i_len != sizeof(struct xfs_rud_log_format)) {688		XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, log->l_mp,689				rud_formatp, item->ri_buf[0].i_len);690		return -EFSCORRUPTED;691	}692 693	xlog_recover_release_intent(log, XFS_LI_RUI, rud_formatp->rud_rui_id);694	return 0;695}696 697const struct xlog_recover_item_ops xlog_rud_item_ops = {698	.item_type		= XFS_LI_RUD,699	.commit_pass2		= xlog_recover_rud_commit_pass2,700};701