Linux kernel -stable discussions
 help / color / mirror / Atom feed
From: Michal Nazarewicz <mina86@mina86.com>
To: Krzysztof Opasiak <k.opasiak@samsung.com>, balbi@ti.com
Cc: stable@vger.kernel.org, david.fisher1@synopsys.com,
	gregkh@linuxfoundation.org, andrzej.p@samsung.com,
	m.szyprowski@samsung.com, linux-usb@vger.kernel.org,
	Krzysztof Opasiak <k.opasiak@samsung.com>
Subject: Re: [PATCH 5/5] usb: gadget: mass_storage: Send correct number of LUNs to host
Date: Mon, 22 Jun 2015 16:34:19 +0200	[thread overview]
Message-ID: <xa1t7fqvizh0.fsf@mina86.com> (raw)
In-Reply-To: <1434979163-5942-6-git-send-email-k.opasiak@samsung.com>

On Mon, Jun 22 2015, Krzysztof Opasiak wrote:
> GET_MAX_LUN request should return number of realy created LUNs
> not the size of preallocated array.
>
> This patch changes fsg_common_set_nluns() to fsg_common_set_max_luns()
> which now only allocates an empty array for luns and set nluns
> to 0. While LUNS are create we simply count them and store result
> in nluns which is send later to host.
>
> Reported-by: David Fisher <david.fisher1@synopsys.com>
> Signed-off-by: Krzysztof Opasiak <k.opasiak@samsung.com>

At this point I would just change common->luns to be an array rather
than a pointer.  This would remove need for max_luns all together.

> ---
>  drivers/usb/gadget/function/f_mass_storage.c |   69 ++++++++++++++------------
>  drivers/usb/gadget/function/f_mass_storage.h |    2 +-
>  drivers/usb/gadget/legacy/acm_ms.c           |    6 +--
>  drivers/usb/gadget/legacy/mass_storage.c     |    6 +--
>  drivers/usb/gadget/legacy/multi.c            |    6 +--
>  5 files changed, 48 insertions(+), 41 deletions(-)
>
> diff --git a/drivers/usb/gadget/function/f_mass_storage.c b/drivers/usb/gadget/function/f_mass_storage.c
> index 4257238..7e37070 100644
> --- a/drivers/usb/gadget/function/f_mass_storage.c
> +++ b/drivers/usb/gadget/function/f_mass_storage.c
> @@ -280,6 +280,7 @@ struct fsg_common {
>  	u8			cmnd[MAX_COMMAND_SIZE];
>  
>  	unsigned int		nluns;
> +	unsigned int            max_luns;
>  	unsigned int		lun;
>  	struct fsg_lun		**luns;
>  	struct fsg_lun		*curlun;
> @@ -2131,7 +2132,7 @@ static int received_cbw(struct fsg_dev *fsg, struct fsg_buffhd *bh)
>  	}
>  
>  	/* Is the CBW meaningful? */
> -	if (cbw->Lun >= FSG_MAX_LUNS || cbw->Flags & ~US_BULK_FLAG_IN ||
> +	if (cbw->Lun >= common->nluns || cbw->Flags & ~US_BULK_FLAG_IN ||
>  			cbw->Length <= 0 || cbw->Length > MAX_COMMAND_SIZE) {
>  		DBG(fsg, "non-meaningful CBW: lun = %u, flags = 0x%x, "
>  				"cmdlen %u\n",
> @@ -2411,8 +2412,7 @@ static void handle_exception(struct fsg_common *common)
>  	else {
>  		for (i = 0; i < common->nluns; ++i) {
>  			curlun = common->luns[i];
> -			if (!curlun)
> -				continue;
> +			WARN_ON(!curlun);
>  			curlun->prevent_medium_removal = 0;
>  			curlun->sense_data = SS_NO_SENSE;
>  			curlun->unit_attention_data = SS_NO_SENSE;
> @@ -2558,7 +2558,9 @@ static int fsg_main_thread(void *common_)
>  		down_write(&common->filesem);
>  		for (; i--; ++curlun_it) {
>  			struct fsg_lun *curlun = *curlun_it;
> -			if (!curlun || !fsg_lun_is_open(curlun))
> +
> +			WARN_ON(!curlun);
> +			if (!fsg_lun_is_open(curlun))
>  				continue;
>  
>  			fsg_lun_close(curlun);
> @@ -2759,6 +2761,8 @@ static void _fsg_common_remove_luns(struct fsg_common *common, int n)
>  		if (common->luns[i]) {
>  			fsg_common_remove_lun(common->luns[i], common->sysfs);
>  			common->luns[i] = NULL;
> +			WARN_ON(common->nluns == 0);
> +			common->nluns--;
>  		}
>  }
>  
> @@ -2773,20 +2777,22 @@ void fsg_common_free_luns(struct fsg_common *common)
>  	fsg_common_remove_luns(common);
>  	kfree(common->luns);
>  	common->luns = NULL;
> +	common->max_luns = 0;
> +	common->nluns = 0;
>  }
>  EXPORT_SYMBOL_GPL(fsg_common_free_luns);
>  
> -int fsg_common_set_nluns(struct fsg_common *common, int nluns)
> +int fsg_common_set_max_luns(struct fsg_common *common, int max_luns)
>  {
>  	struct fsg_lun **curlun;
>  
>  	/* Find out how many LUNs there should be */
> -	if (nluns < 1 || nluns > FSG_MAX_LUNS) {
> -		pr_err("invalid number of LUNs: %u\n", nluns);
> +	if (max_luns < 1 || max_luns > FSG_MAX_LUNS) {
> +		pr_err("invalid number of LUNs: %u\n", max_luns);
>  		return -EINVAL;
>  	}
>  
> -	curlun = kcalloc(nluns, sizeof(*curlun), GFP_KERNEL);
> +	curlun = kcalloc(max_luns, sizeof(*curlun), GFP_KERNEL);
>  	if (unlikely(!curlun))
>  		return -ENOMEM;
>  
> @@ -2794,13 +2800,15 @@ int fsg_common_set_nluns(struct fsg_common *common, int nluns)
>  		fsg_common_free_luns(common);
>  
>  	common->luns = curlun;
> -	common->nluns = nluns;
> +	common->max_luns = max_luns;
> +	common->nluns = 0;
>  
> -	pr_info("Number of LUNs=%d\n", common->nluns);
> +	pr_info("Number of LUNs=%d, max number of LUNs=%d\n",
> +		common->nluns, common->max_luns);
>  
>  	return 0;
>  }
> -EXPORT_SYMBOL_GPL(fsg_common_set_nluns);
> +EXPORT_SYMBOL_GPL(fsg_common_set_max_luns);
>  
>  void fsg_common_set_ops(struct fsg_common *common,
>  			const struct fsg_operations *ops)
> @@ -2882,7 +2890,7 @@ int fsg_common_create_lun(struct fsg_common *common, struct fsg_lun_config *cfg,
>  	char *pathbuf, *p;
>  	int rc = -ENOMEM;
>  
> -	if (!common->nluns || !common->luns)
> +	if (!common->max_luns || !common->luns)
>  		return -ENODEV;
>  
>  	if (common->luns[id])
> @@ -2924,6 +2932,7 @@ int fsg_common_create_lun(struct fsg_common *common, struct fsg_lun_config *cfg,
>  	}
>  
>  	common->luns[id] = lun;
> +	common->nluns++;
>  
>  	if (cfg->filename) {
>  		rc = fsg_lun_open(lun, cfg->filename);
> @@ -2955,6 +2964,7 @@ error_lun:
>  		device_unregister(&lun->dev);
>  	fsg_lun_close(lun);
>  	common->luns[id] = NULL;
> +	common->nluns--;
>  error_sysfs:
>  	kfree(lun);
>  	return rc;
> @@ -2966,7 +2976,10 @@ int fsg_common_create_luns(struct fsg_common *common, struct fsg_config *cfg)
>  	char buf[8]; /* enough for 100000000 different numbers, decimal */
>  	int i, rc;
>  
> -	for (i = 0; i < common->nluns; ++i) {
> +	if (cfg->nluns > common->max_luns)
> +		return -EINVAL;
> +
> +	for (i = 0; i < cfg->nluns; ++i) {
>  		snprintf(buf, sizeof(buf), "lun%d", i);
>  		rc = fsg_common_create_lun(common, &cfg->luns[i], i, buf, NULL);
>  		if (rc)
> @@ -3031,7 +3044,7 @@ static void fsg_common_release(struct kref *ref)
>  
>  	if (likely(common->luns)) {
>  		struct fsg_lun **lun_it = common->luns;
> -		unsigned i = common->nluns;
> +		unsigned i = common->max_luns;
>  
>  		/* In error recovery common->nluns may be zero. */
>  		for (; i; --i, ++lun_it) {
> @@ -3058,6 +3071,7 @@ static void fsg_common_release(struct kref *ref)
>  static int fsg_bind(struct usb_configuration *c, struct usb_function *f)
>  {
>  	struct fsg_dev		*fsg = fsg_from_func(f);
> +	struct fsg_common	*common = fsg->common;
>  	struct usb_gadget	*gadget = c->cdev->gadget;
>  	int			i;
>  	struct usb_ep		*ep;
> @@ -3070,25 +3084,16 @@ static int fsg_bind(struct usb_configuration *c, struct usb_function *f)
>  	 * or LUNs ids are not contiguous.
>  	 */
>  	if (likely(common->luns)) {
> -		bool found_null = false;
> -
> -		for (i = 0; i < common->nluns; ++i) {
> -			if (!common->luns[i]) {
> -				found_null = true;
> -				continue;
> -			}
> -
> -			if (!found_null) {
> -				continue;
> -			} else {
> -				pr_err("LUN ids should be contiguous.\n");
> -				return -EINVAL;
> -			}
> -		}
> +		for (i = 0; i < common->max_luns; ++i)
> +			if (!common->luns[i])
> +				break;
>  
> -		if (i == 0 || !common->luns[i]) {
> +		if (i == 0) {
>  			pr_err("There should be at least one LUN.\n");
>  			return -EINVAL;
> +		} else if (i < common->nluns) {
> +			pr_err("LUN ids should be contiguous.\n");
> +			return -EINVAL;
>  		}
>  	} else {
>  		return -EINVAL;
> @@ -3388,6 +3393,8 @@ static void fsg_lun_drop(struct config_group *group, struct config_item *item)
>  
>  	fsg_common_remove_lun(lun_opts->lun, fsg_opts->common->sysfs);
>  	fsg_opts->common->luns[lun_opts->lun_id] = NULL;
> +	WARN_ON(fsg_opts->common->nluns == 0);
> +	fsg_opts->common->nluns--;
>  	lun_opts->lun_id = 0;
>  	mutex_unlock(&fsg_opts->lock);
>  
> @@ -3540,7 +3547,7 @@ static struct usb_function_instance *fsg_alloc_inst(void)
>  		rc = PTR_ERR(opts->common);
>  		goto release_opts;
>  	}
> -	rc = fsg_common_set_nluns(opts->common, FSG_MAX_LUNS);
> +	rc = fsg_common_set_max_luns(opts->common, FSG_MAX_LUNS);
>  	if (rc)
>  		goto release_opts;
>  
> diff --git a/drivers/usb/gadget/function/f_mass_storage.h b/drivers/usb/gadget/function/f_mass_storage.h
> index b4866fc..47d366a 100644
> --- a/drivers/usb/gadget/function/f_mass_storage.h
> +++ b/drivers/usb/gadget/function/f_mass_storage.h
> @@ -143,7 +143,7 @@ void fsg_common_remove_luns(struct fsg_common *common);
>  
>  void fsg_common_free_luns(struct fsg_common *common);
>  
> -int fsg_common_set_nluns(struct fsg_common *common, int nluns);
> +int fsg_common_set_max_luns(struct fsg_common *common, int max_luns);
>  
>  void fsg_common_set_ops(struct fsg_common *common,
>  			const struct fsg_operations *ops);
> diff --git a/drivers/usb/gadget/legacy/acm_ms.c b/drivers/usb/gadget/legacy/acm_ms.c
> index 1194b09..1c56196 100644
> --- a/drivers/usb/gadget/legacy/acm_ms.c
> +++ b/drivers/usb/gadget/legacy/acm_ms.c
> @@ -200,9 +200,9 @@ static int acm_ms_bind(struct usb_composite_dev *cdev)
>  	if (status)
>  		goto fail;
>  
> -	status = fsg_common_set_nluns(opts->common, config.nluns);
> +	status = fsg_common_set_max_luns(opts->common, config.nluns);
>  	if (status)
> -		goto fail_set_nluns;
> +		goto fail_set_max_luns;
>  
>  	status = fsg_common_set_cdev(opts->common, cdev, config.can_stall);
>  	if (status)
> @@ -240,7 +240,7 @@ fail_string_ids:
>  	fsg_common_remove_luns(opts->common);
>  fail_set_cdev:
>  	fsg_common_free_luns(opts->common);
> -fail_set_nluns:
> +fail_set_max_luns:
>  	fsg_common_free_buffers(opts->common);
>  fail:
>  	usb_put_function_instance(fi_msg);
> diff --git a/drivers/usb/gadget/legacy/mass_storage.c b/drivers/usb/gadget/legacy/mass_storage.c
> index e7bfb08..7c2074c 100644
> --- a/drivers/usb/gadget/legacy/mass_storage.c
> +++ b/drivers/usb/gadget/legacy/mass_storage.c
> @@ -191,9 +191,9 @@ static int msg_bind(struct usb_composite_dev *cdev)
>  	if (status)
>  		goto fail;
>  
> -	status = fsg_common_set_nluns(opts->common, config.nluns);
> +	status = fsg_common_set_max_luns(opts->common, config.nluns);
>  	if (status)
> -		goto fail_set_nluns;
> +		goto fail_set_max_luns;
>  
>  	fsg_common_set_ops(opts->common, &ops);
>  
> @@ -228,7 +228,7 @@ fail_string_ids:
>  	fsg_common_remove_luns(opts->common);
>  fail_set_cdev:
>  	fsg_common_free_luns(opts->common);
> -fail_set_nluns:
> +fail_set_max_luns:
>  	fsg_common_free_buffers(opts->common);
>  fail:
>  	usb_put_function_instance(fi_msg);
> diff --git a/drivers/usb/gadget/legacy/multi.c b/drivers/usb/gadget/legacy/multi.c
> index b21b51f..df441b2 100644
> --- a/drivers/usb/gadget/legacy/multi.c
> +++ b/drivers/usb/gadget/legacy/multi.c
> @@ -407,9 +407,9 @@ static int __ref multi_bind(struct usb_composite_dev *cdev)
>  	if (status)
>  		goto fail2;
>  
> -	status = fsg_common_set_nluns(fsg_opts->common, config.nluns);
> +	status = fsg_common_set_max_luns(fsg_opts->common, config.nluns);
>  	if (status)
> -		goto fail_set_nluns;
> +		goto fail_set_max_luns;
>  
>  	status = fsg_common_set_cdev(fsg_opts->common, cdev, config.can_stall);
>  	if (status)
> @@ -449,7 +449,7 @@ fail_string_ids:
>  	fsg_common_remove_luns(fsg_opts->common);
>  fail_set_cdev:
>  	fsg_common_free_luns(fsg_opts->common);
> -fail_set_nluns:
> +fail_set_max_luns:
>  	fsg_common_free_buffers(fsg_opts->common);
>  fail2:
>  	usb_put_function_instance(fi_msg);
> -- 
> 1.7.9.5
>

-- 
Best regards,                                         _     _
.o. | Liege of Serenely Enlightened Majesty of      o' \,=./ `o
..o | Computer Science,  Michał “mina86” Nazarewicz    (o o)
ooo +--<mpn@google.com>--<xmpp:mina86@jabber.org>--ooO--(_)--Ooo--
--
To unsubscribe from this list: send the line "unsubscribe stable" in

  reply	other threads:[~2015-06-22 14:34 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-06-22 13:19 [PATCH 0/5] Mass storage fixes and improvements Krzysztof Opasiak
2015-06-22 13:19 ` [PATCH 1/5] usb: gadget: mass_storage: Free buffers if create lun fails Krzysztof Opasiak
2015-06-22 14:27   ` Michal Nazarewicz
2015-06-22 13:19 ` [PATCH 2/5] usb: gadget: mass_storage: Enforce contiguous LUN ids Krzysztof Opasiak
2015-06-22 14:31   ` Michal Nazarewicz
2015-06-22 14:45     ` Alan Stern
2015-06-24 16:01       ` Krzysztof Opasiak
2015-06-22 13:19 ` [PATCH 3/5] usb: gadget: mass_storage: Place EXPORT_SYMBOL_GPL() after func definition Krzysztof Opasiak
2015-06-22 14:31   ` Michal Nazarewicz
2015-06-22 13:19 ` [PATCH 4/5] usb: gadget: storage-common: Set FSG_MAX_LUNS to 16 Krzysztof Opasiak
2015-06-22 14:32   ` Michal Nazarewicz
2015-06-22 13:19 ` [PATCH 5/5] usb: gadget: mass_storage: Send correct number of LUNs to host Krzysztof Opasiak
2015-06-22 14:34   ` Michal Nazarewicz [this message]
2015-06-22 14:42     ` Krzysztof Opasiak

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=xa1t7fqvizh0.fsf@mina86.com \
    --to=mina86@mina86.com \
    --cc=andrzej.p@samsung.com \
    --cc=balbi@ti.com \
    --cc=david.fisher1@synopsys.com \
    --cc=gregkh@linuxfoundation.org \
    --cc=k.opasiak@samsung.com \
    --cc=linux-usb@vger.kernel.org \
    --cc=m.szyprowski@samsung.com \
    --cc=stable@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox