mirror of
https://github.com/torvalds/linux.git
synced 2024-11-21 19:41:42 +00:00
fuse fixes for 6.11-rc7
-----BEGIN PGP SIGNATURE----- iHUEABYKAB0WIQSQHSd0lITzzeNWNm3h3BK/laaZPAUCZtbV4AAKCRDh3BK/laaZ PC33AP9XvLpQii0mLo12hTSP11TYpaatdhUvyFFKERle1yWkUgEAvtVutUJryTD2 sz7x5jj4GD9tCWyMlp8Xs5h1Dr4U6wc= =XdIb -----END PGP SIGNATURE----- Merge tag 'fuse-fixes-6.11-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/fuse Pull fuse fixes from Miklos Szeredi: - Fix EIO if splice and page stealing are enabled on the fuse device - Disable problematic combination of passthrough and writeback-cache - Other bug fixes found by code review * tag 'fuse-fixes-6.11-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/fuse: fuse: disable the combination of passthrough and writeback cache fuse: update stats for pages in dropped aux writeback list fuse: clear PG_uptodate when using a stolen page fuse: fix memory leak in fuse_create_open fuse: check aborted connection before adding requests to pending list for resending fuse: use unsigned type for getxattr/listxattr size truncation
This commit is contained in:
commit
88fac17500
@ -31,6 +31,8 @@ MODULE_ALIAS("devname:fuse");
|
||||
|
||||
static struct kmem_cache *fuse_req_cachep;
|
||||
|
||||
static void end_requests(struct list_head *head);
|
||||
|
||||
static struct fuse_dev *fuse_get_dev(struct file *file)
|
||||
{
|
||||
/*
|
||||
@ -773,7 +775,6 @@ static int fuse_check_folio(struct folio *folio)
|
||||
(folio->flags & PAGE_FLAGS_CHECK_AT_PREP &
|
||||
~(1 << PG_locked |
|
||||
1 << PG_referenced |
|
||||
1 << PG_uptodate |
|
||||
1 << PG_lru |
|
||||
1 << PG_active |
|
||||
1 << PG_workingset |
|
||||
@ -818,9 +819,7 @@ static int fuse_try_move_page(struct fuse_copy_state *cs, struct page **pagep)
|
||||
|
||||
newfolio = page_folio(buf->page);
|
||||
|
||||
if (!folio_test_uptodate(newfolio))
|
||||
folio_mark_uptodate(newfolio);
|
||||
|
||||
folio_clear_uptodate(newfolio);
|
||||
folio_clear_mappedtodisk(newfolio);
|
||||
|
||||
if (fuse_check_folio(newfolio) != 0)
|
||||
@ -1822,6 +1821,13 @@ static void fuse_resend(struct fuse_conn *fc)
|
||||
}
|
||||
|
||||
spin_lock(&fiq->lock);
|
||||
if (!fiq->connected) {
|
||||
spin_unlock(&fiq->lock);
|
||||
list_for_each_entry(req, &to_queue, list)
|
||||
clear_bit(FR_PENDING, &req->flags);
|
||||
end_requests(&to_queue);
|
||||
return;
|
||||
}
|
||||
/* iq and pq requests are both oldest to newest */
|
||||
list_splice(&to_queue, &fiq->pending);
|
||||
fiq->ops->wake_pending_and_unlock(fiq);
|
||||
|
@ -670,7 +670,7 @@ static int fuse_create_open(struct inode *dir, struct dentry *entry,
|
||||
|
||||
err = get_create_ext(&args, dir, entry, mode);
|
||||
if (err)
|
||||
goto out_put_forget_req;
|
||||
goto out_free_ff;
|
||||
|
||||
err = fuse_simple_request(fm, &args);
|
||||
free_ext_value(&args);
|
||||
|
@ -1832,10 +1832,16 @@ __acquires(fi->lock)
|
||||
fuse_writepage_finish(fm, wpa);
|
||||
spin_unlock(&fi->lock);
|
||||
|
||||
/* After fuse_writepage_finish() aux request list is private */
|
||||
/* After rb_erase() aux request list is private */
|
||||
for (aux = wpa->next; aux; aux = next) {
|
||||
struct backing_dev_info *bdi = inode_to_bdi(aux->inode);
|
||||
|
||||
next = aux->next;
|
||||
aux->next = NULL;
|
||||
|
||||
dec_wb_stat(&bdi->wb, WB_WRITEBACK);
|
||||
dec_node_page_state(aux->ia.ap.pages[0], NR_WRITEBACK_TEMP);
|
||||
wb_writeout_inc(&bdi->wb);
|
||||
fuse_writepage_free(aux);
|
||||
}
|
||||
|
||||
|
@ -1332,11 +1332,16 @@ static void process_init_reply(struct fuse_mount *fm, struct fuse_args *args,
|
||||
* on a stacked fs (e.g. overlayfs) themselves and with
|
||||
* max_stack_depth == 1, FUSE fs can be stacked as the
|
||||
* underlying fs of a stacked fs (e.g. overlayfs).
|
||||
*
|
||||
* Also don't allow the combination of FUSE_PASSTHROUGH
|
||||
* and FUSE_WRITEBACK_CACHE, current design doesn't handle
|
||||
* them together.
|
||||
*/
|
||||
if (IS_ENABLED(CONFIG_FUSE_PASSTHROUGH) &&
|
||||
(flags & FUSE_PASSTHROUGH) &&
|
||||
arg->max_stack_depth > 0 &&
|
||||
arg->max_stack_depth <= FILESYSTEM_MAX_STACK_DEPTH) {
|
||||
arg->max_stack_depth <= FILESYSTEM_MAX_STACK_DEPTH &&
|
||||
!(flags & FUSE_WRITEBACK_CACHE)) {
|
||||
fc->passthrough = 1;
|
||||
fc->max_stack_depth = arg->max_stack_depth;
|
||||
fm->sb->s_stack_depth = arg->max_stack_depth;
|
||||
|
@ -81,7 +81,7 @@ ssize_t fuse_getxattr(struct inode *inode, const char *name, void *value,
|
||||
}
|
||||
ret = fuse_simple_request(fm, &args);
|
||||
if (!ret && !size)
|
||||
ret = min_t(ssize_t, outarg.size, XATTR_SIZE_MAX);
|
||||
ret = min_t(size_t, outarg.size, XATTR_SIZE_MAX);
|
||||
if (ret == -ENOSYS) {
|
||||
fm->fc->no_getxattr = 1;
|
||||
ret = -EOPNOTSUPP;
|
||||
@ -143,7 +143,7 @@ ssize_t fuse_listxattr(struct dentry *entry, char *list, size_t size)
|
||||
}
|
||||
ret = fuse_simple_request(fm, &args);
|
||||
if (!ret && !size)
|
||||
ret = min_t(ssize_t, outarg.size, XATTR_LIST_MAX);
|
||||
ret = min_t(size_t, outarg.size, XATTR_LIST_MAX);
|
||||
if (ret > 0 && size)
|
||||
ret = fuse_verify_xattr_list(list, ret);
|
||||
if (ret == -ENOSYS) {
|
||||
|
Loading…
Reference in New Issue
Block a user