]>
git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blob - scrub/filemap.c
1 // SPDX-License-Identifier: GPL-2.0+
3 * Copyright (C) 2018 Oracle. All Rights Reserved.
4 * Author: Darrick J. Wong <darrick.wong@oracle.com>
11 #include <sys/types.h>
12 #include <sys/statvfs.h>
14 #include "xfs_scrub.h"
19 * These routines provide a simple interface to query the block
20 * mappings of the fork of a given inode via GETBMAPX and call a
21 * function to iterate each mapping result.
26 /* Iterate all the extent block mappings between the key and fork end. */
29 struct scrub_ctx
*ctx
,
41 char bmap_descr
[DESCR_BUFSZ
];
50 snprintf(bmap_descr
, DESCR_BUFSZ
, _("%s attr"), descr
);
53 snprintf(bmap_descr
, DESCR_BUFSZ
, _("%s CoW"), descr
);
56 snprintf(bmap_descr
, DESCR_BUFSZ
, _("%s data"), descr
);
62 map
= calloc(BMAP_NR
, sizeof(struct getbmapx
));
64 str_errno(ctx
, bmap_descr
);
68 map
->bmv_offset
= BTOBB(key
->bm_offset
);
69 map
->bmv_block
= BTOBB(key
->bm_physical
);
70 if (key
->bm_length
== 0)
71 map
->bmv_length
= ULLONG_MAX
;
73 map
->bmv_length
= BTOBB(key
->bm_length
);
74 map
->bmv_count
= BMAP_NR
;
75 map
->bmv_iflags
= BMV_IF_NO_DMAPI_READ
| BMV_IF_PREALLOC
|
79 getxattr_type
= XFS_IOC_FSGETXATTRA
;
80 map
->bmv_iflags
|= BMV_IF_ATTRFORK
;
83 map
->bmv_iflags
|= BMV_IF_COWFORK
;
84 getxattr_type
= FS_IOC_FSGETXATTR
;
87 getxattr_type
= FS_IOC_FSGETXATTR
;
93 error
= ioctl(fd
, getxattr_type
, &fsx
);
95 str_errno(ctx
, bmap_descr
);
100 while ((error
= ioctl(fd
, XFS_IOC_GETBMAPX
, map
)) == 0) {
101 for (i
= 0, p
= &map
[i
+ 1]; i
< map
->bmv_entries
; i
++, p
++) {
102 bmap
.bm_offset
= BBTOB(p
->bmv_offset
);
103 bmap
.bm_physical
= BBTOB(p
->bmv_block
);
104 bmap
.bm_length
= BBTOB(p
->bmv_length
);
105 bmap
.bm_flags
= p
->bmv_oflags
;
106 moveon
= fn(ctx
, bmap_descr
, fd
, whichfork
, &fsx
,
110 if (xfs_scrub_excessive_errors(ctx
)) {
116 if (map
->bmv_entries
== 0)
118 p
= map
+ map
->bmv_entries
;
119 if (p
->bmv_oflags
& BMV_OF_LAST
)
122 new_off
= p
->bmv_offset
+ p
->bmv_length
;
123 map
->bmv_length
-= new_off
- map
->bmv_offset
;
124 map
->bmv_offset
= new_off
;
128 * Pre-reflink filesystems don't know about CoW forks, so don't
129 * be too surprised if it fails.
131 if (whichfork
== XFS_COW_FORK
&& error
&& errno
== EINVAL
)
135 str_errno(ctx
, bmap_descr
);