blob: do not decrement ref on close until it is done

This ensures we do not end up with a racing close v.
delete.  If we decrement the ref up front, we could
start the close process (which may include persisting
metadata) and then also allow a delete operation to
start.  It is safer to wait until the close operation
is done before decrementing the ref count, because then
it will eliminate this race condition (the delete op
would immediately fail).

Signed-off-by: Jim Harris <james.r.harris@intel.com>
Change-Id: Iad7fd8320d2c9b56f3c4fce054bcb6271e19ad38

Reviewed-on: https://review.gerrithub.io/391493
Reviewed-by: Ben Walker <benjamin.walker@intel.com>
Tested-by: SPDK Automated Test System <sys_sgsw@intel.com>
Reviewed-by: Daniel Verkamp <daniel.verkamp@intel.com>
This commit is contained in:
Jim Harris 2017-12-12 14:54:14 -07:00
parent 751691d24c
commit feba13bbba

View File

@ -2859,17 +2859,20 @@ _spdk_blob_close_cpl(spdk_bs_sequence_t *seq, void *cb_arg, int bserrno)
{
struct spdk_blob_data *blob = cb_arg;
if (blob->open_ref == 0) {
/*
* Blobs with active.num_pages == 0 are deleted blobs.
* these blobs are removed from the blob_store list
* when the deletion process starts - so don't try to
* remove them again.
*/
if (blob->active.num_pages > 0) {
TAILQ_REMOVE(&blob->bs->blobs, blob, link);
if (bserrno == 0) {
blob->open_ref--;
if (blob->open_ref == 0) {
/*
* Blobs with active.num_pages == 0 are deleted blobs.
* these blobs are removed from the blob_store list
* when the deletion process starts - so don't try to
* remove them again.
*/
if (blob->active.num_pages > 0) {
TAILQ_REMOVE(&blob->bs->blobs, blob, link);
}
_spdk_blob_free(blob);
}
_spdk_blob_free(blob);
}
spdk_bs_sequence_finish(seq, bserrno);
@ -2895,8 +2898,6 @@ void spdk_blob_close(struct spdk_blob *b, spdk_blob_op_complete cb_fn, void *cb_
return;
}
blob->open_ref--;
cpl.type = SPDK_BS_CPL_TYPE_BLOB_BASIC;
cpl.u.blob_basic.cb_fn = cb_fn;
cpl.u.blob_basic.cb_arg = cb_arg;