Skip to content

Commit

Permalink
Let zfs diff be more permissive.
Browse files Browse the repository at this point in the history
In the current world, `zfs diff` will die on certain kinds of errors
that come up on ordinary, not-mangled filesystems - like EINVAL,
which can come from a file with multiple hardlinks having the one
whose name is referenced deleted.

Since it should always be safe to continue, let's relax about all
error codes - still print something for most, but don't immediately
abort when we encounter them.

Signed-off-by: Rich Ercolani <rincebrain@gmail.com>
  • Loading branch information
rincebrain committed Jun 1, 2021
1 parent e723838 commit 7535096
Showing 1 changed file with 21 additions and 6 deletions.
27 changes: 21 additions & 6 deletions lib/libzfs/libzfs_diff.c
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,7 @@ write_inuse_diffs_one(FILE *fp, differ_info_t *di, uint64_t dobj)
struct zfs_stat fsb, tsb;
mode_t fmode, tmode;
char fobjname[MAXPATHLEN], tobjname[MAXPATHLEN];
boolean_t already_logged = B_FALSE;
int fobjerr, tobjerr;
int change;

Expand All @@ -254,22 +255,36 @@ write_inuse_diffs_one(FILE *fp, differ_info_t *di, uint64_t dobj)
* we get ENOENT, then the object just didn't exist in that
* snapshot. If we get ENOTSUP, then we tried to get
* info on a non-ZPL object, which we don't care about anyway.
* For any other error we print a warning which includes the
* errno and continue.
*/

fobjerr = get_stats_for_obj(di, di->fromsnap, dobj, fobjname,
MAXPATHLEN, &fsb);
if (fobjerr && di->zerr != ENOENT && di->zerr != ENOTSUP)
return (-1);
if (fobjerr && di->zerr != ENOTSUP && di->zerr != ENOENT) {
zfs_error_aux(di->zhp->zfs_hdl, strerror(di->zerr));
zfs_error(di->zhp->zfs_hdl, di->zerr, di->errbuf);
/*
* Let's not print an error for the same object more than
* once if it happens in both snapshots
*/
already_logged = B_TRUE;
}

tobjerr = get_stats_for_obj(di, di->tosnap, dobj, tobjname,
MAXPATHLEN, &tsb);
if (tobjerr && di->zerr != ENOENT && di->zerr != ENOTSUP)
return (-1);

if (tobjerr && di->zerr != ENOTSUP && di->zerr != ENOENT) {
if (!already_logged) {
zfs_error_aux(di->zhp->zfs_hdl, strerror(di->zerr));
zfs_error(di->zhp->zfs_hdl, di->zerr, di->errbuf);
}
}
/*
* Unallocated object sharing the same meta dnode block
*/
if (fobjerr && tobjerr) {
ASSERT(di->zerr == ENOENT || di->zerr == ENOTSUP);
if (fobjerr && tobjerr &&
(di->zerr == ENOENT || di->zerr == ENOTSUP)) {
di->zerr = 0;
return (0);
}
Expand Down

0 comments on commit 7535096

Please sign in to comment.