Line data Source code
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 :
25 : struct kmem_cache *xfs_rui_cache;
26 : struct kmem_cache *xfs_rud_cache;
27 :
28 : static const struct xfs_item_ops xfs_rui_item_ops;
29 :
30 : static inline struct xfs_rui_log_item *RUI_ITEM(struct xfs_log_item *lip)
31 : {
32 : return container_of(lip, struct xfs_rui_log_item, rui_item);
33 : }
34 :
35 : STATIC void
36 189099479 : xfs_rui_item_free(
37 : struct xfs_rui_log_item *ruip)
38 : {
39 189099479 : kmem_free(ruip->rui_item.li_lv_shadow);
40 189099325 : if (ruip->rui_format.rui_nextents > XFS_RUI_MAX_FAST_EXTENTS)
41 0 : kmem_free(ruip);
42 : else
43 189099325 : kmem_cache_free(xfs_rui_cache, ruip);
44 189098894 : }
45 :
46 : /*
47 : * Freeing the RUI requires that we remove it from the AIL if it has already
48 : * been placed there. However, the RUI may not yet have been placed in the AIL
49 : * when called by xfs_rui_release() from RUD processing due to the ordering of
50 : * committed vs unpin operations in bulk insert operations. Hence the reference
51 : * count to ensure only the last caller frees the RUI.
52 : */
53 : STATIC void
54 378068454 : xfs_rui_release(
55 : struct xfs_rui_log_item *ruip)
56 : {
57 378068454 : ASSERT(atomic_read(&ruip->rui_refcount) > 0);
58 756215132 : if (!atomic_dec_and_test(&ruip->rui_refcount))
59 : return;
60 :
61 189096767 : xfs_trans_ail_delete(&ruip->rui_item, 0);
62 189098607 : xfs_rui_item_free(ruip);
63 : }
64 :
65 : STATIC void
66 189059690 : xfs_rui_item_size(
67 : struct xfs_log_item *lip,
68 : int *nvecs,
69 : int *nbytes)
70 : {
71 189059690 : struct xfs_rui_log_item *ruip = RUI_ITEM(lip);
72 :
73 189059690 : *nvecs += 1;
74 189059690 : *nbytes += xfs_rui_log_format_sizeof(ruip->rui_format.rui_nextents);
75 189059690 : }
76 :
77 : /*
78 : * This is called to fill in the vector of log iovecs for the
79 : * given rui log item. We use only 1 iovec, and we point that
80 : * at the rui_log_format structure embedded in the rui item.
81 : * It is at this point that we assert that all of the extent
82 : * slots in the rui item have been filled.
83 : */
84 : STATIC void
85 189059806 : xfs_rui_item_format(
86 : struct xfs_log_item *lip,
87 : struct xfs_log_vec *lv)
88 : {
89 189059806 : struct xfs_rui_log_item *ruip = RUI_ITEM(lip);
90 189059806 : struct xfs_log_iovec *vecp = NULL;
91 :
92 189059806 : ASSERT(atomic_read(&ruip->rui_next_extent) ==
93 : ruip->rui_format.rui_nextents);
94 :
95 189059806 : ruip->rui_format.rui_type = XFS_LI_RUI;
96 189059806 : ruip->rui_format.rui_size = 1;
97 :
98 189059806 : xlog_copy_iovec(lv, &vecp, XLOG_REG_TYPE_RUI_FORMAT, &ruip->rui_format,
99 189059806 : xfs_rui_log_format_sizeof(ruip->rui_format.rui_nextents));
100 189059951 : }
101 :
102 : /*
103 : * The unpin operation is the last place an RUI is manipulated in the log. It is
104 : * either inserted in the AIL or aborted in the event of a log I/O error. In
105 : * either case, the RUI transaction has been successfully committed to make it
106 : * this far. Therefore, we expect whoever committed the RUI to either construct
107 : * and commit the RUD or drop the RUD's reference in the event of error. Simply
108 : * drop the log's RUI reference now that the log is done with it.
109 : */
110 : STATIC void
111 189057113 : xfs_rui_item_unpin(
112 : struct xfs_log_item *lip,
113 : int remove)
114 : {
115 189057113 : struct xfs_rui_log_item *ruip = RUI_ITEM(lip);
116 :
117 189057113 : xfs_rui_release(ruip);
118 189059392 : }
119 :
120 : /*
121 : * The RUI has been either committed or aborted if the transaction has been
122 : * cancelled. If the transaction was cancelled, an RUD isn't going to be
123 : * constructed and thus we free the RUI here directly.
124 : */
125 : STATIC void
126 37782 : xfs_rui_item_release(
127 : struct xfs_log_item *lip)
128 : {
129 37782 : xfs_rui_release(RUI_ITEM(lip));
130 37782 : }
131 :
132 : /*
133 : * Allocate and initialize an rui item with the given number of extents.
134 : */
135 : STATIC struct xfs_rui_log_item *
136 189067346 : xfs_rui_init(
137 : struct xfs_mount *mp,
138 : uint nextents)
139 :
140 : {
141 189067346 : struct xfs_rui_log_item *ruip;
142 :
143 189067346 : ASSERT(nextents > 0);
144 189067346 : if (nextents > XFS_RUI_MAX_FAST_EXTENTS)
145 0 : ruip = kmem_zalloc(xfs_rui_log_item_sizeof(nextents), 0);
146 : else
147 189067346 : ruip = kmem_cache_zalloc(xfs_rui_cache,
148 : GFP_KERNEL | __GFP_NOFAIL);
149 :
150 189020721 : xfs_log_item_init(mp, &ruip->rui_item, XFS_LI_RUI, &xfs_rui_item_ops);
151 189064309 : ruip->rui_format.rui_nextents = nextents;
152 189064309 : ruip->rui_format.rui_id = (uintptr_t)(void *)ruip;
153 189064309 : atomic_set(&ruip->rui_next_extent, 0);
154 189064309 : atomic_set(&ruip->rui_refcount, 2);
155 :
156 189064309 : return ruip;
157 : }
158 :
159 : static inline struct xfs_rud_log_item *RUD_ITEM(struct xfs_log_item *lip)
160 : {
161 : return container_of(lip, struct xfs_rud_log_item, rud_item);
162 : }
163 :
164 : STATIC void
165 189058868 : xfs_rud_item_size(
166 : struct xfs_log_item *lip,
167 : int *nvecs,
168 : int *nbytes)
169 : {
170 189058868 : *nvecs += 1;
171 189058868 : *nbytes += sizeof(struct xfs_rud_log_format);
172 189058868 : }
173 :
174 : /*
175 : * This is called to fill in the vector of log iovecs for the
176 : * given rud log item. We use only 1 iovec, and we point that
177 : * at the rud_log_format structure embedded in the rud item.
178 : * It is at this point that we assert that all of the extent
179 : * slots in the rud item have been filled.
180 : */
181 : STATIC void
182 289434 : xfs_rud_item_format(
183 : struct xfs_log_item *lip,
184 : struct xfs_log_vec *lv)
185 : {
186 289434 : struct xfs_rud_log_item *rudp = RUD_ITEM(lip);
187 289434 : struct xfs_log_iovec *vecp = NULL;
188 :
189 289434 : rudp->rud_format.rud_type = XFS_LI_RUD;
190 289434 : rudp->rud_format.rud_size = 1;
191 :
192 289434 : xlog_copy_iovec(lv, &vecp, XLOG_REG_TYPE_RUD_FORMAT, &rudp->rud_format,
193 : sizeof(struct xfs_rud_log_format));
194 289434 : }
195 :
196 : /*
197 : * The RUD is either committed or aborted if the transaction is cancelled. If
198 : * the transaction is cancelled, drop our reference to the RUI and free the
199 : * RUD.
200 : */
201 : STATIC void
202 189060743 : xfs_rud_item_release(
203 : struct xfs_log_item *lip)
204 : {
205 189060743 : struct xfs_rud_log_item *rudp = RUD_ITEM(lip);
206 :
207 189060743 : xfs_rui_release(rudp->rud_ruip);
208 189060920 : kmem_free(rudp->rud_item.li_lv_shadow);
209 189061004 : kmem_cache_free(xfs_rud_cache, rudp);
210 189061000 : }
211 :
212 : static struct xfs_log_item *
213 189058229 : xfs_rud_item_intent(
214 : struct xfs_log_item *lip)
215 : {
216 189058229 : return &RUD_ITEM(lip)->rud_ruip->rui_item;
217 : }
218 :
219 : static const struct xfs_item_ops xfs_rud_item_ops = {
220 : .flags = XFS_ITEM_RELEASE_WHEN_COMMITTED |
221 : XFS_ITEM_INTENT_DONE,
222 : .iop_size = xfs_rud_item_size,
223 : .iop_format = xfs_rud_item_format,
224 : .iop_release = xfs_rud_item_release,
225 : .iop_intent = xfs_rud_item_intent,
226 : };
227 :
228 : static struct xfs_rud_log_item *
229 189059514 : xfs_trans_get_rud(
230 : struct xfs_trans *tp,
231 : struct xfs_rui_log_item *ruip)
232 : {
233 189059514 : struct xfs_rud_log_item *rudp;
234 :
235 189059514 : rudp = kmem_cache_zalloc(xfs_rud_cache, GFP_KERNEL | __GFP_NOFAIL);
236 189060396 : xfs_log_item_init(tp->t_mountp, &rudp->rud_item, XFS_LI_RUD,
237 : &xfs_rud_item_ops);
238 189060821 : rudp->rud_ruip = ruip;
239 189060821 : rudp->rud_format.rud_rui_id = ruip->rui_format.rui_id;
240 :
241 189060821 : xfs_trans_add_item(tp, &rudp->rud_item);
242 189060832 : return rudp;
243 : }
244 :
245 : /* Set the map extent flags for this reverse mapping. */
246 : static void
247 208663729 : xfs_trans_set_rmap_flags(
248 : struct xfs_map_extent *map,
249 : enum xfs_rmap_intent_type type,
250 : int whichfork,
251 : xfs_exntst_t state)
252 : {
253 208663729 : map->me_flags = 0;
254 208663729 : if (state == XFS_EXT_UNWRITTEN)
255 27821446 : map->me_flags |= XFS_RMAP_EXTENT_UNWRITTEN;
256 208663729 : if (whichfork == XFS_ATTR_FORK)
257 2431146 : map->me_flags |= XFS_RMAP_EXTENT_ATTR_FORK;
258 208663729 : switch (type) {
259 40368473 : case XFS_RMAP_MAP:
260 40368473 : map->me_flags |= XFS_RMAP_EXTENT_MAP;
261 40368473 : break;
262 63521193 : case XFS_RMAP_MAP_SHARED:
263 63521193 : map->me_flags |= XFS_RMAP_EXTENT_MAP_SHARED;
264 63521193 : break;
265 35124084 : case XFS_RMAP_UNMAP:
266 35124084 : map->me_flags |= XFS_RMAP_EXTENT_UNMAP;
267 35124084 : break;
268 51608820 : case XFS_RMAP_UNMAP_SHARED:
269 51608820 : map->me_flags |= XFS_RMAP_EXTENT_UNMAP_SHARED;
270 51608820 : break;
271 5423900 : case XFS_RMAP_CONVERT:
272 5423900 : map->me_flags |= XFS_RMAP_EXTENT_CONVERT;
273 5423900 : break;
274 10004256 : case XFS_RMAP_CONVERT_SHARED:
275 10004256 : map->me_flags |= XFS_RMAP_EXTENT_CONVERT_SHARED;
276 10004256 : break;
277 324782 : case XFS_RMAP_ALLOC:
278 324782 : map->me_flags |= XFS_RMAP_EXTENT_ALLOC;
279 324782 : break;
280 2288221 : case XFS_RMAP_FREE:
281 2288221 : map->me_flags |= XFS_RMAP_EXTENT_FREE;
282 2288221 : break;
283 0 : default:
284 0 : ASSERT(0);
285 : }
286 208663729 : }
287 :
288 : /*
289 : * Finish an rmap update and log it to the RUD. Note that the transaction is
290 : * marked dirty regardless of whether the rmap update succeeds or fails to
291 : * support the RUI/RUD lifecycle rules.
292 : */
293 : static int
294 208663592 : xfs_trans_log_finish_rmap_update(
295 : struct xfs_trans *tp,
296 : struct xfs_rud_log_item *rudp,
297 : struct xfs_rmap_intent *ri,
298 : struct xfs_btree_cur **pcur)
299 : {
300 208663592 : int error;
301 :
302 208663592 : error = xfs_rmap_finish_one(tp, ri, pcur);
303 :
304 : /*
305 : * Mark the transaction dirty, even on error. This ensures the
306 : * transaction is aborted, which:
307 : *
308 : * 1.) releases the RUI and frees the RUD
309 : * 2.) shuts down the filesystem
310 : */
311 208664495 : tp->t_flags |= XFS_TRANS_DIRTY | XFS_TRANS_HAS_INTENT_DONE;
312 208664495 : set_bit(XFS_LI_DIRTY, &rudp->rud_item.li_flags);
313 :
314 208664691 : return error;
315 : }
316 :
317 : /* Sort rmap intents by AG. */
318 : static int
319 19607822 : xfs_rmap_update_diff_items(
320 : void *priv,
321 : const struct list_head *a,
322 : const struct list_head *b)
323 : {
324 19607822 : struct xfs_rmap_intent *ra;
325 19607822 : struct xfs_rmap_intent *rb;
326 :
327 19607822 : ra = container_of(a, struct xfs_rmap_intent, ri_list);
328 19607822 : rb = container_of(b, struct xfs_rmap_intent, ri_list);
329 :
330 19607822 : return ra->ri_pag->pag_agno - rb->ri_pag->pag_agno;
331 : }
332 :
333 : /* Log rmap updates in the intent item. */
334 : STATIC void
335 208639911 : xfs_rmap_update_log_item(
336 : struct xfs_trans *tp,
337 : struct xfs_rui_log_item *ruip,
338 : struct xfs_rmap_intent *ri)
339 : {
340 208639911 : uint next_extent;
341 208639911 : struct xfs_map_extent *map;
342 :
343 208639911 : tp->t_flags |= XFS_TRANS_DIRTY;
344 208639911 : set_bit(XFS_LI_DIRTY, &ruip->rui_item.li_flags);
345 :
346 : /*
347 : * atomic_inc_return gives us the value after the increment;
348 : * we want to use it as an array index so we need to subtract 1 from
349 : * it.
350 : */
351 208639500 : next_extent = atomic_inc_return(&ruip->rui_next_extent) - 1;
352 208657105 : ASSERT(next_extent < ruip->rui_format.rui_nextents);
353 208657105 : map = &ruip->rui_format.rui_extents[next_extent];
354 208657105 : map->me_owner = ri->ri_owner;
355 208657105 : map->me_startblock = ri->ri_bmap.br_startblock;
356 208657105 : map->me_startoff = ri->ri_bmap.br_startoff;
357 208657105 : map->me_len = ri->ri_bmap.br_blockcount;
358 208657105 : xfs_trans_set_rmap_flags(map, ri->ri_type, ri->ri_whichfork,
359 : ri->ri_bmap.br_state);
360 208657253 : }
361 :
362 : static struct xfs_log_item *
363 189028013 : xfs_rmap_update_create_intent(
364 : struct xfs_trans *tp,
365 : struct list_head *items,
366 : unsigned int count,
367 : bool sort)
368 : {
369 189028013 : struct xfs_mount *mp = tp->t_mountp;
370 189028013 : struct xfs_rui_log_item *ruip = xfs_rui_init(mp, count);
371 189025257 : struct xfs_rmap_intent *ri;
372 :
373 189025257 : ASSERT(count > 0);
374 :
375 189025257 : xfs_trans_add_item(tp, &ruip->rui_item);
376 189028500 : if (sort)
377 189030675 : list_sort(mp, items, xfs_rmap_update_diff_items);
378 397685876 : list_for_each_entry(ri, items, ri_list)
379 208643889 : xfs_rmap_update_log_item(tp, ruip, ri);
380 189041987 : return &ruip->rui_item;
381 : }
382 :
383 : /* Get an RUD so we can process all the deferred rmap updates. */
384 : static struct xfs_log_item *
385 189057130 : xfs_rmap_update_create_done(
386 : struct xfs_trans *tp,
387 : struct xfs_log_item *intent,
388 : unsigned int count)
389 : {
390 189057130 : return &xfs_trans_get_rud(tp, RUI_ITEM(intent))->rud_item;
391 : }
392 :
393 : /* Take a passive ref to the AG containing the space we're rmapping. */
394 : void
395 208658922 : xfs_rmap_update_get_group(
396 : struct xfs_mount *mp,
397 : struct xfs_rmap_intent *ri)
398 : {
399 208658922 : xfs_agnumber_t agno;
400 :
401 208658922 : agno = XFS_FSB_TO_AGNO(mp, ri->ri_bmap.br_startblock);
402 208658922 : ri->ri_pag = xfs_perag_intent_get(mp, agno);
403 208660676 : }
404 :
405 : /* Release a passive AG ref after finishing rmapping work. */
406 : static inline void
407 : xfs_rmap_update_put_group(
408 : struct xfs_rmap_intent *ri)
409 : {
410 208664824 : xfs_perag_intent_put(ri->ri_pag);
411 : }
412 :
413 : /* Process a deferred rmap update. */
414 : STATIC int
415 208663177 : xfs_rmap_update_finish_item(
416 : struct xfs_trans *tp,
417 : struct xfs_log_item *done,
418 : struct list_head *item,
419 : struct xfs_btree_cur **state)
420 : {
421 208663177 : struct xfs_rmap_intent *ri;
422 208663177 : int error;
423 :
424 208663177 : ri = container_of(item, struct xfs_rmap_intent, ri_list);
425 :
426 208663177 : error = xfs_trans_log_finish_rmap_update(tp, RUD_ITEM(done), ri,
427 : state);
428 :
429 208662476 : xfs_rmap_update_put_group(ri);
430 208663075 : kmem_cache_free(xfs_rmap_intent_cache, ri);
431 208663370 : return error;
432 : }
433 :
434 : /* Abort all pending RUIs. */
435 : STATIC void
436 704 : xfs_rmap_update_abort_intent(
437 : struct xfs_log_item *intent)
438 : {
439 704 : xfs_rui_release(RUI_ITEM(intent));
440 704 : }
441 :
442 : /* Cancel a deferred rmap update. */
443 : STATIC void
444 782 : xfs_rmap_update_cancel_item(
445 : struct list_head *item)
446 : {
447 782 : struct xfs_rmap_intent *ri;
448 :
449 782 : ri = container_of(item, struct xfs_rmap_intent, ri_list);
450 :
451 782 : xfs_rmap_update_put_group(ri);
452 782 : kmem_cache_free(xfs_rmap_intent_cache, ri);
453 782 : }
454 :
455 : const struct xfs_defer_op_type xfs_rmap_update_defer_type = {
456 : .max_items = XFS_RUI_MAX_FAST_EXTENTS,
457 : .create_intent = xfs_rmap_update_create_intent,
458 : .abort_intent = xfs_rmap_update_abort_intent,
459 : .create_done = xfs_rmap_update_create_done,
460 : .finish_item = xfs_rmap_update_finish_item,
461 : .finish_cleanup = xfs_rmap_finish_one_cleanup,
462 : .cancel_item = xfs_rmap_update_cancel_item,
463 : };
464 :
465 : /* Is this recovered RUI ok? */
466 : static inline bool
467 1566 : xfs_rui_validate_map(
468 : struct xfs_mount *mp,
469 : struct xfs_map_extent *map)
470 : {
471 1566 : if (!xfs_has_rmapbt(mp))
472 : return false;
473 :
474 1566 : if (map->me_flags & ~XFS_RMAP_EXTENT_FLAGS)
475 : return false;
476 :
477 1566 : switch (map->me_flags & XFS_RMAP_EXTENT_TYPE_MASK) {
478 : case XFS_RMAP_EXTENT_MAP:
479 : case XFS_RMAP_EXTENT_MAP_SHARED:
480 : case XFS_RMAP_EXTENT_UNMAP:
481 : case XFS_RMAP_EXTENT_UNMAP_SHARED:
482 : case XFS_RMAP_EXTENT_CONVERT:
483 : case XFS_RMAP_EXTENT_CONVERT_SHARED:
484 : case XFS_RMAP_EXTENT_ALLOC:
485 : case XFS_RMAP_EXTENT_FREE:
486 1566 : break;
487 : default:
488 : return false;
489 : }
490 :
491 3123 : if (!XFS_RMAP_NON_INODE_OWNER(map->me_owner) &&
492 1557 : !xfs_verify_ino(mp, map->me_owner))
493 : return false;
494 :
495 1566 : if (!xfs_verify_fileext(mp, map->me_startoff, map->me_len))
496 : return false;
497 :
498 1566 : return xfs_verify_fsbext(mp, map->me_startblock, map->me_len);
499 : }
500 :
501 : /*
502 : * Process an rmap update intent item that was recovered from the log.
503 : * We need to update the rmapbt.
504 : */
505 : STATIC int
506 1565 : xfs_rui_item_recover(
507 : struct xfs_log_item *lip,
508 : struct list_head *capture_list)
509 : {
510 1565 : struct xfs_rui_log_item *ruip = RUI_ITEM(lip);
511 1565 : struct xfs_rud_log_item *rudp;
512 1565 : struct xfs_trans *tp;
513 1565 : struct xfs_btree_cur *rcur = NULL;
514 1565 : struct xfs_mount *mp = lip->li_log->l_mp;
515 1565 : int i;
516 1565 : int error = 0;
517 :
518 : /*
519 : * First check the validity of the extents described by the
520 : * RUI. If any are bad, then assume that all are bad and
521 : * just toss the RUI.
522 : */
523 3131 : for (i = 0; i < ruip->rui_format.rui_nextents; i++) {
524 1566 : if (!xfs_rui_validate_map(mp,
525 : &ruip->rui_format.rui_extents[i])) {
526 0 : XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp,
527 : &ruip->rui_format,
528 : sizeof(ruip->rui_format));
529 0 : return -EFSCORRUPTED;
530 : }
531 : }
532 :
533 1565 : error = xfs_trans_alloc(mp, &M_RES(mp)->tr_itruncate,
534 : mp->m_rmap_maxlevels, 0, XFS_TRANS_RESERVE, &tp);
535 1565 : if (error)
536 : return error;
537 1565 : rudp = xfs_trans_get_rud(tp, ruip);
538 :
539 4694 : for (i = 0; i < ruip->rui_format.rui_nextents; i++) {
540 1566 : struct xfs_rmap_intent fake = { };
541 1566 : struct xfs_map_extent *map;
542 :
543 1566 : map = &ruip->rui_format.rui_extents[i];
544 1566 : switch (map->me_flags & XFS_RMAP_EXTENT_TYPE_MASK) {
545 : case XFS_RMAP_EXTENT_MAP:
546 : fake.ri_type = XFS_RMAP_MAP;
547 : break;
548 454 : case XFS_RMAP_EXTENT_MAP_SHARED:
549 454 : fake.ri_type = XFS_RMAP_MAP_SHARED;
550 454 : break;
551 32 : case XFS_RMAP_EXTENT_UNMAP:
552 32 : fake.ri_type = XFS_RMAP_UNMAP;
553 32 : break;
554 884 : case XFS_RMAP_EXTENT_UNMAP_SHARED:
555 884 : fake.ri_type = XFS_RMAP_UNMAP_SHARED;
556 884 : break;
557 21 : case XFS_RMAP_EXTENT_CONVERT:
558 21 : fake.ri_type = XFS_RMAP_CONVERT;
559 21 : break;
560 30 : case XFS_RMAP_EXTENT_CONVERT_SHARED:
561 30 : fake.ri_type = XFS_RMAP_CONVERT_SHARED;
562 30 : break;
563 4 : case XFS_RMAP_EXTENT_ALLOC:
564 4 : fake.ri_type = XFS_RMAP_ALLOC;
565 4 : break;
566 5 : case XFS_RMAP_EXTENT_FREE:
567 5 : fake.ri_type = XFS_RMAP_FREE;
568 5 : break;
569 0 : default:
570 0 : XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp,
571 : &ruip->rui_format,
572 : sizeof(ruip->rui_format));
573 0 : error = -EFSCORRUPTED;
574 0 : goto abort_error;
575 : }
576 :
577 1566 : fake.ri_owner = map->me_owner;
578 1566 : fake.ri_whichfork = (map->me_flags & XFS_RMAP_EXTENT_ATTR_FORK) ?
579 1566 : XFS_ATTR_FORK : XFS_DATA_FORK;
580 1566 : fake.ri_bmap.br_startblock = map->me_startblock;
581 1566 : fake.ri_bmap.br_startoff = map->me_startoff;
582 1566 : fake.ri_bmap.br_blockcount = map->me_len;
583 1566 : fake.ri_bmap.br_state = (map->me_flags & XFS_RMAP_EXTENT_UNWRITTEN) ?
584 1566 : XFS_EXT_UNWRITTEN : XFS_EXT_NORM;
585 :
586 1566 : xfs_rmap_update_get_group(mp, &fake);
587 1566 : error = xfs_trans_log_finish_rmap_update(tp, rudp, &fake,
588 : &rcur);
589 1566 : if (error == -EFSCORRUPTED)
590 2 : XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp,
591 : map, sizeof(*map));
592 1566 : xfs_rmap_update_put_group(&fake);
593 1566 : if (error)
594 2 : goto abort_error;
595 :
596 : }
597 :
598 1563 : xfs_rmap_finish_one_cleanup(tp, rcur, error);
599 1563 : return xfs_defer_ops_capture_and_commit(tp, capture_list);
600 :
601 : abort_error:
602 2 : xfs_rmap_finish_one_cleanup(tp, rcur, error);
603 2 : xfs_trans_cancel(tp);
604 2 : return error;
605 : }
606 :
607 : STATIC bool
608 40327 : xfs_rui_item_match(
609 : struct xfs_log_item *lip,
610 : uint64_t intent_id)
611 : {
612 40327 : return RUI_ITEM(lip)->rui_format.rui_id == intent_id;
613 : }
614 :
615 : /* Relog an intent item to push the log tail forward. */
616 : static struct xfs_log_item *
617 673 : xfs_rui_item_relog(
618 : struct xfs_log_item *intent,
619 : struct xfs_trans *tp)
620 : {
621 673 : struct xfs_rud_log_item *rudp;
622 673 : struct xfs_rui_log_item *ruip;
623 673 : struct xfs_map_extent *map;
624 673 : unsigned int count;
625 :
626 673 : count = RUI_ITEM(intent)->rui_format.rui_nextents;
627 673 : map = RUI_ITEM(intent)->rui_format.rui_extents;
628 :
629 673 : tp->t_flags |= XFS_TRANS_DIRTY;
630 673 : rudp = xfs_trans_get_rud(tp, RUI_ITEM(intent));
631 673 : set_bit(XFS_LI_DIRTY, &rudp->rud_item.li_flags);
632 :
633 673 : ruip = xfs_rui_init(tp->t_mountp, count);
634 1346 : memcpy(ruip->rui_format.rui_extents, map, count * sizeof(*map));
635 673 : atomic_set(&ruip->rui_next_extent, count);
636 673 : xfs_trans_add_item(tp, &ruip->rui_item);
637 673 : set_bit(XFS_LI_DIRTY, &ruip->rui_item.li_flags);
638 673 : return &ruip->rui_item;
639 : }
640 :
641 : static const struct xfs_item_ops xfs_rui_item_ops = {
642 : .flags = XFS_ITEM_INTENT,
643 : .iop_size = xfs_rui_item_size,
644 : .iop_format = xfs_rui_item_format,
645 : .iop_unpin = xfs_rui_item_unpin,
646 : .iop_release = xfs_rui_item_release,
647 : .iop_recover = xfs_rui_item_recover,
648 : .iop_match = xfs_rui_item_match,
649 : .iop_relog = xfs_rui_item_relog,
650 : };
651 :
652 : static inline void
653 39296 : xfs_rui_copy_format(
654 : struct xfs_rui_log_format *dst,
655 : const struct xfs_rui_log_format *src)
656 : {
657 39296 : unsigned int i;
658 :
659 78592 : memcpy(dst, src, offsetof(struct xfs_rui_log_format, rui_extents));
660 :
661 78813 : for (i = 0; i < src->rui_nextents; i++)
662 79034 : memcpy(&dst->rui_extents[i], &src->rui_extents[i],
663 : sizeof(struct xfs_map_extent));
664 39296 : }
665 :
666 : /*
667 : * This routine is called to create an in-core extent rmap update
668 : * item from the rui format structure which was logged on disk.
669 : * It allocates an in-core rui, copies the extents from the format
670 : * structure into it, and adds the rui to the AIL with the given
671 : * LSN.
672 : */
673 : STATIC int
674 39296 : xlog_recover_rui_commit_pass2(
675 : struct xlog *log,
676 : struct list_head *buffer_list,
677 : struct xlog_recover_item *item,
678 : xfs_lsn_t lsn)
679 : {
680 39296 : struct xfs_mount *mp = log->l_mp;
681 39296 : struct xfs_rui_log_item *ruip;
682 39296 : struct xfs_rui_log_format *rui_formatp;
683 39296 : size_t len;
684 :
685 39296 : rui_formatp = item->ri_buf[0].i_addr;
686 :
687 39296 : if (item->ri_buf[0].i_len < xfs_rui_log_format_sizeof(0)) {
688 0 : XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp,
689 : item->ri_buf[0].i_addr, item->ri_buf[0].i_len);
690 0 : return -EFSCORRUPTED;
691 : }
692 :
693 39296 : len = xfs_rui_log_format_sizeof(rui_formatp->rui_nextents);
694 39296 : if (item->ri_buf[0].i_len != len) {
695 0 : XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp,
696 : item->ri_buf[0].i_addr, item->ri_buf[0].i_len);
697 0 : return -EFSCORRUPTED;
698 : }
699 :
700 39296 : ruip = xfs_rui_init(mp, rui_formatp->rui_nextents);
701 39296 : xfs_rui_copy_format(&ruip->rui_format, rui_formatp);
702 39296 : atomic_set(&ruip->rui_next_extent, rui_formatp->rui_nextents);
703 : /*
704 : * Insert the intent into the AIL directly and drop one reference so
705 : * that finishing or canceling the work will drop the other.
706 : */
707 39296 : xfs_trans_ail_insert(log->l_ailp, &ruip->rui_item, lsn);
708 39296 : xfs_rui_release(ruip);
709 39296 : return 0;
710 : }
711 :
712 : const struct xlog_recover_item_ops xlog_rui_item_ops = {
713 : .item_type = XFS_LI_RUI,
714 : .commit_pass2 = xlog_recover_rui_commit_pass2,
715 : };
716 :
717 : /*
718 : * This routine is called when an RUD format structure is found in a committed
719 : * transaction in the log. Its purpose is to cancel the corresponding RUI if it
720 : * was still in the log. To do this it searches the AIL for the RUI with an id
721 : * equal to that in the RUD format structure. If we find it we drop the RUD
722 : * reference, which removes the RUI from the AIL and frees it.
723 : */
724 : STATIC int
725 38004 : xlog_recover_rud_commit_pass2(
726 : struct xlog *log,
727 : struct list_head *buffer_list,
728 : struct xlog_recover_item *item,
729 : xfs_lsn_t lsn)
730 : {
731 38004 : struct xfs_rud_log_format *rud_formatp;
732 :
733 38004 : rud_formatp = item->ri_buf[0].i_addr;
734 38004 : if (item->ri_buf[0].i_len != sizeof(struct xfs_rud_log_format)) {
735 0 : XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, log->l_mp,
736 : rud_formatp, item->ri_buf[0].i_len);
737 0 : return -EFSCORRUPTED;
738 : }
739 :
740 38004 : xlog_recover_release_intent(log, XFS_LI_RUI, rud_formatp->rud_rui_id);
741 38004 : return 0;
742 : }
743 :
744 : const struct xlog_recover_item_ops xlog_rud_item_ops = {
745 : .item_type = XFS_LI_RUD,
746 : .commit_pass2 = xlog_recover_rud_commit_pass2,
747 : };
|