Skip to content

Commit 184429a

Browse files
author
Miklos Szeredi
committed
Revert "fuse: move initialization of fuse_file to fuse_writepages() instead of in callback"
This reverts commit 672c3b7. fuse_writepages() might be called with no dirty pages after all writable opens were closed. In this case __fuse_write_file_get() will return NULL which will trigger the WARNING. The exact conditions under which this is triggered is unclear and syzbot didn't find a reproducer yet. Reported-by: [email protected] Link: https://lore.kernel.org/all/CAJnrk1aQwfvb51wQ5rUSf9N8j1hArTFeSkHqC_3T-mU6_BCD=A@mail.gmail.com/ Signed-off-by: Miklos Szeredi <[email protected]>
1 parent 20121d3 commit 184429a

File tree

1 file changed

+12
-6
lines changed

1 file changed

+12
-6
lines changed

fs/fuse/file.c

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2288,6 +2288,13 @@ static int fuse_writepages_fill(struct folio *folio,
22882288
struct folio *tmp_folio;
22892289
int err;
22902290

2291+
if (!data->ff) {
2292+
err = -EIO;
2293+
data->ff = fuse_write_file_get(fi);
2294+
if (!data->ff)
2295+
goto out_unlock;
2296+
}
2297+
22912298
if (wpa && fuse_writepage_need_send(fc, &folio->page, ap, data)) {
22922299
fuse_writepages_send(data);
22932300
data->wpa = NULL;
@@ -2351,23 +2358,21 @@ static int fuse_writepages(struct address_space *mapping,
23512358
struct writeback_control *wbc)
23522359
{
23532360
struct inode *inode = mapping->host;
2354-
struct fuse_inode *fi = get_fuse_inode(inode);
23552361
struct fuse_conn *fc = get_fuse_conn(inode);
23562362
struct fuse_fill_wb_data data;
23572363
int err;
23582364

2365+
err = -EIO;
23592366
if (fuse_is_bad(inode))
2360-
return -EIO;
2367+
goto out;
23612368

23622369
if (wbc->sync_mode == WB_SYNC_NONE &&
23632370
fc->num_background >= fc->congestion_threshold)
23642371
return 0;
23652372

23662373
data.inode = inode;
23672374
data.wpa = NULL;
2368-
data.ff = fuse_write_file_get(fi);
2369-
if (!data.ff)
2370-
return -EIO;
2375+
data.ff = NULL;
23712376

23722377
err = -ENOMEM;
23732378
data.orig_pages = kcalloc(fc->max_pages,
@@ -2381,10 +2386,11 @@ static int fuse_writepages(struct address_space *mapping,
23812386
WARN_ON(!data.wpa->ia.ap.num_pages);
23822387
fuse_writepages_send(&data);
23832388
}
2389+
if (data.ff)
2390+
fuse_file_put(data.ff, false);
23842391

23852392
kfree(data.orig_pages);
23862393
out:
2387-
fuse_file_put(data.ff, false);
23882394
return err;
23892395
}
23902396

0 commit comments

Comments
 (0)