Fix NULL pointer dereference when doing concurrent 'send' operations
A NULL pointer will occur when doing a 'zfs send -S' on a dataset that is still being received. The problem is that the new 'send' will rightfully fail to own the datasets (i.e. dsl_dataset_own_force() will fail), but then dmu_send() will still do the dsl_dataset_disown(). Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov> Signed-off-by: Luís Henriques <henrix@camandro.org> Closes #14903 Closes #14890
This commit is contained in:
parent
e085e98d54
commit
928c81f4df
|
@ -2793,6 +2793,7 @@ dmu_send(const char *tosnap, const char *fromsnap, boolean_t embedok,
|
|||
}
|
||||
|
||||
if (err == 0) {
|
||||
owned = B_TRUE;
|
||||
err = zap_lookup(dspp.dp->dp_meta_objset,
|
||||
dspp.to_ds->ds_object,
|
||||
DS_FIELD_RESUME_TOGUID, 8, 1,
|
||||
|
@ -2806,21 +2807,24 @@ dmu_send(const char *tosnap, const char *fromsnap, boolean_t embedok,
|
|||
sizeof (dspp.saved_toname),
|
||||
dspp.saved_toname);
|
||||
}
|
||||
if (err != 0)
|
||||
/* Only disown if there was an error in the lookups */
|
||||
if (owned && (err != 0))
|
||||
dsl_dataset_disown(dspp.to_ds, dsflags, FTAG);
|
||||
|
||||
kmem_strfree(name);
|
||||
} else {
|
||||
err = dsl_dataset_own(dspp.dp, tosnap, dsflags,
|
||||
FTAG, &dspp.to_ds);
|
||||
if (err == 0)
|
||||
owned = B_TRUE;
|
||||
}
|
||||
owned = B_TRUE;
|
||||
} else {
|
||||
err = dsl_dataset_hold_flags(dspp.dp, tosnap, dsflags, FTAG,
|
||||
&dspp.to_ds);
|
||||
}
|
||||
|
||||
if (err != 0) {
|
||||
/* Note: dsl dataset is not owned at this point */
|
||||
dsl_pool_rele(dspp.dp, FTAG);
|
||||
return (err);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue