diff mbox series

[v4,15/16] block: sed-opal: don't repeat opal_discovery0 in each steps array

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

Commit Message

David Kozub Feb. 1, 2019, 8:50 p.m. UTC
Originally each of the opal functions that call next include
opal_discovery0 in the array of steps. This is superfluous and
can be done always inside next.

Signed-off-by: David Kozub <zub@linux.fjfi.cvut.cz>
Reviewed-by: Scott Bauer <sbauer@plzdonthack.me>
---
 block/sed-opal.c | 89 +++++++++++++++++++++++-------------------------
 1 file changed, 43 insertions(+), 46 deletions(-)

Comments

Christoph Hellwig Feb. 4, 2019, 3:01 p.m. UTC | #1
> +	/* 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>
David Kozub Feb. 4, 2019, 10:44 p.m. UTC | #2
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
Jon Derrick Feb. 8, 2019, 10:59 p.m. UTC | #3
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>
David Kozub Feb. 10, 2019, 5:46 p.m. UTC | #4
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
Jon Derrick Feb. 11, 2019, 5:22 p.m. UTC | #5
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 mbox series

Patch

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, }