Commit f7571657 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'fuse-fixes-5.6-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/fuse

Pull fuse fixes from Miklos Szeredi:

 - Fix a regression introduced in v5.1 that triggers WARNINGs for some
   fuse filesystems

 - Fix an xfstest failure

 - Allow overlayfs to be used on top of fuse/virtiofs

 - Code and documentation cleanups

* tag 'fuse-fixes-5.6-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/fuse:
  fuse: use true,false for bool variable
  Documentation: filesystems: convert fuse to RST
  fuse: Support RENAME_WHITEOUT flag
  fuse: don't overflow LLONG_MAX with end offset
  fix up iter on short count in fuse_direct_io()
parents 175787e0 cabdb4fa
......@@ -47,6 +47,7 @@ Documentation for filesystem implementations.
:maxdepth: 2
autofs
fuse
overlayfs
virtiofs
vfat
......@@ -6903,7 +6903,7 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/fuse.git
S: Maintained
F: fs/fuse/
F: include/uapi/linux/fuse.h
F: Documentation/filesystems/fuse.txt
F: Documentation/filesystems/fuse.rst
FUTEX SUBSYSTEM
M: Thomas Gleixner <tglx@linutronix.de>
......
......@@ -451,8 +451,8 @@ static int cuse_send_init(struct cuse_conn *cc)
ap->args.out_args[0].size = sizeof(ia->out);
ap->args.out_args[0].value = &ia->out;
ap->args.out_args[1].size = CUSE_INIT_INFO_MAX;
ap->args.out_argvar = 1;
ap->args.out_pages = 1;
ap->args.out_argvar = true;
ap->args.out_pages = true;
ap->num_pages = 1;
ap->pages = &ia->page;
ap->descs = &ia->desc;
......
......@@ -818,7 +818,7 @@ static int fuse_rename2(struct inode *olddir, struct dentry *oldent,
struct fuse_conn *fc = get_fuse_conn(olddir);
int err;
if (flags & ~(RENAME_NOREPLACE | RENAME_EXCHANGE))
if (flags & ~(RENAME_NOREPLACE | RENAME_EXCHANGE | RENAME_WHITEOUT))
return -EINVAL;
if (flags) {
......
......@@ -803,6 +803,10 @@ static int fuse_do_readpage(struct file *file, struct page *page)
attr_ver = fuse_get_attr_version(fc);
/* Don't overflow end offset */
if (pos + (desc.length - 1) == LLONG_MAX)
desc.length--;
fuse_read_args_fill(&ia, file, pos, desc.length, FUSE_READ);
res = fuse_simple_request(fc, &ia.ap.args);
if (res < 0)
......@@ -888,6 +892,14 @@ static void fuse_send_readpages(struct fuse_io_args *ia, struct file *file)
ap->args.out_pages = true;
ap->args.page_zeroing = true;
ap->args.page_replace = true;
/* Don't overflow end offset */
if (pos + (count - 1) == LLONG_MAX) {
count--;
ap->descs[ap->num_pages - 1].length--;
}
WARN_ON((loff_t) (pos + count) < 0);
fuse_read_args_fill(ia, file, pos, count, FUSE_READ);
ia->read.attr_ver = fuse_get_attr_version(fc);
if (fc->async_read) {
......@@ -1397,9 +1409,9 @@ static int fuse_get_user_pages(struct fuse_args_pages *ap, struct iov_iter *ii,
}
if (write)
ap->args.in_pages = 1;
ap->args.in_pages = true;
else
ap->args.out_pages = 1;
ap->args.out_pages = true;
*nbytesp = nbytes;
......@@ -1465,6 +1477,7 @@ ssize_t fuse_direct_io(struct fuse_io_priv *io, struct iov_iter *iter,
}
ia = NULL;
if (nres < 0) {
iov_iter_revert(iter, nbytes);
err = nres;
break;
}
......@@ -1473,8 +1486,10 @@ ssize_t fuse_direct_io(struct fuse_io_priv *io, struct iov_iter *iter,
count -= nres;
res += nres;
pos += nres;
if (nres != nbytes)
if (nres != nbytes) {
iov_iter_revert(iter, nbytes - nres);
break;
}
if (count) {
max_pages = iov_iter_npages(iter, fc->max_pages);
ia = fuse_io_alloc(io, max_pages);
......
......@@ -494,36 +494,36 @@ static int fuse_parse_param(struct fs_context *fc, struct fs_parameter *param)
case OPT_FD:
ctx->fd = result.uint_32;
ctx->fd_present = 1;
ctx->fd_present = true;
break;
case OPT_ROOTMODE:
if (!fuse_valid_type(result.uint_32))
return invalf(fc, "fuse: Invalid rootmode");
ctx->rootmode = result.uint_32;
ctx->rootmode_present = 1;
ctx->rootmode_present = true;
break;
case OPT_USER_ID:
ctx->user_id = make_kuid(fc->user_ns, result.uint_32);
if (!uid_valid(ctx->user_id))
return invalf(fc, "fuse: Invalid user_id");
ctx->user_id_present = 1;
ctx->user_id_present = true;
break;
case OPT_GROUP_ID:
ctx->group_id = make_kgid(fc->user_ns, result.uint_32);
if (!gid_valid(ctx->group_id))
return invalf(fc, "fuse: Invalid group_id");
ctx->group_id_present = 1;
ctx->group_id_present = true;
break;
case OPT_DEFAULT_PERMISSIONS:
ctx->default_permissions = 1;
ctx->default_permissions = true;
break;
case OPT_ALLOW_OTHER:
ctx->allow_other = 1;
ctx->allow_other = true;
break;
case OPT_MAX_READ:
......@@ -997,7 +997,7 @@ void fuse_send_init(struct fuse_conn *fc)
/* Variable length argument used for backward compatibility
with interface version < 7.5. Rest of init_out is zeroed
by do_get_request(), so a short reply is not a problem */
ia->args.out_argvar = 1;
ia->args.out_argvar = true;
ia->args.out_args[0].size = sizeof(ia->out);
ia->args.out_args[0].value = &ia->out;
ia->args.force = true;
......
......@@ -332,7 +332,7 @@ static int fuse_readdir_uncached(struct file *file, struct dir_context *ctx)
return -ENOMEM;
plus = fuse_use_readdirplus(inode, ctx);
ap->args.out_pages = 1;
ap->args.out_pages = true;
ap->num_pages = 1;
ap->pages = &page;
ap->descs = &desc;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment