Re: [PATCH] Add O_ASYNC support to FUSE

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



> This adds asynchronous notification to FUSE - a FUSE server can
> request O_ASYNC on a /dev/fuse file descriptor and receive SIGIO
> when there is input available.
> 
> One subtlety - fuse_dev_fasync, which is called when O_ASYNC is
> requested, does no locking, unlike the other methods.  I think it's
> unnecessary, as the fuse_conn.fasync list is manipulated only by
> fasync_helper and kill_fasync, which provide their own locking.

Yes, but you need to use fuse_get_conn() and check the result (see
fuse_dev_poll()).

> It would also be wrong to use fuse_lock, as it's a spin lock and
> fasync_helper can sleep.  My one concern with this is the fuse_conn
> going away underneath fuse_dev_fasync - sys_fcntl takes a reference
> on the file struct, so this seems not to be a problem.

Yes, file holds a reference to fuse_conn.

> One possible bug - there is a wakeup in inode.c:fuse_put_super, but
> sticking a kill_fasync there causes BUGs because the /dev/fuse
> file struct seems to have gone away.

I don't see how that could happen.  fuse_dev_release() removes the
file from fc->fasync, and fasync_helper() and kill_fasync() are
protected with fasync_lock against racing with each other.

Although it may be possible that kill_fasync() races with the final
fput(), but as I see kill_fasync() only uses the file->f_owner field
which should still be valid before and during file->release().

Which BUG is triggered?

> So, this may be lacking when a FUSE mount is unmounted from
> underneath the server (is that possible, or must the server be
> killed in order to do the umount?).

Yes it's possible, it is how a normal unmount happens:

  - umount() called on the filesystem, filesystem unmounted
  - read on /dev/fuse returns -ENODEV
  - userspace filesystem exits gracefuly

> @@ -894,6 +895,7 @@ void fuse_abort_conn(struct fuse_conn *f
>  		end_requests(fc, &fc->pending);
>  		end_requests(fc, &fc->processing);
>  		wake_up_all(&fc->waitq);
> +		kill_fasync(&fc->fasync, SIGIO, POLLIN);

This should be POLL_IN too, no?

> +static int fuse_dev_fasync(int fd, struct file *file, int on)
> +{
> +	struct fuse_conn *fc;
> +
> +	/* No locking - fasync_helper does its own locking */
> +	fc = file->private_data;
> +	return(fasync_helper(fd, file, on, &fc->fasync));

I like this style better:

	return fasync_helper(fd, file, on, &fc->fasync);

Thanks,
Miklos
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[Index of Archives]     [Kernel Newbies]     [Netfilter]     [Bugtraq]     [Photo]     [Stuff]     [Gimp]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Video 4 Linux]     [Linux for the blind]     [Linux Resources]
  Powered by Linux