]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blame - db/fsmap.c
misc: fix libxfs api violations
[thirdparty/xfsprogs-dev.git] / db / fsmap.c
CommitLineData
86bb49e4
DW
1/*
2 * Copyright (C) 2016 Oracle. All Rights Reserved.
3 *
4 * Author: Darrick J. Wong <darrick.wong@oracle.com>
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it would be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write the Free Software Foundation,
18 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
19 */
20#include "libxfs.h"
21#include "command.h"
22#include "fsmap.h"
23#include "output.h"
24#include "init.h"
25
26struct fsmap_info {
27 unsigned long long nr;
28 xfs_agnumber_t agno;
29};
30
31static int
32fsmap_fn(
33 struct xfs_btree_cur *cur,
34 struct xfs_rmap_irec *rec,
35 void *priv)
36{
37 struct fsmap_info *info = priv;
38
39 dbprintf(_("%llu: %u/%u len %u owner %lld offset %llu bmbt %d attrfork %d extflag %d\n"),
40 info->nr, info->agno, rec->rm_startblock,
41 rec->rm_blockcount, rec->rm_owner, rec->rm_offset,
42 !!(rec->rm_flags & XFS_RMAP_BMBT_BLOCK),
43 !!(rec->rm_flags & XFS_RMAP_ATTR_FORK),
44 !!(rec->rm_flags & XFS_RMAP_UNWRITTEN));
45 info->nr++;
46
47 return 0;
48}
49
50static void
51fsmap(
52 xfs_fsblock_t start_fsb,
53 xfs_fsblock_t end_fsb)
54{
55 struct fsmap_info info;
56 xfs_agnumber_t start_ag;
57 xfs_agnumber_t end_ag;
58 xfs_agnumber_t agno;
59 xfs_daddr_t eofs;
138ce9ff
DW
60 struct xfs_rmap_irec low = {0};
61 struct xfs_rmap_irec high = {0};
86bb49e4
DW
62 struct xfs_btree_cur *bt_cur;
63 struct xfs_buf *agbp;
64 int error;
65
66 eofs = XFS_FSB_TO_BB(mp, mp->m_sb.sb_dblocks);
67 if (XFS_FSB_TO_DADDR(mp, end_fsb) >= eofs)
68 end_fsb = XFS_DADDR_TO_FSB(mp, eofs - 1);
69
70 low.rm_startblock = XFS_FSB_TO_AGBNO(mp, start_fsb);
86bb49e4
DW
71 high.rm_startblock = -1U;
72 high.rm_owner = ULLONG_MAX;
73 high.rm_offset = ULLONG_MAX;
74 high.rm_flags = XFS_RMAP_ATTR_FORK | XFS_RMAP_BMBT_BLOCK | XFS_RMAP_UNWRITTEN;
75
76 start_ag = XFS_FSB_TO_AGNO(mp, start_fsb);
77 end_ag = XFS_FSB_TO_AGNO(mp, end_fsb);
78
79 info.nr = 0;
80 for (agno = start_ag; agno <= end_ag; agno++) {
81 if (agno == end_ag)
82 high.rm_startblock = XFS_FSB_TO_AGBNO(mp, end_fsb);
83
e2f60652 84 error = -libxfs_alloc_read_agf(mp, NULL, agno, 0, &agbp);
86bb49e4
DW
85 if (error) {
86 dbprintf(_("Error %d while reading AGF.\n"), error);
87 return;
88 }
89
e2f60652 90 bt_cur = libxfs_rmapbt_init_cursor(mp, NULL, agbp, agno);
86bb49e4
DW
91 if (!bt_cur) {
92 libxfs_putbuf(agbp);
93 dbprintf(_("Not enough memory.\n"));
94 return;
95 }
96
97 info.agno = agno;
98 error = -libxfs_rmap_query_range(bt_cur, &low, &high,
99 fsmap_fn, &info);
100 if (error) {
e2f60652 101 libxfs_btree_del_cursor(bt_cur, XFS_BTREE_ERROR);
86bb49e4
DW
102 libxfs_putbuf(agbp);
103 dbprintf(_("Error %d while querying fsmap btree.\n"),
104 error);
105 return;
106 }
107
e2f60652 108 libxfs_btree_del_cursor(bt_cur, XFS_BTREE_NOERROR);
86bb49e4
DW
109 libxfs_putbuf(agbp);
110
111 if (agno == start_ag)
112 low.rm_startblock = 0;
113 }
114}
115
116int
117fsmap_f(
118 int argc,
119 char **argv)
120{
121 char *p;
122 int c;
123 xfs_fsblock_t start_fsb = 0;
124 xfs_fsblock_t end_fsb = NULLFSBLOCK;
125
126 if (!xfs_sb_version_hasrmapbt(&mp->m_sb)) {
127 dbprintf(_("Filesystem does not support reverse mapping btree.\n"));
128 return 0;
129 }
130
131 while ((c = getopt(argc, argv, "")) != EOF) {
132 switch (c) {
133 default:
134 dbprintf(_("Bad option for fsmap command.\n"));
135 return 0;
136 }
137 }
138
139 if (argc > optind) {
140 start_fsb = strtoull(argv[optind], &p, 0);
141 if (*p != '\0' || start_fsb >= mp->m_sb.sb_dblocks) {
142 dbprintf(_("Bad fsmap start_fsb %s.\n"), argv[optind]);
143 return 0;
144 }
145 }
146
147 if (argc > optind + 1) {
148 end_fsb = strtoull(argv[optind + 1], &p, 0);
149 if (*p != '\0') {
150 dbprintf(_("Bad fsmap end_fsb %s.\n"), argv[optind + 1]);
151 return 0;
152 }
153 }
154
155 fsmap(start_fsb, end_fsb);
156
157 return 0;
158}
159
160static const cmdinfo_t fsmap_cmd =
161 { "fsmap", NULL, fsmap_f, 0, 2, 0,
162 N_("[start_fsb] [end_fsb]"),
163 N_("display reverse mapping(s)"), NULL };
164
165void
166fsmap_init(void)
167{
168 add_command(&fsmap_cmd);
169}