Let zfs diff be more permissive
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. Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov> Reviewed-by: Tony Nguyen <tony.nguyen@delphix.com> Signed-off-by: Rich Ercolani <rincebrain@gmail.com> Closes #12072
This commit is contained in:
parent
8dddb25d2c
commit
50353dbd05
|
@ -243,6 +243,7 @@ write_inuse_diffs_one(FILE *fp, differ_info_t *di, uint64_t dobj)
|
||||||
struct zfs_stat fsb, tsb;
|
struct zfs_stat fsb, tsb;
|
||||||
mode_t fmode, tmode;
|
mode_t fmode, tmode;
|
||||||
char fobjname[MAXPATHLEN], tobjname[MAXPATHLEN];
|
char fobjname[MAXPATHLEN], tobjname[MAXPATHLEN];
|
||||||
|
boolean_t already_logged = B_FALSE;
|
||||||
int fobjerr, tobjerr;
|
int fobjerr, tobjerr;
|
||||||
int change;
|
int change;
|
||||||
|
|
||||||
|
@ -254,22 +255,35 @@ 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
|
* we get ENOENT, then the object just didn't exist in that
|
||||||
* snapshot. If we get ENOTSUP, then we tried to get
|
* snapshot. If we get ENOTSUP, then we tried to get
|
||||||
* info on a non-ZPL object, which we don't care about anyway.
|
* 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,
|
fobjerr = get_stats_for_obj(di, di->fromsnap, dobj, fobjname,
|
||||||
MAXPATHLEN, &fsb);
|
MAXPATHLEN, &fsb);
|
||||||
if (fobjerr && di->zerr != ENOENT && di->zerr != ENOTSUP)
|
if (fobjerr && di->zerr != ENOTSUP && di->zerr != ENOENT) {
|
||||||
return (-1);
|
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,
|
tobjerr = get_stats_for_obj(di, di->tosnap, dobj, tobjname,
|
||||||
MAXPATHLEN, &tsb);
|
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
|
* Unallocated object sharing the same meta dnode block
|
||||||
*/
|
*/
|
||||||
if (fobjerr && tobjerr) {
|
if (fobjerr && tobjerr) {
|
||||||
ASSERT(di->zerr == ENOENT || di->zerr == ENOTSUP);
|
|
||||||
di->zerr = 0;
|
di->zerr = 0;
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
@ -344,12 +358,11 @@ describe_free(FILE *fp, differ_info_t *di, uint64_t object, char *namebuf,
|
||||||
{
|
{
|
||||||
struct zfs_stat sb;
|
struct zfs_stat sb;
|
||||||
|
|
||||||
if (get_stats_for_obj(di, di->fromsnap, object, namebuf,
|
(void) get_stats_for_obj(di, di->fromsnap, object, namebuf,
|
||||||
maxlen, &sb) != 0) {
|
maxlen, &sb);
|
||||||
return (-1);
|
|
||||||
}
|
|
||||||
/* Don't print if in the delete queue on from side */
|
/* Don't print if in the delete queue on from side */
|
||||||
if (di->zerr == ESTALE) {
|
if (di->zerr == ESTALE || di->zerr == ENOENT) {
|
||||||
di->zerr = 0;
|
di->zerr = 0;
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
@ -384,8 +397,6 @@ write_free_diffs(FILE *fp, differ_info_t *di, dmu_diff_record_t *dr)
|
||||||
}
|
}
|
||||||
err = describe_free(fp, di, zc.zc_obj, fobjname,
|
err = describe_free(fp, di, zc.zc_obj, fobjname,
|
||||||
MAXPATHLEN);
|
MAXPATHLEN);
|
||||||
if (err)
|
|
||||||
break;
|
|
||||||
} else if (errno == ESRCH) {
|
} else if (errno == ESRCH) {
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
|
|
Loading…
Reference in New Issue