diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2022-11-03 23:41:29 +0300 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2022-11-03 23:41:29 +0300 |
commit | 7f7bac08d9e31cd6e2c0ea1685c86ec6f1e7e03c (patch) | |
tree | b02d0641869ab9d8a6eeb733ada9b87fc6ca722d /fs | |
parent | f2f32f8af2b0ca9d619e5183eae3eed431793baf (diff) | |
parent | 4a6f278d4827b59ba26ceae0ff4529ee826aa258 (diff) | |
download | linux-7f7bac08d9e31cd6e2c0ea1685c86ec6f1e7e03c.tar.xz |
Merge tag 'fuse-fixes-6.1-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/fuse
Pull fuse fixes from Miklos Szeredi:
"Fix two rarely triggered but long-standing issues"
* tag 'fuse-fixes-6.1-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/fuse:
fuse: add file_modified() to fallocate
fuse: fix readdir cache race
Diffstat (limited to 'fs')
-rw-r--r-- | fs/fuse/file.c | 4 | ||||
-rw-r--r-- | fs/fuse/readdir.c | 10 |
2 files changed, 13 insertions, 1 deletions
diff --git a/fs/fuse/file.c b/fs/fuse/file.c index 1a3afd469e3a..71bfb663aac5 100644 --- a/fs/fuse/file.c +++ b/fs/fuse/file.c @@ -3001,6 +3001,10 @@ static long fuse_file_fallocate(struct file *file, int mode, loff_t offset, goto out; } + err = file_modified(file); + if (err) + goto out; + if (!(mode & FALLOC_FL_KEEP_SIZE)) set_bit(FUSE_I_SIZE_UNSTABLE, &fi->state); diff --git a/fs/fuse/readdir.c b/fs/fuse/readdir.c index b4e565711045..e8deaacf1832 100644 --- a/fs/fuse/readdir.c +++ b/fs/fuse/readdir.c @@ -77,8 +77,10 @@ static void fuse_add_dirent_to_cache(struct file *file, goto unlock; addr = kmap_local_page(page); - if (!offset) + if (!offset) { clear_page(addr); + SetPageUptodate(page); + } memcpy(addr + offset, dirent, reclen); kunmap_local(addr); fi->rdc.size = (index << PAGE_SHIFT) + offset + reclen; @@ -516,6 +518,12 @@ retry_locked: page = find_get_page_flags(file->f_mapping, index, FGP_ACCESSED | FGP_LOCK); + /* Page gone missing, then re-added to cache, but not initialized? */ + if (page && !PageUptodate(page)) { + unlock_page(page); + put_page(page); + page = NULL; + } spin_lock(&fi->rdc.lock); if (!page) { /* |