diff -u -p linux/include/net/irda/irias_object.d0.h linux/include/net/irda/irias_object.h --- linux/include/net/irda/irias_object.d0.h Tue Sep 21 11:41:13 2004 +++ linux/include/net/irda/irias_object.h Tue Sep 21 11:50:18 2004 @@ -81,7 +81,8 @@ struct ias_attrib { struct ias_object *irias_new_object(char *name, int id); void irias_insert_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_add_integer_attrib(struct ias_object *obj, char *name, int value, diff -u -p linux/net/irda/irias_object.d0.c linux/net/irda/irias_object.c --- linux/net/irda/irias_object.d0.c Tue Sep 21 11:31:31 2004 +++ linux/net/irda/irias_object.c Tue Sep 21 11:50:11 2004 @@ -159,11 +159,14 @@ int irias_delete_object(struct ias_objec ASSERT(obj != NULL, return -1;); ASSERT(obj->magic == IAS_OBJECT_MAGIC, return -1;); + /* Remove from list */ node = hashbin_remove_this(irias_objects, (irda_queue_t *) obj); 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; } @@ -176,7 +179,8 @@ EXPORT_SYMBOL(irias_delete_object); * 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; @@ -192,9 +196,13 @@ int irias_delete_attrib(struct ias_objec /* Deallocate attribute */ __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); - if (!node) + if (cleanobject && !node) irias_delete_object(obj); return 0; diff -u -p linux/net/irda/af_irda.d0.c linux/net/irda/af_irda.c --- linux/net/irda/af_irda.d0.c Tue Sep 21 12:16:29 2004 +++ linux/net/irda/af_irda.c Tue Sep 21 11:47:06 2004 @@ -2005,7 +2005,7 @@ static int irda_setsockopt(struct socket } /* 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); break; case IRLMP_MAX_SDU_SIZE: