mirror of
				https://git.proxmox.com/git/mirror_zfs.git
				synced 2025-10-26 18:05:04 +03:00 
			
		
		
		
	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
							
								
									439b4b134d
								
							
						
					
					
						commit
						c64c17328b
					
				| @ -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; | ||||
| 
 | ||||
| @ -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 | ||||
| 	 * 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); | ||||
| 		di->zerr = 0; | ||||
| 		return (0); | ||||
| 	} | ||||
| @ -344,12 +358,11 @@ describe_free(FILE *fp, differ_info_t *di, uint64_t object, char *namebuf, | ||||
| { | ||||
| 	struct zfs_stat sb; | ||||
| 
 | ||||
| 	if (get_stats_for_obj(di, di->fromsnap, object, namebuf, | ||||
| 	    maxlen, &sb) != 0) { | ||||
| 		return (-1); | ||||
| 	} | ||||
| 	(void) get_stats_for_obj(di, di->fromsnap, object, namebuf, | ||||
| 	    maxlen, &sb); | ||||
| 
 | ||||
| 	/* 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; | ||||
| 		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, | ||||
| 			    MAXPATHLEN); | ||||
| 			if (err) | ||||
| 				break; | ||||
| 		} else if (errno == ESRCH) { | ||||
| 			break; | ||||
| 		} else { | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 Rich Ercolani
						Rich Ercolani