On Mon, Dec 02 2013, Andrzej Pietrasiewicz wrote:
> -     ffs_dev_lock();
>       for (i = 0; i < func_num; i++) {
> -             ffs_tab[i] = ffs_alloc_dev();
> -             if (IS_ERR(ffs_tab[i])) {
> -                     ret = PTR_ERR(ffs_tab[i]);
> -                     --i;
> +             /*
> +              * usb_get_function_instance() takes ffs_lock,
> +              * so we must not take it here...
> +              */
> +             fi_ffs[i] = usb_get_function_instance("ffs");

Technically, usb_get_function_instance doesn't take ffs_lock, but
perhaps some function called from it does.  Could you explain in the
comment what *actually* takes the lock and how it is called from
usb_get_function_instance?

> +             if (IS_ERR(fi_ffs[i])) {
> +                     ret = PTR_ERR(fi_ffs[i]);
>                       goto no_dev;
>               }
> -             ret = ffs_single_dev(ffs_tab[i], gfs_single_func);
> +             /*
> +              * ... but we need it below
> +              *
> +              * What happens if some thread of execution kicks in between
> +              * usb_get_function_instance() above and ffs_dev_lock() below
> +              * and (after taking the lock) accesses the devices list?
> +              *
> +              * The other thread can be a configfs-based gadget only,
> +              * since we cannot load this (g_ffs) module twice.
> +              *
> +              * For the device to be used it needs so be acquired first.
> +              * ffs_acquire_dev() finds the device by name and it will get
> +              * some string to match against as a device name given for
> +              * mount by the user. So devices which don't have their name set
> +              * will never be matched, so our device just created above will
> +              * not be abused.
> +              *
> +              * There is an exception to the matching rule: the g_ffs, if
> +              * no functions= parameter is given on module load, will assume
> +              * there is only one "device" and will accept any "device" name
> +              * given for mount. If this is the case here, then the other
> +              * thread potentially creates another device and the device list
> +              * consists no more of a single device. Then setting the device
> +              * created above as "single" will not succeed and g_ffs will
> +              * refuse loading with EBUSY.
> +              */
> +             ffs_dev_lock();

I'm wondering whether it would be feasible to change
usb_get_function_instance's path so that ffs_lock is not taken.  This
would save us this long comment… ;)

> +             opts = to_f_fs_opts(fi_ffs[i]);
> +             ret = ffs_single_dev(opts->dev, gfs_single_func);
>               if (ret)
> -                     goto no_dev;
> +                     goto no_dev_unlock;
>               if (!gfs_single_func) {
> -                     ret = ffs_name_dev(ffs_tab[i], func_names[i]);
> +                     ret = ffs_name_dev(opts->dev, func_names[i]);
>                       if (ret)
> -                             goto no_dev;
> +                             goto no_dev_unlock;
>               }
> -             ffs_tab[i]->ffs_ready_callback = functionfs_ready_callback;
> -             ffs_tab[i]->ffs_closed_callback = functionfs_closed_callback;
> +             opts->dev->ffs_ready_callback = functionfs_ready_callback;
> +             opts->dev->ffs_closed_callback = functionfs_closed_callback;
> +             opts->dev->ffs_acquire_dev_callback = functionfs_acquire_dev;
> +             opts->dev->ffs_release_dev_callback = functionfs_release_dev;
> +             opts->no_configfs = true;
> +             ffs_dev_unlock();
>       }
> -     ffs_dev_unlock();

-- 
Best regards,                                         _     _
.o. | Liege of Serenely Enlightened Majesty of      o' \,=./ `o
..o | Computer Science,  Michał “mina86” Nazarewicz    (o o)
ooo +--<m...@google.com>--<xmpp:min...@jabber.org>--ooO--(_)--Ooo--

Attachment: signature.asc
Description: PGP signature

Reply via email to