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 214742733 : xfs_rui_item_free(
37 : struct xfs_rui_log_item *ruip)
38 : {
39 214742733 : kmem_free(ruip->rui_item.li_lv_shadow);
40 214742379 : if (ruip->rui_format.rui_nextents > XFS_RUI_MAX_FAST_EXTENTS)
41 0 : kmem_free(ruip);
42 : else
43 214742379 : kmem_cache_free(xfs_rui_cache, ruip);
44 214733070 : }
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 429350148 : xfs_rui_release(
55 : struct xfs_rui_log_item *ruip)
56 : {
57 429350148 : ASSERT(atomic_read(&ruip->rui_refcount) > 0);
58 858773791 : if (!atomic_dec_and_test(&ruip->rui_refcount))
59 : return;
60 :
61 214737086 : xfs_trans_ail_delete(&ruip->rui_item, 0);
62 214742276 : xfs_rui_item_free(ruip);
63 : }
64 :
65 : STATIC void
66 214697395 : xfs_rui_item_size(
67 : struct xfs_log_item *lip,
68 : int *nvecs,
69 : int *nbytes)
70 : {
71 214697395 : struct xfs_rui_log_item *ruip = RUI_ITEM(lip);
72 :
73 214697395 : *nvecs += 1;
74 214697395 : *nbytes += xfs_rui_log_format_sizeof(ruip->rui_format.rui_nextents);
75 214697395 : }
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 214697436 : xfs_rui_item_format(
86 : struct xfs_log_item *lip,
87 : struct xfs_log_vec *lv)
88 : {
89 214697436 : struct xfs_rui_log_item *ruip = RUI_ITEM(lip);
90 214697436 : struct xfs_log_iovec *vecp = NULL;
91 :
92 214697436 : ASSERT(atomic_read(&ruip->rui_next_extent) ==
93 : ruip->rui_format.rui_nextents);
94 :
95 214697436 : ruip->rui_format.rui_type = XFS_LI_RUI;
96 214697436 : ruip->rui_format.rui_size = 1;
97 :
98 214697436 : xlog_copy_iovec(lv, &vecp, XLOG_REG_TYPE_RUI_FORMAT, &ruip->rui_format,
99 214697436 : xfs_rui_log_format_sizeof(ruip->rui_format.rui_nextents));
100 214697685 : }
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 214679026 : xfs_rui_item_unpin(
112 : struct xfs_log_item *lip,
113 : int remove)
114 : {
115 214679026 : struct xfs_rui_log_item *ruip = RUI_ITEM(lip);
116 :
117 214679026 : xfs_rui_release(ruip);
118 214695227 : }
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 43381 : xfs_rui_item_release(
127 : struct xfs_log_item *lip)
128 : {
129 43381 : xfs_rui_release(RUI_ITEM(lip));
130 43381 : }
131 :
132 : /*
133 : * Allocate and initialize an rui item with the given number of extents.
134 : */
135 : STATIC struct xfs_rui_log_item *
136 214705354 : xfs_rui_init(
137 : struct xfs_mount *mp,
138 : uint nextents)
139 :
140 : {
141 214705354 : struct xfs_rui_log_item *ruip;
142 :
143 214705354 : ASSERT(nextents > 0);
144 214705354 : if (nextents > XFS_RUI_MAX_FAST_EXTENTS)
145 0 : ruip = kmem_zalloc(xfs_rui_log_item_sizeof(nextents), 0);
146 : else
147 214705354 : ruip = kmem_cache_zalloc(xfs_rui_cache,
148 : GFP_KERNEL | __GFP_NOFAIL);
149 :
150 214665921 : xfs_log_item_init(mp, &ruip->rui_item, XFS_LI_RUI, &xfs_rui_item_ops);
151 214705588 : ruip->rui_format.rui_nextents = nextents;
152 214705588 : ruip->rui_format.rui_id = (uintptr_t)(void *)ruip;
153 214705588 : atomic_set(&ruip->rui_next_extent, 0);
154 214705588 : atomic_set(&ruip->rui_refcount, 2);
155 :
156 214705588 : 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 214696491 : xfs_rud_item_size(
166 : struct xfs_log_item *lip,
167 : int *nvecs,
168 : int *nbytes)
169 : {
170 214696491 : *nvecs += 1;
171 214696491 : *nbytes += sizeof(struct xfs_rud_log_format);
172 214696491 : }
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 292983 : xfs_rud_item_format(
183 : struct xfs_log_item *lip,
184 : struct xfs_log_vec *lv)
185 : {
186 292983 : struct xfs_rud_log_item *rudp = RUD_ITEM(lip);
187 292983 : struct xfs_log_iovec *vecp = NULL;
188 :
189 292983 : rudp->rud_format.rud_type = XFS_LI_RUD;
190 292983 : rudp->rud_format.rud_size = 1;
191 :
192 292983 : xlog_copy_iovec(lv, &vecp, XLOG_REG_TYPE_RUD_FORMAT, &rudp->rud_format,
193 : sizeof(struct xfs_rud_log_format));
194 292983 : }
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 214698513 : xfs_rud_item_release(
203 : struct xfs_log_item *lip)
204 : {
205 214698513 : struct xfs_rud_log_item *rudp = RUD_ITEM(lip);
206 :
207 214698513 : xfs_rui_release(rudp->rud_ruip);
208 214698764 : kmem_free(rudp->rud_item.li_lv_shadow);
209 214698805 : kmem_cache_free(xfs_rud_cache, rudp);
210 214698698 : }
211 :
212 : static struct xfs_log_item *
213 214695894 : xfs_rud_item_intent(
214 : struct xfs_log_item *lip)
215 : {
216 214695894 : 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 214697099 : xfs_trans_get_rud(
230 : struct xfs_trans *tp,
231 : struct xfs_rui_log_item *ruip)
232 : {
233 214697099 : struct xfs_rud_log_item *rudp;
234 :
235 214697099 : rudp = kmem_cache_zalloc(xfs_rud_cache, GFP_KERNEL | __GFP_NOFAIL);
236 214698132 : xfs_log_item_init(tp->t_mountp, &rudp->rud_item, XFS_LI_RUD,
237 : &xfs_rud_item_ops);
238 214698434 : rudp->rud_ruip = ruip;
239 214698434 : rudp->rud_format.rud_rui_id = ruip->rui_format.rui_id;
240 :
241 214698434 : xfs_trans_add_item(tp, &rudp->rud_item);
242 214698424 : return rudp;
243 : }
244 :
245 : /* Set the map extent flags for this reverse mapping. */
246 : static void
247 234290316 : 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 234290316 : map->me_flags = 0;
254 234290316 : if (state == XFS_EXT_UNWRITTEN)
255 32067274 : map->me_flags |= XFS_RMAP_EXTENT_UNWRITTEN;
256 234290316 : if (whichfork == XFS_ATTR_FORK)
257 5529629 : map->me_flags |= XFS_RMAP_EXTENT_ATTR_FORK;
258 234290316 : switch (type) {
259 46924730 : case XFS_RMAP_MAP:
260 46924730 : map->me_flags |= XFS_RMAP_EXTENT_MAP;
261 46924730 : break;
262 68738887 : case XFS_RMAP_MAP_SHARED:
263 68738887 : map->me_flags |= XFS_RMAP_EXTENT_MAP_SHARED;
264 68738887 : break;
265 40392979 : case XFS_RMAP_UNMAP:
266 40392979 : map->me_flags |= XFS_RMAP_EXTENT_UNMAP;
267 40392979 : break;
268 57317595 : case XFS_RMAP_UNMAP_SHARED:
269 57317595 : map->me_flags |= XFS_RMAP_EXTENT_UNMAP_SHARED;
270 57317595 : break;
271 5979789 : case XFS_RMAP_CONVERT:
272 5979789 : map->me_flags |= XFS_RMAP_EXTENT_CONVERT;
273 5979789 : break;
274 12345975 : case XFS_RMAP_CONVERT_SHARED:
275 12345975 : map->me_flags |= XFS_RMAP_EXTENT_CONVERT_SHARED;
276 12345975 : break;
277 359535 : case XFS_RMAP_ALLOC:
278 359535 : map->me_flags |= XFS_RMAP_EXTENT_ALLOC;
279 359535 : break;
280 2230826 : case XFS_RMAP_FREE:
281 2230826 : map->me_flags |= XFS_RMAP_EXTENT_FREE;
282 2230826 : break;
283 0 : default:
284 0 : ASSERT(0);
285 : }
286 234290316 : }
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 234291649 : 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 234291649 : int error;
301 :
302 234291649 : 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 234291210 : tp->t_flags |= XFS_TRANS_DIRTY | XFS_TRANS_HAS_INTENT_DONE;
312 234291210 : set_bit(XFS_LI_DIRTY, &rudp->rud_item.li_flags);
313 :
314 234291570 : return error;
315 : }
316 :
317 : /* Sort rmap intents by AG. */
318 : static int
319 19596353 : xfs_rmap_update_diff_items(
320 : void *priv,
321 : const struct list_head *a,
322 : const struct list_head *b)
323 : {
324 19596353 : struct xfs_rmap_intent *ra;
325 19596353 : struct xfs_rmap_intent *rb;
326 :
327 19596353 : ra = container_of(a, struct xfs_rmap_intent, ri_list);
328 19596353 : rb = container_of(b, struct xfs_rmap_intent, ri_list);
329 :
330 19596353 : 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 234269667 : 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 234269667 : uint next_extent;
341 234269667 : struct xfs_map_extent *map;
342 :
343 234269667 : tp->t_flags |= XFS_TRANS_DIRTY;
344 234269667 : 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 234268478 : next_extent = atomic_inc_return(&ruip->rui_next_extent) - 1;
352 234284684 : ASSERT(next_extent < ruip->rui_format.rui_nextents);
353 234284684 : map = &ruip->rui_format.rui_extents[next_extent];
354 234284684 : map->me_owner = ri->ri_owner;
355 234284684 : map->me_startblock = ri->ri_bmap.br_startblock;
356 234284684 : map->me_startoff = ri->ri_bmap.br_startoff;
357 234284684 : map->me_len = ri->ri_bmap.br_blockcount;
358 234284684 : xfs_trans_set_rmap_flags(map, ri->ri_type, ri->ri_whichfork,
359 : ri->ri_bmap.br_state);
360 234282232 : }
361 :
362 : static struct xfs_log_item *
363 214664361 : xfs_rmap_update_create_intent(
364 : struct xfs_trans *tp,
365 : struct list_head *items,
366 : unsigned int count,
367 : bool sort)
368 : {
369 214664361 : struct xfs_mount *mp = tp->t_mountp;
370 214664361 : struct xfs_rui_log_item *ruip = xfs_rui_init(mp, count);
371 214641122 : struct xfs_rmap_intent *ri;
372 :
373 214641122 : ASSERT(count > 0);
374 :
375 214641122 : xfs_trans_add_item(tp, &ruip->rui_item);
376 214667129 : if (sort)
377 214669546 : list_sort(mp, items, xfs_rmap_update_diff_items);
378 448951370 : list_for_each_entry(ri, items, ri_list)
379 234271565 : xfs_rmap_update_log_item(tp, ruip, ri);
380 214679805 : 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 214694946 : xfs_rmap_update_create_done(
386 : struct xfs_trans *tp,
387 : struct xfs_log_item *intent,
388 : unsigned int count)
389 : {
390 214694946 : 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 234282107 : xfs_rmap_update_get_group(
396 : struct xfs_mount *mp,
397 : struct xfs_rmap_intent *ri)
398 : {
399 234282107 : xfs_agnumber_t agno;
400 :
401 234282107 : agno = XFS_FSB_TO_AGNO(mp, ri->ri_bmap.br_startblock);
402 234282107 : ri->ri_pag = xfs_perag_intent_get(mp, agno);
403 234276971 : }
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 234291929 : xfs_perag_intent_put(ri->ri_pag);
411 : }
412 :
413 : /* Process a deferred rmap update. */
414 : STATIC int
415 234290992 : 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 234290992 : struct xfs_rmap_intent *ri;
422 234290992 : int error;
423 :
424 234290992 : ri = container_of(item, struct xfs_rmap_intent, ri_list);
425 :
426 234290992 : error = xfs_trans_log_finish_rmap_update(tp, RUD_ITEM(done), ri,
427 : state);
428 :
429 234289732 : xfs_rmap_update_put_group(ri);
430 234290144 : kmem_cache_free(xfs_rmap_intent_cache, ri);
431 234290978 : return error;
432 : }
433 :
434 : /* Abort all pending RUIs. */
435 : STATIC void
436 687 : xfs_rmap_update_abort_intent(
437 : struct xfs_log_item *intent)
438 : {
439 687 : xfs_rui_release(RUI_ITEM(intent));
440 687 : }
441 :
442 : /* Cancel a deferred rmap update. */
443 : STATIC void
444 769 : xfs_rmap_update_cancel_item(
445 : struct list_head *item)
446 : {
447 769 : struct xfs_rmap_intent *ri;
448 :
449 769 : ri = container_of(item, struct xfs_rmap_intent, ri_list);
450 :
451 769 : xfs_rmap_update_put_group(ri);
452 769 : kmem_cache_free(xfs_rmap_intent_cache, ri);
453 769 : }
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 1428 : xfs_rui_validate_map(
468 : struct xfs_mount *mp,
469 : struct xfs_map_extent *map)
470 : {
471 1428 : if (!xfs_has_rmapbt(mp))
472 : return false;
473 :
474 1428 : if (map->me_flags & ~XFS_RMAP_EXTENT_FLAGS)
475 : return false;
476 :
477 1428 : 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 1428 : break;
487 : default:
488 : return false;
489 : }
490 :
491 2844 : if (!XFS_RMAP_NON_INODE_OWNER(map->me_owner) &&
492 1416 : !xfs_verify_ino(mp, map->me_owner))
493 : return false;
494 :
495 1428 : if (!xfs_verify_fileext(mp, map->me_startoff, map->me_len))
496 : return false;
497 :
498 1428 : 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 1423 : xfs_rui_item_recover(
507 : struct xfs_log_item *lip,
508 : struct list_head *capture_list)
509 : {
510 1423 : struct xfs_rui_log_item *ruip = RUI_ITEM(lip);
511 1423 : struct xfs_rud_log_item *rudp;
512 1423 : struct xfs_trans *tp;
513 1423 : struct xfs_btree_cur *rcur = NULL;
514 1423 : struct xfs_mount *mp = lip->li_log->l_mp;
515 1423 : int i;
516 1423 : 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 2851 : for (i = 0; i < ruip->rui_format.rui_nextents; i++) {
524 1428 : 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 1423 : error = xfs_trans_alloc(mp, &M_RES(mp)->tr_itruncate,
534 : mp->m_rmap_maxlevels, 0, XFS_TRANS_RESERVE, &tp);
535 1423 : if (error)
536 : return error;
537 1423 : rudp = xfs_trans_get_rud(tp, ruip);
538 :
539 4272 : for (i = 0; i < ruip->rui_format.rui_nextents; i++) {
540 1428 : struct xfs_rmap_intent fake = { };
541 1428 : struct xfs_map_extent *map;
542 :
543 1428 : map = &ruip->rui_format.rui_extents[i];
544 1428 : 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 350 : case XFS_RMAP_EXTENT_MAP_SHARED:
549 350 : fake.ri_type = XFS_RMAP_MAP_SHARED;
550 350 : break;
551 33 : case XFS_RMAP_EXTENT_UNMAP:
552 33 : fake.ri_type = XFS_RMAP_UNMAP;
553 33 : break;
554 812 : case XFS_RMAP_EXTENT_UNMAP_SHARED:
555 812 : fake.ri_type = XFS_RMAP_UNMAP_SHARED;
556 812 : break;
557 18 : case XFS_RMAP_EXTENT_CONVERT:
558 18 : fake.ri_type = XFS_RMAP_CONVERT;
559 18 : break;
560 74 : case XFS_RMAP_EXTENT_CONVERT_SHARED:
561 74 : fake.ri_type = XFS_RMAP_CONVERT_SHARED;
562 74 : break;
563 4 : case XFS_RMAP_EXTENT_ALLOC:
564 4 : fake.ri_type = XFS_RMAP_ALLOC;
565 4 : break;
566 8 : case XFS_RMAP_EXTENT_FREE:
567 8 : fake.ri_type = XFS_RMAP_FREE;
568 8 : 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 1428 : fake.ri_owner = map->me_owner;
578 1428 : fake.ri_whichfork = (map->me_flags & XFS_RMAP_EXTENT_ATTR_FORK) ?
579 1428 : XFS_ATTR_FORK : XFS_DATA_FORK;
580 1428 : fake.ri_bmap.br_startblock = map->me_startblock;
581 1428 : fake.ri_bmap.br_startoff = map->me_startoff;
582 1428 : fake.ri_bmap.br_blockcount = map->me_len;
583 1428 : fake.ri_bmap.br_state = (map->me_flags & XFS_RMAP_EXTENT_UNWRITTEN) ?
584 1428 : XFS_EXT_UNWRITTEN : XFS_EXT_NORM;
585 :
586 1428 : xfs_rmap_update_get_group(mp, &fake);
587 1428 : error = xfs_trans_log_finish_rmap_update(tp, rudp, &fake,
588 : &rcur);
589 1428 : if (error == -EFSCORRUPTED)
590 2 : XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp,
591 : map, sizeof(*map));
592 1428 : xfs_rmap_update_put_group(&fake);
593 1428 : if (error)
594 2 : goto abort_error;
595 :
596 : }
597 :
598 1421 : xfs_rmap_finish_one_cleanup(tp, rcur, error);
599 1421 : 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 46986 : xfs_rui_item_match(
609 : struct xfs_log_item *lip,
610 : uint64_t intent_id)
611 : {
612 46986 : 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 655 : xfs_rui_item_relog(
618 : struct xfs_log_item *intent,
619 : struct xfs_trans *tp)
620 : {
621 655 : struct xfs_rud_log_item *rudp;
622 655 : struct xfs_rui_log_item *ruip;
623 655 : struct xfs_map_extent *map;
624 655 : unsigned int count;
625 :
626 655 : count = RUI_ITEM(intent)->rui_format.rui_nextents;
627 655 : map = RUI_ITEM(intent)->rui_format.rui_extents;
628 :
629 655 : tp->t_flags |= XFS_TRANS_DIRTY;
630 655 : rudp = xfs_trans_get_rud(tp, RUI_ITEM(intent));
631 656 : set_bit(XFS_LI_DIRTY, &rudp->rud_item.li_flags);
632 :
633 656 : ruip = xfs_rui_init(tp->t_mountp, count);
634 1312 : memcpy(ruip->rui_format.rui_extents, map, count * sizeof(*map));
635 656 : atomic_set(&ruip->rui_next_extent, count);
636 656 : xfs_trans_add_item(tp, &ruip->rui_item);
637 656 : set_bit(XFS_LI_DIRTY, &ruip->rui_item.li_flags);
638 656 : 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 44762 : xfs_rui_copy_format(
654 : struct xfs_rui_log_format *dst,
655 : const struct xfs_rui_log_format *src)
656 : {
657 44762 : unsigned int i;
658 :
659 89524 : memcpy(dst, src, offsetof(struct xfs_rui_log_format, rui_extents));
660 :
661 89770 : for (i = 0; i < src->rui_nextents; i++)
662 90016 : memcpy(&dst->rui_extents[i], &src->rui_extents[i],
663 : sizeof(struct xfs_map_extent));
664 44762 : }
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 44762 : 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 44762 : struct xfs_mount *mp = log->l_mp;
681 44762 : struct xfs_rui_log_item *ruip;
682 44762 : struct xfs_rui_log_format *rui_formatp;
683 44762 : size_t len;
684 :
685 44762 : rui_formatp = item->ri_buf[0].i_addr;
686 :
687 44762 : 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 44762 : len = xfs_rui_log_format_sizeof(rui_formatp->rui_nextents);
694 44762 : 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 44762 : ruip = xfs_rui_init(mp, rui_formatp->rui_nextents);
701 44762 : xfs_rui_copy_format(&ruip->rui_format, rui_formatp);
702 44762 : 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 44762 : xfs_trans_ail_insert(log->l_ailp, &ruip->rui_item, lsn);
708 44762 : xfs_rui_release(ruip);
709 44762 : 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 43578 : 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 43578 : struct xfs_rud_log_format *rud_formatp;
732 :
733 43578 : rud_formatp = item->ri_buf[0].i_addr;
734 43578 : 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 43578 : xlog_recover_release_intent(log, XFS_LI_RUI, rud_formatp->rud_rui_id);
741 43578 : 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 : };
|