Skip to content

Commit cdf3c10

Browse files
adam900710kdave
authored andcommitted
btrfs-progs: fix-data-checksum: show affected files
Previously "btrfs rescue fix-data-checksum" only showed affected logical bytenr, which is not helpful to determine which files are affected. Enhance the output by also printing the affected subvolumes (in numeric form), and the file paths inside that subvolume. The example looks like this: logical=13631488 corrtuped mirrors=1 affected files: (subvolume 5)/foo (subvolume 5)/dir/bar logical=13635584 corrtuped mirrors=1 affected files: (subvolume 5)/foo (subvolume 5)/dir/bar Although the end result is still not perfect, it's much easier to find out which files are affected. Signed-off-by: Qu Wenruo <wqu@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
1 parent 46c93e3 commit cdf3c10

File tree

1 file changed

+57
-3
lines changed

1 file changed

+57
-3
lines changed

cmds/rescue-fix-data-checksum.c

Lines changed: 57 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include "kernel-shared/disk-io.h"
1919
#include "kernel-shared/ctree.h"
2020
#include "kernel-shared/volumes.h"
21+
#include "kernel-shared/backref.h"
2122
#include "common/messages.h"
2223
#include "common/open-utils.h"
2324
#include "cmds/rescue.h"
@@ -159,6 +160,50 @@ static int iterate_one_csum_item(struct btrfs_fs_info *fs_info, struct btrfs_pat
159160
return ret;
160161
}
161162

163+
static int print_filenames(u64 ino, u64 offset, u64 rootid, void *ctx)
164+
{
165+
struct btrfs_fs_info *fs_info = ctx;
166+
struct btrfs_root *root;
167+
struct btrfs_key key;
168+
struct inode_fs_paths *ipath;
169+
struct btrfs_path path = { 0 };
170+
int ret;
171+
172+
key.objectid = rootid;
173+
key.type = BTRFS_ROOT_ITEM_KEY;
174+
key.offset = (u64)-1;
175+
176+
root = btrfs_read_fs_root(fs_info, &key);
177+
if (IS_ERR(root)) {
178+
ret = PTR_ERR(root);
179+
errno = -ret;
180+
error("failed to get subvolume %llu: %m", rootid);
181+
return ret;
182+
}
183+
ipath = init_ipath(128 * BTRFS_PATH_NAME_MAX, root, &path);
184+
if (IS_ERR(ipath)) {
185+
ret = PTR_ERR(ipath);
186+
errno = -ret;
187+
error("failed to initialize ipath: %m");
188+
return ret;
189+
}
190+
ret = paths_from_inode(ino, ipath);
191+
if (ret < 0) {
192+
errno = -ret;
193+
error("failed to resolve root %llu ino %llu to paths: %m", rootid, ino);
194+
goto out;
195+
}
196+
for (int i = 0; i < ipath->fspath->elem_cnt; i++)
197+
pr_verbose(LOG_DEFAULT, " (subvolume %llu)/%s\n", rootid,
198+
(char *)ipath->fspath->val[i]);
199+
if (ipath->fspath->elem_missed)
200+
pr_verbose(LOG_DEFAULT, " (subvolume %llu) %d files not printed\n",
201+
rootid, ipath->fspath->elem_missed);
202+
out:
203+
free_ipath(ipath);
204+
return ret;
205+
}
206+
162207
static int iterate_csum_root(struct btrfs_fs_info *fs_info, struct btrfs_root *csum_root)
163208
{
164209
struct btrfs_path path = { 0 };
@@ -198,9 +243,10 @@ static int iterate_csum_root(struct btrfs_fs_info *fs_info, struct btrfs_root *c
198243
return ret;
199244
}
200245

201-
static void report_corrupted_blocks(void)
246+
static void report_corrupted_blocks(struct btrfs_fs_info *fs_info)
202247
{
203248
struct corrupted_block *entry;
249+
struct btrfs_path path = { 0 };
204250

205251
if (list_empty(&corrupted_blocks)) {
206252
pr_verbose(LOG_DEFAULT, "no data checksum mismatch found\n");
@@ -209,6 +255,7 @@ static void report_corrupted_blocks(void)
209255

210256
list_for_each_entry(entry, &corrupted_blocks, list) {
211257
bool has_printed = false;
258+
int ret;
212259

213260
pr_verbose(LOG_DEFAULT, "logical=%llu corrtuped mirrors=", entry->logical);
214261
/* Open coded bitmap print. */
@@ -224,7 +271,14 @@ static void report_corrupted_blocks(void)
224271
has_printed=true;
225272
}
226273
}
227-
pr_verbose(LOG_DEFAULT, "\n");
274+
pr_verbose(LOG_DEFAULT, " affected files:\n");
275+
ret = iterate_inodes_from_logical(entry->logical, fs_info, &path,
276+
print_filenames, fs_info);
277+
if (ret < 0) {
278+
errno = -ret;
279+
error("failed to iterate involved files: %m");
280+
break;
281+
}
228282
}
229283
}
230284

@@ -280,7 +334,7 @@ int btrfs_recover_fix_data_checksum(const char *path, enum btrfs_fix_data_checks
280334
errno = -ret;
281335
error("failed to iterate csum tree: %m");
282336
}
283-
report_corrupted_blocks();
337+
report_corrupted_blocks(fs_info);
284338
out_close:
285339
free_corrupted_blocks();
286340
close_ctree_fs_info(fs_info);

0 commit comments

Comments
 (0)