Skip to content

Commit a4b2923

Browse files
committed
Merge patch series "fscache/cachefiles: Some bugfixes"
Zizhi Wo <[email protected]> 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/[email protected]: 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/[email protected] Signed-off-by: Christian Brauner <[email protected]>
2 parents 9b8e809 + 22f9400 commit a4b2923

File tree

4 files changed

+40
-20
lines changed

4 files changed

+40
-20
lines changed

fs/cachefiles/interface.c

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -327,6 +327,8 @@ static void cachefiles_commit_object(struct cachefiles_object *object,
327327
static void cachefiles_clean_up_object(struct cachefiles_object *object,
328328
struct cachefiles_cache *cache)
329329
{
330+
struct file *file;
331+
330332
if (test_bit(FSCACHE_COOKIE_RETIRED, &object->cookie->flags)) {
331333
if (!test_bit(CACHEFILES_OBJECT_USING_TMPFILE, &object->flags)) {
332334
cachefiles_see_object(object, cachefiles_obj_see_clean_delete);
@@ -342,10 +344,14 @@ static void cachefiles_clean_up_object(struct cachefiles_object *object,
342344
}
343345

344346
cachefiles_unmark_inode_in_use(object, object->file);
345-
if (object->file) {
346-
fput(object->file);
347-
object->file = NULL;
348-
}
347+
348+
spin_lock(&object->lock);
349+
file = object->file;
350+
object->file = NULL;
351+
spin_unlock(&object->lock);
352+
353+
if (file)
354+
fput(file);
349355
}
350356

351357
/*

fs/cachefiles/namei.c

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -691,11 +691,6 @@ bool cachefiles_commit_tmpfile(struct cachefiles_cache *cache,
691691
}
692692

693693
if (!d_is_negative(dentry)) {
694-
if (d_backing_inode(dentry) == file_inode(object->file)) {
695-
success = true;
696-
goto out_dput;
697-
}
698-
699694
ret = cachefiles_unlink(volume->cache, object, fan, dentry,
700695
FSCACHE_OBJECT_IS_STALE);
701696
if (ret < 0)

fs/cachefiles/ondemand.c

Lines changed: 29 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -60,39 +60,59 @@ static ssize_t cachefiles_ondemand_fd_write_iter(struct kiocb *kiocb,
6060
{
6161
struct cachefiles_object *object = kiocb->ki_filp->private_data;
6262
struct cachefiles_cache *cache = object->volume->cache;
63-
struct file *file = object->file;
64-
size_t len = iter->count;
63+
struct file *file;
64+
size_t len = iter->count, aligned_len = len;
6565
loff_t pos = kiocb->ki_pos;
6666
const struct cred *saved_cred;
6767
int ret;
6868

69-
if (!file)
69+
spin_lock(&object->lock);
70+
file = object->file;
71+
if (!file) {
72+
spin_unlock(&object->lock);
7073
return -ENOBUFS;
74+
}
75+
get_file(file);
76+
spin_unlock(&object->lock);
7177

7278
cachefiles_begin_secure(cache, &saved_cred);
73-
ret = __cachefiles_prepare_write(object, file, &pos, &len, len, true);
79+
ret = __cachefiles_prepare_write(object, file, &pos, &aligned_len, len, true);
7480
cachefiles_end_secure(cache, saved_cred);
7581
if (ret < 0)
76-
return ret;
82+
goto out;
7783

7884
trace_cachefiles_ondemand_fd_write(object, file_inode(file), pos, len);
7985
ret = __cachefiles_write(object, file, pos, iter, NULL, NULL);
80-
if (!ret)
86+
if (!ret) {
8187
ret = len;
88+
kiocb->ki_pos += ret;
89+
}
8290

91+
out:
92+
fput(file);
8393
return ret;
8494
}
8595

8696
static loff_t cachefiles_ondemand_fd_llseek(struct file *filp, loff_t pos,
8797
int whence)
8898
{
8999
struct cachefiles_object *object = filp->private_data;
90-
struct file *file = object->file;
100+
struct file *file;
101+
loff_t ret;
91102

92-
if (!file)
103+
spin_lock(&object->lock);
104+
file = object->file;
105+
if (!file) {
106+
spin_unlock(&object->lock);
93107
return -ENOBUFS;
108+
}
109+
get_file(file);
110+
spin_unlock(&object->lock);
94111

95-
return vfs_llseek(file, pos, whence);
112+
ret = vfs_llseek(file, pos, whence);
113+
fput(file);
114+
115+
return ret;
96116
}
97117

98118
static long cachefiles_ondemand_fd_ioctl(struct file *filp, unsigned int ioctl,

fs/netfs/fscache_volume.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -322,8 +322,7 @@ void fscache_create_volume(struct fscache_volume *volume, bool wait)
322322
}
323323
return;
324324
no_wait:
325-
clear_bit_unlock(FSCACHE_VOLUME_CREATING, &volume->flags);
326-
wake_up_bit(&volume->flags, FSCACHE_VOLUME_CREATING);
325+
clear_and_wake_up_bit(FSCACHE_VOLUME_CREATING, &volume->flags);
327326
}
328327

329328
/*

0 commit comments

Comments
 (0)