]>
Commit | Line | Data |
---|---|---|
2bd0ea18 | 1 | /* |
da23017d NS |
2 | * Copyright (c) 2000-2005 Silicon Graphics, Inc. |
3 | * All Rights Reserved. | |
dfc130f3 | 4 | * |
da23017d NS |
5 | * This program is free software; you can redistribute it and/or |
6 | * modify it under the terms of the GNU General Public License as | |
2bd0ea18 | 7 | * published by the Free Software Foundation. |
dfc130f3 | 8 | * |
da23017d NS |
9 | * This program is distributed in the hope that it would be useful, |
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
12 | * GNU General Public License for more details. | |
dfc130f3 | 13 | * |
da23017d NS |
14 | * You should have received a copy of the GNU General Public License |
15 | * along with this program; if not, write the Free Software Foundation, | |
16 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | |
2bd0ea18 NS |
17 | */ |
18 | ||
dcabd4e7 | 19 | #include "platform_defs.h" |
6b803e5a | 20 | #include "command.h" |
e246ba5f | 21 | #include "init.h" |
48c46ee3 | 22 | #include "io.h" |
2bd0ea18 | 23 | |
e246ba5f | 24 | static cmdinfo_t bmap_cmd; |
2bd0ea18 | 25 | |
e246ba5f NS |
26 | static void |
27 | bmap_help(void) | |
2bd0ea18 | 28 | { |
e246ba5f NS |
29 | printf(_( |
30 | "\n" | |
31 | " prints the block mapping for an XFS file's data or attribute forks" | |
32 | "\n" | |
33 | " Example:\n" | |
34 | " 'bmap -vp' - tabular format verbose map, including unwritten extents\n" | |
35 | "\n" | |
36 | " bmap prints the map of disk blocks used by the current file.\n" | |
37 | " The map lists each extent used by the file, as well as regions in the\n" | |
38 | " file that do not have any corresponding blocks (holes).\n" | |
39 | " By default, each line of the listing takes the following form:\n" | |
40 | " extent: [startoffset..endoffset]: startblock..endblock\n" | |
41 | " Holes are marked by replacing the startblock..endblock with 'hole'.\n" | |
42 | " All the file offsets and disk blocks are in units of 512-byte blocks.\n" | |
43 | " -a -- prints the attribute fork map instead of the data fork.\n" | |
7536ce44 | 44 | " -c -- prints the copy-on-write fork map instead of the data fork.\n" |
e246ba5f | 45 | " -d -- suppresses a DMAPI read event, offline portions shown as holes.\n" |
7536ce44 | 46 | " -e -- print delayed allocation extents.\n" |
e246ba5f | 47 | " -l -- also displays the length of each extent in 512-byte blocks.\n" |
6f0d352c ES |
48 | " -n -- query n extents.\n" |
49 | " -p -- obtain all unwritten extents as well (w/ -v show which are unwritten.)\n" | |
50 | " -v -- Verbose information, specify ag info. Show flags legend on 2nd -v\n" | |
e246ba5f NS |
51 | " Note: the bmap for non-regular files can be obtained provided the file\n" |
52 | " was opened appropriately (in particular, must be opened read-only).\n" | |
53 | "\n")); | |
54 | } | |
2bd0ea18 | 55 | |
e246ba5f NS |
56 | static int |
57 | numlen( | |
58 | off64_t val) | |
59 | { | |
60 | off64_t tmp; | |
61 | int len; | |
9440d84d | 62 | |
e246ba5f NS |
63 | for (len = 0, tmp = val; tmp > 0; tmp = tmp/10) |
64 | len++; | |
65 | return (len == 0 ? 1 : len); | |
66 | } | |
67 | ||
68 | int | |
69 | bmap_f( | |
70 | int argc, | |
71 | char **argv) | |
72 | { | |
73 | struct fsxattr fsx; | |
74 | struct getbmapx *map; | |
c0211f67 | 75 | struct xfs_fsop_geom fsgeo; |
e246ba5f NS |
76 | int map_size; |
77 | int loop = 0; | |
78 | int flg = 0; | |
79 | int aflag = 0; | |
7536ce44 | 80 | int cflag = 0; |
e246ba5f NS |
81 | int lflag = 0; |
82 | int nflag = 0; | |
66b57340 | 83 | int pflag = 0; |
e246ba5f | 84 | int vflag = 0; |
e2eb7f3a | 85 | int is_rt = 0; |
e246ba5f NS |
86 | int bmv_iflags = 0; /* flags for XFS_IOC_GETBMAPX */ |
87 | int i = 0; | |
88 | int c; | |
619df821 | 89 | int egcnt; |
e246ba5f | 90 | |
7536ce44 | 91 | while ((c = getopt(argc, argv, "acdeln:pv")) != EOF) { |
e246ba5f NS |
92 | switch (c) { |
93 | case 'a': /* Attribute fork. */ | |
2bd0ea18 NS |
94 | bmv_iflags |= BMV_IF_ATTRFORK; |
95 | aflag = 1; | |
96 | break; | |
7536ce44 DW |
97 | case 'c': /* CoW fork. */ |
98 | bmv_iflags |= BMV_IF_COWFORK | BMV_IF_DELALLOC; | |
99 | cflag = 1; | |
100 | break; | |
101 | case 'e': | |
102 | bmv_iflags |= BMV_IF_DELALLOC; | |
103 | break; | |
e246ba5f | 104 | case 'l': /* list number of blocks with each extent */ |
2bd0ea18 NS |
105 | lflag = 1; |
106 | break; | |
e246ba5f | 107 | case 'n': /* number of extents specified */ |
2bd0ea18 NS |
108 | nflag = atoi(optarg); |
109 | break; | |
110 | case 'd': | |
111 | /* do not recall possibly offline DMAPI files */ | |
112 | bmv_iflags |= BMV_IF_NO_DMAPI_READ; | |
113 | break; | |
114 | case 'p': | |
115 | /* report unwritten preallocated blocks */ | |
66b57340 | 116 | pflag = 1; |
2bd0ea18 NS |
117 | bmv_iflags |= BMV_IF_PREALLOC; |
118 | break; | |
e246ba5f | 119 | case 'v': /* Verbose output */ |
2bd0ea18 NS |
120 | vflag++; |
121 | break; | |
2bd0ea18 | 122 | default: |
48c46ee3 | 123 | return command_usage(&bmap_cmd); |
2bd0ea18 NS |
124 | } |
125 | } | |
7536ce44 | 126 | if (aflag || cflag) |
e246ba5f | 127 | bmv_iflags &= ~(BMV_IF_PREALLOC|BMV_IF_NO_DMAPI_READ); |
2bd0ea18 NS |
128 | |
129 | if (vflag) { | |
48c46ee3 NS |
130 | c = xfsctl(file->name, file->fd, XFS_IOC_FSGEOMETRY_V1, &fsgeo); |
131 | if (c < 0) { | |
9440d84d NS |
132 | fprintf(stderr, |
133 | _("%s: can't get geometry [\"%s\"]: %s\n"), | |
48c46ee3 | 134 | progname, file->name, strerror(errno)); |
e246ba5f NS |
135 | exitcode = 1; |
136 | return 0; | |
2bd0ea18 | 137 | } |
83f4b5ac | 138 | c = xfsctl(file->name, file->fd, FS_IOC_FSGETXATTR, &fsx); |
48c46ee3 | 139 | if (c < 0) { |
9440d84d NS |
140 | fprintf(stderr, |
141 | _("%s: cannot read attrs on \"%s\": %s\n"), | |
48c46ee3 | 142 | progname, file->name, strerror(errno)); |
e246ba5f NS |
143 | exitcode = 1; |
144 | return 0; | |
2bd0ea18 NS |
145 | } |
146 | ||
83f4b5ac | 147 | if (fsx.fsx_xflags == FS_XFLAG_REALTIME) { |
dfc130f3 | 148 | /* |
2bd0ea18 NS |
149 | * ag info not applicable to rt, continue |
150 | * without ag output. | |
151 | */ | |
e2eb7f3a | 152 | is_rt = 1; |
2bd0ea18 NS |
153 | } |
154 | } | |
155 | ||
0b52c691 | 156 | map_size = nflag ? nflag+2 : 32; /* initial guess - 32 */ |
2bd0ea18 NS |
157 | map = malloc(map_size*sizeof(*map)); |
158 | if (map == NULL) { | |
9440d84d | 159 | fprintf(stderr, _("%s: malloc of %d bytes failed.\n"), |
c03d02f8 | 160 | progname, (int)(map_size * sizeof(*map))); |
e246ba5f NS |
161 | exitcode = 1; |
162 | return 0; | |
2bd0ea18 | 163 | } |
dfc130f3 | 164 | |
2bd0ea18 | 165 | |
93d9f139 | 166 | /* Try the xfsctl(XFS_IOC_GETBMAPX) for the number of extents specified |
0b52c691 | 167 | * by nflag, or the initial guess number of extents (32). |
2bd0ea18 | 168 | * |
93d9f139 | 169 | * If there are more extents than we guessed, use xfsctl |
83f4b5ac | 170 | * (FS_IOC_FSGETXATTR[A]) to get the extent count, realloc some more |
2bd0ea18 NS |
171 | * space based on this count, and try again. |
172 | * | |
173 | * If the initial FGETBMAPX attempt returns EINVAL, this may mean | |
174 | * that we tried the FGETBMAPX on a zero length file. If we get | |
175 | * EINVAL, check the length with fstat() and return "no extents" | |
176 | * if the length == 0. | |
177 | * | |
83f4b5ac | 178 | * Why not do the xfsctl(FS_IOC_FSGETXATTR[A]) first? Two reasons: |
2bd0ea18 NS |
179 | * (1) The extent count may be wrong for a file with delayed |
180 | * allocation blocks. The XFS_IOC_GETBMAPX forces the real | |
181 | * allocation and fixes up the extent count. | |
dfc130f3 RC |
182 | * (2) For XFS_IOC_GETBMAP[X] on a DMAPI file that has been moved |
183 | * offline by a DMAPI application (e.g., DMF) the | |
83f4b5ac | 184 | * FS_IOC_FSGETXATTR only reflects the extents actually online. |
2bd0ea18 NS |
185 | * Doing XFS_IOC_GETBMAPX call first forces that data blocks online |
186 | * and then everything proceeds normally (see PV #545725). | |
dfc130f3 | 187 | * |
2bd0ea18 NS |
188 | * If you don't want this behavior on a DMAPI offline file, |
189 | * try the "-d" option which sets the BMV_IF_NO_DMAPI_READ | |
190 | * iflag for XFS_IOC_GETBMAPX. | |
191 | */ | |
192 | ||
193 | do { /* loop a miximum of two times */ | |
194 | ||
dab9b8d6 | 195 | memset(map, 0, sizeof(*map)); /* zero header */ |
2bd0ea18 NS |
196 | |
197 | map->bmv_length = -1; | |
198 | map->bmv_count = map_size; | |
199 | map->bmv_iflags = bmv_iflags; | |
200 | ||
48c46ee3 | 201 | i = xfsctl(file->name, file->fd, XFS_IOC_GETBMAPX, map); |
2bd0ea18 NS |
202 | if (i < 0) { |
203 | if ( errno == EINVAL | |
e246ba5f | 204 | && !aflag && filesize() == 0) { |
2bd0ea18 NS |
205 | break; |
206 | } else { | |
93d9f139 NS |
207 | fprintf(stderr, _("%s: xfsctl(XFS_IOC_GETBMAPX)" |
208 | " iflags=0x%x [\"%s\"]: %s\n"), | |
48c46ee3 | 209 | progname, map->bmv_iflags, file->name, |
c03d02f8 | 210 | strerror(errno)); |
2bd0ea18 | 211 | free(map); |
e246ba5f NS |
212 | exitcode = 1; |
213 | return 0; | |
2bd0ea18 NS |
214 | } |
215 | } | |
216 | if (nflag) | |
217 | break; | |
218 | if (map->bmv_entries < map->bmv_count-1) | |
219 | break; | |
83f4b5ac | 220 | /* Get number of extents from xfsctl FS_IOC_FSGETXATTR[A] |
2bd0ea18 NS |
221 | * syscall. |
222 | */ | |
48c46ee3 | 223 | i = xfsctl(file->name, file->fd, aflag ? |
83f4b5ac | 224 | XFS_IOC_FSGETXATTRA : FS_IOC_FSGETXATTR, &fsx); |
2bd0ea18 | 225 | if (i < 0) { |
83f4b5ac | 226 | fprintf(stderr, "%s: xfsctl(FS_IOC_FSGETXATTR%s) " |
93d9f139 | 227 | "[\"%s\"]: %s\n", progname, aflag ? "A" : "", |
48c46ee3 | 228 | file->name, strerror(errno)); |
2bd0ea18 | 229 | free(map); |
e246ba5f NS |
230 | exitcode = 1; |
231 | return 0; | |
2bd0ea18 | 232 | } |
f6d1a563 TM |
233 | if (2 * fsx.fsx_nextents > map_size) { |
234 | map_size = 2 * fsx.fsx_nextents + 1; | |
2bd0ea18 NS |
235 | map = realloc(map, map_size*sizeof(*map)); |
236 | if (map == NULL) { | |
9440d84d NS |
237 | fprintf(stderr, |
238 | _("%s: cannot realloc %d bytes\n"), | |
c03d02f8 | 239 | progname, (int)(map_size*sizeof(*map))); |
e246ba5f NS |
240 | exitcode = 1; |
241 | return 0; | |
2bd0ea18 NS |
242 | } |
243 | } | |
244 | } while (++loop < 2); | |
245 | if (!nflag) { | |
246 | if (map->bmv_entries <= 0) { | |
48c46ee3 | 247 | printf(_("%s: no extents\n"), file->name); |
2bd0ea18 NS |
248 | free(map); |
249 | return 0; | |
250 | } | |
251 | } | |
619df821 | 252 | egcnt = nflag ? min(nflag, map->bmv_entries) : map->bmv_entries; |
48c46ee3 | 253 | printf("%s:\n", file->name); |
2bd0ea18 | 254 | if (!vflag) { |
619df821 | 255 | for (i = 0; i < egcnt; i++) { |
2bd0ea18 | 256 | printf("\t%d: [%lld..%lld]: ", i, |
5b64e00a | 257 | (long long) map[i + 1].bmv_offset, |
dfc130f3 | 258 | (long long)(map[i + 1].bmv_offset + |
5b64e00a | 259 | map[i + 1].bmv_length - 1LL)); |
2bd0ea18 | 260 | if (map[i + 1].bmv_block == -1) |
9440d84d | 261 | printf(_("hole")); |
1c47bd67 DW |
262 | else if (map[i + 1].bmv_block == -2) |
263 | printf(_("delalloc")); | |
2bd0ea18 | 264 | else { |
5b64e00a NS |
265 | printf("%lld..%lld", |
266 | (long long) map[i + 1].bmv_block, | |
267 | (long long)(map[i + 1].bmv_block + | |
268 | map[i + 1].bmv_length - 1LL)); | |
2bd0ea18 NS |
269 | |
270 | } | |
271 | if (lflag) | |
9440d84d NS |
272 | printf(_(" %lld blocks\n"), |
273 | (long long)map[i+1].bmv_length); | |
2bd0ea18 NS |
274 | else |
275 | printf("\n"); | |
276 | } | |
277 | } else { | |
278 | /* | |
dfc130f3 | 279 | * Verbose mode displays: |
2bd0ea18 | 280 | * extent: [startoffset..endoffset]: startblock..endblock \ |
dfc130f3 | 281 | * ag# (agoffset..agendoffset) totalbbs |
2bd0ea18 NS |
282 | */ |
283 | #define MINRANGE_WIDTH 16 | |
284 | #define MINAG_WIDTH 2 | |
285 | #define MINTOT_WIDTH 5 | |
7536ce44 DW |
286 | #define NFLG 6 /* count of flags */ |
287 | #define FLG_NULL 0000000 /* Null flag */ | |
288 | #define FLG_SHARED 0100000 /* shared extent */ | |
289 | #define FLG_PRE 0010000 /* Unwritten extent */ | |
290 | #define FLG_BSU 0001000 /* Not on begin of stripe unit */ | |
291 | #define FLG_ESU 0000100 /* Not on end of stripe unit */ | |
292 | #define FLG_BSW 0000010 /* Not on begin of stripe width */ | |
293 | #define FLG_ESW 0000001 /* Not on end of stripe width */ | |
4ca431fc NS |
294 | int agno; |
295 | off64_t agoff, bbperag; | |
dfc130f3 RC |
296 | int foff_w, boff_w, aoff_w, tot_w, agno_w; |
297 | char rbuf[32], bbuf[32], abuf[32]; | |
4ca431fc | 298 | int sunit, swidth; |
2bd0ea18 NS |
299 | |
300 | foff_w = boff_w = aoff_w = MINRANGE_WIDTH; | |
301 | tot_w = MINTOT_WIDTH; | |
e2eb7f3a BN |
302 | if (is_rt) |
303 | sunit = swidth = bbperag = 0; | |
304 | else { | |
305 | bbperag = (off64_t)fsgeo.agblocks * | |
306 | (off64_t)fsgeo.blocksize / BBSIZE; | |
307 | sunit = (fsgeo.sunit * fsgeo.blocksize) / BBSIZE; | |
308 | swidth = (fsgeo.swidth * fsgeo.blocksize) / BBSIZE; | |
309 | } | |
66b57340 | 310 | flg = sunit | pflag; |
2bd0ea18 | 311 | |
dfc130f3 | 312 | /* |
2bd0ea18 NS |
313 | * Go through the extents and figure out the width |
314 | * needed for all columns. | |
315 | */ | |
619df821 | 316 | for (i = 0; i < egcnt; i++) { |
dfc130f3 | 317 | snprintf(rbuf, sizeof(rbuf), "[%lld..%lld]:", |
5b64e00a NS |
318 | (long long) map[i + 1].bmv_offset, |
319 | (long long)(map[i + 1].bmv_offset + | |
320 | map[i + 1].bmv_length - 1LL)); | |
d371bee3 NS |
321 | if (map[i + 1].bmv_oflags & BMV_OF_PREALLOC) |
322 | flg = 1; | |
2bd0ea18 | 323 | if (map[i + 1].bmv_block == -1) { |
dfc130f3 RC |
324 | foff_w = max(foff_w, strlen(rbuf)); |
325 | tot_w = max(tot_w, | |
2bd0ea18 NS |
326 | numlen(map[i+1].bmv_length)); |
327 | } else { | |
dfc130f3 | 328 | snprintf(bbuf, sizeof(bbuf), "%lld..%lld", |
5b64e00a NS |
329 | (long long) map[i + 1].bmv_block, |
330 | (long long)(map[i + 1].bmv_block + | |
331 | map[i + 1].bmv_length - 1LL)); | |
dfc130f3 | 332 | boff_w = max(boff_w, strlen(bbuf)); |
e2eb7f3a BN |
333 | if (!is_rt) { |
334 | agno = map[i + 1].bmv_block / bbperag; | |
335 | agoff = map[i + 1].bmv_block - | |
336 | (agno * bbperag); | |
337 | snprintf(abuf, sizeof(abuf), | |
338 | "(%lld..%lld)", | |
339 | (long long)agoff, | |
340 | (long long)(agoff + | |
341 | map[i + 1].bmv_length - 1LL)); | |
342 | aoff_w = max(aoff_w, strlen(abuf)); | |
343 | } else | |
344 | aoff_w = 0; | |
345 | foff_w = max(foff_w, strlen(rbuf)); | |
dfc130f3 | 346 | tot_w = max(tot_w, |
2bd0ea18 NS |
347 | numlen(map[i+1].bmv_length)); |
348 | } | |
349 | } | |
e2eb7f3a | 350 | agno_w = is_rt ? 0 : max(MINAG_WIDTH, numlen(fsgeo.agcount)); |
d371bee3 | 351 | printf("%4s: %-*s %-*s %*s %-*s %*s%s\n", |
9440d84d NS |
352 | _("EXT"), |
353 | foff_w, _("FILE-OFFSET"), | |
e2eb7f3a BN |
354 | boff_w, is_rt ? _("RT-BLOCK-RANGE") : _("BLOCK-RANGE"), |
355 | agno_w, is_rt ? "" : _("AG"), | |
356 | aoff_w, is_rt ? "" : _("AG-OFFSET"), | |
d371bee3 NS |
357 | tot_w, _("TOTAL"), |
358 | flg ? _(" FLAGS") : ""); | |
619df821 | 359 | for (i = 0; i < egcnt; i++) { |
d371bee3 NS |
360 | flg = FLG_NULL; |
361 | if (map[i + 1].bmv_oflags & BMV_OF_PREALLOC) { | |
362 | flg |= FLG_PRE; | |
363 | } | |
7536ce44 DW |
364 | if (map[i + 1].bmv_oflags & BMV_OF_SHARED) |
365 | flg |= FLG_SHARED; | |
366 | if (map[i + 1].bmv_oflags & BMV_OF_DELALLOC) | |
367 | map[i + 1].bmv_block = -2; | |
4595c940 JK |
368 | /* |
369 | * If striping enabled, determine if extent starts/ends | |
370 | * on a stripe unit boundary. | |
371 | */ | |
4ca431fc | 372 | if (sunit) { |
4ca431fc NS |
373 | if (map[i + 1].bmv_block % sunit != 0) { |
374 | flg |= FLG_BSU; | |
375 | } | |
dfc130f3 | 376 | if (((map[i + 1].bmv_block + |
4ca431fc NS |
377 | map[i + 1].bmv_length ) % sunit ) != 0) { |
378 | flg |= FLG_ESU; | |
379 | } | |
380 | if (map[i + 1].bmv_block % swidth != 0) { | |
381 | flg |= FLG_BSW; | |
382 | } | |
dfc130f3 | 383 | if (((map[i + 1].bmv_block + |
4ca431fc NS |
384 | map[i + 1].bmv_length ) % swidth ) != 0) { |
385 | flg |= FLG_ESW; | |
386 | } | |
387 | } | |
dfc130f3 | 388 | snprintf(rbuf, sizeof(rbuf), "[%lld..%lld]:", |
5b64e00a NS |
389 | (long long) map[i + 1].bmv_offset, |
390 | (long long)(map[i + 1].bmv_offset + | |
391 | map[i + 1].bmv_length - 1LL)); | |
2bd0ea18 | 392 | if (map[i + 1].bmv_block == -1) { |
dfc130f3 RC |
393 | printf("%4d: %-*s %-*s %*s %-*s %*lld\n", |
394 | i, | |
395 | foff_w, rbuf, | |
9440d84d | 396 | boff_w, _("hole"), |
2bd0ea18 | 397 | agno_w, "", |
dfc130f3 | 398 | aoff_w, "", |
5b64e00a | 399 | tot_w, (long long)map[i+1].bmv_length); |
7536ce44 DW |
400 | } else if (map[i + 1].bmv_block == -2) { |
401 | printf("%4d: %-*s %-*s %*s %-*s %*lld\n", | |
402 | i, | |
403 | foff_w, rbuf, | |
404 | boff_w, _("delalloc"), | |
405 | agno_w, "", | |
406 | aoff_w, "", | |
407 | tot_w, (long long)map[i+1].bmv_length); | |
2bd0ea18 | 408 | } else { |
dfc130f3 | 409 | snprintf(bbuf, sizeof(bbuf), "%lld..%lld", |
5b64e00a NS |
410 | (long long) map[i + 1].bmv_block, |
411 | (long long)(map[i + 1].bmv_block + | |
412 | map[i + 1].bmv_length - 1LL)); | |
e2eb7f3a BN |
413 | printf("%4d: %-*s %-*s", i, foff_w, rbuf, |
414 | boff_w, bbuf); | |
415 | if (!is_rt) { | |
416 | agno = map[i + 1].bmv_block / bbperag; | |
417 | agoff = map[i + 1].bmv_block - | |
418 | (agno * bbperag); | |
419 | snprintf(abuf, sizeof(abuf), | |
420 | "(%lld..%lld)", | |
421 | (long long)agoff, | |
422 | (long long)(agoff + | |
423 | map[i + 1].bmv_length - 1LL)); | |
424 | printf(" %*d %-*s", agno_w, agno, | |
425 | aoff_w, abuf); | |
426 | } else | |
427 | printf(" "); | |
428 | printf(" %*lld", tot_w, | |
429 | (long long)map[i+1].bmv_length); | |
66b57340 | 430 | if (flg == FLG_NULL && !pflag) { |
4ca431fc NS |
431 | printf("\n"); |
432 | } else { | |
d371bee3 | 433 | printf(" %-*.*o\n", NFLG, NFLG, flg); |
4ca431fc | 434 | } |
2bd0ea18 NS |
435 | } |
436 | } | |
66b57340 | 437 | if ((flg || pflag) && vflag > 1) { |
d371bee3 | 438 | printf(_(" FLAG Values:\n")); |
7536ce44 DW |
439 | printf(_(" %*.*o Shared extent\n"), |
440 | NFLG+1, NFLG+1, FLG_SHARED); | |
d371bee3 NS |
441 | printf(_(" %*.*o Unwritten preallocated extent\n"), |
442 | NFLG+1, NFLG+1, FLG_PRE); | |
443 | printf(_(" %*.*o Doesn't begin on stripe unit\n"), | |
444 | NFLG+1, NFLG+1, FLG_BSU); | |
445 | printf(_(" %*.*o Doesn't end on stripe unit\n"), | |
446 | NFLG+1, NFLG+1, FLG_ESU); | |
447 | printf(_(" %*.*o Doesn't begin on stripe width\n"), | |
448 | NFLG+1, NFLG+1, FLG_BSW); | |
449 | printf(_(" %*.*o Doesn't end on stripe width\n"), | |
450 | NFLG+1, NFLG+1, FLG_ESW); | |
4ca431fc | 451 | } |
2bd0ea18 NS |
452 | } |
453 | free(map); | |
454 | return 0; | |
455 | } | |
456 | ||
e246ba5f NS |
457 | void |
458 | bmap_init(void) | |
2bd0ea18 | 459 | { |
ad765595 | 460 | bmap_cmd.name = "bmap"; |
e246ba5f NS |
461 | bmap_cmd.cfunc = bmap_f; |
462 | bmap_cmd.argmin = 0; | |
463 | bmap_cmd.argmax = -1; | |
48c46ee3 | 464 | bmap_cmd.flags = CMD_NOMAP_OK; |
e246ba5f NS |
465 | bmap_cmd.args = _("[-adlpv] [-n nx]"); |
466 | bmap_cmd.oneline = _("print block mapping for an XFS file"); | |
467 | bmap_cmd.help = bmap_help; | |
2bd0ea18 | 468 | |
e246ba5f | 469 | add_command(&bmap_cmd); |
2bd0ea18 | 470 | } |