kfusd/kfusd.c
static int fusd_client_open(struct inode *inode, struct file *file)
{
	int retval;
	int device_freed = 0;
	fusd_dev_t *fusd_dev = find_user_device(inode->i_rdev);
	fusd_file_t *fusd_file;
	fusd_msg_t fusd_msg;
	struct fusd_transaction *transaction;

	/* If the device wasn't on our valid list, stop here. */
	if (!fusd_dev_is_valid(fusd_dev))
		return -ENOENT;

	/* fusd_dev->open_in_progress now set */

	/* Lock the fusd device.  Note, when we finally do acquire the lock,
	 * the device might be a zombie (driver disappeared). */
	RAWLOCK_FUSD_DEV(fusd_dev);

	RDEBUG(3, "got an open for /dev/%s (owned by pid %d) from pid %d",
	       NAME(fusd_dev), fusd_dev->pid, current->pid);

	/* Try to add ourselves to the device's file list.  If retval==0, we
	   are now part of the file array.  */
	retval = fusd_dev_add_file(file, fusd_dev, &fusd_file);

	/*
	 * It is now safe to unset the open_in_progress flag.  Either:
	 *   1) We are part of the file array, so dev won't be freed, or;
	 *   2) Something failed, so we are returning a failure now and no
	 *   longer need the device.
	 * Note, open_in_progress must be protected by the global sem, not
	 * the device lock, due to the access of it in fusd_dev_is_valid().
	 */
	down(&fusd_devlist_sem);
	fusd_dev->open_in_progress--;
	up(&fusd_devlist_sem);

	/* If adding ourselves to the device list failed, give up.  Possibly
	 * free the device if it was a zombie and waiting for us to complete
	 * our open. */
	if (retval < 0) {
		if (!maybe_free_fusd_dev(fusd_dev))
			UNLOCK_FUSD_DEV(fusd_dev);
		return retval;
	}

	/* send message to userspace and get retval */
	init_fusd_msg(&fusd_msg);
	fusd_msg.subcmd = FUSD_OPEN;

	/* send message to userspace and get the reply.  Device can't be
	 * locked during that operation. */

	UNLOCK_FUSD_DEV(fusd_dev);
	retval = fusd_fops_call_send(fusd_file, &fusd_msg, &transaction);

	if (retval >= 0)
		retval = fusd_fops_call_wait(fusd_file, NULL, transaction);
	RAWLOCK_FUSD_DEV(fusd_dev);

	/* If the device zombified (while we were waiting to reacquire the
	 * lock)... consider that a failure */
	if (ZOMBIE(fusd_dev))
		retval = -ENOENT;

	/* if retval is negative, throw away state... the file open failed */
	if (retval < 0) {
		RDEBUG(3, "...open failed for /dev/%s (owned by pid %d) from pid %d",
		       NAME(fusd_dev), fusd_dev->pid, current->pid);

		device_freed = free_fusd_file(fusd_dev, fusd_file);
	}

	/* Now unlock the device, if it still exists.  (It may have been
	 * freed if the open failed, and we were the last outstanding
	 * request for it.) */
	if (!device_freed)
		UNLOCK_FUSD_DEV(fusd_dev);

	return retval;
}
/*
 * A client has called open() has been called on a registered device.
 * See comment higher up for detailed notes on this function.
 */
