Merge patch series "fscache/cachefiles: Some bugfixes"

Zizhi Wo <wozizhi@huawei.com> says:

This patchset mainly includes 5 fix patches about fscache/cachefiles.
The first patch fixes an issue with the incorrect return length, and the
fourth patch addresses a null pointer dereference issue with file.

* patches from https://lore.kernel.org/r/20241107110649.3980193-1-wozizhi@huawei.com:
  netfs/fscache: Add a memory barrier for FSCACHE_VOLUME_CREATING
  cachefiles: Fix NULL pointer dereference in object->file
  cachefiles: Clean up in cachefiles_commit_tmpfile()
  cachefiles: Fix missing pos updates in cachefiles_ondemand_fd_write_iter()
  cachefiles: Fix incorrect length return value in cachefiles_ondemand_fd_write_iter()

Link: https://lore.kernel.org/r/20241107110649.3980193-1-wozizhi@huawei.com
Signed-off-by: Christian Brauner <brauner@kernel.org>
This commit is contained in:
Christian Brauner 2024-11-11 12:31:42 +01:00
commit a4b2923376
No known key found for this signature in database
GPG Key ID: 91C61BC06578DCA2
4 changed files with 40 additions and 20 deletions

View File

@ -327,6 +327,8 @@ static void cachefiles_commit_object(struct cachefiles_object *object,
static void cachefiles_clean_up_object(struct cachefiles_object *object,
struct cachefiles_cache *cache)
{
struct file *file;
if (test_bit(FSCACHE_COOKIE_RETIRED, &object->cookie->flags)) {
if (!test_bit(CACHEFILES_OBJECT_USING_TMPFILE, &object->flags)) {
cachefiles_see_object(object, cachefiles_obj_see_clean_delete);
@ -342,10 +344,14 @@ static void cachefiles_clean_up_object(struct cachefiles_object *object,
}
cachefiles_unmark_inode_in_use(object, object->file);
if (object->file) {
fput(object->file);
object->file = NULL;
}
spin_lock(&object->lock);
file = object->file;
object->file = NULL;
spin_unlock(&object->lock);
if (file)
fput(file);
}
/*

View File

@ -691,11 +691,6 @@ bool cachefiles_commit_tmpfile(struct cachefiles_cache *cache,
}
if (!d_is_negative(dentry)) {
if (d_backing_inode(dentry) == file_inode(object->file)) {
success = true;
goto out_dput;
}
ret = cachefiles_unlink(volume->cache, object, fan, dentry,
FSCACHE_OBJECT_IS_STALE);
if (ret < 0)

View File

@ -60,26 +60,36 @@ static ssize_t cachefiles_ondemand_fd_write_iter(struct kiocb *kiocb,
{
struct cachefiles_object *object = kiocb->ki_filp->private_data;
struct cachefiles_cache *cache = object->volume->cache;
struct file *file = object->file;
size_t len = iter->count;
struct file *file;
size_t len = iter->count, aligned_len = len;
loff_t pos = kiocb->ki_pos;
const struct cred *saved_cred;
int ret;
if (!file)
spin_lock(&object->lock);
file = object->file;
if (!file) {
spin_unlock(&object->lock);
return -ENOBUFS;
}
get_file(file);
spin_unlock(&object->lock);
cachefiles_begin_secure(cache, &saved_cred);
ret = __cachefiles_prepare_write(object, file, &pos, &len, len, true);
ret = __cachefiles_prepare_write(object, file, &pos, &aligned_len, len, true);
cachefiles_end_secure(cache, saved_cred);
if (ret < 0)
return ret;
goto out;
trace_cachefiles_ondemand_fd_write(object, file_inode(file), pos, len);
ret = __cachefiles_write(object, file, pos, iter, NULL, NULL);
if (!ret)
if (!ret) {
ret = len;
kiocb->ki_pos += ret;
}
out:
fput(file);
return ret;
}
@ -87,12 +97,22 @@ static loff_t cachefiles_ondemand_fd_llseek(struct file *filp, loff_t pos,
int whence)
{
struct cachefiles_object *object = filp->private_data;
struct file *file = object->file;
struct file *file;
loff_t ret;
if (!file)
spin_lock(&object->lock);
file = object->file;
if (!file) {
spin_unlock(&object->lock);
return -ENOBUFS;
}
get_file(file);
spin_unlock(&object->lock);
return vfs_llseek(file, pos, whence);
ret = vfs_llseek(file, pos, whence);
fput(file);
return ret;
}
static long cachefiles_ondemand_fd_ioctl(struct file *filp, unsigned int ioctl,

View File

@ -322,8 +322,7 @@ maybe_wait:
}
return;
no_wait:
clear_bit_unlock(FSCACHE_VOLUME_CREATING, &volume->flags);
wake_up_bit(&volume->flags, FSCACHE_VOLUME_CREATING);
clear_and_wake_up_bit(FSCACHE_VOLUME_CREATING, &volume->flags);
}
/*