Skip to content

Commit

Permalink
unmap: merge allocation/free code
Browse files Browse the repository at this point in the history
Merge unmap_state allocation/free code.

This fixes a tiny possibly leak where handle_unmap_in_writesame
did not pthread_mutex_destroy in the error path.

Signed-off-by: Mike Christie <[email protected]>
  • Loading branch information
Mike Christie committed Aug 15, 2017
1 parent 5b55720 commit 33e1107
Showing 1 changed file with 51 additions and 49 deletions.
100 changes: 51 additions & 49 deletions tcmur_cmd_handler.c
Original file line number Diff line number Diff line change
@@ -176,6 +176,50 @@ struct unmap_descriptor {
struct tcmulib_cmd *origcmd;
};

static struct unmap_state *unmap_state_alloc(struct tcmu_device *dev,
struct tcmulib_cmd *cmd,
int *return_err)
{
uint8_t *sense = cmd->sense_buf;
struct unmap_state *state;
int ret;

*return_err = 0;

state = calloc(1, sizeof(*state));
if (!state) {
tcmu_dev_err(dev, "Failed to calloc memory for unmap_state!\n");
*return_err = tcmu_set_sense_data(sense, HARDWARE_ERROR,
ASC_INTERNAL_TARGET_FAILURE,
NULL);
return NULL;
}

ret = pthread_mutex_init(&state->lock, NULL);
if (ret == -1) {
tcmu_dev_err(dev, "Failed to init spin lock in state!\n");
*return_err = tcmu_set_sense_data(sense, HARDWARE_ERROR,
ASC_INTERNAL_TARGET_FAILURE,
NULL);
goto out_free_state;
}

state->refcount = 0;
state->error = false;
cmd->cmdstate = state;
return state;

out_free_state:
free(state);
return NULL;
}

static void unmap_state_free(struct unmap_state *state)
{
pthread_mutex_destroy(&state->lock);
free(state);
}

static void handle_unmap_cbk(struct tcmu_device *dev, struct tcmulib_cmd *ucmd,
int ret)
{
@@ -208,8 +252,7 @@ static void handle_unmap_cbk(struct tcmu_device *dev, struct tcmulib_cmd *ucmd,
error = state->error;
pthread_mutex_unlock(&state->lock);

pthread_mutex_destroy(&state->lock);
free(state);
unmap_state_free(state);

aio_command_finish(dev, origcmd, error ? status : ret);
}
@@ -381,8 +424,7 @@ static int handle_unmap_internal(struct tcmu_device *dev, struct tcmulib_cmd *or
* No unmaps have been dispatched, so return the error and free
* resources now.
*/
pthread_mutex_destroy(&state->lock);
free(state);
unmap_state_free(state);

return ret;
}
@@ -495,35 +537,15 @@ static int handle_unmap(struct tcmu_device *dev, struct tcmulib_cmd *origcmd)
goto out_free_par;
}

state = calloc(1, sizeof(*state));
if (!state) {
tcmu_dev_err(dev, "Failed to calloc memory for unmap_state!\n");
ret = tcmu_set_sense_data(sense, HARDWARE_ERROR,
ASC_INTERNAL_TARGET_FAILURE,
NULL);
state = unmap_state_alloc(dev, origcmd, &ret);
if (!state)
goto out_free_par;
}

ret = pthread_mutex_init(&state->lock, NULL);
if (ret == -1) {
tcmu_dev_err(dev, "Failed to init spin lock in state!\n");
ret = tcmu_set_sense_data(sense, HARDWARE_ERROR,
ASC_INTERNAL_TARGET_FAILURE,
NULL);
goto out_free_state;
}

state->refcount = 0;
state->error = false;
origcmd->cmdstate = state;

ret = handle_unmap_internal(dev, origcmd, bddl, par);

free(par);
return ret;

out_free_state:
free(state);
out_free_par:
free(par);
return ret;
@@ -668,7 +690,6 @@ static int handle_writesame_check(struct tcmu_device *dev, struct tcmulib_cmd *c
static int handle_unmap_in_writesame(struct tcmu_device *dev,
struct tcmulib_cmd *cmd)
{
uint8_t *sense = cmd->sense_buf;
uint8_t *cdb = cmd->cdb;
uint64_t lba = tcmu_get_lba(cdb);
uint64_t nlbas = tcmu_get_xfer_length(cdb);
@@ -678,28 +699,9 @@ static int handle_unmap_in_writesame(struct tcmu_device *dev,

tcmu_dev_dbg(dev, "Do UNMAP in WRITE_SAME cmd!\n");

state = calloc(1, sizeof(*state));
if (!state) {
tcmu_dev_err(dev, "Failed to calloc memory for unmap_state!\n");
ret = tcmu_set_sense_data(sense, HARDWARE_ERROR,
ASC_INTERNAL_TARGET_FAILURE,
NULL);
return ret;
}

ret = pthread_mutex_init(&state->lock, NULL);
if (ret == -1) {
tcmu_dev_err(dev, "Failed to init spin lock in state!\n");
ret = tcmu_set_sense_data(sense, HARDWARE_ERROR,
ASC_INTERNAL_TARGET_FAILURE,
NULL);
free(state);
state = unmap_state_alloc(dev, cmd, &ret);
if (!state)
return ret;
}

state->refcount = 0;
state->error = false;
cmd->cmdstate = state;

pthread_mutex_lock(&state->lock);
ret = align_and_split_unmap(dev, cmd, lba, nlbas);
@@ -711,7 +713,7 @@ static int handle_unmap_in_writesame(struct tcmu_device *dev,

/* Or will let the cbk to do the release */
if (!refcount)
free(state);
unmap_state_free(state);

return ret;
}

0 comments on commit 33e1107

Please sign in to comment.