hc
2023-12-08 01573e231f18eb2d99162747186f59511f56b64d
kernel/fs/xfs/xfs_fsmap.c
....@@ -9,16 +9,12 @@
99 #include "xfs_format.h"
1010 #include "xfs_log_format.h"
1111 #include "xfs_trans_resv.h"
12
-#include "xfs_sb.h"
1312 #include "xfs_mount.h"
14
-#include "xfs_defer.h"
1513 #include "xfs_inode.h"
1614 #include "xfs_trans.h"
17
-#include "xfs_error.h"
1815 #include "xfs_btree.h"
1916 #include "xfs_rmap_btree.h"
2017 #include "xfs_trace.h"
21
-#include "xfs_log.h"
2218 #include "xfs_rmap.h"
2319 #include "xfs_alloc.h"
2420 #include "xfs_bit.h"
....@@ -30,7 +26,7 @@
3026 #include "xfs_rtalloc.h"
3127
3228 /* Convert an xfs_fsmap to an fsmap. */
33
-void
29
+static void
3430 xfs_fsmap_from_internal(
3531 struct fsmap *dest,
3632 struct xfs_fsmap *src)
....@@ -150,6 +146,7 @@
150146 dest->fmr_owner = XFS_FMR_OWN_FREE;
151147 break;
152148 default:
149
+ ASSERT(0);
153150 return -EFSCORRUPTED;
154151 }
155152 return 0;
....@@ -158,8 +155,7 @@
158155 /* getfsmap query state */
159156 struct xfs_getfsmap_info {
160157 struct xfs_fsmap_head *head;
161
- xfs_fsmap_format_t formatter; /* formatting fn */
162
- void *format_arg; /* format buffer */
158
+ struct fsmap *fsmap_recs; /* mapping records */
163159 struct xfs_buf *agf_bp; /* AGF, for refcount queries */
164160 xfs_daddr_t next_daddr; /* next daddr we expect */
165161 u64 missing_owner; /* owner of holes */
....@@ -227,6 +223,20 @@
227223 return 0;
228224 }
229225
226
+static inline void
227
+xfs_getfsmap_format(
228
+ struct xfs_mount *mp,
229
+ struct xfs_fsmap *xfm,
230
+ struct xfs_getfsmap_info *info)
231
+{
232
+ struct fsmap *rec;
233
+
234
+ trace_xfs_getfsmap_mapping(mp, xfm);
235
+
236
+ rec = &info->fsmap_recs[info->head->fmh_entries++];
237
+ xfs_fsmap_from_internal(rec, xfm);
238
+}
239
+
230240 /*
231241 * Format a reverse mapping for getfsmap, having translated rm_startblock
232242 * into the appropriate daddr units.
....@@ -254,7 +264,7 @@
254264 rec_daddr += XFS_FSB_TO_BB(mp, rec->rm_blockcount);
255265 if (info->next_daddr < rec_daddr)
256266 info->next_daddr = rec_daddr;
257
- return XFS_BTREE_QUERY_RANGE_CONTINUE;
267
+ return 0;
258268 }
259269
260270 /* Are we just counting mappings? */
....@@ -266,14 +276,14 @@
266276 info->head->fmh_entries++;
267277
268278 if (info->last)
269
- return XFS_BTREE_QUERY_RANGE_CONTINUE;
279
+ return 0;
270280
271281 info->head->fmh_entries++;
272282
273283 rec_daddr += XFS_FSB_TO_BB(mp, rec->rm_blockcount);
274284 if (info->next_daddr < rec_daddr)
275285 info->next_daddr = rec_daddr;
276
- return XFS_BTREE_QUERY_RANGE_CONTINUE;
286
+ return 0;
277287 }
278288
279289 /*
....@@ -283,7 +293,7 @@
283293 */
284294 if (rec_daddr > info->next_daddr) {
285295 if (info->head->fmh_entries >= info->head->fmh_count)
286
- return XFS_BTREE_QUERY_RANGE_ABORT;
296
+ return -ECANCELED;
287297
288298 fmr.fmr_device = info->dev;
289299 fmr.fmr_physical = info->next_daddr;
....@@ -291,10 +301,7 @@
291301 fmr.fmr_offset = 0;
292302 fmr.fmr_length = rec_daddr - info->next_daddr;
293303 fmr.fmr_flags = FMR_OF_SPECIAL_OWNER;
294
- error = info->formatter(&fmr, info->format_arg);
295
- if (error)
296
- return error;
297
- info->head->fmh_entries++;
304
+ xfs_getfsmap_format(mp, &fmr, info);
298305 }
299306
300307 if (info->last)
....@@ -302,7 +309,7 @@
302309
303310 /* Fill out the extent we found */
304311 if (info->head->fmh_entries >= info->head->fmh_count)
305
- return XFS_BTREE_QUERY_RANGE_ABORT;
312
+ return -ECANCELED;
306313
307314 trace_xfs_fsmap_mapping(mp, info->dev, info->agno, rec);
308315
....@@ -326,16 +333,13 @@
326333 if (shared)
327334 fmr.fmr_flags |= FMR_OF_SHARED;
328335 }
329
- error = info->formatter(&fmr, info->format_arg);
330
- if (error)
331
- return error;
332
- info->head->fmh_entries++;
333336
337
+ xfs_getfsmap_format(mp, &fmr, info);
334338 out:
335339 rec_daddr += XFS_FSB_TO_BB(mp, rec->rm_blockcount);
336340 if (info->next_daddr < rec_daddr)
337341 info->next_daddr = rec_daddr;
338
- return XFS_BTREE_QUERY_RANGE_CONTINUE;
342
+ return 0;
339343 }
340344
341345 /* Transform a rmapbt irec into a fsmap */
....@@ -350,7 +354,7 @@
350354 xfs_fsblock_t fsb;
351355 xfs_daddr_t rec_daddr;
352356
353
- fsb = XFS_AGB_TO_FSB(mp, cur->bc_private.a.agno, rec->rm_startblock);
357
+ fsb = XFS_AGB_TO_FSB(mp, cur->bc_ag.agno, rec->rm_startblock);
354358 rec_daddr = XFS_FSB_TO_DADDR(mp, fsb);
355359
356360 return xfs_getfsmap_helper(cur->bc_tp, info, rec, rec_daddr);
....@@ -368,7 +372,7 @@
368372 struct xfs_rmap_irec irec;
369373 xfs_daddr_t rec_daddr;
370374
371
- rec_daddr = XFS_AGB_TO_DADDR(mp, cur->bc_private.a.agno,
375
+ rec_daddr = XFS_AGB_TO_DADDR(mp, cur->bc_ag.agno,
372376 rec->ar_startblock);
373377
374378 irec.rm_startblock = rec->ar_startblock;
....@@ -798,11 +802,11 @@
798802 #endif /* CONFIG_XFS_RT */
799803
800804 /*
801
- * Get filesystem's extents as described in head, and format for
802
- * output. Calls formatter to fill the user's buffer until all
803
- * extents are mapped, until the passed-in head->fmh_count slots have
804
- * been filled, or until the formatter short-circuits the loop, if it
805
- * is tracking filled-in extents on its own.
805
+ * Get filesystem's extents as described in head, and format for output. Fills
806
+ * in the supplied records array until there are no more reverse mappings to
807
+ * return or head.fmh_entries == head.fmh_count. In the second case, this
808
+ * function returns -ECANCELED to indicate that more records would have been
809
+ * returned.
806810 *
807811 * Key to Confusion
808812 * ----------------
....@@ -822,8 +826,7 @@
822826 xfs_getfsmap(
823827 struct xfs_mount *mp,
824828 struct xfs_fsmap_head *head,
825
- xfs_fsmap_format_t formatter,
826
- void *arg)
829
+ struct fsmap *fsmap_recs)
827830 {
828831 struct xfs_trans *tp = NULL;
829832 struct xfs_fsmap dkeys[2]; /* per-dev keys */
....@@ -898,9 +901,16 @@
898901
899902 info.next_daddr = head->fmh_keys[0].fmr_physical +
900903 head->fmh_keys[0].fmr_length;
901
- info.formatter = formatter;
902
- info.format_arg = arg;
904
+ info.fsmap_recs = fsmap_recs;
903905 info.head = head;
906
+
907
+ /*
908
+ * If fsmap runs concurrently with a scrub, the freeze can be delayed
909
+ * indefinitely as we walk the rmapbt and iterate over metadata
910
+ * buffers. Freeze quiesces the log (which waits for the buffer LRU to
911
+ * be emptied) and that won't happen while we're reading buffers.
912
+ */
913
+ sb_start_write(mp->m_super);
904914
905915 /* For each device we support... */
906916 for (i = 0; i < XFS_GETFSMAP_DEVS; i++) {
....@@ -941,6 +951,7 @@
941951
942952 if (tp)
943953 xfs_trans_cancel(tp);
954
+ sb_end_write(mp->m_super);
944955 head->fmh_oflags = FMH_OF_DEV_T;
945956 return error;
946957 }