Merge tag 'clk-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/clk/linux
[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         const struct list_head          *a,
273         const 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_has_reflink(mp))
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 == -EFSCORRUPTED)
526                         XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp,
527                                         refc, sizeof(*refc));
528                 if (error)
529                         goto abort_error;
530
531                 /* Requeue what we didn't finish. */
532                 if (new_len > 0) {
533                         irec.br_startblock = new_fsb;
534                         irec.br_blockcount = new_len;
535                         switch (type) {
536                         case XFS_REFCOUNT_INCREASE:
537                                 xfs_refcount_increase_extent(tp, &irec);
538                                 break;
539                         case XFS_REFCOUNT_DECREASE:
540                                 xfs_refcount_decrease_extent(tp, &irec);
541                                 break;
542                         case XFS_REFCOUNT_ALLOC_COW:
543                                 xfs_refcount_alloc_cow_extent(tp,
544                                                 irec.br_startblock,
545                                                 irec.br_blockcount);
546                                 break;
547                         case XFS_REFCOUNT_FREE_COW:
548                                 xfs_refcount_free_cow_extent(tp,
549                                                 irec.br_startblock,
550                                                 irec.br_blockcount);
551                                 break;
552                         default:
553                                 ASSERT(0);
554                         }
555                         requeue_only = true;
556                 }
557         }
558
559         xfs_refcount_finish_one_cleanup(tp, rcur, error);
560         return xfs_defer_ops_capture_and_commit(tp, NULL, capture_list);
561
562 abort_error:
563         xfs_refcount_finish_one_cleanup(tp, rcur, error);
564         xfs_trans_cancel(tp);
565         return error;
566 }
567
568 STATIC bool
569 xfs_cui_item_match(
570         struct xfs_log_item     *lip,
571         uint64_t                intent_id)
572 {
573         return CUI_ITEM(lip)->cui_format.cui_id == intent_id;
574 }
575
576 /* Relog an intent item to push the log tail forward. */
577 static struct xfs_log_item *
578 xfs_cui_item_relog(
579         struct xfs_log_item             *intent,
580         struct xfs_trans                *tp)
581 {
582         struct xfs_cud_log_item         *cudp;
583         struct xfs_cui_log_item         *cuip;
584         struct xfs_phys_extent          *extp;
585         unsigned int                    count;
586
587         count = CUI_ITEM(intent)->cui_format.cui_nextents;
588         extp = CUI_ITEM(intent)->cui_format.cui_extents;
589
590         tp->t_flags |= XFS_TRANS_DIRTY;
591         cudp = xfs_trans_get_cud(tp, CUI_ITEM(intent));
592         set_bit(XFS_LI_DIRTY, &cudp->cud_item.li_flags);
593
594         cuip = xfs_cui_init(tp->t_mountp, count);
595         memcpy(cuip->cui_format.cui_extents, extp, count * sizeof(*extp));
596         atomic_set(&cuip->cui_next_extent, count);
597         xfs_trans_add_item(tp, &cuip->cui_item);
598         set_bit(XFS_LI_DIRTY, &cuip->cui_item.li_flags);
599         return &cuip->cui_item;
600 }
601
602 static const struct xfs_item_ops xfs_cui_item_ops = {
603         .iop_size       = xfs_cui_item_size,
604         .iop_format     = xfs_cui_item_format,
605         .iop_unpin      = xfs_cui_item_unpin,
606         .iop_release    = xfs_cui_item_release,
607         .iop_recover    = xfs_cui_item_recover,
608         .iop_match      = xfs_cui_item_match,
609         .iop_relog      = xfs_cui_item_relog,
610 };
611
612 /*
613  * Copy an CUI format buffer from the given buf, and into the destination
614  * CUI format structure.  The CUI/CUD items were designed not to need any
615  * special alignment handling.
616  */
617 static int
618 xfs_cui_copy_format(
619         struct xfs_log_iovec            *buf,
620         struct xfs_cui_log_format       *dst_cui_fmt)
621 {
622         struct xfs_cui_log_format       *src_cui_fmt;
623         uint                            len;
624
625         src_cui_fmt = buf->i_addr;
626         len = xfs_cui_log_format_sizeof(src_cui_fmt->cui_nextents);
627
628         if (buf->i_len == len) {
629                 memcpy(dst_cui_fmt, src_cui_fmt, len);
630                 return 0;
631         }
632         XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_LOW, NULL);
633         return -EFSCORRUPTED;
634 }
635
636 /*
637  * This routine is called to create an in-core extent refcount update
638  * item from the cui format structure which was logged on disk.
639  * It allocates an in-core cui, copies the extents from the format
640  * structure into it, and adds the cui to the AIL with the given
641  * LSN.
642  */
643 STATIC int
644 xlog_recover_cui_commit_pass2(
645         struct xlog                     *log,
646         struct list_head                *buffer_list,
647         struct xlog_recover_item        *item,
648         xfs_lsn_t                       lsn)
649 {
650         int                             error;
651         struct xfs_mount                *mp = log->l_mp;
652         struct xfs_cui_log_item         *cuip;
653         struct xfs_cui_log_format       *cui_formatp;
654
655         cui_formatp = item->ri_buf[0].i_addr;
656
657         cuip = xfs_cui_init(mp, cui_formatp->cui_nextents);
658         error = xfs_cui_copy_format(&item->ri_buf[0], &cuip->cui_format);
659         if (error) {
660                 xfs_cui_item_free(cuip);
661                 return error;
662         }
663         atomic_set(&cuip->cui_next_extent, cui_formatp->cui_nextents);
664         /*
665          * Insert the intent into the AIL directly and drop one reference so
666          * that finishing or canceling the work will drop the other.
667          */
668         xfs_trans_ail_insert(log->l_ailp, &cuip->cui_item, lsn);
669         xfs_cui_release(cuip);
670         return 0;
671 }
672
673 const struct xlog_recover_item_ops xlog_cui_item_ops = {
674         .item_type              = XFS_LI_CUI,
675         .commit_pass2           = xlog_recover_cui_commit_pass2,
676 };
677
678 /*
679  * This routine is called when an CUD format structure is found in a committed
680  * transaction in the log. Its purpose is to cancel the corresponding CUI if it
681  * was still in the log. To do this it searches the AIL for the CUI with an id
682  * equal to that in the CUD format structure. If we find it we drop the CUD
683  * reference, which removes the CUI from the AIL and frees it.
684  */
685 STATIC int
686 xlog_recover_cud_commit_pass2(
687         struct xlog                     *log,
688         struct list_head                *buffer_list,
689         struct xlog_recover_item        *item,
690         xfs_lsn_t                       lsn)
691 {
692         struct xfs_cud_log_format       *cud_formatp;
693
694         cud_formatp = item->ri_buf[0].i_addr;
695         if (item->ri_buf[0].i_len != sizeof(struct xfs_cud_log_format)) {
696                 XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_LOW, log->l_mp);
697                 return -EFSCORRUPTED;
698         }
699
700         xlog_recover_release_intent(log, XFS_LI_CUI, cud_formatp->cud_cui_id);
701         return 0;
702 }
703
704 const struct xlog_recover_item_ops xlog_cud_item_ops = {
705         .item_type              = XFS_LI_CUD,
706         .commit_pass2           = xlog_recover_cud_commit_pass2,
707 };