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 345918528 : xfs_rui_item_free(
37 : struct xfs_rui_log_item *ruip)
38 : {
39 345918528 : kmem_free(ruip->rui_item.li_lv_shadow);
40 345918878 : if (ruip->rui_format.rui_nextents > XFS_RUI_MAX_FAST_EXTENTS)
41 0 : kmem_free(ruip);
42 : else
43 345918878 : kmem_cache_free(xfs_rui_cache, ruip);
44 345918761 : }
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 691733994 : xfs_rui_release(
55 : struct xfs_rui_log_item *ruip)
56 : {
57 691733994 : ASSERT(atomic_read(&ruip->rui_refcount) > 0);
58 691733994 : if (!atomic_dec_and_test(&ruip->rui_refcount))
59 : return;
60 :
61 345915431 : xfs_trans_ail_delete(&ruip->rui_item, 0);
62 345919549 : xfs_rui_item_free(ruip);
63 : }
64 :
65 : STATIC void
66 345860502 : xfs_rui_item_size(
67 : struct xfs_log_item *lip,
68 : int *nvecs,
69 : int *nbytes)
70 : {
71 345860502 : struct xfs_rui_log_item *ruip = RUI_ITEM(lip);
72 :
73 345860502 : *nvecs += 1;
74 345860502 : *nbytes += xfs_rui_log_format_sizeof(ruip->rui_format.rui_nextents);
75 345860502 : }
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 345861580 : xfs_rui_item_format(
86 : struct xfs_log_item *lip,
87 : struct xfs_log_vec *lv)
88 : {
89 345861580 : struct xfs_rui_log_item *ruip = RUI_ITEM(lip);
90 345861580 : struct xfs_log_iovec *vecp = NULL;
91 :
92 345861580 : ASSERT(atomic_read(&ruip->rui_next_extent) ==
93 : ruip->rui_format.rui_nextents);
94 :
95 345861580 : ruip->rui_format.rui_type = XFS_LI_RUI;
96 345861580 : ruip->rui_format.rui_size = 1;
97 :
98 345861580 : xlog_copy_iovec(lv, &vecp, XLOG_REG_TYPE_RUI_FORMAT, &ruip->rui_format,
99 345861580 : xfs_rui_log_format_sizeof(ruip->rui_format.rui_nextents));
100 345852138 : }
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 345845165 : xfs_rui_item_unpin(
112 : struct xfs_log_item *lip,
113 : int remove)
114 : {
115 345845165 : struct xfs_rui_log_item *ruip = RUI_ITEM(lip);
116 :
117 345845165 : xfs_rui_release(ruip);
118 345853859 : }
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 54846 : xfs_rui_item_release(
127 : struct xfs_log_item *lip)
128 : {
129 54846 : xfs_rui_release(RUI_ITEM(lip));
130 54846 : }
131 :
132 : /*
133 : * Allocate and initialize an rui item with the given number of extents.
134 : */
135 : STATIC struct xfs_rui_log_item *
136 345808108 : xfs_rui_init(
137 : struct xfs_mount *mp,
138 : uint nextents)
139 :
140 : {
141 345808108 : struct xfs_rui_log_item *ruip;
142 :
143 345808108 : ASSERT(nextents > 0);
144 345808108 : if (nextents > XFS_RUI_MAX_FAST_EXTENTS)
145 0 : ruip = kmem_zalloc(xfs_rui_log_item_sizeof(nextents), 0);
146 : else
147 345808108 : ruip = kmem_cache_zalloc(xfs_rui_cache,
148 : GFP_KERNEL | __GFP_NOFAIL);
149 :
150 345895400 : xfs_log_item_init(mp, &ruip->rui_item, XFS_LI_RUI, &xfs_rui_item_ops);
151 345845644 : ruip->rui_format.rui_nextents = nextents;
152 345845644 : ruip->rui_format.rui_id = (uintptr_t)(void *)ruip;
153 345845644 : atomic_set(&ruip->rui_next_extent, 0);
154 345845644 : atomic_set(&ruip->rui_refcount, 2);
155 :
156 345845644 : 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 345854544 : xfs_rud_item_size(
166 : struct xfs_log_item *lip,
167 : int *nvecs,
168 : int *nbytes)
169 : {
170 345854544 : *nvecs += 1;
171 345854544 : *nbytes += sizeof(struct xfs_rud_log_format);
172 345854544 : }
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 410251 : xfs_rud_item_format(
183 : struct xfs_log_item *lip,
184 : struct xfs_log_vec *lv)
185 : {
186 410251 : struct xfs_rud_log_item *rudp = RUD_ITEM(lip);
187 410251 : struct xfs_log_iovec *vecp = NULL;
188 :
189 410251 : rudp->rud_format.rud_type = XFS_LI_RUD;
190 410251 : rudp->rud_format.rud_size = 1;
191 :
192 410251 : xlog_copy_iovec(lv, &vecp, XLOG_REG_TYPE_RUD_FORMAT, &rudp->rud_format,
193 : sizeof(struct xfs_rud_log_format));
194 410244 : }
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 345860149 : xfs_rud_item_release(
203 : struct xfs_log_item *lip)
204 : {
205 345860149 : struct xfs_rud_log_item *rudp = RUD_ITEM(lip);
206 :
207 345860149 : xfs_rui_release(rudp->rud_ruip);
208 345864920 : kmem_free(rudp->rud_item.li_lv_shadow);
209 345863645 : kmem_cache_free(xfs_rud_cache, rudp);
210 345860721 : }
211 :
212 : static struct xfs_log_item *
213 345854577 : xfs_rud_item_intent(
214 : struct xfs_log_item *lip)
215 : {
216 345854577 : 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 345847983 : xfs_trans_get_rud(
230 : struct xfs_trans *tp,
231 : struct xfs_rui_log_item *ruip)
232 : {
233 345847983 : struct xfs_rud_log_item *rudp;
234 :
235 345847983 : rudp = kmem_cache_zalloc(xfs_rud_cache, GFP_KERNEL | __GFP_NOFAIL);
236 345859307 : xfs_log_item_init(tp->t_mountp, &rudp->rud_item, XFS_LI_RUD,
237 : &xfs_rud_item_ops);
238 345851573 : rudp->rud_ruip = ruip;
239 345851573 : rudp->rud_format.rud_rui_id = ruip->rui_format.rui_id;
240 :
241 345851573 : xfs_trans_add_item(tp, &rudp->rud_item);
242 345855522 : return rudp;
243 : }
244 :
245 : /* Set the map extent flags for this reverse mapping. */
246 : static void
247 407784186 : 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 407784186 : map->me_flags = 0;
254 407784186 : if (state == XFS_EXT_UNWRITTEN)
255 58393605 : map->me_flags |= XFS_RMAP_EXTENT_UNWRITTEN;
256 407784186 : if (whichfork == XFS_ATTR_FORK)
257 2807228 : map->me_flags |= XFS_RMAP_EXTENT_ATTR_FORK;
258 407784186 : switch (type) {
259 86618553 : case XFS_RMAP_MAP:
260 86618553 : map->me_flags |= XFS_RMAP_EXTENT_MAP;
261 86618553 : break;
262 109598708 : case XFS_RMAP_MAP_SHARED:
263 109598708 : map->me_flags |= XFS_RMAP_EXTENT_MAP_SHARED;
264 109598708 : break;
265 76813802 : case XFS_RMAP_UNMAP:
266 76813802 : map->me_flags |= XFS_RMAP_EXTENT_UNMAP;
267 76813802 : break;
268 92821216 : case XFS_RMAP_UNMAP_SHARED:
269 92821216 : map->me_flags |= XFS_RMAP_EXTENT_UNMAP_SHARED;
270 92821216 : break;
271 9903074 : case XFS_RMAP_CONVERT:
272 9903074 : map->me_flags |= XFS_RMAP_EXTENT_CONVERT;
273 9903074 : break;
274 14792915 : case XFS_RMAP_CONVERT_SHARED:
275 14792915 : map->me_flags |= XFS_RMAP_EXTENT_CONVERT_SHARED;
276 14792915 : break;
277 3400509 : case XFS_RMAP_ALLOC:
278 3400509 : map->me_flags |= XFS_RMAP_EXTENT_ALLOC;
279 3400509 : break;
280 13835409 : case XFS_RMAP_FREE:
281 13835409 : map->me_flags |= XFS_RMAP_EXTENT_FREE;
282 13835409 : break;
283 0 : default:
284 0 : ASSERT(0);
285 : }
286 407784186 : }
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 407812783 : 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 407812783 : int error;
301 :
302 407812783 : 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 407809901 : tp->t_flags |= XFS_TRANS_DIRTY | XFS_TRANS_HAS_INTENT_DONE;
312 407809901 : set_bit(XFS_LI_DIRTY, &rudp->rud_item.li_flags);
313 :
314 407826993 : return error;
315 : }
316 :
317 : /* Sort rmap intents by AG. */
318 : static int
319 61974268 : xfs_rmap_update_diff_items(
320 : void *priv,
321 : const struct list_head *a,
322 : const struct list_head *b)
323 : {
324 61974268 : struct xfs_rmap_intent *ra;
325 61974268 : struct xfs_rmap_intent *rb;
326 :
327 61974268 : ra = container_of(a, struct xfs_rmap_intent, ri_list);
328 61974268 : rb = container_of(b, struct xfs_rmap_intent, ri_list);
329 :
330 61974268 : 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 407752791 : 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 407752791 : uint next_extent;
341 407752791 : struct xfs_map_extent *map;
342 :
343 407752791 : tp->t_flags |= XFS_TRANS_DIRTY;
344 407752791 : 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 407813443 : next_extent = atomic_inc_return(&ruip->rui_next_extent) - 1;
352 407780650 : ASSERT(next_extent < ruip->rui_format.rui_nextents);
353 407780650 : map = &ruip->rui_format.rui_extents[next_extent];
354 407780650 : map->me_owner = ri->ri_owner;
355 407780650 : map->me_startblock = ri->ri_bmap.br_startblock;
356 407780650 : map->me_startoff = ri->ri_bmap.br_startoff;
357 407780650 : map->me_len = ri->ri_bmap.br_blockcount;
358 407780650 : xfs_trans_set_rmap_flags(map, ri->ri_type, ri->ri_whichfork,
359 : ri->ri_bmap.br_state);
360 407767229 : }
361 :
362 : static struct xfs_log_item *
363 345772927 : xfs_rmap_update_create_intent(
364 : struct xfs_trans *tp,
365 : struct list_head *items,
366 : unsigned int count,
367 : bool sort)
368 : {
369 345772927 : struct xfs_mount *mp = tp->t_mountp;
370 345772927 : struct xfs_rui_log_item *ruip = xfs_rui_init(mp, count);
371 345791707 : struct xfs_rmap_intent *ri;
372 :
373 345791707 : ASSERT(count > 0);
374 :
375 345791707 : xfs_trans_add_item(tp, &ruip->rui_item);
376 345782564 : if (sort)
377 345785130 : list_sort(mp, items, xfs_rmap_update_diff_items);
378 753564019 : list_for_each_entry(ri, items, ri_list)
379 407760267 : xfs_rmap_update_log_item(tp, ruip, ri);
380 345803752 : 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 345848394 : xfs_rmap_update_create_done(
386 : struct xfs_trans *tp,
387 : struct xfs_log_item *intent,
388 : unsigned int count)
389 : {
390 345848394 : 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 407789593 : xfs_rmap_update_get_group(
396 : struct xfs_mount *mp,
397 : struct xfs_rmap_intent *ri)
398 : {
399 407789593 : xfs_agnumber_t agno;
400 :
401 407789593 : agno = XFS_FSB_TO_AGNO(mp, ri->ri_bmap.br_startblock);
402 407789593 : ri->ri_pag = xfs_perag_intent_get(mp, agno);
403 407816223 : }
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 407826084 : xfs_perag_intent_put(ri->ri_pag);
411 : }
412 :
413 : /* Process a deferred rmap update. */
414 : STATIC int
415 407811939 : 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 407811939 : struct xfs_rmap_intent *ri;
422 407811939 : int error;
423 :
424 407811939 : ri = container_of(item, struct xfs_rmap_intent, ri_list);
425 :
426 407811939 : error = xfs_trans_log_finish_rmap_update(tp, RUD_ITEM(done), ri,
427 : state);
428 :
429 407822797 : xfs_rmap_update_put_group(ri);
430 407821690 : kmem_cache_free(xfs_rmap_intent_cache, ri);
431 407816394 : return error;
432 : }
433 :
434 : /* Abort all pending RUIs. */
435 : STATIC void
436 1029 : xfs_rmap_update_abort_intent(
437 : struct xfs_log_item *intent)
438 : {
439 1029 : xfs_rui_release(RUI_ITEM(intent));
440 1029 : }
441 :
442 : /* Cancel a deferred rmap update. */
443 : STATIC void
444 1120 : xfs_rmap_update_cancel_item(
445 : struct list_head *item)
446 : {
447 1120 : struct xfs_rmap_intent *ri;
448 :
449 1120 : ri = container_of(item, struct xfs_rmap_intent, ri_list);
450 :
451 1120 : xfs_rmap_update_put_group(ri);
452 1120 : kmem_cache_free(xfs_rmap_intent_cache, ri);
453 1120 : }
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 2167 : xfs_rui_validate_map(
468 : struct xfs_mount *mp,
469 : struct xfs_map_extent *map)
470 : {
471 2167 : if (!xfs_has_rmapbt(mp))
472 : return false;
473 :
474 2167 : if (map->me_flags & ~XFS_RMAP_EXTENT_FLAGS)
475 : return false;
476 :
477 2167 : 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 2167 : break;
487 : default:
488 : return false;
489 : }
490 :
491 4295 : if (!XFS_RMAP_NON_INODE_OWNER(map->me_owner) &&
492 2128 : !xfs_verify_ino(mp, map->me_owner))
493 : return false;
494 :
495 2167 : if (!xfs_verify_fileext(mp, map->me_startoff, map->me_len))
496 : return false;
497 :
498 2167 : 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 2162 : xfs_rui_item_recover(
507 : struct xfs_log_item *lip,
508 : struct list_head *capture_list)
509 : {
510 2162 : struct xfs_rui_log_item *ruip = RUI_ITEM(lip);
511 2162 : struct xfs_rud_log_item *rudp;
512 2162 : struct xfs_trans *tp;
513 2162 : struct xfs_btree_cur *rcur = NULL;
514 2162 : struct xfs_mount *mp = lip->li_log->l_mp;
515 2162 : int i;
516 2162 : 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 4329 : for (i = 0; i < ruip->rui_format.rui_nextents; i++) {
524 2167 : 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 2162 : error = xfs_trans_alloc(mp, &M_RES(mp)->tr_itruncate,
534 : mp->m_rmap_maxlevels, 0, XFS_TRANS_RESERVE, &tp);
535 2162 : if (error)
536 : return error;
537 2162 : rudp = xfs_trans_get_rud(tp, ruip);
538 :
539 6485 : for (i = 0; i < ruip->rui_format.rui_nextents; i++) {
540 2167 : struct xfs_rmap_intent fake = { };
541 2167 : struct xfs_map_extent *map;
542 :
543 2167 : map = &ruip->rui_format.rui_extents[i];
544 2167 : 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 465 : case XFS_RMAP_EXTENT_MAP_SHARED:
549 465 : fake.ri_type = XFS_RMAP_MAP_SHARED;
550 465 : break;
551 61 : case XFS_RMAP_EXTENT_UNMAP:
552 61 : fake.ri_type = XFS_RMAP_UNMAP;
553 61 : break;
554 1169 : case XFS_RMAP_EXTENT_UNMAP_SHARED:
555 1169 : fake.ri_type = XFS_RMAP_UNMAP_SHARED;
556 1169 : break;
557 30 : case XFS_RMAP_EXTENT_CONVERT:
558 30 : fake.ri_type = XFS_RMAP_CONVERT;
559 30 : break;
560 90 : case XFS_RMAP_EXTENT_CONVERT_SHARED:
561 90 : fake.ri_type = XFS_RMAP_CONVERT_SHARED;
562 90 : break;
563 14 : case XFS_RMAP_EXTENT_ALLOC:
564 14 : fake.ri_type = XFS_RMAP_ALLOC;
565 14 : break;
566 25 : case XFS_RMAP_EXTENT_FREE:
567 25 : fake.ri_type = XFS_RMAP_FREE;
568 25 : 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 2167 : fake.ri_owner = map->me_owner;
578 2167 : fake.ri_whichfork = (map->me_flags & XFS_RMAP_EXTENT_ATTR_FORK) ?
579 2167 : XFS_ATTR_FORK : XFS_DATA_FORK;
580 2167 : fake.ri_bmap.br_startblock = map->me_startblock;
581 2167 : fake.ri_bmap.br_startoff = map->me_startoff;
582 2167 : fake.ri_bmap.br_blockcount = map->me_len;
583 2167 : fake.ri_bmap.br_state = (map->me_flags & XFS_RMAP_EXTENT_UNWRITTEN) ?
584 2167 : XFS_EXT_UNWRITTEN : XFS_EXT_NORM;
585 :
586 2167 : xfs_rmap_update_get_group(mp, &fake);
587 2167 : error = xfs_trans_log_finish_rmap_update(tp, rudp, &fake,
588 : &rcur);
589 2167 : if (error == -EFSCORRUPTED)
590 6 : XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp,
591 : map, sizeof(*map));
592 2167 : xfs_rmap_update_put_group(&fake);
593 2167 : if (error)
594 6 : goto abort_error;
595 :
596 : }
597 :
598 2156 : xfs_rmap_finish_one_cleanup(tp, rcur, error);
599 2156 : return xfs_defer_ops_capture_and_commit(tp, capture_list);
600 :
601 : abort_error:
602 6 : xfs_rmap_finish_one_cleanup(tp, rcur, error);
603 6 : xfs_trans_cancel(tp);
604 6 : return error;
605 : }
606 :
607 : STATIC bool
608 59838 : xfs_rui_item_match(
609 : struct xfs_log_item *lip,
610 : uint64_t intent_id)
611 : {
612 59838 : 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 2470 : xfs_rui_item_relog(
618 : struct xfs_log_item *intent,
619 : struct xfs_trans *tp)
620 : {
621 2470 : struct xfs_rud_log_item *rudp;
622 2470 : struct xfs_rui_log_item *ruip;
623 2470 : struct xfs_map_extent *map;
624 2470 : unsigned int count;
625 :
626 2470 : count = RUI_ITEM(intent)->rui_format.rui_nextents;
627 2470 : map = RUI_ITEM(intent)->rui_format.rui_extents;
628 :
629 2470 : tp->t_flags |= XFS_TRANS_DIRTY;
630 2470 : rudp = xfs_trans_get_rud(tp, RUI_ITEM(intent));
631 2470 : set_bit(XFS_LI_DIRTY, &rudp->rud_item.li_flags);
632 :
633 2470 : ruip = xfs_rui_init(tp->t_mountp, count);
634 4940 : memcpy(ruip->rui_format.rui_extents, map, count * sizeof(*map));
635 2470 : atomic_set(&ruip->rui_next_extent, count);
636 2470 : xfs_trans_add_item(tp, &ruip->rui_item);
637 2470 : set_bit(XFS_LI_DIRTY, &ruip->rui_item.li_flags);
638 2470 : 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 56994 : xfs_rui_copy_format(
654 : struct xfs_rui_log_format *dst,
655 : const struct xfs_rui_log_format *src)
656 : {
657 56994 : unsigned int i;
658 :
659 113988 : memcpy(dst, src, offsetof(struct xfs_rui_log_format, rui_extents));
660 :
661 114317 : for (i = 0; i < src->rui_nextents; i++)
662 114646 : memcpy(&dst->rui_extents[i], &src->rui_extents[i],
663 : sizeof(struct xfs_map_extent));
664 56994 : }
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 56994 : 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 56994 : struct xfs_mount *mp = log->l_mp;
681 56994 : struct xfs_rui_log_item *ruip;
682 56994 : struct xfs_rui_log_format *rui_formatp;
683 56994 : size_t len;
684 :
685 56994 : rui_formatp = item->ri_buf[0].i_addr;
686 :
687 56994 : 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 56994 : len = xfs_rui_log_format_sizeof(rui_formatp->rui_nextents);
694 56994 : 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 56994 : ruip = xfs_rui_init(mp, rui_formatp->rui_nextents);
701 56994 : xfs_rui_copy_format(&ruip->rui_format, rui_formatp);
702 56994 : 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 56994 : xfs_trans_ail_insert(log->l_ailp, &ruip->rui_item, lsn);
708 56994 : xfs_rui_release(ruip);
709 56994 : 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 55106 : 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 55106 : struct xfs_rud_log_format *rud_formatp;
732 :
733 55106 : rud_formatp = item->ri_buf[0].i_addr;
734 55106 : 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 55106 : xlog_recover_release_intent(log, XFS_LI_RUI, rud_formatp->rud_rui_id);
741 55106 : 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 : };
|