On Wed, 6 May 2020 09:25:54 +0300 Vasily Averin <[email protected]> wrote:

> new_pos should jump through hole of unused ids,
> pos can be updated inside "for" cycle.
> 
> Cc: [email protected]
> Fixes: 89163f93c6f9 ("ipc/util.c: sysvipc_find_ipc() should increase position 
> index")

This:

> --- a/ipc/util.c
> +++ b/ipc/util.c
> @@ -764,21 +764,21 @@ static struct kern_ipc_perm *sysvipc_find_ipc(struct 
> ipc_ids *ids, loff_t pos,
>                       total++;
>       }
>  
> -     *new_pos = pos + 1;
> +     ipc = NULL;
>       if (total >= ids->in_use)
> -             return NULL;
> +             goto out;
>  
>       for (; pos < ipc_mni; pos++) {
>               ipc = idr_find(&ids->ipcs_idr, pos);
>               if (ipc != NULL) {
>                       rcu_read_lock();
>                       ipc_lock_object(ipc);
> -                     return ipc;
> +                     break;
>               }
>       }
> -
> -     /* Out of range - return NULL to terminate iteration */
> -     return NULL;
> +out:
> +     *new_pos = pos + 1;
> +     return ipc;
>  }
>  
>  static void *sysvipc_proc_next(struct seq_file *s, void *it, loff_t *pos)

Messes up Matthew's "ipc: convert ipcs_idr to XArray"
(http://lkml.kernel.org/r/[email protected]).

Here's how I resolved things.  Please check?

static struct kern_ipc_perm *sysvipc_find_ipc(struct ipc_ids *ids, loff_t pos,
                                              loff_t *new_pos)
{
        unsigned long index = pos;
        struct kern_ipc_perm *ipc;

        rcu_read_lock();
        ipc = xa_find(&ids->ipcs, &index, ULONG_MAX, XA_PRESENT);
        if (ipc)
                ipc_lock_object(ipc);
        else
                rcu_read_unlock();
        *new_pos = pos + 1;
        return ipc;
}

Reply via email to