opp: Call the missing clk_put() on error
[linux-2.6-microblaze.git] / fs / xfs / xfs_refcount_item.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_refcount_item.h"
18 #include "xfs_log.h"
19 #include "xfs_refcount.h"
20 #include "xfs_error.h"
21 #include "xfs_log_priv.h"
22 #include "xfs_log_recover.h"
23
24 kmem_zone_t     *xfs_cui_zone;
25 kmem_zone_t     *xfs_cud_zone;
26
27 static const struct xfs_item_ops xfs_cui_item_ops;
28
29 static inline struct xfs_cui_log_item *CUI_ITEM(struct xfs_log_item *lip)
30 {
31         return container_of(lip, struct xfs_cui_log_item, cui_item);
32 }
33
34 STATIC void
35 xfs_cui_item_free(
36         struct xfs_cui_log_item *cuip)
37 {
38         if (cuip->cui_format.cui_nextents > XFS_CUI_MAX_FAST_EXTENTS)
39                 kmem_free(cuip);
40         else
41                 kmem_cache_free(xfs_cui_zone, cuip);
42 }
43
44 /*
45  * Freeing the CUI requires that we remove it from the AIL if it has already
46  * been placed there. However, the CUI may not yet have been placed in the AIL
47  * when called by xfs_cui_release() from CUD processing due to the ordering of
48  * committed vs unpin operations in bulk insert operations. Hence the reference
49  * count to ensure only the last caller frees the CUI.
50  */
51 STATIC void
52 xfs_cui_release(
53         struct xfs_cui_log_item *cuip)
54 {
55         ASSERT(atomic_read(&cuip->cui_refcount) > 0);
56         if (atomic_dec_and_test(&cuip->cui_refcount)) {
57                 xfs_trans_ail_delete(&cuip->cui_item, SHUTDOWN_LOG_IO_ERROR);
58                 xfs_cui_item_free(cuip);
59         }
60 }
61
62
63 STATIC void
64 xfs_cui_item_size(
65         struct xfs_log_item     *lip,
66         int                     *nvecs,
67         int                     *nbytes)
68 {
69         struct xfs_cui_log_item *cuip = CUI_ITEM(lip);
70
71         *nvecs += 1;
72         *nbytes += xfs_cui_log_format_sizeof(cuip->cui_format.cui_nextents);
73 }
74
75 /*
76  * This is called to fill in the vector of log iovecs for the
77  * given cui log item. We use only 1 iovec, and we point that
78  * at the cui_log_format structure embedded in the cui item.
79  * It is at this point that we assert that all of the extent
80  * slots in the cui item have been filled.
81  */
82 STATIC void
83 xfs_cui_item_format(
84         struct xfs_log_item     *lip,
85         struct xfs_log_vec      *lv)
86 {
87         struct xfs_cui_log_item *cuip = CUI_ITEM(lip);
88         struct xfs_log_iovec    *vecp = NULL;
89
90         ASSERT(atomic_read(&cuip->cui_next_extent) ==
91                         cuip->cui_format.cui_nextents);
92
93         cuip->cui_format.cui_type = XFS_LI_CUI;
94         cuip->cui_format.cui_size = 1;
95
96         xlog_copy_iovec(lv, &vecp, XLOG_REG_TYPE_CUI_FORMAT, &cuip->cui_format,
97                         xfs_cui_log_format_sizeof(cuip->cui_format.cui_nextents));
98 }
99
100 /*
101  * The unpin operation is the last place an CUI is manipulated in the log. It is
102  * either inserted in the AIL or aborted in the event of a log I/O error. In
103  * either case, the CUI transaction has been successfully committed to make it
104  * this far. Therefore, we expect whoever committed the CUI to either construct
105  * and commit the CUD or drop the CUD's reference in the event of error. Simply
106  * drop the log's CUI reference now that the log is done with it.
107  */
108 STATIC void
109 xfs_cui_item_unpin(
110         struct xfs_log_item     *lip,
111         int                     remove)
112 {
113         struct xfs_cui_log_item *cuip = CUI_ITEM(lip);
114
115         xfs_cui_release(cuip);
116 }
117
118 /*
119  * The CUI has been either committed or aborted if the transaction has been
120  * cancelled. If the transaction was cancelled, an CUD isn't going to be
121  * constructed and thus we free the CUI here directly.
122  */
123 STATIC void
124 xfs_cui_item_release(
125         struct xfs_log_item     *lip)
126 {
127         xfs_cui_release(CUI_ITEM(lip));
128 }
129
130 /*
131  * Allocate and initialize an cui item with the given number of extents.
132  */
133 STATIC struct xfs_cui_log_item *
134 xfs_cui_init(
135         struct xfs_mount                *mp,
136         uint                            nextents)
137
138 {
139         struct xfs_cui_log_item         *cuip;
140
141         ASSERT(nextents > 0);
142         if (nextents > XFS_CUI_MAX_FAST_EXTENTS)
143                 cuip = kmem_zalloc(xfs_cui_log_item_sizeof(nextents),
144                                 0);
145         else
146                 cuip = kmem_cache_zalloc(xfs_cui_zone,
147                                          GFP_KERNEL | __GFP_NOFAIL);
148
149         xfs_log_item_init(mp, &cuip->cui_item, XFS_LI_CUI, &xfs_cui_item_ops);
150         cuip->cui_format.cui_nextents = nextents;
151         cuip->cui_format.cui_id = (uintptr_t)(void *)cuip;
152         atomic_set(&cuip->cui_next_extent, 0);
153         atomic_set(&cuip->cui_refcount, 2);
154
155         return cuip;
156 }
157
158 static inline struct xfs_cud_log_item *CUD_ITEM(struct xfs_log_item *lip)
159 {
160         return container_of(lip, struct xfs_cud_log_item, cud_item);
161 }
162
163 STATIC void
164 xfs_cud_item_size(
165         struct xfs_log_item     *lip,
166         int                     *nvecs,
167         int                     *nbytes)
168 {
169         *nvecs += 1;
170         *nbytes += sizeof(struct xfs_cud_log_format);
171 }
172
173 /*
174  * This is called to fill in the vector of log iovecs for the
175  * given cud log item. We use only 1 iovec, and we point that
176  * at the cud_log_format structure embedded in the cud item.
177  * It is at this point that we assert that all of the extent
178  * slots in the cud item have been filled.
179  */
180 STATIC void
181 xfs_cud_item_format(
182         struct xfs_log_item     *lip,
183         struct xfs_log_vec      *lv)
184 {
185         struct xfs_cud_log_item *cudp = CUD_ITEM(lip);
186         struct xfs_log_iovec    *vecp = NULL;
187
188         cudp->cud_format.cud_type = XFS_LI_CUD;
189         cudp->cud_format.cud_size = 1;
190
191         xlog_copy_iovec(lv, &vecp, XLOG_REG_TYPE_CUD_FORMAT, &cudp->cud_format,
192                         sizeof(struct xfs_cud_log_format));
193 }
194
195 /*
196  * The CUD is either committed or aborted if the transaction is cancelled. If
197  * the transaction is cancelled, drop our reference to the CUI and free the
198  * CUD.
199  */
200 STATIC void
201 xfs_cud_item_release(
202         struct xfs_log_item     *lip)
203 {
204         struct xfs_cud_log_item *cudp = CUD_ITEM(lip);
205
206         xfs_cui_release(cudp->cud_cuip);
207         kmem_cache_free(xfs_cud_zone, cudp);
208 }
209
210 static const struct xfs_item_ops xfs_cud_item_ops = {
211         .flags          = XFS_ITEM_RELEASE_WHEN_COMMITTED,
212         .iop_size       = xfs_cud_item_size,
213         .iop_format     = xfs_cud_item_format,
214         .iop_release    = xfs_cud_item_release,
215 };
216
217 static struct xfs_cud_log_item *
218 xfs_trans_get_cud(
219         struct xfs_trans                *tp,
220         struct xfs_cui_log_item         *cuip)
221 {
222         struct xfs_cud_log_item         *cudp;
223
224         cudp = kmem_cache_zalloc(xfs_cud_zone, GFP_KERNEL | __GFP_NOFAIL);
225         xfs_log_item_init(tp->t_mountp, &cudp->cud_item, XFS_LI_CUD,
226                           &xfs_cud_item_ops);
227         cudp->cud_cuip = cuip;
228         cudp->cud_format.cud_cui_id = cuip->cui_format.cui_id;
229
230         xfs_trans_add_item(tp, &cudp->cud_item);
231         return cudp;
232 }
233
234 /*
235  * Finish an refcount update and log it to the CUD. Note that the
236  * transaction is marked dirty regardless of whether the refcount
237  * update succeeds or fails to support the CUI/CUD lifecycle rules.
238  */
239 static int
240 xfs_trans_log_finish_refcount_update(
241         struct xfs_trans                *tp,
242         struct xfs_cud_log_item         *cudp,
243         enum xfs_refcount_intent_type   type,
244         xfs_fsblock_t                   startblock,
245         xfs_extlen_t                    blockcount,
246         xfs_fsblock_t                   *new_fsb,
247         xfs_extlen_t                    *new_len,
248         struct xfs_btree_cur            **pcur)
249 {
250         int                             error;
251
252         error = xfs_refcount_finish_one(tp, type, startblock,
253                         blockcount, new_fsb, new_len, pcur);
254
255         /*
256          * Mark the transaction dirty, even on error. This ensures the
257          * transaction is aborted, which:
258          *
259          * 1.) releases the CUI and frees the CUD
260          * 2.) shuts down the filesystem
261          */
262         tp->t_flags |= XFS_TRANS_DIRTY;
263         set_bit(XFS_LI_DIRTY, &cudp->cud_item.li_flags);
264
265         return error;
266 }
267
268 /* Sort refcount intents by AG. */
269 static int
270 xfs_refcount_update_diff_items(
271         void                            *priv,
272         struct list_head                *a,
273         struct list_head                *b)
274 {
275         struct xfs_mount                *mp = priv;
276         struct xfs_refcount_intent      *ra;
277         struct xfs_refcount_intent      *rb;
278
279         ra = container_of(a, struct xfs_refcount_intent, ri_list);
280         rb = container_of(b, struct xfs_refcount_intent, ri_list);
281         return  XFS_FSB_TO_AGNO(mp, ra->ri_startblock) -
282                 XFS_FSB_TO_AGNO(mp, rb->ri_startblock);
283 }
284
285 /* Set the phys extent flags for this reverse mapping. */
286 static void
287 xfs_trans_set_refcount_flags(
288         struct xfs_phys_extent          *refc,
289         enum xfs_refcount_intent_type   type)
290 {
291         refc->pe_flags = 0;
292         switch (type) {
293         case XFS_REFCOUNT_INCREASE:
294         case XFS_REFCOUNT_DECREASE:
295         case XFS_REFCOUNT_ALLOC_COW:
296         case XFS_REFCOUNT_FREE_COW:
297                 refc->pe_flags |= type;
298                 break;
299         default:
300                 ASSERT(0);
301         }
302 }
303
304 /* Log refcount updates in the intent item. */
305 STATIC void
306 xfs_refcount_update_log_item(
307         struct xfs_trans                *tp,
308         struct xfs_cui_log_item         *cuip,
309         struct xfs_refcount_intent      *refc)
310 {
311         uint                            next_extent;
312         struct xfs_phys_extent          *ext;
313
314         tp->t_flags |= XFS_TRANS_DIRTY;
315         set_bit(XFS_LI_DIRTY, &cuip->cui_item.li_flags);
316
317         /*
318          * atomic_inc_return gives us the value after the increment;
319          * we want to use it as an array index so we need to subtract 1 from
320          * it.
321          */
322         next_extent = atomic_inc_return(&cuip->cui_next_extent) - 1;
323         ASSERT(next_extent < cuip->cui_format.cui_nextents);
324         ext = &cuip->cui_format.cui_extents[next_extent];
325         ext->pe_startblock = refc->ri_startblock;
326         ext->pe_len = refc->ri_blockcount;
327         xfs_trans_set_refcount_flags(ext, refc->ri_type);
328 }
329
330 static struct xfs_log_item *
331 xfs_refcount_update_create_intent(
332         struct xfs_trans                *tp,
333         struct list_head                *items,
334         unsigned int                    count,
335         bool                            sort)
336 {
337         struct xfs_mount                *mp = tp->t_mountp;
338         struct xfs_cui_log_item         *cuip = xfs_cui_init(mp, count);
339         struct xfs_refcount_intent      *refc;
340
341         ASSERT(count > 0);
342
343         xfs_trans_add_item(tp, &cuip->cui_item);
344         if (sort)
345                 list_sort(mp, items, xfs_refcount_update_diff_items);
346         list_for_each_entry(refc, items, ri_list)
347                 xfs_refcount_update_log_item(tp, cuip, refc);
348         return &cuip->cui_item;
349 }
350
351 /* Get an CUD so we can process all the deferred refcount updates. */
352 static struct xfs_log_item *
353 xfs_refcount_update_create_done(
354         struct xfs_trans                *tp,
355         struct xfs_log_item             *intent,
356         unsigned int                    count)
357 {
358         return &xfs_trans_get_cud(tp, CUI_ITEM(intent))->cud_item;
359 }
360
361 /* Process a deferred refcount update. */
362 STATIC int
363 xfs_refcount_update_finish_item(
364         struct xfs_trans                *tp,
365         struct xfs_log_item             *done,
366         struct list_head                *item,
367         struct xfs_btree_cur            **state)
368 {
369         struct xfs_refcount_intent      *refc;
370         xfs_fsblock_t                   new_fsb;
371         xfs_extlen_t                    new_aglen;
372         int                             error;
373
374         refc = container_of(item, struct xfs_refcount_intent, ri_list);
375         error = xfs_trans_log_finish_refcount_update(tp, CUD_ITEM(done),
376                         refc->ri_type, refc->ri_startblock, refc->ri_blockcount,
377                         &new_fsb, &new_aglen, state);
378
379         /* Did we run out of reservation?  Requeue what we didn't finish. */
380         if (!error && new_aglen > 0) {
381                 ASSERT(refc->ri_type == XFS_REFCOUNT_INCREASE ||
382                        refc->ri_type == XFS_REFCOUNT_DECREASE);
383                 refc->ri_startblock = new_fsb;
384                 refc->ri_blockcount = new_aglen;
385                 return -EAGAIN;
386         }
387         kmem_free(refc);
388         return error;
389 }
390
391 /* Abort all pending CUIs. */
392 STATIC void
393 xfs_refcount_update_abort_intent(
394         struct xfs_log_item             *intent)
395 {
396         xfs_cui_release(CUI_ITEM(intent));
397 }
398
399 /* Cancel a deferred refcount update. */
400 STATIC void
401 xfs_refcount_update_cancel_item(
402         struct list_head                *item)
403 {
404         struct xfs_refcount_intent      *refc;
405
406         refc = container_of(item, struct xfs_refcount_intent, ri_list);
407         kmem_free(refc);
408 }
409
410 const struct xfs_defer_op_type xfs_refcount_update_defer_type = {
411         .max_items      = XFS_CUI_MAX_FAST_EXTENTS,
412         .create_intent  = xfs_refcount_update_create_intent,
413         .abort_intent   = xfs_refcount_update_abort_intent,
414         .create_done    = xfs_refcount_update_create_done,
415         .finish_item    = xfs_refcount_update_finish_item,
416         .finish_cleanup = xfs_refcount_finish_one_cleanup,
417         .cancel_item    = xfs_refcount_update_cancel_item,
418 };
419
420 /* Is this recovered CUI ok? */
421 static inline bool
422 xfs_cui_validate_phys(
423         struct xfs_mount                *mp,
424         struct xfs_phys_extent          *refc)
425 {
426         if (!xfs_sb_version_hasreflink(&mp->m_sb))
427                 return false;
428
429         if (refc->pe_flags & ~XFS_REFCOUNT_EXTENT_FLAGS)
430                 return false;
431
432         switch (refc->pe_flags & XFS_REFCOUNT_EXTENT_TYPE_MASK) {
433         case XFS_REFCOUNT_INCREASE:
434         case XFS_REFCOUNT_DECREASE:
435         case XFS_REFCOUNT_ALLOC_COW:
436         case XFS_REFCOUNT_FREE_COW:
437                 break;
438         default:
439                 return false;
440         }
441
442         return xfs_verify_fsbext(mp, refc->pe_startblock, refc->pe_len);
443 }
444
445 /*
446  * Process a refcount update intent item that was recovered from the log.
447  * We need to update the refcountbt.
448  */
449 STATIC int
450 xfs_cui_item_recover(
451         struct xfs_log_item             *lip,
452         struct list_head                *capture_list)
453 {
454         struct xfs_bmbt_irec            irec;
455         struct xfs_cui_log_item         *cuip = CUI_ITEM(lip);
456         struct xfs_phys_extent          *refc;
457         struct xfs_cud_log_item         *cudp;
458         struct xfs_trans                *tp;
459         struct xfs_btree_cur            *rcur = NULL;
460         struct xfs_mount                *mp = lip->li_mountp;
461         xfs_fsblock_t                   new_fsb;
462         xfs_extlen_t                    new_len;
463         unsigned int                    refc_type;
464         bool                            requeue_only = false;
465         enum xfs_refcount_intent_type   type;
466         int                             i;
467         int                             error = 0;
468
469         /*
470          * First check the validity of the extents described by the
471          * CUI.  If any are bad, then assume that all are bad and
472          * just toss the CUI.
473          */
474         for (i = 0; i < cuip->cui_format.cui_nextents; i++) {
475                 if (!xfs_cui_validate_phys(mp,
476                                         &cuip->cui_format.cui_extents[i])) {
477                         XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp,
478                                         &cuip->cui_format,
479                                         sizeof(cuip->cui_format));
480                         return -EFSCORRUPTED;
481                 }
482         }
483
484         /*
485          * Under normal operation, refcount updates are deferred, so we
486          * wouldn't be adding them directly to a transaction.  All
487          * refcount updates manage reservation usage internally and
488          * dynamically by deferring work that won't fit in the
489          * transaction.  Normally, any work that needs to be deferred
490          * gets attached to the same defer_ops that scheduled the
491          * refcount update.  However, we're in log recovery here, so we
492          * use the passed in defer_ops and to finish up any work that
493          * doesn't fit.  We need to reserve enough blocks to handle a
494          * full btree split on either end of the refcount range.
495          */
496         error = xfs_trans_alloc(mp, &M_RES(mp)->tr_itruncate,
497                         mp->m_refc_maxlevels * 2, 0, XFS_TRANS_RESERVE, &tp);
498         if (error)
499                 return error;
500
501         cudp = xfs_trans_get_cud(tp, cuip);
502
503         for (i = 0; i < cuip->cui_format.cui_nextents; i++) {
504                 refc = &cuip->cui_format.cui_extents[i];
505                 refc_type = refc->pe_flags & XFS_REFCOUNT_EXTENT_TYPE_MASK;
506                 switch (refc_type) {
507                 case XFS_REFCOUNT_INCREASE:
508                 case XFS_REFCOUNT_DECREASE:
509                 case XFS_REFCOUNT_ALLOC_COW:
510                 case XFS_REFCOUNT_FREE_COW:
511                         type = refc_type;
512                         break;
513                 default:
514                         XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_LOW, mp);
515                         error = -EFSCORRUPTED;
516                         goto abort_error;
517                 }
518                 if (requeue_only) {
519                         new_fsb = refc->pe_startblock;
520                         new_len = refc->pe_len;
521                 } else
522                         error = xfs_trans_log_finish_refcount_update(tp, cudp,
523                                 type, refc->pe_startblock, refc->pe_len,
524                                 &new_fsb, &new_len, &rcur);
525                 if (error)
526                         goto abort_error;
527
528                 /* Requeue what we didn't finish. */
529                 if (new_len > 0) {
530                         irec.br_startblock = new_fsb;
531                         irec.br_blockcount = new_len;
532                         switch (type) {
533                         case XFS_REFCOUNT_INCREASE:
534                                 xfs_refcount_increase_extent(tp, &irec);
535                                 break;
536                         case XFS_REFCOUNT_DECREASE:
537                                 xfs_refcount_decrease_extent(tp, &irec);
538                                 break;
539                         case XFS_REFCOUNT_ALLOC_COW:
540                                 xfs_refcount_alloc_cow_extent(tp,
541                                                 irec.br_startblock,
542                                                 irec.br_blockcount);
543                                 break;
544                         case XFS_REFCOUNT_FREE_COW:
545                                 xfs_refcount_free_cow_extent(tp,
546                                                 irec.br_startblock,
547                                                 irec.br_blockcount);
548                                 break;
549                         default:
550                                 ASSERT(0);
551                         }
552                         requeue_only = true;
553                 }
554         }
555
556         xfs_refcount_finish_one_cleanup(tp, rcur, error);
557         return xfs_defer_ops_capture_and_commit(tp, NULL, capture_list);
558
559 abort_error:
560         xfs_refcount_finish_one_cleanup(tp, rcur, error);
561         xfs_trans_cancel(tp);
562         return error;
563 }
564
565 STATIC bool
566 xfs_cui_item_match(
567         struct xfs_log_item     *lip,
568         uint64_t                intent_id)
569 {
570         return CUI_ITEM(lip)->cui_format.cui_id == intent_id;
571 }
572
573 /* Relog an intent item to push the log tail forward. */
574 static struct xfs_log_item *
575 xfs_cui_item_relog(
576         struct xfs_log_item             *intent,
577         struct xfs_trans                *tp)
578 {
579         struct xfs_cud_log_item         *cudp;
580         struct xfs_cui_log_item         *cuip;
581         struct xfs_phys_extent          *extp;
582         unsigned int                    count;
583
584         count = CUI_ITEM(intent)->cui_format.cui_nextents;
585         extp = CUI_ITEM(intent)->cui_format.cui_extents;
586
587         tp->t_flags |= XFS_TRANS_DIRTY;
588         cudp = xfs_trans_get_cud(tp, CUI_ITEM(intent));
589         set_bit(XFS_LI_DIRTY, &cudp->cud_item.li_flags);
590
591         cuip = xfs_cui_init(tp->t_mountp, count);
592         memcpy(cuip->cui_format.cui_extents, extp, count * sizeof(*extp));
593         atomic_set(&cuip->cui_next_extent, count);
594         xfs_trans_add_item(tp, &cuip->cui_item);
595         set_bit(XFS_LI_DIRTY, &cuip->cui_item.li_flags);
596         return &cuip->cui_item;
597 }
598
599 static const struct xfs_item_ops xfs_cui_item_ops = {
600         .iop_size       = xfs_cui_item_size,
601         .iop_format     = xfs_cui_item_format,
602         .iop_unpin      = xfs_cui_item_unpin,
603         .iop_release    = xfs_cui_item_release,
604         .iop_recover    = xfs_cui_item_recover,
605         .iop_match      = xfs_cui_item_match,
606         .iop_relog      = xfs_cui_item_relog,
607 };
608
609 /*
610  * Copy an CUI format buffer from the given buf, and into the destination
611  * CUI format structure.  The CUI/CUD items were designed not to need any
612  * special alignment handling.
613  */
614 static int
615 xfs_cui_copy_format(
616         struct xfs_log_iovec            *buf,
617         struct xfs_cui_log_format       *dst_cui_fmt)
618 {
619         struct xfs_cui_log_format       *src_cui_fmt;
620         uint                            len;
621
622         src_cui_fmt = buf->i_addr;
623         len = xfs_cui_log_format_sizeof(src_cui_fmt->cui_nextents);
624
625         if (buf->i_len == len) {
626                 memcpy(dst_cui_fmt, src_cui_fmt, len);
627                 return 0;
628         }
629         XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_LOW, NULL);
630         return -EFSCORRUPTED;
631 }
632
633 /*
634  * This routine is called to create an in-core extent refcount update
635  * item from the cui format structure which was logged on disk.
636  * It allocates an in-core cui, copies the extents from the format
637  * structure into it, and adds the cui to the AIL with the given
638  * LSN.
639  */
640 STATIC int
641 xlog_recover_cui_commit_pass2(
642         struct xlog                     *log,
643         struct list_head                *buffer_list,
644         struct xlog_recover_item        *item,
645         xfs_lsn_t                       lsn)
646 {
647         int                             error;
648         struct xfs_mount                *mp = log->l_mp;
649         struct xfs_cui_log_item         *cuip;
650         struct xfs_cui_log_format       *cui_formatp;
651
652         cui_formatp = item->ri_buf[0].i_addr;
653
654         cuip = xfs_cui_init(mp, cui_formatp->cui_nextents);
655         error = xfs_cui_copy_format(&item->ri_buf[0], &cuip->cui_format);
656         if (error) {
657                 xfs_cui_item_free(cuip);
658                 return error;
659         }
660         atomic_set(&cuip->cui_next_extent, cui_formatp->cui_nextents);
661         /*
662          * Insert the intent into the AIL directly and drop one reference so
663          * that finishing or canceling the work will drop the other.
664          */
665         xfs_trans_ail_insert(log->l_ailp, &cuip->cui_item, lsn);
666         xfs_cui_release(cuip);
667         return 0;
668 }
669
670 const struct xlog_recover_item_ops xlog_cui_item_ops = {
671         .item_type              = XFS_LI_CUI,
672         .commit_pass2           = xlog_recover_cui_commit_pass2,
673 };
674
675 /*
676  * This routine is called when an CUD format structure is found in a committed
677  * transaction in the log. Its purpose is to cancel the corresponding CUI if it
678  * was still in the log. To do this it searches the AIL for the CUI with an id
679  * equal to that in the CUD format structure. If we find it we drop the CUD
680  * reference, which removes the CUI from the AIL and frees it.
681  */
682 STATIC int
683 xlog_recover_cud_commit_pass2(
684         struct xlog                     *log,
685         struct list_head                *buffer_list,
686         struct xlog_recover_item        *item,
687         xfs_lsn_t                       lsn)
688 {
689         struct xfs_cud_log_format       *cud_formatp;
690
691         cud_formatp = item->ri_buf[0].i_addr;
692         if (item->ri_buf[0].i_len != sizeof(struct xfs_cud_log_format)) {
693                 XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_LOW, log->l_mp);
694                 return -EFSCORRUPTED;
695         }
696
697         xlog_recover_release_intent(log, XFS_LI_CUI, cud_formatp->cud_cui_id);
698         return 0;
699 }
700
701 const struct xlog_recover_item_ops xlog_cud_item_ops = {
702         .item_type              = XFS_LI_CUD,
703         .commit_pass2           = xlog_recover_cud_commit_pass2,
704 };