Message ID | 1549054223-12220-16-git-send-email-zub@linux.fjfi.cvut.cz (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | block: sed-opal: support shadow MBR done flag and write | expand |
> + /* first do a discovery0 */ > + error = opal_discovery0_step(dev); > > + for (state = 0; !error && state < n_steps; state++) > + error = execute_step(dev, &steps[state], state); > + > + /* > + * For each OPAL command the first step in steps starts some sort of > + * session. If an error occurred in the initial discovery0 or if an > + * error occurred in the first step (and thus stopping the loop with > + * state == 1) then there was an error before or during the attempt to > + * start a session. Therefore we shouldn't attempt to terminate a > + * session, as one has not yet been created. > + */ > + if (error && state > 1) > + end_opal_session_error(dev); > > return error; The flow here is a little too condensed for my taste. Why not the plain obvoious, if a little longer: error = error = opal_discovery0_step(dev); if (error) return error; for (state = 0; state < n_steps; state++) { error = execute_step(dev, &steps[state], state); if (error) goto out_error; } return 0; out_error: if (state > 1) end_opal_session_error(dev); return error; Otherwise looks good: Reviewed-by: Christoph Hellwig <hch@lst.de>
On Mon, 4 Feb 2019, Christoph Hellwig wrote: >> + /* first do a discovery0 */ >> + error = opal_discovery0_step(dev); >> >> + for (state = 0; !error && state < n_steps; state++) >> + error = execute_step(dev, &steps[state], state); >> + >> + /* >> + * For each OPAL command the first step in steps starts some sort of >> + * session. If an error occurred in the initial discovery0 or if an >> + * error occurred in the first step (and thus stopping the loop with >> + * state == 1) then there was an error before or during the attempt to >> + * start a session. Therefore we shouldn't attempt to terminate a >> + * session, as one has not yet been created. >> + */ >> + if (error && state > 1) >> + end_opal_session_error(dev); >> >> return error; > > The flow here is a little too condensed for my taste. Why not the > plain obvoious, if a little longer: > > error = error = opal_discovery0_step(dev); > if (error) > return error; > > for (state = 0; state < n_steps; state++) { > error = execute_step(dev, &steps[state], state); > if (error) > goto out_error; > } > > return 0; > > out_error: > if (state > 1) > end_opal_session_error(dev); > return error; No problem, I can use this version. But I think there is a minor issue - the same one I hit in my original change, just from the other direction: If the loop succeds for the 0-th element of steps, and then fails for the 1st element, then state equals 1 yet the session has been started, so we should close it. I think the condition in out_error should be if (state > 0). Best regards, David
On Mon, 2019-02-04 at 23:44 +0100, David Kozub wrote: > On Mon, 4 Feb 2019, Christoph Hellwig wrote: > > > > + /* first do a discovery0 */ > > > + error = opal_discovery0_step(dev); > > > > > > + for (state = 0; !error && state < n_steps; state++) > > > + error = execute_step(dev, &steps[state], state); > > > + > > > + /* > > > + * For each OPAL command the first step in steps starts some sort of > > > + * session. If an error occurred in the initial discovery0 or if an > > > + * error occurred in the first step (and thus stopping the loop with > > > + * state == 1) then there was an error before or during the attempt to > > > + * start a session. Therefore we shouldn't attempt to terminate a > > > + * session, as one has not yet been created. > > > + */ > > > + if (error && state > 1) > > > + end_opal_session_error(dev); > > > > > > return error; > > > > The flow here is a little too condensed for my taste. Why not the > > plain obvoious, if a little longer: > > > > error = error = opal_discovery0_step(dev); > > if (error) > > return error; > > > > for (state = 0; state < n_steps; state++) { > > error = execute_step(dev, &steps[state], state); > > if (error) > > goto out_error; > > } > > > > return 0; > > > > out_error: > > if (state > 1) > > end_opal_session_error(dev); > > return error; > > No problem, I can use this version. But I think there is a minor issue - > the same one I hit in my original change, just from the other direction: > > If the loop succeds for the 0-th element of steps, and then fails for the > 1st element, then state equals 1 yet the session has been started, so we > should close it. > > I think the condition in out_error should be if (state > 0). > > Best regards, > David Looks good with Christoph's suggestion (for 14/16) and your state check fix Reviewed-by: Jon Derrick <jonathan.derrick@intel.com>
On Fri, 8 Feb 2019, Derrick, Jonathan wrote: > On Mon, 2019-02-04 at 23:44 +0100, David Kozub wrote: >> On Mon, 4 Feb 2019, Christoph Hellwig wrote: >> >>>> + /* first do a discovery0 */ >>>> + error = opal_discovery0_step(dev); >>>> >>>> + for (state = 0; !error && state < n_steps; state++) >>>> + error = execute_step(dev, &steps[state], state); >>>> + >>>> + /* >>>> + * For each OPAL command the first step in steps starts some sort of >>>> + * session. If an error occurred in the initial discovery0 or if an >>>> + * error occurred in the first step (and thus stopping the loop with >>>> + * state == 1) then there was an error before or during the attempt to >>>> + * start a session. Therefore we shouldn't attempt to terminate a >>>> + * session, as one has not yet been created. >>>> + */ >>>> + if (error && state > 1) >>>> + end_opal_session_error(dev); >>>> >>>> return error; >>> >>> The flow here is a little too condensed for my taste. Why not the >>> plain obvoious, if a little longer: >>> >>> error = error = opal_discovery0_step(dev); >>> if (error) >>> return error; >>> >>> for (state = 0; state < n_steps; state++) { >>> error = execute_step(dev, &steps[state], state); >>> if (error) >>> goto out_error; >>> } >>> >>> return 0; >>> >>> out_error: >>> if (state > 1) >>> end_opal_session_error(dev); >>> return error; >> >> No problem, I can use this version. But I think there is a minor issue - >> the same one I hit in my original change, just from the other direction: >> >> If the loop succeds for the 0-th element of steps, and then fails for the >> 1st element, then state equals 1 yet the session has been started, so we >> should close it. >> >> I think the condition in out_error should be if (state > 0). >> >> Best regards, >> David > Looks good with Christoph's suggestion (for 14/16) and your state check fix > > > Reviewed-by: Jon Derrick <jonathan.derrick@intel.com> Hi Jon, What suggestion by Christoph you have in mind? I don't see any for 14/16. Currently, in my git repo, for this patch, I applied Christoph suggestion for this (15/16) patch + the "state > 0" fix. Is this what you mean? Best regards, David
Hi David, On Sun, 2019-02-10 at 18:46 +0100, David Kozub wrote: > On Fri, 8 Feb 2019, Derrick, Jonathan wrote: > > > On Mon, 2019-02-04 at 23:44 +0100, David Kozub wrote: > > > On Mon, 4 Feb 2019, Christoph Hellwig wrote: > > > > > > > > + /* first do a discovery0 */ > > > > > + error = opal_discovery0_step(dev); > > > > > > > > > > + for (state = 0; !error && state < n_steps; state++) > > > > > + error = execute_step(dev, &steps[state], state); This was implemented in v4's 14/16, rather than this patch (15/16) > > > > > + > > > > > + /* > > > > > + * For each OPAL command the first step in steps starts some sort of > > > > > + * session. If an error occurred in the initial discovery0 or if an > > > > > + * error occurred in the first step (and thus stopping the loop with > > > > > + * state == 1) then there was an error before or during the attempt to > > > > > + * start a session. Therefore we shouldn't attempt to terminate a > > > > > + * session, as one has not yet been created. > > > > > + */ > > > > > + if (error && state > 1) > > > > > + end_opal_session_error(dev); > > > > > > > > > > return error; > > > > > > > > The flow here is a little too condensed for my taste. Why not the > > > > plain obvoious, if a little longer: > > > > > > > > error = error = opal_discovery0_step(dev); > > > > if (error) > > > > return error; > > > > > > > > for (state = 0; state < n_steps; state++) { > > > > error = execute_step(dev, &steps[state], state); > > > > if (error) > > > > goto out_error; > > > > } > > > > > > > > return 0; > > > > > > > > out_error: > > > > if (state > 1) > > > > end_opal_session_error(dev); > > > > return error; > > > > > > No problem, I can use this version. But I think there is a minor issue - > > > the same one I hit in my original change, just from the other direction: > > > > > > If the loop succeds for the 0-th element of steps, and then fails for the > > > 1st element, then state equals 1 yet the session has been started, so we > > > should close it. > > > > > > I think the condition in out_error should be if (state > 0). > > > > > > Best regards, > > > David > > > > Looks good with Christoph's suggestion (for 14/16) and your state check fix > > > > > > Reviewed-by: Jon Derrick <jonathan.derrick@intel.com> > > Hi Jon, > > What suggestion by Christoph you have in mind? I don't see any for 14/16. > Currently, in my git repo, for this patch, I applied Christoph suggestion > for this (15/16) patch + the "state > 0" fix. Is this what you mean? > > Best regards, > David
diff --git a/block/sed-opal.c b/block/sed-opal.c index 21f2789a20cb..3362741dd198 100644 --- a/block/sed-opal.c +++ b/block/sed-opal.c @@ -221,6 +221,7 @@ static const u8 opalmethod[][OPAL_METHOD_LENGTH] = { }; static int end_opal_session_error(struct opal_dev *dev); +static int opal_discovery0_step(struct opal_dev *dev); struct opal_suspend_data { struct opal_lock_unlock unlk; @@ -386,36 +387,42 @@ static void check_geometry(struct opal_dev *dev, const void *data) dev->lowest_lba = geo->lowest_aligned_lba; } +static int execute_step(struct opal_dev *dev, + const struct opal_step *step, size_t stepIndex) +{ + int error = step->fn(dev, step->data); + + if (error) { + pr_debug("Step %zu (%pS) failed with error %d: %s\n", + stepIndex, step->fn, error, + opal_error_to_human(error)); + } + + return error; +} + static int next(struct opal_dev *dev, const struct opal_step *steps, size_t n_steps) { - const struct opal_step *step; size_t state; - int error = 0; + int error; - for (state = 0; !error && state < n_steps; state++) { - step = &steps[state]; - - error = step->fn(dev, step->data); - if (error) { - pr_debug("Step %zu (%pS) failed with error %d: %s\n", - state, step->fn, error, - opal_error_to_human(error)); - - /* For each OPAL command we do a discovery0 then we - * start some sort of session. - * If we haven't passed state 1 then there was an error - * on discovery0 or during the attempt to start a - * session. Therefore we shouldn't attempt to terminate - * a session, as one has not yet been created. - */ - if (state > 1) { - end_opal_session_error(dev); - return error; - } + /* first do a discovery0 */ + error = opal_discovery0_step(dev); - } - } + for (state = 0; !error && state < n_steps; state++) + error = execute_step(dev, &steps[state], state); + + /* + * For each OPAL command the first step in steps starts some sort of + * session. If an error occurred in the initial discovery0 or if an + * error occurred in the first step (and thus stopping the loop with + * state == 1) then there was an error before or during the attempt to + * start a session. Therefore we shouldn't attempt to terminate a + * session, as one has not yet been created. + */ + if (error && state > 1) + end_opal_session_error(dev); return error; } @@ -513,6 +520,14 @@ static int opal_discovery0(struct opal_dev *dev, void *data) return opal_discovery0_end(dev); } +static int opal_discovery0_step(struct opal_dev *dev) +{ + const struct opal_step discovery0_step = { + opal_discovery0, + }; + return execute_step(dev, &discovery0_step, 0); +} + static size_t remaining_size(struct opal_dev *cmd) { return IO_BUFFER_LENGTH - cmd->pos; @@ -1938,10 +1953,10 @@ static int end_opal_session(struct opal_dev *dev, void *data) static int end_opal_session_error(struct opal_dev *dev) { - const struct opal_step error_end_session[] = { - { end_opal_session, } + const struct opal_step error_end_session = { + end_opal_session, }; - return next(dev, error_end_session, ARRAY_SIZE(error_end_session)); + return execute_step(dev, &error_end_session, 0); } static inline void setup_opal_dev(struct opal_dev *dev) @@ -1953,14 +1968,11 @@ static inline void setup_opal_dev(struct opal_dev *dev) static int check_opal_support(struct opal_dev *dev) { - const struct opal_step steps[] = { - { opal_discovery0, } - }; int ret; mutex_lock(&dev->dev_lock); setup_opal_dev(dev); - ret = next(dev, steps, ARRAY_SIZE(steps)); + ret = opal_discovery0_step(dev); dev->supported = !ret; mutex_unlock(&dev->dev_lock); return ret; @@ -2013,7 +2025,6 @@ static int opal_secure_erase_locking_range(struct opal_dev *dev, struct opal_session_info *opal_session) { const struct opal_step erase_steps[] = { - { opal_discovery0, }, { start_auth_opal_session, opal_session }, { get_active_key, &opal_session->opal_key.lr }, { gen_key, }, @@ -2032,7 +2043,6 @@ static int opal_erase_locking_range(struct opal_dev *dev, struct opal_session_info *opal_session) { const struct opal_step erase_steps[] = { - { opal_discovery0, }, { start_auth_opal_session, opal_session }, { erase_locking_range, opal_session }, { end_opal_session, } @@ -2052,7 +2062,6 @@ static int opal_enable_disable_shadow_mbr(struct opal_dev *dev, u8 token = opal_mbr->enable_disable == OPAL_MBR_ENABLE ? OPAL_TRUE : OPAL_FALSE; const struct opal_step mbr_steps[] = { - { opal_discovery0, }, { start_admin1LSP_opal_session, &opal_mbr->key }, { set_mbr_done, &token }, { end_opal_session, }, @@ -2078,7 +2087,6 @@ static int opal_mbr_status(struct opal_dev *dev, struct opal_mbr_data *opal_mbr) u8 token = opal_mbr->enable_disable == OPAL_MBR_ENABLE ? OPAL_TRUE : OPAL_FALSE; const struct opal_step mbr_steps[] = { - { opal_discovery0, }, { start_admin1LSP_opal_session, &opal_mbr->key }, { set_mbr_done, &token }, { end_opal_session, } @@ -2100,7 +2108,6 @@ static int opal_write_shadow_mbr(struct opal_dev *dev, struct opal_shadow_mbr *info) { const struct opal_step mbr_steps[] = { - { opal_discovery0, }, { start_admin1LSP_opal_session, &info->key }, { write_shadow_mbr, info }, { end_opal_session, } @@ -2142,7 +2149,6 @@ static int opal_add_user_to_lr(struct opal_dev *dev, struct opal_lock_unlock *lk_unlk) { const struct opal_step steps[] = { - { opal_discovery0, }, { start_admin1LSP_opal_session, &lk_unlk->session.opal_key }, { add_user_to_lr, lk_unlk }, { end_opal_session, } @@ -2176,7 +2182,6 @@ static int opal_add_user_to_lr(struct opal_dev *dev, static int opal_reverttper(struct opal_dev *dev, struct opal_key *opal) { const struct opal_step revert_steps[] = { - { opal_discovery0, }, { start_SIDASP_opal_session, opal }, { revert_tper, } /* controller will terminate session */ }; @@ -2201,13 +2206,11 @@ static int __opal_lock_unlock(struct opal_dev *dev, struct opal_lock_unlock *lk_unlk) { const struct opal_step unlock_steps[] = { - { opal_discovery0, }, { start_auth_opal_session, &lk_unlk->session }, { lock_unlock_locking_range, lk_unlk }, { end_opal_session, } }; const struct opal_step unlock_sum_steps[] = { - { opal_discovery0, }, { start_auth_opal_session, &lk_unlk->session }, { lock_unlock_locking_range_sum, lk_unlk }, { end_opal_session, } @@ -2224,7 +2227,6 @@ static int __opal_set_mbr_done(struct opal_dev *dev, struct opal_key *key) { u8 mbr_done_tf = 1; const struct opal_step mbrdone_step[] = { - { opal_discovery0, }, { start_admin1LSP_opal_session, key }, { set_mbr_done, &mbr_done_tf }, { end_opal_session, } @@ -2251,7 +2253,6 @@ static int opal_lock_unlock(struct opal_dev *dev, static int opal_take_ownership(struct opal_dev *dev, struct opal_key *opal) { const struct opal_step owner_steps[] = { - { opal_discovery0, }, { start_anybodyASP_opal_session, }, { get_msid_cpin_pin, }, { end_opal_session, }, @@ -2275,7 +2276,6 @@ static int opal_activate_lsp(struct opal_dev *dev, struct opal_lr_act *opal_lr_act) { const struct opal_step active_steps[] = { - { opal_discovery0, }, { start_SIDASP_opal_session, &opal_lr_act->key }, { get_lsp_lifecycle, }, { activate_lsp, opal_lr_act }, @@ -2297,7 +2297,6 @@ static int opal_setup_locking_range(struct opal_dev *dev, struct opal_user_lr_setup *opal_lrs) { const struct opal_step lr_steps[] = { - { opal_discovery0, }, { start_auth_opal_session, &opal_lrs->session }, { setup_locking_range, opal_lrs }, { end_opal_session, } @@ -2314,7 +2313,6 @@ static int opal_setup_locking_range(struct opal_dev *dev, static int opal_set_new_pw(struct opal_dev *dev, struct opal_new_pw *opal_pw) { const struct opal_step pw_steps[] = { - { opal_discovery0, }, { start_auth_opal_session, &opal_pw->session }, { set_new_pw, &opal_pw->new_user_pw }, { end_opal_session, } @@ -2338,7 +2336,6 @@ static int opal_activate_user(struct opal_dev *dev, struct opal_session_info *opal_session) { const struct opal_step act_steps[] = { - { opal_discovery0, }, { start_admin1LSP_opal_session, &opal_session->opal_key }, { internal_activate_user, opal_session }, { end_opal_session, }