Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 16 Jul 2011 14:20:10 GMT
From:      Martin Matuska <mm@FreeBSD.org>
To:        freebsd-fs@FreeBSD.org
Subject:   Re: kern/157728: [zfs] zfs (v28) incremental receive may leave behind temporary clones
Message-ID:  <201107161420.p6GEKAL2072415@freefall.freebsd.org>

next in thread | raw e-mail | index | archive | help
The following reply was made to PR kern/157728; it has been noted by GNATS.

From: Martin Matuska <mm@FreeBSD.org>
To: bug-followup@FreeBSD.org, mm@FreeBSD.org
Cc:  
Subject: Re: kern/157728: [zfs] zfs (v28) incremental receive may leave behind
 temporary clones
Date: Sat, 16 Jul 2011 16:13:12 +0200

 I have debugged this a little and have now more information.
 The snapshot is set for deferred destroy but the temporary clone does
 not get deleted, because of an extra hold:
 
 sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c: #3558,
 zfs_ioc_recv():
 end_err = dmu_recv_end(&drc);
 
 sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_send.c: #1621,
 dmu_recv_end():
 return (dmu_recv_existing_end(drc));
 
 sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_send.c: #1581,
 dmu_recv_existing_end():
 (void) dsl_dataset_destroy(drc->drc_real_ds, dmu_recv_tag, B_FALSE);
 
 This dataset does not get destroyed , error EBUSY.
 
 sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_dataset.c: #1158,
 dsl_dataset_destroy():
 
 dstg = dsl_sync_task_group_create(ds->ds_dir->dd_pool);
 dsl_sync_task_create(dstg, dsl_dataset_destroy_check,
     dsl_dataset_destroy_sync, &dsda, tag, 0);
 dsl_sync_task_create(dstg, dsl_dir_destroy_check,
      dsl_dir_destroy_sync, &dummy_ds, FTAG, 0);
 err = dsl_sync_task_group_wait(dstg);
 dsl_sync_task_group_destroy(dstg);
 
 dsl_sync_task_group_wait() calls:
 - dsl_dataset_destroy_check (returns 0)
 - dsl_dir_destroy_check (returns EBUSY, should return 0) <-- error comes
 from here
 
 sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_dir.c: #466,
 dsl_dir_destroy_check():
 if (dmu_buf_refcount(dd->dd_dbuf) > 2)
     return (EBUSY); <--- EBUSY comes from here
 
 sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dbuf.c: #2101
 #pragma weak dmu_buf_refcount = dbuf_refcount
 uint64_t
 dbuf_refcount(dmu_buf_impl_t *db)
 {
         return (refcount_count(&db->db_holds));
 }
 
 If we issue zfs list or zfs get (recursive or on the dataset) the
 db->db_holds for the clone has a value of 3, otherwise a value of 2.
 With 3, destroying the temporary clone fails and deferred destroy of the
 snapshot fails, too.
 Looks like a extra hold is placed on the temporary clone.
 
 -- 
 Martin Matuska
 FreeBSD committer
 http://blog.vx.sk
 



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201107161420.p6GEKAL2072415>