Commit dbc5a5f9 authored by Jean Tourrilhes's avatar Jean Tourrilhes Committed by David S. Miller

[IRDA]: IAS safety comments

o [FEATURE] Make optional the del of IAS object when del IAS attrib
o [FEATURE] Clarify when/why it's safe to to the above
Signed-off-by: default avatarJean Tourrilhes <jt@hpl.hp.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 3f2812ec
...@@ -81,7 +81,8 @@ struct ias_attrib { ...@@ -81,7 +81,8 @@ struct ias_attrib {
struct ias_object *irias_new_object(char *name, int id); struct ias_object *irias_new_object(char *name, int id);
void irias_insert_object(struct ias_object *obj); void irias_insert_object(struct ias_object *obj);
int irias_delete_object(struct ias_object *obj); int irias_delete_object(struct ias_object *obj);
int irias_delete_attrib(struct ias_object *obj, struct ias_attrib *attrib); int irias_delete_attrib(struct ias_object *obj, struct ias_attrib *attrib,
int cleanobject);
void __irias_delete_object(struct ias_object *obj); void __irias_delete_object(struct ias_object *obj);
void irias_add_integer_attrib(struct ias_object *obj, char *name, int value, void irias_add_integer_attrib(struct ias_object *obj, char *name, int value,
......
...@@ -2005,7 +2005,7 @@ static int irda_setsockopt(struct socket *sock, int level, int optname, ...@@ -2005,7 +2005,7 @@ static int irda_setsockopt(struct socket *sock, int level, int optname,
} }
/* Remove the attribute (and maybe the object) */ /* Remove the attribute (and maybe the object) */
irias_delete_attrib(ias_obj, ias_attr); irias_delete_attrib(ias_obj, ias_attr, 1);
kfree(ias_opt); kfree(ias_opt);
break; break;
case IRLMP_MAX_SDU_SIZE: case IRLMP_MAX_SDU_SIZE:
......
...@@ -159,11 +159,14 @@ int irias_delete_object(struct ias_object *obj) ...@@ -159,11 +159,14 @@ int irias_delete_object(struct ias_object *obj)
ASSERT(obj != NULL, return -1;); ASSERT(obj != NULL, return -1;);
ASSERT(obj->magic == IAS_OBJECT_MAGIC, return -1;); ASSERT(obj->magic == IAS_OBJECT_MAGIC, return -1;);
/* Remove from list */
node = hashbin_remove_this(irias_objects, (irda_queue_t *) obj); node = hashbin_remove_this(irias_objects, (irda_queue_t *) obj);
if (!node) if (!node)
return 0; /* Already removed */ IRDA_DEBUG( 0, "%s(), object already removed!\n",
__FUNCTION__);
__irias_delete_object(node); /* Destroy */
__irias_delete_object(obj);
return 0; return 0;
} }
...@@ -176,7 +179,8 @@ EXPORT_SYMBOL(irias_delete_object); ...@@ -176,7 +179,8 @@ EXPORT_SYMBOL(irias_delete_object);
* the object, remove the object as well. * the object, remove the object as well.
* *
*/ */
int irias_delete_attrib(struct ias_object *obj, struct ias_attrib *attrib) int irias_delete_attrib(struct ias_object *obj, struct ias_attrib *attrib,
int cleanobject)
{ {
struct ias_attrib *node; struct ias_attrib *node;
...@@ -192,9 +196,13 @@ int irias_delete_attrib(struct ias_object *obj, struct ias_attrib *attrib) ...@@ -192,9 +196,13 @@ int irias_delete_attrib(struct ias_object *obj, struct ias_attrib *attrib)
/* Deallocate attribute */ /* Deallocate attribute */
__irias_delete_attrib(node); __irias_delete_attrib(node);
/* Check if object has still some attributes */ /* Check if object has still some attributes, destroy it if none.
* At first glance, this look dangerous, as the kernel reference
* various IAS objects. However, we only use this function on
* user attributes, not kernel attributes, so there is no risk
* of deleting a kernel object this way. Jean II */
node = (struct ias_attrib *) hashbin_get_first(obj->attribs); node = (struct ias_attrib *) hashbin_get_first(obj->attribs);
if (!node) if (cleanobject && !node)
irias_delete_object(obj); irias_delete_object(obj);
return 0; return 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment