kfusd/kfusd.c
static int maybe_free_fusd_dev(fusd_dev_t *fusd_dev)
{
	fusd_msgC_t *ptr, *next;

	down(&fusd_devlist_sem);

	/* DON'T free the device under conditions listed above */
	if (!fusd_dev->zombie || fusd_dev->num_files || fusd_dev->open_in_progress) {
		up(&fusd_devlist_sem);
		return 0;
	}

	/* OK - bombs away!  This fusd_dev_t is on its way out the door! */

	RDEBUG(8, "freeing state associated with /dev/%s", NAME(fusd_dev));

	/* delete it off the list of valid devices, and unlock */
	list_del(&fusd_dev->devlist);
	up(&fusd_devlist_sem);

	/* free any outgoing messages that the device might have waiting */
	for (ptr = fusd_dev->msg_head; ptr != NULL; ptr = next) {
		next = ptr->next;
		FREE_FUSD_MSGC(ptr);
	}

	/* free the device's dev name */
	if (fusd_dev->dev_name != NULL) {
		KFREE(fusd_dev->dev_name);
		fusd_dev->dev_name = NULL;
	}

	/* free the device's class name */
	if (fusd_dev->class_name != NULL) {
		KFREE(fusd_dev->class_name);
		fusd_dev->class_name = NULL;
	}

	/* free the device's name */
	if (fusd_dev->name != NULL) {
		KFREE(fusd_dev->name);
		fusd_dev->name = NULL;
	}


	/* free the array used to store pointers to fusd_file_t's */
	if (fusd_dev->files != NULL) {
		KFREE(fusd_dev->files);
		fusd_dev->files = NULL;
	}

	/* clear the structure and free it! */
	memset(fusd_dev, 0, sizeof(fusd_dev_t));
	KFREE(fusd_dev);

	/* notify fusd_status readers that there has been a change in the
	 * list of registered devices */
	atomic_inc_and_ret(&last_version);
	wake_up_interruptible(&new_device_wait);

	//MOD_DEC_USE_COUNT;
	return 1;
}
/*
 * DEVICE LOCK MUST BE HELD TO CALL THIS FUNCTION
 * 
 * This function frees a device IF there is nothing left that is
 * referencing it.
 *
 * Specifically, we do not free the device if:
 *   - The driver is still active (i.e. device is not a zombie)
 *   - There are still files with the device open
 *   - There is an open in progress, i.e. a client has verified that
 *   this is a valid device and is getting ready to add itself as an
 *   open file.
 *
 * If the device is safe to free, it is removed from the valid list
 * (in verysafe mode only) and freed.
 *
 * Returns:  1 if the device was freed
 *           0 if the device still exists (and can be unlocked) */
DEVICE LOCK MUST BE HELD TO CALL THIS FUNCTION

This function frees a device IF there is nothing left that is
referencing it.

Specifically, we do not free the device if:
- The driver is still active
- There are still files with the device open
- There is an open in progress, i.e. a client has verified that
this is a valid device and is getting ready to add itself as an
open file.

If the device is safe to free, it is removed from the valid list
(in verysafe mode only) and freed.

1 if the device was freed
0 if the device still exists (and can be unlocked)
DEVICE LOCK MUST BE HELD TO CALL THIS FUNCTION This function frees a device IF there is nothing left that is referencing it . Specifically we do not free the device if : - The driver is still active - There are still files with the device open - There is an open in progress i . e . a client has verified that this is a valid device and is getting ready to add itself as an open file . If the device is safe to free it is removed from the valid list ( in verysafe mode only ) and freed . 1 if the device was freed 0 if the device still exists ( and can be unlocked )
static int maybe_free_fusd_dev(fusd_dev_t *fusd_dev)
{
	fusd_msgC_t *ptr, *next;
	down(&fusd_devlist_sem);
	if (!fusd_dev->zombie || fusd_dev->num_files || fusd_dev->open_in_progress) {
		up(&fusd_devlist_sem);
		return 0;
	}
	RDEBUG(8, "freeing state associated with /dev/%s", NAME(fusd_dev));
	list_del(&fusd_dev->devlist);
	up(&fusd_devlist_sem);
	for (ptr = fusd_dev->msg_head; ptr != NULL; ptr = next) {
		next = ptr->next;
		FREE_FUSD_MSGC(ptr);
	}
	if (fusd_dev->dev_name != NULL) {
		KFREE(fusd_dev->dev_name);
		fusd_dev->dev_name = NULL;
	}
	if (fusd_dev->class_name != NULL) {
		KFREE(fusd_dev->class_name);
		fusd_dev->class_name = NULL;
	}
	if (fusd_dev->name != NULL) {
		KFREE(fusd_dev->name);
		fusd_dev->name = NULL;
	}
	if (fusd_dev->files != NULL) {
		KFREE(fusd_dev->files);
		fusd_dev->files = NULL;
	}
	memset(fusd_dev, 0, sizeof(fusd_dev_t));
	KFREE(fusd_dev);
	atomic_inc_and_ret(&last_version);
	wake_up_interruptible(&new_device_wait);
	return 1;
}
static int maybe_free_fusd_dev ( fusd_dev_t * fusd_dev ) { fusd_msgC_t * ptr , * next ; down ( & fusd_devlist_sem ) ; if ( ! fusd_dev -> zombie || fusd_dev -> num_files || fusd_dev -> open_in_progress ) { up ( & fusd_devlist_sem ) ; return 0 ; } RDEBUG ( 8 , " " , NAME ( fusd_dev ) ) ; list_del ( & fusd_dev -> devlist ) ; up ( & fusd_devlist_sem ) ; for ( ptr = fusd_dev -> msg_head ; ptr != NULL ; ptr = next ) { next = ptr -> next ; FREE_FUSD_MSGC ( ptr ) ; } if ( fusd_dev -> dev_name != NULL ) { KFREE ( fusd_dev -> dev_name ) ; fusd_dev -> dev_name = NULL ; } if ( fusd_dev -> class_name != NULL ) { KFREE ( fusd_dev -> class_name ) ; fusd_dev -> class_name = NULL ; } if ( fusd_dev -> name != NULL ) { KFREE ( fusd_dev -> name ) ; fusd_dev -> name = NULL ; } if ( fusd_dev -> files != NULL ) { KFREE ( fusd_dev -> files ) ; fusd_dev -> files = NULL ; } memset ( fusd_dev , 0 , sizeof ( fusd_dev_t ) ) ; KFREE ( fusd_dev ) ; atomic_inc_and_ret ( & last_version ) ; wake_up_interruptible ( & new_device_wait ) ; return 1 ; }
DEVICE LOCK MUST BE HELD TO CALL THIS FUNCTION
DEVICE LOCK MUST BE HELD TO CALL THIS FUNCTION
/* DON'T free the device under conditions listed above */ /* OK - bombs away!  This fusd_dev_t is on its way out the door! */ /* delete it off the list of valid devices, and unlock */ /* free any outgoing messages that the device might have waiting */ /* free the device's dev name */ /* free the device's class name */ /* free the device's name */ /* free the array used to store pointers to fusd_file_t's */ /* clear the structure and free it! */ /* notify fusd_status readers that there has been a change in the
	 * list of registered devices */ //MOD_DEC_USE_COUNT;