All of lore.kernel.org
 help / color / mirror / Atom feed
From: Hannes Reinecke <hare@suse.de>
To: "Ewan D. Milne" <emilne@redhat.com>, linux-scsi@vger.kernel.org
Subject: Re: [PATCH RFC 2/2] scsi_proc: Change /proc/scsi/scsi to use bus device iterator
Date: Fri, 18 Dec 2015 10:23:26 +0100	[thread overview]
Message-ID: <5673D08E.3040202@suse.de> (raw)
In-Reply-To: <1449583704-32400-3-git-send-email-emilne@redhat.com>

On 12/08/2015 03:08 PM, Ewan D. Milne wrote:
> From: "Ewan D. Milne" <emilne@redhat.com>
>
> This prevents crashing due to accessing a removed element on the list,
> the iterator will now hold the correct reference.  It was not sufficient
> to rely on the klist's reference on the containing device object.
>
>  From a patch originally developed by David Jeffery <djeffery@redhat.com>
>
> Signed-off-by: Ewan D. Milne <emilne@redhat.com>
> ---
>   drivers/scsi/scsi_proc.c | 49 ++++++++++++++++++++++++++++--------------------
>   1 file changed, 29 insertions(+), 20 deletions(-)
>
> diff --git a/drivers/scsi/scsi_proc.c b/drivers/scsi/scsi_proc.c
> index 251598e..6c1b79d 100644
> --- a/drivers/scsi/scsi_proc.c
> +++ b/drivers/scsi/scsi_proc.c
> @@ -40,6 +40,11 @@
>   /* 4K page size, but our output routines, use some slack for overruns */
>   #define PROC_BLOCK_SIZE (3*1024)
>
> +struct scsi_proc_state {
> +	struct klist_iter iter;
> +	int pos;
> +};
> +
>   static struct proc_dir_entry *proc_scsi;
>
>   /* Protect sht->present and sht->proc_dir */
> @@ -370,47 +375,50 @@ static ssize_t proc_scsi_write(struct file *file, const char __user *buf,
>   	return err;
>   }
>
> -static int always_match(struct device *dev, void *data)
> -{
> -	return 1;
> -}
> -
> -static inline struct device *next_scsi_device(struct device *start)
> -{
> -	struct device *next = bus_find_device(&scsi_bus_type, start, NULL,
> -					      always_match);
> -	put_device(start);
> -	return next;
> -}
> -
>   static void *scsi_seq_start(struct seq_file *sfile, loff_t *pos)
>   {
> +	struct scsi_proc_state *state = sfile->private;
>   	struct device *dev = NULL;
>   	loff_t n = *pos;
> +	int err;
> +
> +	err = bus_device_iter_init(&state->iter, &scsi_bus_type);
> +	if (err < 0)
> +		return ERR_PTR(err);
>
> -	while ((dev = next_scsi_device(dev))) {
> +	while ((dev = bus_device_iter_next(&state->iter))) {
>   		if (!n--)
>   			break;
> -		sfile->private++;
> +		put_device(dev);
> +		state->pos++;
>   	}
>   	return dev;
>   }
>
>   static void *scsi_seq_next(struct seq_file *sfile, void *v, loff_t *pos)
>   {
> +	struct scsi_proc_state *state = sfile->private;
> +
>   	(*pos)++;
> -	sfile->private++;
> -	return next_scsi_device(v);
> +	put_device(v);
> +	state->pos++;
> +
> +	return bus_device_iter_next(&state->iter);
>   }
>
>   static void scsi_seq_stop(struct seq_file *sfile, void *v)
>   {
> +	struct scsi_proc_state *state = sfile->private;
> +
>   	put_device(v);
> +	bus_device_iter_exit(&state->iter);
>   }
>
>   static int scsi_seq_show(struct seq_file *sfile, void *dev)
>   {
> -	if (!sfile->private)
> +	struct scsi_proc_state *state = sfile->private;
> +
> +	if (!state->pos)
>   		seq_puts(sfile, "Attached devices:\n");
>
>   	return proc_print_scsidevice(dev, sfile);
> @@ -436,7 +444,8 @@ static int proc_scsi_open(struct inode *inode, struct file *file)
>   	 * We don't really need this for the write case but it doesn't
>   	 * harm either.
>   	 */
> -	return seq_open(file, &scsi_seq_ops);
> +	return seq_open_private(file, &scsi_seq_ops,
> +				sizeof(struct scsi_proc_state));
>   }
>
>   static const struct file_operations proc_scsi_operations = {
> @@ -445,7 +454,7 @@ static const struct file_operations proc_scsi_operations = {
>   	.read		= seq_read,
>   	.write		= proc_scsi_write,
>   	.llseek		= seq_lseek,
> -	.release	= seq_release,
> +	.release	= seq_release_private,
>   };
>
>   /**
>
Reviewed-by: Hannes Reinecke <hare@suse.com>

Cheers,

Hannes
-- 
Dr. Hannes Reinecke		               zSeries & Storage
hare@suse.de			               +49 911 74053 688
SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: F. Imendörffer, J. Smithard, J. Guild, D. Upmanyu, G. Norton
HRB 21284 (AG Nürnberg)
--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

  reply	other threads:[~2015-12-18  9:23 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-12-08 14:08 [PATCH RFC 0/2] avoid crashing when reading /proc/scsi/scsi and simultaneously removing devices Ewan D. Milne
2015-12-08 14:08 ` [PATCH RFC 1/2] drivers/base: add bus_device_iter_init, bus_device_iter_next, bus_device_iter_exit Ewan D. Milne
2015-12-18  9:22   ` Hannes Reinecke
2015-12-08 14:08 ` [PATCH RFC 2/2] scsi_proc: Change /proc/scsi/scsi to use bus device iterator Ewan D. Milne
2015-12-18  9:23   ` Hannes Reinecke [this message]
2015-12-18  9:22 ` [PATCH RFC 0/2] avoid crashing when reading /proc/scsi/scsi and simultaneously removing devices Hannes Reinecke
2016-01-05  1:58 ` Martin K. Petersen

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=5673D08E.3040202@suse.de \
    --to=hare@suse.de \
    --cc=emilne@redhat.com \
    --cc=linux-scsi@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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.