On Mon, Nov 23, 2015 at 6:28 AM, Dan McDonald <dan...@omniti.com> wrote:
> > > On Nov 20, 2015, at 1:30 PM, Matthew Ahrens <mahr...@delphix.com> wrote: > > > > The problem is that we set the refreservation, then receive the first > snapshot which references more than it's allowed to, so it fails. The > alternative would be to set the refreservation at the end, with the > understanding that you might be in violation then. > > Refreservation? Or refquota? Yes, sorry I meant refquota. > The datasets I'm dealing with have refquota set, but not refreservation at > all, and I don't immediately see any internal code that sets > refreservation. The failure of the zfs recv in the bug's reproduction is a > quota check failure: > > 10 -> dsl_dir_tempreserve_impl > 10 -> dsl_dir_space_towrite > 10 <- dsl_dir_space_towrite Returns 0x660000 > 10 -> dsl_dataset_check_quota > 10 <- dsl_dataset_check_quota Returns 0x5b > 10 <- dsl_dir_tempreserve_impl Returns 0x5b > > I'm attaching a DTrace script that I used to catch it in the act (and > produce those lines of output above, among others). Run it before invoking > the "zfs send ... | zfs recv..." portion of the bug's reproduction, and hit > ^C on it after the command fails. I will also provide an example output. > > My first inclination at solving this problem is simple, and probably > missing cases for the newly-pushed resumable-receive case: > > - Check the existence and non-zero-ness of ZFS_PROP_REFQUOTA in the > receive dataset inside dmu_recv_stream(), toward the beginning. > > - Save it off, and set the dataset's refquota to 0/don't-enforce > > - Proceed with receive. > > - If we've saved off a REFQUOTA, restore it on the received dataset, > failing the receive if setting the refquota fails (it shouldn't, but let's > be conservative). > > Am I on crack? I'm concerned that setting REFQUOTA > (dsl_dataset_set_refquota()) uses the name of the dataset and calls > dsl_sync_task, while we already have a dsl_dataset pointer in > dmu_recv_stream(). > That seems like it would work and would be pretty conservative. It wouldn't help if the filesystem already existed and had the refquota set. It could also leave you in a strange state, where you have a filesystem that references more than what the send stream says is the refquota, and the refquota is not set (if it fails, or if you crash right before it fails?). Note that there is no command to resume a "zfs send -R/-p/-I", so you wouldn't break resuming. You can resume individual streams, or you can redo the "zfs send -R", which will send the properties again. I wonder if a better semantic would be: if you specify a new flag (--allow-overquota?) to zfs receive, we set the quota/refquota as normal, but we disable enforcement of it while doing the receives. When the receive completes, enforcement would be re-enabled, and you might be over quota/refquota. (The disablement would not be stored on disk, so if you crash the quota would again be enforced.) --matt
_______________________________________________ developer mailing list developer@open-zfs.org http://lists.open-zfs.org/mailman/listinfo/developer