>  typedef struct sg_request {  /* SG_MAX_QUEUE requests outstanding per file */
> -     struct sg_request *nextrp;      /* NULL -> tail request (slist) */
> +     struct list_head nextrp;        /* list entry */

s/nextrp/entry/

> @@ -2078,16 +2076,13 @@ static long sg_compat_ioctl(struct file *filp, 
> unsigned int cmd_in, unsigned lon
>                       if (k < SG_MAX_QUEUE) {
>                               memset(rp, 0, sizeof (Sg_request));
>                               rp->parentfp = sfp;
> +                             list_add(&rp->nextrp, &sfp->rq_list);

The old code did a tail insertation.  And this whole function should
become a lot simpler with proper lists anyway:

static Sg_request *
sg_add_request(Sg_fd * sfp)
{
        int k;
        unsigned long iflags;
        Sg_request *rp = sfp->req_arr;

        write_lock_irqsave(&sfp->rq_list_lock, iflags);
        if (!list_empty(&sfp->rq_list)) {
                if (!sfp->cmd_q)
                        goto out_unlock;

                for (k = 0; k < SG_MAX_QUEUE; ++k, ++rp) {
                        if (!rp->parentfp)
                                break;
                }
                if (k >= SG_MAX_QUEUE)
                        goto out_unlock;
        }

        memset(rp, 0, sizeof (Sg_request));
        rp->parentfp = sfp;
        rp->header.duration = jiffies_to_msecs(jiffies);
        list_add_tail(&rp->nextrp, &sfp->rq_list);
        write_unlock_irqrestore(&sfp->rq_list_lock, iflags);
        return rp;

out_unlock:
        write_unlock_irqrestore(&sfp->rq_list_lock, iflags);
        return NULL;

> +     if ((!sfp) || (!srp) || (list_empty(&sfp->rq_list)))

No need for all these braces.

> +     if (!list_empty(&srp->nextrp)) {
> +             list_del_init(&srp->nextrp);

I don't think we need the _init as we never check for an empty entry.

>  {
>       struct sg_fd *sfp = container_of(work, struct sg_fd, ew.work);
>       struct sg_device *sdp = sfp->parentdp;
> +     Sg_request *srp, *tmp;
>  
>       /* Cleanup any responses which were never read(). */
> -     while (sfp->headrp)
> -             sg_finish_rem_req(sfp->headrp);
> +     list_for_each_entry_safe(srp, tmp, &sfp->rq_list, nextrp)
> +             sg_finish_rem_req(srp);

What protects us from concurrent removals here?

Either way I'd rather keep the whіle not emptry style even with
proper lists.

Reply via email to