[lustre-devel] [PATCH 19/21] lustre: obdclass: avoid races in class_register_type()

James Simmons jsimmons at infradead.org
Mon Feb 11 21:03:43 PST 2019


> If there are two parallel attempts to register the
> same class name, it could get registered twice.
> So re-check after allocation to make sure the name is
> still unique.
> 
> Signed-off-by: NeilBrown <neilb at suse.com>
> ---
>  drivers/staging/lustre/lustre/obdclass/genops.c |   29 +++++++++++++++--------
>  1 file changed, 19 insertions(+), 10 deletions(-)
> 
> diff --git a/drivers/staging/lustre/lustre/obdclass/genops.c b/drivers/staging/lustre/lustre/obdclass/genops.c
> index 382eaf519a79..a174f538dd0d 100644
> --- a/drivers/staging/lustre/lustre/obdclass/genops.c
> +++ b/drivers/staging/lustre/lustre/obdclass/genops.c
> @@ -86,17 +86,23 @@ static void obd_device_free(struct obd_device *obd)
>  	kmem_cache_free(obd_device_cachep, obd);
>  }
>  
> -static struct obd_type *class_search_type(const char *name)
> +static struct obd_type *__class_search_type(const char *name)
>  {
>  	struct obd_type *type;
>  
> -	spin_lock(&obd_types_lock);
>  	list_for_each_entry(type, &obd_types, typ_chain) {

This change is fine but we really don't need typ_chain anymore.
We have a list of obd_types already due to the power of kobjects!!!!

We can do an

static struct obd_type *class_search_type(const char *name)
{
	struct kobject *kobj;
	struct obd_type *type;

	kobj = kset_find_obj(lustre_kset, name);

	return "some_mapping from kobj to type"

Hmm. This kobj is not embedded in struct obd_types. Might need more
surgery to make that work.

> -		if (strcmp(type->typ_name, name) == 0) {
> -			spin_unlock(&obd_types_lock);
> +		if (strcmp(type->typ_name, name) == 0)
>  			return type;
> -		}
>  	}
> +	return NULL;
> +}
> +
> +static struct obd_type *class_search_type(const char *name)
> +{
> +	struct obd_type *type;
> +
> +	spin_lock(&obd_types_lock);
> +	type = __class_search_type(name);
>  	spin_unlock(&obd_types_lock);
>  	return NULL;
>  }
> @@ -214,19 +220,22 @@ int class_register_type(struct obd_ops *dt_ops, struct md_ops *md_ops,
>  	if (ldt) {
>  		type->typ_lu = ldt;
>  		rc = lu_device_type_init(ldt);
> -		if (rc != 0) {
> -			kobject_put(type->typ_kobj);
> +		if (rc != 0)
>  			goto failed;
> -		}
>  	}
>  
> +	INIT_LIST_HEAD(&type->typ_chain);
>  	spin_lock(&obd_types_lock);
> -	list_add(&type->typ_chain, &obd_types);
> +	if (__class_search_type(name) == NULL)
> +		list_add(&type->typ_chain, &obd_types);
>  	spin_unlock(&obd_types_lock);
>  
> -	return 0;
> +	if (!list_empty(&type->typ_chain))
> +		return 0;
>  
>  failed:
> +	if (!IS_ERR_OR_NULL(type->typ_kobj))
> +		kobject_put(type->typ_kobj);
>  	kfree(type->typ_name);
>  	kfree(type->typ_md_ops);
>  	kfree(type->typ_dt_ops);
> 
> 
> 


More information about the lustre-devel mailing list