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 they don't appear to indicate the snapshot is mangled in any
way, let's relax about ENOENT and EINVAL - still print an error,
but don't immediately abort when we encounter them.

Signed-off-by: Rich Ercolani <rincebrain@gmail.com>
  • Loading branch information
rincebrain committed May 18, 2021
1 parent 7457b02 commit 77d316a
Showing 1 changed file with 23 additions and 2 deletions.
25 changes: 23 additions & 2 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;
int fobjerr, tobjerr;
int change;

Expand All @@ -257,14 +258,34 @@ write_inuse_diffs_one(FILE *fp, differ_info_t *di, uint64_t dobj)
*/
fobjerr = get_stats_for_obj(di, di->fromsnap, dobj, fobjname,
MAXPATHLEN, &fsb);
if (fobjerr && di->zerr != ENOENT && di->zerr != ENOTSUP)
if (fobjerr && di->zerr != ENOENT && di->zerr != ENOTSUP &&
di->zerr != EINVAL && di->zerr != ENOENT)
return (-1);

if (fobjerr && (di->zerr == EINVAL || di->zerr == ENOENT)) {
// previously, we printed out an error message on EINVAL and
// died immediately. Let's keep the error message but continue.
zfs_error_aux(di->zhp->zfs_hdl, strerror(di->zerr));
// the error code we pass here doesn't matter, because we filled
// in the message above
zfs_error(di->zhp->zfs_hdl, di->zerr, di->errbuf);
// let's not print an error for the same object twice - once for
// each snapshot
already_logged = B_TRUE;
}

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

if (tobjerr && (di->zerr == EINVAL || 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
*/
Expand Down

0 comments on commit 77d316a

Please sign in to comment.