A client has called open() has been called on a registered device.
See comment higher up for detailed notes on this function.
A client has called open () has been called on a registered device . See comment higher up for detailed notes on this function .
static int fusd_client_open(struct inode *inode, struct file *file)
{
	int retval;
	int device_freed = 0;
	fusd_dev_t *fusd_dev = find_user_device(inode->i_rdev);
	fusd_file_t *fusd_file;
	fusd_msg_t fusd_msg;
	struct fusd_transaction *transaction;
	if (!fusd_dev_is_valid(fusd_dev))
		return -ENOENT;
	RAWLOCK_FUSD_DEV(fusd_dev);
	RDEBUG(3, "got an open for /dev/%s (owned by pid %d) from pid %d",
	       NAME(fusd_dev), fusd_dev->pid, current->pid);
	retval = fusd_dev_add_file(file, fusd_dev, &fusd_file);
	down(&fusd_devlist_sem);
	fusd_dev->open_in_progress--;
	up(&fusd_devlist_sem);
	if (retval < 0) {
		if (!maybe_free_fusd_dev(fusd_dev))
			UNLOCK_FUSD_DEV(fusd_dev);
		return retval;
	}
	init_fusd_msg(&fusd_msg);
	fusd_msg.subcmd = FUSD_OPEN;
	UNLOCK_FUSD_DEV(fusd_dev);
	retval = fusd_fops_call_send(fusd_file, &fusd_msg, &transaction);
	if (retval >= 0)
		retval = fusd_fops_call_wait(fusd_file, NULL, transaction);
	RAWLOCK_FUSD_DEV(fusd_dev);
	if (ZOMBIE(fusd_dev))
		retval = -ENOENT;
	if (retval < 0) {
		RDEBUG(3, "...open failed for /dev/%s (owned by pid %d) from pid %d",
		       NAME(fusd_dev), fusd_dev->pid, current->pid);
		device_freed = free_fusd_file(fusd_dev, fusd_file);
	}
	if (!device_freed)
		UNLOCK_FUSD_DEV(fusd_dev);
	return retval;
}
static int fusd_client_open ( struct inode * inode , struct file * file ) { int retval ; int device_freed = 0 ; fusd_dev_t * fusd_dev = find_user_device ( inode -> i_rdev ) ; fusd_file_t * fusd_file ; fusd_msg_t fusd_msg ; struct fusd_transaction * transaction ; if ( ! fusd_dev_is_valid ( fusd_dev ) ) return - ENOENT ; RAWLOCK_FUSD_DEV ( fusd_dev ) ; RDEBUG ( 3 , " " , NAME ( fusd_dev ) , fusd_dev -> pid , current -> pid ) ; retval = fusd_dev_add_file ( file , fusd_dev , & fusd_file ) ; down ( & fusd_devlist_sem ) ; fusd_dev -> open_in_progress -- ; up ( & fusd_devlist_sem ) ; if ( retval < 0 ) { if ( ! maybe_free_fusd_dev ( fusd_dev ) ) UNLOCK_FUSD_DEV ( fusd_dev ) ; return retval ; } init_fusd_msg ( & fusd_msg ) ; fusd_msg . subcmd = FUSD_OPEN ; UNLOCK_FUSD_DEV ( fusd_dev ) ; retval = fusd_fops_call_send ( fusd_file , & fusd_msg , & transaction ) ; if ( retval >= 0 ) retval = fusd_fops_call_wait ( fusd_file , NULL , transaction ) ; RAWLOCK_FUSD_DEV ( fusd_dev ) ; if ( ZOMBIE ( fusd_dev ) ) retval = - ENOENT ; if ( retval < 0 ) { RDEBUG ( 3 , " " , NAME ( fusd_dev ) , fusd_dev -> pid , current -> pid ) ; device_freed = free_fusd_file ( fusd_dev , fusd_file ) ; } if ( ! device_freed ) UNLOCK_FUSD_DEV ( fusd_dev ) ; return retval ; }
A client has called open() has been called on a registered device.
A client has called open () has been called on a registered device .
/* If the device wasn't on our valid list, stop here. */ /* fusd_dev->open_in_progress now set */ /* Lock the fusd device.  Note, when we finally do acquire the lock,
	 * the device might be a zombie (driver disappeared). */ /* Try to add ourselves to the device's file list.  If retval==0, we
	   are now part of the file array.  */ /*
	 * It is now safe to unset the open_in_progress flag.  Either:
	 *   1) We are part of the file array, so dev won't be freed, or;
	 *   2) Something failed, so we are returning a failure now and no
	 *   longer need the device.
	 * Note, open_in_progress must be protected by the global sem, not
	 * the device lock, due to the access of it in fusd_dev_is_valid().
	 */ /* If adding ourselves to the device list failed, give up.  Possibly
	 * free the device if it was a zombie and waiting for us to complete
	 * our open. */ /* send message to userspace and get retval */ /* send message to userspace and get the reply.  Device can't be
	 * locked during that operation. */ /* If the device zombified (while we were waiting to reacquire the
	 * lock)... consider that a failure */ /* if retval is negative, throw away state... the file open failed */ /* Now unlock the device, if it still exists.  (It may have been
	 * freed if the open failed, and we were the last outstanding
	 * request for it.) */