Commit daa75776 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull fuse fixes from Miklos Szeredi:

 - Fix two bugs in the new passthrough mode

 - Fix a statx bug introduced in v6.6

 - Fix code documentation

* tag 'fuse-fixes-6.9-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/fuse:
  cuse: add kernel-doc comments to cuse_process_init_reply()
  fuse: fix leaked ENOSYS error on first statx call
  fuse: fix parallel dio write on file open in passthrough mode
  fuse: fix wrong ff->iomode state changes from parallel dio write
parents 25ec51ec 09492cb4
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -310,6 +310,10 @@ struct cuse_init_args {
/**
 * cuse_process_init_reply - finish initializing CUSE channel
 *
 * @fm: The fuse mount information containing the CUSE connection.
 * @args: The arguments passed to the init reply.
 * @error: The error code signifying if any error occurred during the process.
 *
 * This function creates the character device and sets up all the
 * required data structures for it.  Please read the comment at the
 * top of this file for high level overview.
+1 −0
Original line number Diff line number Diff line
@@ -1321,6 +1321,7 @@ static int fuse_update_get_attr(struct inode *inode, struct file *file,
			err = fuse_do_statx(inode, file, stat);
			if (err == -ENOSYS) {
				fc->no_statx = 1;
				err = 0;
				goto retry;
			}
		} else {
+7 −5
Original line number Diff line number Diff line
@@ -1362,7 +1362,7 @@ static void fuse_dio_lock(struct kiocb *iocb, struct iov_iter *from,
			  bool *exclusive)
{
	struct inode *inode = file_inode(iocb->ki_filp);
	struct fuse_file *ff = iocb->ki_filp->private_data;
	struct fuse_inode *fi = get_fuse_inode(inode);

	*exclusive = fuse_dio_wr_exclusive_lock(iocb, from);
	if (*exclusive) {
@@ -1377,7 +1377,7 @@ static void fuse_dio_lock(struct kiocb *iocb, struct iov_iter *from,
		 * have raced, so check it again.
		 */
		if (fuse_io_past_eof(iocb, from) ||
		    fuse_file_uncached_io_start(inode, ff, NULL) != 0) {
		    fuse_inode_uncached_io_start(fi, NULL) != 0) {
			inode_unlock_shared(inode);
			inode_lock(inode);
			*exclusive = true;
@@ -1388,13 +1388,13 @@ static void fuse_dio_lock(struct kiocb *iocb, struct iov_iter *from,
static void fuse_dio_unlock(struct kiocb *iocb, bool exclusive)
{
	struct inode *inode = file_inode(iocb->ki_filp);
	struct fuse_file *ff = iocb->ki_filp->private_data;
	struct fuse_inode *fi = get_fuse_inode(inode);

	if (exclusive) {
		inode_unlock(inode);
	} else {
		/* Allow opens in caching mode after last parallel dio end */
		fuse_file_uncached_io_end(inode, ff);
		fuse_inode_uncached_io_end(fi);
		inode_unlock_shared(inode);
	}
}
@@ -2574,8 +2574,10 @@ static int fuse_file_mmap(struct file *file, struct vm_area_struct *vma)
		 * First mmap of direct_io file enters caching inode io mode.
		 * Also waits for parallel dio writers to go into serial mode
		 * (exclusive instead of shared lock).
		 * After first mmap, the inode stays in caching io mode until
		 * the direct_io file release.
		 */
		rc = fuse_file_cached_io_start(inode, ff);
		rc = fuse_file_cached_io_open(inode, ff);
		if (rc)
			return rc;
	}
+4 −3
Original line number Diff line number Diff line
@@ -1394,9 +1394,10 @@ int fuse_fileattr_set(struct mnt_idmap *idmap,
		      struct dentry *dentry, struct fileattr *fa);

/* iomode.c */
int fuse_file_cached_io_start(struct inode *inode, struct fuse_file *ff);
int fuse_file_uncached_io_start(struct inode *inode, struct fuse_file *ff, struct fuse_backing *fb);
void fuse_file_uncached_io_end(struct inode *inode, struct fuse_file *ff);
int fuse_file_cached_io_open(struct inode *inode, struct fuse_file *ff);
int fuse_inode_uncached_io_start(struct fuse_inode *fi,
				 struct fuse_backing *fb);
void fuse_inode_uncached_io_end(struct fuse_inode *fi);

int fuse_file_io_open(struct file *file, struct inode *inode);
void fuse_file_io_release(struct fuse_file *ff, struct inode *inode);
+1 −0
Original line number Diff line number Diff line
@@ -175,6 +175,7 @@ static void fuse_evict_inode(struct inode *inode)
		}
	}
	if (S_ISREG(inode->i_mode) && !fuse_is_bad(inode)) {
		WARN_ON(fi->iocachectr != 0);
		WARN_ON(!list_empty(&fi->write_files));
		WARN_ON(!list_empty(&fi->queued_writes));
	}
Loading