Skip to content

Commit 88fac17

Browse files
committed
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
2 parents 67784a7 + 3ab394b commit 88fac17

File tree

5 files changed

+26
-9
lines changed

5 files changed

+26
-9
lines changed

fs/fuse/dev.c

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ MODULE_ALIAS("devname:fuse");
3131

3232
static struct kmem_cache *fuse_req_cachep;
3333

34+
static void end_requests(struct list_head *head);
35+
3436
static struct fuse_dev *fuse_get_dev(struct file *file)
3537
{
3638
/*
@@ -773,7 +775,6 @@ static int fuse_check_folio(struct folio *folio)
773775
(folio->flags & PAGE_FLAGS_CHECK_AT_PREP &
774776
~(1 << PG_locked |
775777
1 << PG_referenced |
776-
1 << PG_uptodate |
777778
1 << PG_lru |
778779
1 << PG_active |
779780
1 << PG_workingset |
@@ -818,9 +819,7 @@ static int fuse_try_move_page(struct fuse_copy_state *cs, struct page **pagep)
818819

819820
newfolio = page_folio(buf->page);
820821

821-
if (!folio_test_uptodate(newfolio))
822-
folio_mark_uptodate(newfolio);
823-
822+
folio_clear_uptodate(newfolio);
824823
folio_clear_mappedtodisk(newfolio);
825824

826825
if (fuse_check_folio(newfolio) != 0)
@@ -1822,6 +1821,13 @@ static void fuse_resend(struct fuse_conn *fc)
18221821
}
18231822

18241823
spin_lock(&fiq->lock);
1824+
if (!fiq->connected) {
1825+
spin_unlock(&fiq->lock);
1826+
list_for_each_entry(req, &to_queue, list)
1827+
clear_bit(FR_PENDING, &req->flags);
1828+
end_requests(&to_queue);
1829+
return;
1830+
}
18251831
/* iq and pq requests are both oldest to newest */
18261832
list_splice(&to_queue, &fiq->pending);
18271833
fiq->ops->wake_pending_and_unlock(fiq);

fs/fuse/dir.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -670,7 +670,7 @@ static int fuse_create_open(struct inode *dir, struct dentry *entry,
670670

671671
err = get_create_ext(&args, dir, entry, mode);
672672
if (err)
673-
goto out_put_forget_req;
673+
goto out_free_ff;
674674

675675
err = fuse_simple_request(fm, &args);
676676
free_ext_value(&args);

fs/fuse/file.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1832,10 +1832,16 @@ __acquires(fi->lock)
18321832
fuse_writepage_finish(fm, wpa);
18331833
spin_unlock(&fi->lock);
18341834

1835-
/* After fuse_writepage_finish() aux request list is private */
1835+
/* After rb_erase() aux request list is private */
18361836
for (aux = wpa->next; aux; aux = next) {
1837+
struct backing_dev_info *bdi = inode_to_bdi(aux->inode);
1838+
18371839
next = aux->next;
18381840
aux->next = NULL;
1841+
1842+
dec_wb_stat(&bdi->wb, WB_WRITEBACK);
1843+
dec_node_page_state(aux->ia.ap.pages[0], NR_WRITEBACK_TEMP);
1844+
wb_writeout_inc(&bdi->wb);
18391845
fuse_writepage_free(aux);
18401846
}
18411847

fs/fuse/inode.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1332,11 +1332,16 @@ static void process_init_reply(struct fuse_mount *fm, struct fuse_args *args,
13321332
* on a stacked fs (e.g. overlayfs) themselves and with
13331333
* max_stack_depth == 1, FUSE fs can be stacked as the
13341334
* underlying fs of a stacked fs (e.g. overlayfs).
1335+
*
1336+
* Also don't allow the combination of FUSE_PASSTHROUGH
1337+
* and FUSE_WRITEBACK_CACHE, current design doesn't handle
1338+
* them together.
13351339
*/
13361340
if (IS_ENABLED(CONFIG_FUSE_PASSTHROUGH) &&
13371341
(flags & FUSE_PASSTHROUGH) &&
13381342
arg->max_stack_depth > 0 &&
1339-
arg->max_stack_depth <= FILESYSTEM_MAX_STACK_DEPTH) {
1343+
arg->max_stack_depth <= FILESYSTEM_MAX_STACK_DEPTH &&
1344+
!(flags & FUSE_WRITEBACK_CACHE)) {
13401345
fc->passthrough = 1;
13411346
fc->max_stack_depth = arg->max_stack_depth;
13421347
fm->sb->s_stack_depth = arg->max_stack_depth;

fs/fuse/xattr.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ ssize_t fuse_getxattr(struct inode *inode, const char *name, void *value,
8181
}
8282
ret = fuse_simple_request(fm, &args);
8383
if (!ret && !size)
84-
ret = min_t(ssize_t, outarg.size, XATTR_SIZE_MAX);
84+
ret = min_t(size_t, outarg.size, XATTR_SIZE_MAX);
8585
if (ret == -ENOSYS) {
8686
fm->fc->no_getxattr = 1;
8787
ret = -EOPNOTSUPP;
@@ -143,7 +143,7 @@ ssize_t fuse_listxattr(struct dentry *entry, char *list, size_t size)
143143
}
144144
ret = fuse_simple_request(fm, &args);
145145
if (!ret && !size)
146-
ret = min_t(ssize_t, outarg.size, XATTR_LIST_MAX);
146+
ret = min_t(size_t, outarg.size, XATTR_LIST_MAX);
147147
if (ret > 0 && size)
148148
ret = fuse_verify_xattr_list(list, ret);
149149
if (ret == -ENOSYS) {

0 commit comments

Comments
 (0)