]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blame - libxfs/defer_item.c
xfs_db: print freecount in xfs_inobt_rec as unsigned
[thirdparty/xfsprogs-dev.git] / libxfs / defer_item.c
CommitLineData
959ef981 1// SPDX-License-Identifier: GPL-2.0+
dc3bce02
DW
2/*
3 * Copyright (C) 2016 Oracle. All Rights Reserved.
dc3bce02 4 * Author: Darrick J. Wong <darrick.wong@oracle.com>
dc3bce02
DW
5 */
6#include "libxfs_priv.h"
7#include "xfs_fs.h"
8#include "xfs_shared.h"
9#include "xfs_format.h"
10#include "xfs_log_format.h"
11#include "xfs_trans_resv.h"
12#include "xfs_bit.h"
13#include "xfs_sb.h"
14#include "xfs_mount.h"
15#include "xfs_defer.h"
16#include "xfs_trans.h"
17#include "xfs_bmap.h"
18#include "xfs_alloc.h"
19#include "xfs_rmap.h"
cdc9cf25 20#include "xfs_refcount.h"
f8f8c8a0
DW
21#include "xfs_bmap.h"
22#include "xfs_inode.h"
dc3bce02
DW
23
24/* Dummy defer item ops, since we don't do logging. */
25
26/* Extent Freeing */
27
28/* Sort bmap items by AG. */
29static int
30xfs_extent_free_diff_items(
31 void *priv,
32 struct list_head *a,
33 struct list_head *b)
34{
35 struct xfs_mount *mp = priv;
36 struct xfs_extent_free_item *ra;
37 struct xfs_extent_free_item *rb;
38
39 ra = container_of(a, struct xfs_extent_free_item, xefi_list);
40 rb = container_of(b, struct xfs_extent_free_item, xefi_list);
41 return XFS_FSB_TO_AGNO(mp, ra->xefi_startblock) -
42 XFS_FSB_TO_AGNO(mp, rb->xefi_startblock);
43}
44
45/* Get an EFI. */
46STATIC void *
47xfs_extent_free_create_intent(
48 struct xfs_trans *tp,
49 unsigned int count)
50{
51 return NULL;
52}
53
54/* Log a free extent to the intent item. */
55STATIC void
56xfs_extent_free_log_item(
57 struct xfs_trans *tp,
58 void *intent,
59 struct list_head *item)
60{
61}
62
63/* Get an EFD so we can process all the free extents. */
64STATIC void *
65xfs_extent_free_create_done(
66 struct xfs_trans *tp,
67 void *intent,
68 unsigned int count)
69{
70 return NULL;
71}
72
73/* Process a free extent. */
74STATIC int
75xfs_extent_free_finish_item(
76 struct xfs_trans *tp,
dc3bce02
DW
77 struct list_head *item,
78 void *done_item,
79 void **state)
80{
81 struct xfs_extent_free_item *free;
82 int error;
83
84 free = container_of(item, struct xfs_extent_free_item, xefi_list);
85 error = xfs_free_extent(tp, free->xefi_startblock,
cf8ce220
DW
86 free->xefi_blockcount, &free->xefi_oinfo,
87 XFS_AG_RESV_NONE);
dc3bce02
DW
88 kmem_free(free);
89 return error;
90}
91
92/* Abort all pending EFIs. */
93STATIC void
94xfs_extent_free_abort_intent(
95 void *intent)
96{
97}
98
99/* Cancel a free extent. */
100STATIC void
101xfs_extent_free_cancel_item(
102 struct list_head *item)
103{
104 struct xfs_extent_free_item *free;
105
106 free = container_of(item, struct xfs_extent_free_item, xefi_list);
107 kmem_free(free);
108}
109
110static const struct xfs_defer_op_type xfs_extent_free_defer_type = {
111 .type = XFS_DEFER_OPS_TYPE_FREE,
112 .diff_items = xfs_extent_free_diff_items,
113 .create_intent = xfs_extent_free_create_intent,
114 .abort_intent = xfs_extent_free_abort_intent,
115 .log_item = xfs_extent_free_log_item,
116 .create_done = xfs_extent_free_create_done,
117 .finish_item = xfs_extent_free_finish_item,
118 .cancel_item = xfs_extent_free_cancel_item,
119};
120
121/* Register the deferred op type. */
122void
123xfs_extent_free_init_defer_op(void)
124{
125 xfs_defer_init_op_type(&xfs_extent_free_defer_type);
126}
127
128/* Reverse Mapping */
129
130/* Sort rmap intents by AG. */
131static int
132xfs_rmap_update_diff_items(
133 void *priv,
134 struct list_head *a,
135 struct list_head *b)
136{
137 struct xfs_mount *mp = priv;
138 struct xfs_rmap_intent *ra;
139 struct xfs_rmap_intent *rb;
140
141 ra = container_of(a, struct xfs_rmap_intent, ri_list);
142 rb = container_of(b, struct xfs_rmap_intent, ri_list);
143 return XFS_FSB_TO_AGNO(mp, ra->ri_bmap.br_startblock) -
144 XFS_FSB_TO_AGNO(mp, rb->ri_bmap.br_startblock);
145}
146
147/* Get an RUI. */
148STATIC void *
149xfs_rmap_update_create_intent(
150 struct xfs_trans *tp,
151 unsigned int count)
152{
153 return NULL;
154}
155
156/* Log rmap updates in the intent item. */
157STATIC void
158xfs_rmap_update_log_item(
159 struct xfs_trans *tp,
160 void *intent,
161 struct list_head *item)
162{
163}
164
165/* Get an RUD so we can process all the deferred rmap updates. */
166STATIC void *
167xfs_rmap_update_create_done(
168 struct xfs_trans *tp,
169 void *intent,
170 unsigned int count)
171{
172 return NULL;
173}
174
175/* Process a deferred rmap update. */
176STATIC int
177xfs_rmap_update_finish_item(
178 struct xfs_trans *tp,
dc3bce02
DW
179 struct list_head *item,
180 void *done_item,
181 void **state)
182{
183 struct xfs_rmap_intent *rmap;
184 int error;
185
186 rmap = container_of(item, struct xfs_rmap_intent, ri_list);
187 error = xfs_rmap_finish_one(tp,
188 rmap->ri_type,
189 rmap->ri_owner, rmap->ri_whichfork,
190 rmap->ri_bmap.br_startoff,
191 rmap->ri_bmap.br_startblock,
192 rmap->ri_bmap.br_blockcount,
193 rmap->ri_bmap.br_state,
194 (struct xfs_btree_cur **)state);
195 kmem_free(rmap);
196 return error;
197}
198
199/* Clean up after processing deferred rmaps. */
200STATIC void
201xfs_rmap_update_finish_cleanup(
202 struct xfs_trans *tp,
203 void *state,
204 int error)
205{
206 struct xfs_btree_cur *rcur = state;
207
208 xfs_rmap_finish_one_cleanup(tp, rcur, error);
209}
210
211/* Abort all pending RUIs. */
212STATIC void
213xfs_rmap_update_abort_intent(
214 void *intent)
215{
216}
217
218/* Cancel a deferred rmap update. */
219STATIC void
220xfs_rmap_update_cancel_item(
221 struct list_head *item)
222{
223 struct xfs_rmap_intent *rmap;
224
225 rmap = container_of(item, struct xfs_rmap_intent, ri_list);
226 kmem_free(rmap);
227}
228
229static const struct xfs_defer_op_type xfs_rmap_update_defer_type = {
230 .type = XFS_DEFER_OPS_TYPE_RMAP,
231 .diff_items = xfs_rmap_update_diff_items,
232 .create_intent = xfs_rmap_update_create_intent,
233 .abort_intent = xfs_rmap_update_abort_intent,
234 .log_item = xfs_rmap_update_log_item,
235 .create_done = xfs_rmap_update_create_done,
236 .finish_item = xfs_rmap_update_finish_item,
237 .finish_cleanup = xfs_rmap_update_finish_cleanup,
238 .cancel_item = xfs_rmap_update_cancel_item,
239};
240
241/* Register the deferred op type. */
242void
243xfs_rmap_update_init_defer_op(void)
244{
245 xfs_defer_init_op_type(&xfs_rmap_update_defer_type);
246}
cdc9cf25
DW
247
248/* Reference Counting */
249
250/* Sort refcount intents by AG. */
251static int
252xfs_refcount_update_diff_items(
253 void *priv,
254 struct list_head *a,
255 struct list_head *b)
256{
257 struct xfs_mount *mp = priv;
258 struct xfs_refcount_intent *ra;
259 struct xfs_refcount_intent *rb;
260
261 ra = container_of(a, struct xfs_refcount_intent, ri_list);
262 rb = container_of(b, struct xfs_refcount_intent, ri_list);
263 return XFS_FSB_TO_AGNO(mp, ra->ri_startblock) -
264 XFS_FSB_TO_AGNO(mp, rb->ri_startblock);
265}
266
267/* Get an CUI. */
268STATIC void *
269xfs_refcount_update_create_intent(
270 struct xfs_trans *tp,
271 unsigned int count)
272{
273 return NULL;
274}
275
276/* Log refcount updates in the intent item. */
277STATIC void
278xfs_refcount_update_log_item(
279 struct xfs_trans *tp,
280 void *intent,
281 struct list_head *item)
282{
283}
284
285/* Get an CUD so we can process all the deferred refcount updates. */
286STATIC void *
287xfs_refcount_update_create_done(
288 struct xfs_trans *tp,
289 void *intent,
290 unsigned int count)
291{
292 return NULL;
293}
294
295/* Process a deferred refcount update. */
296STATIC int
297xfs_refcount_update_finish_item(
298 struct xfs_trans *tp,
cdc9cf25
DW
299 struct list_head *item,
300 void *done_item,
301 void **state)
302{
303 struct xfs_refcount_intent *refc;
304 xfs_fsblock_t new_fsb;
305 xfs_extlen_t new_aglen;
306 int error;
307
308 refc = container_of(item, struct xfs_refcount_intent, ri_list);
7b3ab230 309 error = xfs_refcount_finish_one(tp,
cdc9cf25
DW
310 refc->ri_type,
311 refc->ri_startblock,
312 refc->ri_blockcount,
313 &new_fsb, &new_aglen,
314 (struct xfs_btree_cur **)state);
315 /* Did we run out of reservation? Requeue what we didn't finish. */
316 if (!error && new_aglen > 0) {
317 ASSERT(refc->ri_type == XFS_REFCOUNT_INCREASE ||
318 refc->ri_type == XFS_REFCOUNT_DECREASE);
319 refc->ri_startblock = new_fsb;
320 refc->ri_blockcount = new_aglen;
321 return -EAGAIN;
322 }
323 kmem_free(refc);
324 return error;
325}
326
327/* Clean up after processing deferred refcounts. */
328STATIC void
329xfs_refcount_update_finish_cleanup(
330 struct xfs_trans *tp,
331 void *state,
332 int error)
333{
334 struct xfs_btree_cur *rcur = state;
335
336 xfs_refcount_finish_one_cleanup(tp, rcur, error);
337}
338
339/* Abort all pending CUIs. */
340STATIC void
341xfs_refcount_update_abort_intent(
342 void *intent)
343{
344}
345
346/* Cancel a deferred refcount update. */
347STATIC void
348xfs_refcount_update_cancel_item(
349 struct list_head *item)
350{
351 struct xfs_refcount_intent *refc;
352
353 refc = container_of(item, struct xfs_refcount_intent, ri_list);
354 kmem_free(refc);
355}
356
357static const struct xfs_defer_op_type xfs_refcount_update_defer_type = {
358 .type = XFS_DEFER_OPS_TYPE_REFCOUNT,
359 .diff_items = xfs_refcount_update_diff_items,
360 .create_intent = xfs_refcount_update_create_intent,
361 .abort_intent = xfs_refcount_update_abort_intent,
362 .log_item = xfs_refcount_update_log_item,
363 .create_done = xfs_refcount_update_create_done,
364 .finish_item = xfs_refcount_update_finish_item,
365 .finish_cleanup = xfs_refcount_update_finish_cleanup,
366 .cancel_item = xfs_refcount_update_cancel_item,
367};
368
369/* Register the deferred op type. */
370void
371xfs_refcount_update_init_defer_op(void)
372{
373 xfs_defer_init_op_type(&xfs_refcount_update_defer_type);
374}
f8f8c8a0
DW
375
376/* Inode Block Mapping */
377
378/* Sort bmap intents by inode. */
379static int
380xfs_bmap_update_diff_items(
381 void *priv,
382 struct list_head *a,
383 struct list_head *b)
384{
385 struct xfs_bmap_intent *ba;
386 struct xfs_bmap_intent *bb;
387
388 ba = container_of(a, struct xfs_bmap_intent, bi_list);
389 bb = container_of(b, struct xfs_bmap_intent, bi_list);
390 return ba->bi_owner->i_ino - bb->bi_owner->i_ino;
391}
392
393/* Get an BUI. */
394STATIC void *
395xfs_bmap_update_create_intent(
396 struct xfs_trans *tp,
397 unsigned int count)
398{
399 return NULL;
400}
401
402/* Log bmap updates in the intent item. */
403STATIC void
404xfs_bmap_update_log_item(
405 struct xfs_trans *tp,
406 void *intent,
407 struct list_head *item)
408{
409}
410
411/* Get an BUD so we can process all the deferred rmap updates. */
412STATIC void *
413xfs_bmap_update_create_done(
414 struct xfs_trans *tp,
415 void *intent,
416 unsigned int count)
417{
418 return NULL;
419}
420
421/* Process a deferred rmap update. */
422STATIC int
423xfs_bmap_update_finish_item(
424 struct xfs_trans *tp,
f8f8c8a0
DW
425 struct list_head *item,
426 void *done_item,
427 void **state)
428{
429 struct xfs_bmap_intent *bmap;
594956fa 430 xfs_filblks_t count;
f8f8c8a0
DW
431 int error;
432
433 bmap = container_of(item, struct xfs_bmap_intent, bi_list);
594956fa 434 count = bmap->bi_bmap.br_blockcount;
7b3ab230 435 error = xfs_bmap_finish_one(tp,
f8f8c8a0
DW
436 bmap->bi_owner,
437 bmap->bi_type, bmap->bi_whichfork,
438 bmap->bi_bmap.br_startoff,
439 bmap->bi_bmap.br_startblock,
594956fa 440 &count,
f8f8c8a0 441 bmap->bi_bmap.br_state);
594956fa
DW
442 if (!error && count > 0) {
443 ASSERT(bmap->bi_type == XFS_BMAP_UNMAP);
444 bmap->bi_bmap.br_blockcount = count;
445 return -EAGAIN;
446 }
f8f8c8a0
DW
447 kmem_free(bmap);
448 return error;
449}
450
451/* Abort all pending BUIs. */
452STATIC void
453xfs_bmap_update_abort_intent(
454 void *intent)
455{
456}
457
458/* Cancel a deferred rmap update. */
459STATIC void
460xfs_bmap_update_cancel_item(
461 struct list_head *item)
462{
463 struct xfs_bmap_intent *bmap;
464
465 bmap = container_of(item, struct xfs_bmap_intent, bi_list);
466 kmem_free(bmap);
467}
468
469static const struct xfs_defer_op_type xfs_bmap_update_defer_type = {
470 .type = XFS_DEFER_OPS_TYPE_BMAP,
471 .diff_items = xfs_bmap_update_diff_items,
472 .create_intent = xfs_bmap_update_create_intent,
473 .abort_intent = xfs_bmap_update_abort_intent,
474 .log_item = xfs_bmap_update_log_item,
475 .create_done = xfs_bmap_update_create_done,
476 .finish_item = xfs_bmap_update_finish_item,
477 .cancel_item = xfs_bmap_update_cancel_item,
478};
479
480/* Register the deferred op type. */
481void
482xfs_bmap_update_init_defer_op(void)
483{
484 xfs_defer_init_op_type(&xfs_bmap_update_defer_type);
485}