cachefiles: notify the user daemon when looking up cookie
Fscache/CacheFiles used to serve as a local cache for a remote
networking fs. A new on-demand read mode will be introduced for
CacheFiles, which can boost the scenario where on-demand read semantics
are needed, e.g. container image distribution.
The essential difference between these two modes is seen when a cache
miss occurs: In the original mode, the netfs will fetch the data from
the remote server and then write it to the cache file; in on-demand
read mode, fetching the data and writing it into the cache is delegated
to a user daemon.
As the first step, notify the user daemon when looking up cookie. In
this case, an anonymous fd is sent to the user daemon, through which the
user daemon can write the fetched data to the cache file. Since the user
daemon may move the anonymous fd around, e.g. through dup(), an object
ID uniquely identifying the cache file is also attached.
Also add one advisory flag (FSCACHE_ADV_WANT_CACHE_SIZE) suggesting that
the cache file size shall be retrieved at runtime. This helps the
scenario where one cache file contains multiple netfs files, e.g. for
the purpose of deduplication. In this case, netfs itself has no idea the
size of the cache file, whilst the user daemon should give the hint on
it.
Signed-off-by: Jeffle Xu <jefflexu@linux.alibaba.com>
Link: https://lore.kernel.org/r/20220509074028.74954-3-jefflexu@linux.alibaba.com
Acked-by: David Howells <dhowells@redhat.com>
Signed-off-by: Gao Xiang <hsiangkao@linux.alibaba.com>
2022-04-25 20:21:24 +08:00
|
|
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
|
|
|
#include <linux/fdtable.h>
|
|
|
|
|
#include <linux/anon_inodes.h>
|
|
|
|
|
#include <linux/uio.h>
|
|
|
|
|
#include "internal.h"
|
|
|
|
|
|
cachefiles: fix slab-use-after-free in cachefiles_ondemand_get_fd()
We got the following issue in a fuzz test of randomly issuing the restore
command:
==================================================================
BUG: KASAN: slab-use-after-free in cachefiles_ondemand_daemon_read+0x609/0xab0
Write of size 4 at addr ffff888109164a80 by task ondemand-04-dae/4962
CPU: 11 PID: 4962 Comm: ondemand-04-dae Not tainted 6.8.0-rc7-dirty #542
Call Trace:
kasan_report+0x94/0xc0
cachefiles_ondemand_daemon_read+0x609/0xab0
vfs_read+0x169/0xb50
ksys_read+0xf5/0x1e0
Allocated by task 626:
__kmalloc+0x1df/0x4b0
cachefiles_ondemand_send_req+0x24d/0x690
cachefiles_create_tmpfile+0x249/0xb30
cachefiles_create_file+0x6f/0x140
cachefiles_look_up_object+0x29c/0xa60
cachefiles_lookup_cookie+0x37d/0xca0
fscache_cookie_state_machine+0x43c/0x1230
[...]
Freed by task 626:
kfree+0xf1/0x2c0
cachefiles_ondemand_send_req+0x568/0x690
cachefiles_create_tmpfile+0x249/0xb30
cachefiles_create_file+0x6f/0x140
cachefiles_look_up_object+0x29c/0xa60
cachefiles_lookup_cookie+0x37d/0xca0
fscache_cookie_state_machine+0x43c/0x1230
[...]
==================================================================
Following is the process that triggers the issue:
mount | daemon_thread1 | daemon_thread2
------------------------------------------------------------
cachefiles_ondemand_init_object
cachefiles_ondemand_send_req
REQ_A = kzalloc(sizeof(*req) + data_len)
wait_for_completion(&REQ_A->done)
cachefiles_daemon_read
cachefiles_ondemand_daemon_read
REQ_A = cachefiles_ondemand_select_req
cachefiles_ondemand_get_fd
copy_to_user(_buffer, msg, n)
process_open_req(REQ_A)
------ restore ------
cachefiles_ondemand_restore
xas_for_each(&xas, req, ULONG_MAX)
xas_set_mark(&xas, CACHEFILES_REQ_NEW);
cachefiles_daemon_read
cachefiles_ondemand_daemon_read
REQ_A = cachefiles_ondemand_select_req
write(devfd, ("copen %u,%llu", msg->msg_id, size));
cachefiles_ondemand_copen
xa_erase(&cache->reqs, id)
complete(&REQ_A->done)
kfree(REQ_A)
cachefiles_ondemand_get_fd(REQ_A)
fd = get_unused_fd_flags
file = anon_inode_getfile
fd_install(fd, file)
load = (void *)REQ_A->msg.data;
load->fd = fd;
// load UAF !!!
This issue is caused by issuing a restore command when the daemon is still
alive, which results in a request being processed multiple times thus
triggering a UAF. So to avoid this problem, add an additional reference
count to cachefiles_req, which is held while waiting and reading, and then
released when the waiting and reading is over.
Note that since there is only one reference count for waiting, we need to
avoid the same request being completed multiple times, so we can only
complete the request if it is successfully removed from the xarray.
Fixes: e73fa11a356c ("cachefiles: add restore command to recover inflight ondemand read requests")
Suggested-by: Hou Tao <houtao1@huawei.com>
Signed-off-by: Baokun Li <libaokun1@huawei.com>
Link: https://lore.kernel.org/r/20240522114308.2402121-4-libaokun@huaweicloud.com
Acked-by: Jeff Layton <jlayton@kernel.org>
Reviewed-by: Jia Zhu <zhujia.zj@bytedance.com>
Reviewed-by: Jingbo Xu <jefflexu@linux.alibaba.com>
Signed-off-by: Christian Brauner <brauner@kernel.org>
2024-05-22 19:42:59 +08:00
|
|
|
static inline void cachefiles_req_put(struct cachefiles_req *req)
|
|
|
|
|
{
|
|
|
|
|
if (refcount_dec_and_test(&req->ref))
|
|
|
|
|
kfree(req);
|
|
|
|
|
}
|
|
|
|
|
|
cachefiles: notify the user daemon when looking up cookie
Fscache/CacheFiles used to serve as a local cache for a remote
networking fs. A new on-demand read mode will be introduced for
CacheFiles, which can boost the scenario where on-demand read semantics
are needed, e.g. container image distribution.
The essential difference between these two modes is seen when a cache
miss occurs: In the original mode, the netfs will fetch the data from
the remote server and then write it to the cache file; in on-demand
read mode, fetching the data and writing it into the cache is delegated
to a user daemon.
As the first step, notify the user daemon when looking up cookie. In
this case, an anonymous fd is sent to the user daemon, through which the
user daemon can write the fetched data to the cache file. Since the user
daemon may move the anonymous fd around, e.g. through dup(), an object
ID uniquely identifying the cache file is also attached.
Also add one advisory flag (FSCACHE_ADV_WANT_CACHE_SIZE) suggesting that
the cache file size shall be retrieved at runtime. This helps the
scenario where one cache file contains multiple netfs files, e.g. for
the purpose of deduplication. In this case, netfs itself has no idea the
size of the cache file, whilst the user daemon should give the hint on
it.
Signed-off-by: Jeffle Xu <jefflexu@linux.alibaba.com>
Link: https://lore.kernel.org/r/20220509074028.74954-3-jefflexu@linux.alibaba.com
Acked-by: David Howells <dhowells@redhat.com>
Signed-off-by: Gao Xiang <hsiangkao@linux.alibaba.com>
2022-04-25 20:21:24 +08:00
|
|
|
static int cachefiles_ondemand_fd_release(struct inode *inode,
|
|
|
|
|
struct file *file)
|
|
|
|
|
{
|
|
|
|
|
struct cachefiles_object *object = file->private_data;
|
|
|
|
|
struct cachefiles_cache *cache = object->volume->cache;
|
2023-11-20 12:14:19 +08:00
|
|
|
struct cachefiles_ondemand_info *info = object->ondemand;
|
|
|
|
|
int object_id = info->ondemand_id;
|
2022-04-25 20:21:27 +08:00
|
|
|
struct cachefiles_req *req;
|
|
|
|
|
XA_STATE(xas, &cache->reqs, 0);
|
cachefiles: notify the user daemon when looking up cookie
Fscache/CacheFiles used to serve as a local cache for a remote
networking fs. A new on-demand read mode will be introduced for
CacheFiles, which can boost the scenario where on-demand read semantics
are needed, e.g. container image distribution.
The essential difference between these two modes is seen when a cache
miss occurs: In the original mode, the netfs will fetch the data from
the remote server and then write it to the cache file; in on-demand
read mode, fetching the data and writing it into the cache is delegated
to a user daemon.
As the first step, notify the user daemon when looking up cookie. In
this case, an anonymous fd is sent to the user daemon, through which the
user daemon can write the fetched data to the cache file. Since the user
daemon may move the anonymous fd around, e.g. through dup(), an object
ID uniquely identifying the cache file is also attached.
Also add one advisory flag (FSCACHE_ADV_WANT_CACHE_SIZE) suggesting that
the cache file size shall be retrieved at runtime. This helps the
scenario where one cache file contains multiple netfs files, e.g. for
the purpose of deduplication. In this case, netfs itself has no idea the
size of the cache file, whilst the user daemon should give the hint on
it.
Signed-off-by: Jeffle Xu <jefflexu@linux.alibaba.com>
Link: https://lore.kernel.org/r/20220509074028.74954-3-jefflexu@linux.alibaba.com
Acked-by: David Howells <dhowells@redhat.com>
Signed-off-by: Gao Xiang <hsiangkao@linux.alibaba.com>
2022-04-25 20:21:24 +08:00
|
|
|
|
2022-04-25 20:21:27 +08:00
|
|
|
xa_lock(&cache->reqs);
|
2023-11-20 12:14:19 +08:00
|
|
|
info->ondemand_id = CACHEFILES_ONDEMAND_ID_CLOSED;
|
2023-11-20 12:14:18 +08:00
|
|
|
cachefiles_ondemand_set_object_close(object);
|
2022-04-25 20:21:27 +08:00
|
|
|
|
2023-11-20 12:14:20 +08:00
|
|
|
/* Only flush CACHEFILES_REQ_NEW marked req to avoid race with daemon_read */
|
|
|
|
|
xas_for_each_marked(&xas, req, ULONG_MAX, CACHEFILES_REQ_NEW) {
|
2022-06-09 16:54:10 +08:00
|
|
|
if (req->msg.object_id == object_id &&
|
2023-11-20 12:14:20 +08:00
|
|
|
req->msg.opcode == CACHEFILES_OP_CLOSE) {
|
2022-04-25 20:21:27 +08:00
|
|
|
complete(&req->done);
|
|
|
|
|
xas_store(&xas, NULL);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
xa_unlock(&cache->reqs);
|
|
|
|
|
|
cachefiles: notify the user daemon when looking up cookie
Fscache/CacheFiles used to serve as a local cache for a remote
networking fs. A new on-demand read mode will be introduced for
CacheFiles, which can boost the scenario where on-demand read semantics
are needed, e.g. container image distribution.
The essential difference between these two modes is seen when a cache
miss occurs: In the original mode, the netfs will fetch the data from
the remote server and then write it to the cache file; in on-demand
read mode, fetching the data and writing it into the cache is delegated
to a user daemon.
As the first step, notify the user daemon when looking up cookie. In
this case, an anonymous fd is sent to the user daemon, through which the
user daemon can write the fetched data to the cache file. Since the user
daemon may move the anonymous fd around, e.g. through dup(), an object
ID uniquely identifying the cache file is also attached.
Also add one advisory flag (FSCACHE_ADV_WANT_CACHE_SIZE) suggesting that
the cache file size shall be retrieved at runtime. This helps the
scenario where one cache file contains multiple netfs files, e.g. for
the purpose of deduplication. In this case, netfs itself has no idea the
size of the cache file, whilst the user daemon should give the hint on
it.
Signed-off-by: Jeffle Xu <jefflexu@linux.alibaba.com>
Link: https://lore.kernel.org/r/20220509074028.74954-3-jefflexu@linux.alibaba.com
Acked-by: David Howells <dhowells@redhat.com>
Signed-off-by: Gao Xiang <hsiangkao@linux.alibaba.com>
2022-04-25 20:21:24 +08:00
|
|
|
xa_erase(&cache->ondemand_ids, object_id);
|
2022-04-25 20:21:29 +08:00
|
|
|
trace_cachefiles_ondemand_fd_release(object, object_id);
|
cachefiles: notify the user daemon when looking up cookie
Fscache/CacheFiles used to serve as a local cache for a remote
networking fs. A new on-demand read mode will be introduced for
CacheFiles, which can boost the scenario where on-demand read semantics
are needed, e.g. container image distribution.
The essential difference between these two modes is seen when a cache
miss occurs: In the original mode, the netfs will fetch the data from
the remote server and then write it to the cache file; in on-demand
read mode, fetching the data and writing it into the cache is delegated
to a user daemon.
As the first step, notify the user daemon when looking up cookie. In
this case, an anonymous fd is sent to the user daemon, through which the
user daemon can write the fetched data to the cache file. Since the user
daemon may move the anonymous fd around, e.g. through dup(), an object
ID uniquely identifying the cache file is also attached.
Also add one advisory flag (FSCACHE_ADV_WANT_CACHE_SIZE) suggesting that
the cache file size shall be retrieved at runtime. This helps the
scenario where one cache file contains multiple netfs files, e.g. for
the purpose of deduplication. In this case, netfs itself has no idea the
size of the cache file, whilst the user daemon should give the hint on
it.
Signed-off-by: Jeffle Xu <jefflexu@linux.alibaba.com>
Link: https://lore.kernel.org/r/20220509074028.74954-3-jefflexu@linux.alibaba.com
Acked-by: David Howells <dhowells@redhat.com>
Signed-off-by: Gao Xiang <hsiangkao@linux.alibaba.com>
2022-04-25 20:21:24 +08:00
|
|
|
cachefiles_put_object(object, cachefiles_obj_put_ondemand_fd);
|
2022-04-25 20:21:25 +08:00
|
|
|
cachefiles_put_unbind_pincount(cache);
|
cachefiles: notify the user daemon when looking up cookie
Fscache/CacheFiles used to serve as a local cache for a remote
networking fs. A new on-demand read mode will be introduced for
CacheFiles, which can boost the scenario where on-demand read semantics
are needed, e.g. container image distribution.
The essential difference between these two modes is seen when a cache
miss occurs: In the original mode, the netfs will fetch the data from
the remote server and then write it to the cache file; in on-demand
read mode, fetching the data and writing it into the cache is delegated
to a user daemon.
As the first step, notify the user daemon when looking up cookie. In
this case, an anonymous fd is sent to the user daemon, through which the
user daemon can write the fetched data to the cache file. Since the user
daemon may move the anonymous fd around, e.g. through dup(), an object
ID uniquely identifying the cache file is also attached.
Also add one advisory flag (FSCACHE_ADV_WANT_CACHE_SIZE) suggesting that
the cache file size shall be retrieved at runtime. This helps the
scenario where one cache file contains multiple netfs files, e.g. for
the purpose of deduplication. In this case, netfs itself has no idea the
size of the cache file, whilst the user daemon should give the hint on
it.
Signed-off-by: Jeffle Xu <jefflexu@linux.alibaba.com>
Link: https://lore.kernel.org/r/20220509074028.74954-3-jefflexu@linux.alibaba.com
Acked-by: David Howells <dhowells@redhat.com>
Signed-off-by: Gao Xiang <hsiangkao@linux.alibaba.com>
2022-04-25 20:21:24 +08:00
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static ssize_t cachefiles_ondemand_fd_write_iter(struct kiocb *kiocb,
|
|
|
|
|
struct iov_iter *iter)
|
|
|
|
|
{
|
|
|
|
|
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;
|
|
|
|
|
loff_t pos = kiocb->ki_pos;
|
|
|
|
|
const struct cred *saved_cred;
|
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
|
|
if (!file)
|
|
|
|
|
return -ENOBUFS;
|
|
|
|
|
|
|
|
|
|
cachefiles_begin_secure(cache, &saved_cred);
|
2023-11-22 17:18:17 +00:00
|
|
|
ret = __cachefiles_prepare_write(object, file, &pos, &len, len, true);
|
cachefiles: notify the user daemon when looking up cookie
Fscache/CacheFiles used to serve as a local cache for a remote
networking fs. A new on-demand read mode will be introduced for
CacheFiles, which can boost the scenario where on-demand read semantics
are needed, e.g. container image distribution.
The essential difference between these two modes is seen when a cache
miss occurs: In the original mode, the netfs will fetch the data from
the remote server and then write it to the cache file; in on-demand
read mode, fetching the data and writing it into the cache is delegated
to a user daemon.
As the first step, notify the user daemon when looking up cookie. In
this case, an anonymous fd is sent to the user daemon, through which the
user daemon can write the fetched data to the cache file. Since the user
daemon may move the anonymous fd around, e.g. through dup(), an object
ID uniquely identifying the cache file is also attached.
Also add one advisory flag (FSCACHE_ADV_WANT_CACHE_SIZE) suggesting that
the cache file size shall be retrieved at runtime. This helps the
scenario where one cache file contains multiple netfs files, e.g. for
the purpose of deduplication. In this case, netfs itself has no idea the
size of the cache file, whilst the user daemon should give the hint on
it.
Signed-off-by: Jeffle Xu <jefflexu@linux.alibaba.com>
Link: https://lore.kernel.org/r/20220509074028.74954-3-jefflexu@linux.alibaba.com
Acked-by: David Howells <dhowells@redhat.com>
Signed-off-by: Gao Xiang <hsiangkao@linux.alibaba.com>
2022-04-25 20:21:24 +08:00
|
|
|
cachefiles_end_secure(cache, saved_cred);
|
|
|
|
|
if (ret < 0)
|
|
|
|
|
return ret;
|
|
|
|
|
|
2022-04-25 20:21:29 +08:00
|
|
|
trace_cachefiles_ondemand_fd_write(object, file_inode(file), pos, len);
|
cachefiles: notify the user daemon when looking up cookie
Fscache/CacheFiles used to serve as a local cache for a remote
networking fs. A new on-demand read mode will be introduced for
CacheFiles, which can boost the scenario where on-demand read semantics
are needed, e.g. container image distribution.
The essential difference between these two modes is seen when a cache
miss occurs: In the original mode, the netfs will fetch the data from
the remote server and then write it to the cache file; in on-demand
read mode, fetching the data and writing it into the cache is delegated
to a user daemon.
As the first step, notify the user daemon when looking up cookie. In
this case, an anonymous fd is sent to the user daemon, through which the
user daemon can write the fetched data to the cache file. Since the user
daemon may move the anonymous fd around, e.g. through dup(), an object
ID uniquely identifying the cache file is also attached.
Also add one advisory flag (FSCACHE_ADV_WANT_CACHE_SIZE) suggesting that
the cache file size shall be retrieved at runtime. This helps the
scenario where one cache file contains multiple netfs files, e.g. for
the purpose of deduplication. In this case, netfs itself has no idea the
size of the cache file, whilst the user daemon should give the hint on
it.
Signed-off-by: Jeffle Xu <jefflexu@linux.alibaba.com>
Link: https://lore.kernel.org/r/20220509074028.74954-3-jefflexu@linux.alibaba.com
Acked-by: David Howells <dhowells@redhat.com>
Signed-off-by: Gao Xiang <hsiangkao@linux.alibaba.com>
2022-04-25 20:21:24 +08:00
|
|
|
ret = __cachefiles_write(object, file, pos, iter, NULL, NULL);
|
|
|
|
|
if (!ret)
|
|
|
|
|
ret = len;
|
|
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
|
|
|
|
|
if (!file)
|
|
|
|
|
return -ENOBUFS;
|
|
|
|
|
|
|
|
|
|
return vfs_llseek(file, pos, whence);
|
|
|
|
|
}
|
|
|
|
|
|
2022-04-25 20:21:27 +08:00
|
|
|
static long cachefiles_ondemand_fd_ioctl(struct file *filp, unsigned int ioctl,
|
2024-05-22 19:43:02 +08:00
|
|
|
unsigned long id)
|
2022-04-25 20:21:27 +08:00
|
|
|
{
|
|
|
|
|
struct cachefiles_object *object = filp->private_data;
|
|
|
|
|
struct cachefiles_cache *cache = object->volume->cache;
|
|
|
|
|
struct cachefiles_req *req;
|
2024-05-22 19:43:02 +08:00
|
|
|
XA_STATE(xas, &cache->reqs, id);
|
2022-04-25 20:21:27 +08:00
|
|
|
|
|
|
|
|
if (ioctl != CACHEFILES_IOC_READ_COMPLETE)
|
|
|
|
|
return -EINVAL;
|
|
|
|
|
|
|
|
|
|
if (!test_bit(CACHEFILES_ONDEMAND_MODE, &cache->flags))
|
|
|
|
|
return -EOPNOTSUPP;
|
|
|
|
|
|
2024-05-22 19:43:02 +08:00
|
|
|
xa_lock(&cache->reqs);
|
|
|
|
|
req = xas_load(&xas);
|
|
|
|
|
if (!req || req->msg.opcode != CACHEFILES_OP_READ ||
|
|
|
|
|
req->object != object) {
|
|
|
|
|
xa_unlock(&cache->reqs);
|
2022-04-25 20:21:27 +08:00
|
|
|
return -EINVAL;
|
2024-05-22 19:43:02 +08:00
|
|
|
}
|
|
|
|
|
xas_store(&xas, NULL);
|
|
|
|
|
xa_unlock(&cache->reqs);
|
2022-04-25 20:21:27 +08:00
|
|
|
|
2022-04-25 20:21:29 +08:00
|
|
|
trace_cachefiles_ondemand_cread(object, id);
|
2022-04-25 20:21:27 +08:00
|
|
|
complete(&req->done);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
cachefiles: notify the user daemon when looking up cookie
Fscache/CacheFiles used to serve as a local cache for a remote
networking fs. A new on-demand read mode will be introduced for
CacheFiles, which can boost the scenario where on-demand read semantics
are needed, e.g. container image distribution.
The essential difference between these two modes is seen when a cache
miss occurs: In the original mode, the netfs will fetch the data from
the remote server and then write it to the cache file; in on-demand
read mode, fetching the data and writing it into the cache is delegated
to a user daemon.
As the first step, notify the user daemon when looking up cookie. In
this case, an anonymous fd is sent to the user daemon, through which the
user daemon can write the fetched data to the cache file. Since the user
daemon may move the anonymous fd around, e.g. through dup(), an object
ID uniquely identifying the cache file is also attached.
Also add one advisory flag (FSCACHE_ADV_WANT_CACHE_SIZE) suggesting that
the cache file size shall be retrieved at runtime. This helps the
scenario where one cache file contains multiple netfs files, e.g. for
the purpose of deduplication. In this case, netfs itself has no idea the
size of the cache file, whilst the user daemon should give the hint on
it.
Signed-off-by: Jeffle Xu <jefflexu@linux.alibaba.com>
Link: https://lore.kernel.org/r/20220509074028.74954-3-jefflexu@linux.alibaba.com
Acked-by: David Howells <dhowells@redhat.com>
Signed-off-by: Gao Xiang <hsiangkao@linux.alibaba.com>
2022-04-25 20:21:24 +08:00
|
|
|
static const struct file_operations cachefiles_ondemand_fd_fops = {
|
|
|
|
|
.owner = THIS_MODULE,
|
|
|
|
|
.release = cachefiles_ondemand_fd_release,
|
|
|
|
|
.write_iter = cachefiles_ondemand_fd_write_iter,
|
|
|
|
|
.llseek = cachefiles_ondemand_fd_llseek,
|
2022-04-25 20:21:27 +08:00
|
|
|
.unlocked_ioctl = cachefiles_ondemand_fd_ioctl,
|
cachefiles: notify the user daemon when looking up cookie
Fscache/CacheFiles used to serve as a local cache for a remote
networking fs. A new on-demand read mode will be introduced for
CacheFiles, which can boost the scenario where on-demand read semantics
are needed, e.g. container image distribution.
The essential difference between these two modes is seen when a cache
miss occurs: In the original mode, the netfs will fetch the data from
the remote server and then write it to the cache file; in on-demand
read mode, fetching the data and writing it into the cache is delegated
to a user daemon.
As the first step, notify the user daemon when looking up cookie. In
this case, an anonymous fd is sent to the user daemon, through which the
user daemon can write the fetched data to the cache file. Since the user
daemon may move the anonymous fd around, e.g. through dup(), an object
ID uniquely identifying the cache file is also attached.
Also add one advisory flag (FSCACHE_ADV_WANT_CACHE_SIZE) suggesting that
the cache file size shall be retrieved at runtime. This helps the
scenario where one cache file contains multiple netfs files, e.g. for
the purpose of deduplication. In this case, netfs itself has no idea the
size of the cache file, whilst the user daemon should give the hint on
it.
Signed-off-by: Jeffle Xu <jefflexu@linux.alibaba.com>
Link: https://lore.kernel.org/r/20220509074028.74954-3-jefflexu@linux.alibaba.com
Acked-by: David Howells <dhowells@redhat.com>
Signed-off-by: Gao Xiang <hsiangkao@linux.alibaba.com>
2022-04-25 20:21:24 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* OPEN request Completion (copen)
|
|
|
|
|
* - command: "copen <id>,<cache_size>"
|
|
|
|
|
* <cache_size> indicates the object size if >=0, error code if negative
|
|
|
|
|
*/
|
|
|
|
|
int cachefiles_ondemand_copen(struct cachefiles_cache *cache, char *args)
|
|
|
|
|
{
|
|
|
|
|
struct cachefiles_req *req;
|
|
|
|
|
struct fscache_cookie *cookie;
|
|
|
|
|
char *pid, *psize;
|
|
|
|
|
unsigned long id;
|
|
|
|
|
long size;
|
|
|
|
|
int ret;
|
2024-05-22 19:43:02 +08:00
|
|
|
XA_STATE(xas, &cache->reqs, 0);
|
cachefiles: notify the user daemon when looking up cookie
Fscache/CacheFiles used to serve as a local cache for a remote
networking fs. A new on-demand read mode will be introduced for
CacheFiles, which can boost the scenario where on-demand read semantics
are needed, e.g. container image distribution.
The essential difference between these two modes is seen when a cache
miss occurs: In the original mode, the netfs will fetch the data from
the remote server and then write it to the cache file; in on-demand
read mode, fetching the data and writing it into the cache is delegated
to a user daemon.
As the first step, notify the user daemon when looking up cookie. In
this case, an anonymous fd is sent to the user daemon, through which the
user daemon can write the fetched data to the cache file. Since the user
daemon may move the anonymous fd around, e.g. through dup(), an object
ID uniquely identifying the cache file is also attached.
Also add one advisory flag (FSCACHE_ADV_WANT_CACHE_SIZE) suggesting that
the cache file size shall be retrieved at runtime. This helps the
scenario where one cache file contains multiple netfs files, e.g. for
the purpose of deduplication. In this case, netfs itself has no idea the
size of the cache file, whilst the user daemon should give the hint on
it.
Signed-off-by: Jeffle Xu <jefflexu@linux.alibaba.com>
Link: https://lore.kernel.org/r/20220509074028.74954-3-jefflexu@linux.alibaba.com
Acked-by: David Howells <dhowells@redhat.com>
Signed-off-by: Gao Xiang <hsiangkao@linux.alibaba.com>
2022-04-25 20:21:24 +08:00
|
|
|
|
|
|
|
|
if (!test_bit(CACHEFILES_ONDEMAND_MODE, &cache->flags))
|
|
|
|
|
return -EOPNOTSUPP;
|
|
|
|
|
|
|
|
|
|
if (!*args) {
|
|
|
|
|
pr_err("Empty id specified\n");
|
|
|
|
|
return -EINVAL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pid = args;
|
|
|
|
|
psize = strchr(args, ',');
|
|
|
|
|
if (!psize) {
|
|
|
|
|
pr_err("Cache size is not specified\n");
|
|
|
|
|
return -EINVAL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
*psize = 0;
|
|
|
|
|
psize++;
|
|
|
|
|
|
|
|
|
|
ret = kstrtoul(pid, 0, &id);
|
|
|
|
|
if (ret)
|
|
|
|
|
return ret;
|
|
|
|
|
|
2024-05-22 19:43:02 +08:00
|
|
|
xa_lock(&cache->reqs);
|
|
|
|
|
xas.xa_index = id;
|
|
|
|
|
req = xas_load(&xas);
|
|
|
|
|
if (!req || req->msg.opcode != CACHEFILES_OP_OPEN ||
|
|
|
|
|
!req->object->ondemand->ondemand_id) {
|
|
|
|
|
xa_unlock(&cache->reqs);
|
cachefiles: notify the user daemon when looking up cookie
Fscache/CacheFiles used to serve as a local cache for a remote
networking fs. A new on-demand read mode will be introduced for
CacheFiles, which can boost the scenario where on-demand read semantics
are needed, e.g. container image distribution.
The essential difference between these two modes is seen when a cache
miss occurs: In the original mode, the netfs will fetch the data from
the remote server and then write it to the cache file; in on-demand
read mode, fetching the data and writing it into the cache is delegated
to a user daemon.
As the first step, notify the user daemon when looking up cookie. In
this case, an anonymous fd is sent to the user daemon, through which the
user daemon can write the fetched data to the cache file. Since the user
daemon may move the anonymous fd around, e.g. through dup(), an object
ID uniquely identifying the cache file is also attached.
Also add one advisory flag (FSCACHE_ADV_WANT_CACHE_SIZE) suggesting that
the cache file size shall be retrieved at runtime. This helps the
scenario where one cache file contains multiple netfs files, e.g. for
the purpose of deduplication. In this case, netfs itself has no idea the
size of the cache file, whilst the user daemon should give the hint on
it.
Signed-off-by: Jeffle Xu <jefflexu@linux.alibaba.com>
Link: https://lore.kernel.org/r/20220509074028.74954-3-jefflexu@linux.alibaba.com
Acked-by: David Howells <dhowells@redhat.com>
Signed-off-by: Gao Xiang <hsiangkao@linux.alibaba.com>
2022-04-25 20:21:24 +08:00
|
|
|
return -EINVAL;
|
2024-05-22 19:43:02 +08:00
|
|
|
}
|
|
|
|
|
xas_store(&xas, NULL);
|
|
|
|
|
xa_unlock(&cache->reqs);
|
cachefiles: notify the user daemon when looking up cookie
Fscache/CacheFiles used to serve as a local cache for a remote
networking fs. A new on-demand read mode will be introduced for
CacheFiles, which can boost the scenario where on-demand read semantics
are needed, e.g. container image distribution.
The essential difference between these two modes is seen when a cache
miss occurs: In the original mode, the netfs will fetch the data from
the remote server and then write it to the cache file; in on-demand
read mode, fetching the data and writing it into the cache is delegated
to a user daemon.
As the first step, notify the user daemon when looking up cookie. In
this case, an anonymous fd is sent to the user daemon, through which the
user daemon can write the fetched data to the cache file. Since the user
daemon may move the anonymous fd around, e.g. through dup(), an object
ID uniquely identifying the cache file is also attached.
Also add one advisory flag (FSCACHE_ADV_WANT_CACHE_SIZE) suggesting that
the cache file size shall be retrieved at runtime. This helps the
scenario where one cache file contains multiple netfs files, e.g. for
the purpose of deduplication. In this case, netfs itself has no idea the
size of the cache file, whilst the user daemon should give the hint on
it.
Signed-off-by: Jeffle Xu <jefflexu@linux.alibaba.com>
Link: https://lore.kernel.org/r/20220509074028.74954-3-jefflexu@linux.alibaba.com
Acked-by: David Howells <dhowells@redhat.com>
Signed-off-by: Gao Xiang <hsiangkao@linux.alibaba.com>
2022-04-25 20:21:24 +08:00
|
|
|
|
|
|
|
|
/* fail OPEN request if copen format is invalid */
|
|
|
|
|
ret = kstrtol(psize, 0, &size);
|
|
|
|
|
if (ret) {
|
|
|
|
|
req->error = ret;
|
|
|
|
|
goto out;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* fail OPEN request if daemon reports an error */
|
|
|
|
|
if (size < 0) {
|
2022-08-26 10:35:15 +08:00
|
|
|
if (!IS_ERR_VALUE(size)) {
|
|
|
|
|
req->error = -EINVAL;
|
|
|
|
|
ret = -EINVAL;
|
|
|
|
|
} else {
|
|
|
|
|
req->error = size;
|
|
|
|
|
ret = 0;
|
|
|
|
|
}
|
cachefiles: notify the user daemon when looking up cookie
Fscache/CacheFiles used to serve as a local cache for a remote
networking fs. A new on-demand read mode will be introduced for
CacheFiles, which can boost the scenario where on-demand read semantics
are needed, e.g. container image distribution.
The essential difference between these two modes is seen when a cache
miss occurs: In the original mode, the netfs will fetch the data from
the remote server and then write it to the cache file; in on-demand
read mode, fetching the data and writing it into the cache is delegated
to a user daemon.
As the first step, notify the user daemon when looking up cookie. In
this case, an anonymous fd is sent to the user daemon, through which the
user daemon can write the fetched data to the cache file. Since the user
daemon may move the anonymous fd around, e.g. through dup(), an object
ID uniquely identifying the cache file is also attached.
Also add one advisory flag (FSCACHE_ADV_WANT_CACHE_SIZE) suggesting that
the cache file size shall be retrieved at runtime. This helps the
scenario where one cache file contains multiple netfs files, e.g. for
the purpose of deduplication. In this case, netfs itself has no idea the
size of the cache file, whilst the user daemon should give the hint on
it.
Signed-off-by: Jeffle Xu <jefflexu@linux.alibaba.com>
Link: https://lore.kernel.org/r/20220509074028.74954-3-jefflexu@linux.alibaba.com
Acked-by: David Howells <dhowells@redhat.com>
Signed-off-by: Gao Xiang <hsiangkao@linux.alibaba.com>
2022-04-25 20:21:24 +08:00
|
|
|
goto out;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
cookie = req->object->cookie;
|
|
|
|
|
cookie->object_size = size;
|
|
|
|
|
if (size)
|
|
|
|
|
clear_bit(FSCACHE_COOKIE_NO_DATA_TO_READ, &cookie->flags);
|
|
|
|
|
else
|
|
|
|
|
set_bit(FSCACHE_COOKIE_NO_DATA_TO_READ, &cookie->flags);
|
2022-04-25 20:21:29 +08:00
|
|
|
trace_cachefiles_ondemand_copen(req->object, id, size);
|
cachefiles: notify the user daemon when looking up cookie
Fscache/CacheFiles used to serve as a local cache for a remote
networking fs. A new on-demand read mode will be introduced for
CacheFiles, which can boost the scenario where on-demand read semantics
are needed, e.g. container image distribution.
The essential difference between these two modes is seen when a cache
miss occurs: In the original mode, the netfs will fetch the data from
the remote server and then write it to the cache file; in on-demand
read mode, fetching the data and writing it into the cache is delegated
to a user daemon.
As the first step, notify the user daemon when looking up cookie. In
this case, an anonymous fd is sent to the user daemon, through which the
user daemon can write the fetched data to the cache file. Since the user
daemon may move the anonymous fd around, e.g. through dup(), an object
ID uniquely identifying the cache file is also attached.
Also add one advisory flag (FSCACHE_ADV_WANT_CACHE_SIZE) suggesting that
the cache file size shall be retrieved at runtime. This helps the
scenario where one cache file contains multiple netfs files, e.g. for
the purpose of deduplication. In this case, netfs itself has no idea the
size of the cache file, whilst the user daemon should give the hint on
it.
Signed-off-by: Jeffle Xu <jefflexu@linux.alibaba.com>
Link: https://lore.kernel.org/r/20220509074028.74954-3-jefflexu@linux.alibaba.com
Acked-by: David Howells <dhowells@redhat.com>
Signed-off-by: Gao Xiang <hsiangkao@linux.alibaba.com>
2022-04-25 20:21:24 +08:00
|
|
|
|
2023-11-20 12:14:18 +08:00
|
|
|
cachefiles_ondemand_set_object_open(req->object);
|
2023-11-20 12:14:20 +08:00
|
|
|
wake_up_all(&cache->daemon_pollwq);
|
2023-11-20 12:14:18 +08:00
|
|
|
|
cachefiles: notify the user daemon when looking up cookie
Fscache/CacheFiles used to serve as a local cache for a remote
networking fs. A new on-demand read mode will be introduced for
CacheFiles, which can boost the scenario where on-demand read semantics
are needed, e.g. container image distribution.
The essential difference between these two modes is seen when a cache
miss occurs: In the original mode, the netfs will fetch the data from
the remote server and then write it to the cache file; in on-demand
read mode, fetching the data and writing it into the cache is delegated
to a user daemon.
As the first step, notify the user daemon when looking up cookie. In
this case, an anonymous fd is sent to the user daemon, through which the
user daemon can write the fetched data to the cache file. Since the user
daemon may move the anonymous fd around, e.g. through dup(), an object
ID uniquely identifying the cache file is also attached.
Also add one advisory flag (FSCACHE_ADV_WANT_CACHE_SIZE) suggesting that
the cache file size shall be retrieved at runtime. This helps the
scenario where one cache file contains multiple netfs files, e.g. for
the purpose of deduplication. In this case, netfs itself has no idea the
size of the cache file, whilst the user daemon should give the hint on
it.
Signed-off-by: Jeffle Xu <jefflexu@linux.alibaba.com>
Link: https://lore.kernel.org/r/20220509074028.74954-3-jefflexu@linux.alibaba.com
Acked-by: David Howells <dhowells@redhat.com>
Signed-off-by: Gao Xiang <hsiangkao@linux.alibaba.com>
2022-04-25 20:21:24 +08:00
|
|
|
out:
|
|
|
|
|
complete(&req->done);
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
2023-11-20 12:14:22 +08:00
|
|
|
int cachefiles_ondemand_restore(struct cachefiles_cache *cache, char *args)
|
|
|
|
|
{
|
|
|
|
|
struct cachefiles_req *req;
|
|
|
|
|
|
|
|
|
|
XA_STATE(xas, &cache->reqs, 0);
|
|
|
|
|
|
|
|
|
|
if (!test_bit(CACHEFILES_ONDEMAND_MODE, &cache->flags))
|
|
|
|
|
return -EOPNOTSUPP;
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Reset the requests to CACHEFILES_REQ_NEW state, so that the
|
|
|
|
|
* requests have been processed halfway before the crash of the
|
|
|
|
|
* user daemon could be reprocessed after the recovery.
|
|
|
|
|
*/
|
|
|
|
|
xas_lock(&xas);
|
|
|
|
|
xas_for_each(&xas, req, ULONG_MAX)
|
|
|
|
|
xas_set_mark(&xas, CACHEFILES_REQ_NEW);
|
|
|
|
|
xas_unlock(&xas);
|
|
|
|
|
|
|
|
|
|
wake_up_all(&cache->daemon_pollwq);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
cachefiles: notify the user daemon when looking up cookie
Fscache/CacheFiles used to serve as a local cache for a remote
networking fs. A new on-demand read mode will be introduced for
CacheFiles, which can boost the scenario where on-demand read semantics
are needed, e.g. container image distribution.
The essential difference between these two modes is seen when a cache
miss occurs: In the original mode, the netfs will fetch the data from
the remote server and then write it to the cache file; in on-demand
read mode, fetching the data and writing it into the cache is delegated
to a user daemon.
As the first step, notify the user daemon when looking up cookie. In
this case, an anonymous fd is sent to the user daemon, through which the
user daemon can write the fetched data to the cache file. Since the user
daemon may move the anonymous fd around, e.g. through dup(), an object
ID uniquely identifying the cache file is also attached.
Also add one advisory flag (FSCACHE_ADV_WANT_CACHE_SIZE) suggesting that
the cache file size shall be retrieved at runtime. This helps the
scenario where one cache file contains multiple netfs files, e.g. for
the purpose of deduplication. In this case, netfs itself has no idea the
size of the cache file, whilst the user daemon should give the hint on
it.
Signed-off-by: Jeffle Xu <jefflexu@linux.alibaba.com>
Link: https://lore.kernel.org/r/20220509074028.74954-3-jefflexu@linux.alibaba.com
Acked-by: David Howells <dhowells@redhat.com>
Signed-off-by: Gao Xiang <hsiangkao@linux.alibaba.com>
2022-04-25 20:21:24 +08:00
|
|
|
static int cachefiles_ondemand_get_fd(struct cachefiles_req *req)
|
|
|
|
|
{
|
|
|
|
|
struct cachefiles_object *object;
|
|
|
|
|
struct cachefiles_cache *cache;
|
|
|
|
|
struct cachefiles_open *load;
|
|
|
|
|
struct file *file;
|
|
|
|
|
u32 object_id;
|
|
|
|
|
int ret, fd;
|
|
|
|
|
|
|
|
|
|
object = cachefiles_grab_object(req->object,
|
|
|
|
|
cachefiles_obj_get_ondemand_fd);
|
|
|
|
|
cache = object->volume->cache;
|
|
|
|
|
|
|
|
|
|
ret = xa_alloc_cyclic(&cache->ondemand_ids, &object_id, NULL,
|
|
|
|
|
XA_LIMIT(1, INT_MAX),
|
|
|
|
|
&cache->ondemand_id_next, GFP_KERNEL);
|
|
|
|
|
if (ret < 0)
|
|
|
|
|
goto err;
|
|
|
|
|
|
|
|
|
|
fd = get_unused_fd_flags(O_WRONLY);
|
|
|
|
|
if (fd < 0) {
|
|
|
|
|
ret = fd;
|
|
|
|
|
goto err_free_id;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
file = anon_inode_getfile("[cachefiles]", &cachefiles_ondemand_fd_fops,
|
|
|
|
|
object, O_WRONLY);
|
|
|
|
|
if (IS_ERR(file)) {
|
|
|
|
|
ret = PTR_ERR(file);
|
|
|
|
|
goto err_put_fd;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
file->f_mode |= FMODE_PWRITE | FMODE_LSEEK;
|
|
|
|
|
fd_install(fd, file);
|
|
|
|
|
|
|
|
|
|
load = (void *)req->msg.data;
|
|
|
|
|
load->fd = fd;
|
2023-11-20 12:14:19 +08:00
|
|
|
object->ondemand->ondemand_id = object_id;
|
2022-04-25 20:21:25 +08:00
|
|
|
|
|
|
|
|
cachefiles_get_unbind_pincount(cache);
|
2022-04-25 20:21:29 +08:00
|
|
|
trace_cachefiles_ondemand_open(object, &req->msg, load);
|
cachefiles: notify the user daemon when looking up cookie
Fscache/CacheFiles used to serve as a local cache for a remote
networking fs. A new on-demand read mode will be introduced for
CacheFiles, which can boost the scenario where on-demand read semantics
are needed, e.g. container image distribution.
The essential difference between these two modes is seen when a cache
miss occurs: In the original mode, the netfs will fetch the data from
the remote server and then write it to the cache file; in on-demand
read mode, fetching the data and writing it into the cache is delegated
to a user daemon.
As the first step, notify the user daemon when looking up cookie. In
this case, an anonymous fd is sent to the user daemon, through which the
user daemon can write the fetched data to the cache file. Since the user
daemon may move the anonymous fd around, e.g. through dup(), an object
ID uniquely identifying the cache file is also attached.
Also add one advisory flag (FSCACHE_ADV_WANT_CACHE_SIZE) suggesting that
the cache file size shall be retrieved at runtime. This helps the
scenario where one cache file contains multiple netfs files, e.g. for
the purpose of deduplication. In this case, netfs itself has no idea the
size of the cache file, whilst the user daemon should give the hint on
it.
Signed-off-by: Jeffle Xu <jefflexu@linux.alibaba.com>
Link: https://lore.kernel.org/r/20220509074028.74954-3-jefflexu@linux.alibaba.com
Acked-by: David Howells <dhowells@redhat.com>
Signed-off-by: Gao Xiang <hsiangkao@linux.alibaba.com>
2022-04-25 20:21:24 +08:00
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
err_put_fd:
|
|
|
|
|
put_unused_fd(fd);
|
|
|
|
|
err_free_id:
|
|
|
|
|
xa_erase(&cache->ondemand_ids, object_id);
|
|
|
|
|
err:
|
|
|
|
|
cachefiles_put_object(object, cachefiles_obj_put_ondemand_fd);
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
2023-11-20 12:14:20 +08:00
|
|
|
static void ondemand_object_worker(struct work_struct *work)
|
|
|
|
|
{
|
|
|
|
|
struct cachefiles_ondemand_info *info =
|
|
|
|
|
container_of(work, struct cachefiles_ondemand_info, ondemand_work);
|
|
|
|
|
|
|
|
|
|
cachefiles_ondemand_init_object(info->object);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* If there are any inflight or subsequent READ requests on the
|
|
|
|
|
* closed object, reopen it.
|
|
|
|
|
* Skip read requests whose related object is reopening.
|
|
|
|
|
*/
|
|
|
|
|
static struct cachefiles_req *cachefiles_ondemand_select_req(struct xa_state *xas,
|
|
|
|
|
unsigned long xa_max)
|
|
|
|
|
{
|
|
|
|
|
struct cachefiles_req *req;
|
|
|
|
|
struct cachefiles_object *object;
|
|
|
|
|
struct cachefiles_ondemand_info *info;
|
|
|
|
|
|
|
|
|
|
xas_for_each_marked(xas, req, xa_max, CACHEFILES_REQ_NEW) {
|
|
|
|
|
if (req->msg.opcode != CACHEFILES_OP_READ)
|
|
|
|
|
return req;
|
|
|
|
|
object = req->object;
|
|
|
|
|
info = object->ondemand;
|
|
|
|
|
if (cachefiles_ondemand_object_is_close(object)) {
|
|
|
|
|
cachefiles_ondemand_set_object_reopening(object);
|
|
|
|
|
queue_work(fscache_wq, &info->ondemand_work);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
if (cachefiles_ondemand_object_is_reopening(object))
|
|
|
|
|
continue;
|
|
|
|
|
return req;
|
|
|
|
|
}
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
cachefiles: notify the user daemon when looking up cookie
Fscache/CacheFiles used to serve as a local cache for a remote
networking fs. A new on-demand read mode will be introduced for
CacheFiles, which can boost the scenario where on-demand read semantics
are needed, e.g. container image distribution.
The essential difference between these two modes is seen when a cache
miss occurs: In the original mode, the netfs will fetch the data from
the remote server and then write it to the cache file; in on-demand
read mode, fetching the data and writing it into the cache is delegated
to a user daemon.
As the first step, notify the user daemon when looking up cookie. In
this case, an anonymous fd is sent to the user daemon, through which the
user daemon can write the fetched data to the cache file. Since the user
daemon may move the anonymous fd around, e.g. through dup(), an object
ID uniquely identifying the cache file is also attached.
Also add one advisory flag (FSCACHE_ADV_WANT_CACHE_SIZE) suggesting that
the cache file size shall be retrieved at runtime. This helps the
scenario where one cache file contains multiple netfs files, e.g. for
the purpose of deduplication. In this case, netfs itself has no idea the
size of the cache file, whilst the user daemon should give the hint on
it.
Signed-off-by: Jeffle Xu <jefflexu@linux.alibaba.com>
Link: https://lore.kernel.org/r/20220509074028.74954-3-jefflexu@linux.alibaba.com
Acked-by: David Howells <dhowells@redhat.com>
Signed-off-by: Gao Xiang <hsiangkao@linux.alibaba.com>
2022-04-25 20:21:24 +08:00
|
|
|
ssize_t cachefiles_ondemand_daemon_read(struct cachefiles_cache *cache,
|
|
|
|
|
char __user *_buffer, size_t buflen)
|
|
|
|
|
{
|
|
|
|
|
struct cachefiles_req *req;
|
|
|
|
|
struct cachefiles_msg *msg;
|
|
|
|
|
size_t n;
|
|
|
|
|
int ret = 0;
|
2022-08-25 10:09:45 +08:00
|
|
|
XA_STATE(xas, &cache->reqs, cache->req_id_next);
|
cachefiles: notify the user daemon when looking up cookie
Fscache/CacheFiles used to serve as a local cache for a remote
networking fs. A new on-demand read mode will be introduced for
CacheFiles, which can boost the scenario where on-demand read semantics
are needed, e.g. container image distribution.
The essential difference between these two modes is seen when a cache
miss occurs: In the original mode, the netfs will fetch the data from
the remote server and then write it to the cache file; in on-demand
read mode, fetching the data and writing it into the cache is delegated
to a user daemon.
As the first step, notify the user daemon when looking up cookie. In
this case, an anonymous fd is sent to the user daemon, through which the
user daemon can write the fetched data to the cache file. Since the user
daemon may move the anonymous fd around, e.g. through dup(), an object
ID uniquely identifying the cache file is also attached.
Also add one advisory flag (FSCACHE_ADV_WANT_CACHE_SIZE) suggesting that
the cache file size shall be retrieved at runtime. This helps the
scenario where one cache file contains multiple netfs files, e.g. for
the purpose of deduplication. In this case, netfs itself has no idea the
size of the cache file, whilst the user daemon should give the hint on
it.
Signed-off-by: Jeffle Xu <jefflexu@linux.alibaba.com>
Link: https://lore.kernel.org/r/20220509074028.74954-3-jefflexu@linux.alibaba.com
Acked-by: David Howells <dhowells@redhat.com>
Signed-off-by: Gao Xiang <hsiangkao@linux.alibaba.com>
2022-04-25 20:21:24 +08:00
|
|
|
|
2023-11-20 12:14:20 +08:00
|
|
|
xa_lock(&cache->reqs);
|
cachefiles: notify the user daemon when looking up cookie
Fscache/CacheFiles used to serve as a local cache for a remote
networking fs. A new on-demand read mode will be introduced for
CacheFiles, which can boost the scenario where on-demand read semantics
are needed, e.g. container image distribution.
The essential difference between these two modes is seen when a cache
miss occurs: In the original mode, the netfs will fetch the data from
the remote server and then write it to the cache file; in on-demand
read mode, fetching the data and writing it into the cache is delegated
to a user daemon.
As the first step, notify the user daemon when looking up cookie. In
this case, an anonymous fd is sent to the user daemon, through which the
user daemon can write the fetched data to the cache file. Since the user
daemon may move the anonymous fd around, e.g. through dup(), an object
ID uniquely identifying the cache file is also attached.
Also add one advisory flag (FSCACHE_ADV_WANT_CACHE_SIZE) suggesting that
the cache file size shall be retrieved at runtime. This helps the
scenario where one cache file contains multiple netfs files, e.g. for
the purpose of deduplication. In this case, netfs itself has no idea the
size of the cache file, whilst the user daemon should give the hint on
it.
Signed-off-by: Jeffle Xu <jefflexu@linux.alibaba.com>
Link: https://lore.kernel.org/r/20220509074028.74954-3-jefflexu@linux.alibaba.com
Acked-by: David Howells <dhowells@redhat.com>
Signed-off-by: Gao Xiang <hsiangkao@linux.alibaba.com>
2022-04-25 20:21:24 +08:00
|
|
|
/*
|
2022-08-25 10:09:45 +08:00
|
|
|
* Cyclically search for a request that has not ever been processed,
|
|
|
|
|
* to prevent requests from being processed repeatedly, and make
|
|
|
|
|
* request distribution fair.
|
cachefiles: notify the user daemon when looking up cookie
Fscache/CacheFiles used to serve as a local cache for a remote
networking fs. A new on-demand read mode will be introduced for
CacheFiles, which can boost the scenario where on-demand read semantics
are needed, e.g. container image distribution.
The essential difference between these two modes is seen when a cache
miss occurs: In the original mode, the netfs will fetch the data from
the remote server and then write it to the cache file; in on-demand
read mode, fetching the data and writing it into the cache is delegated
to a user daemon.
As the first step, notify the user daemon when looking up cookie. In
this case, an anonymous fd is sent to the user daemon, through which the
user daemon can write the fetched data to the cache file. Since the user
daemon may move the anonymous fd around, e.g. through dup(), an object
ID uniquely identifying the cache file is also attached.
Also add one advisory flag (FSCACHE_ADV_WANT_CACHE_SIZE) suggesting that
the cache file size shall be retrieved at runtime. This helps the
scenario where one cache file contains multiple netfs files, e.g. for
the purpose of deduplication. In this case, netfs itself has no idea the
size of the cache file, whilst the user daemon should give the hint on
it.
Signed-off-by: Jeffle Xu <jefflexu@linux.alibaba.com>
Link: https://lore.kernel.org/r/20220509074028.74954-3-jefflexu@linux.alibaba.com
Acked-by: David Howells <dhowells@redhat.com>
Signed-off-by: Gao Xiang <hsiangkao@linux.alibaba.com>
2022-04-25 20:21:24 +08:00
|
|
|
*/
|
2023-11-20 12:14:20 +08:00
|
|
|
req = cachefiles_ondemand_select_req(&xas, ULONG_MAX);
|
2022-08-25 10:09:45 +08:00
|
|
|
if (!req && cache->req_id_next > 0) {
|
|
|
|
|
xas_set(&xas, 0);
|
2023-11-20 12:14:20 +08:00
|
|
|
req = cachefiles_ondemand_select_req(&xas, cache->req_id_next - 1);
|
2022-08-25 10:09:45 +08:00
|
|
|
}
|
cachefiles: notify the user daemon when looking up cookie
Fscache/CacheFiles used to serve as a local cache for a remote
networking fs. A new on-demand read mode will be introduced for
CacheFiles, which can boost the scenario where on-demand read semantics
are needed, e.g. container image distribution.
The essential difference between these two modes is seen when a cache
miss occurs: In the original mode, the netfs will fetch the data from
the remote server and then write it to the cache file; in on-demand
read mode, fetching the data and writing it into the cache is delegated
to a user daemon.
As the first step, notify the user daemon when looking up cookie. In
this case, an anonymous fd is sent to the user daemon, through which the
user daemon can write the fetched data to the cache file. Since the user
daemon may move the anonymous fd around, e.g. through dup(), an object
ID uniquely identifying the cache file is also attached.
Also add one advisory flag (FSCACHE_ADV_WANT_CACHE_SIZE) suggesting that
the cache file size shall be retrieved at runtime. This helps the
scenario where one cache file contains multiple netfs files, e.g. for
the purpose of deduplication. In this case, netfs itself has no idea the
size of the cache file, whilst the user daemon should give the hint on
it.
Signed-off-by: Jeffle Xu <jefflexu@linux.alibaba.com>
Link: https://lore.kernel.org/r/20220509074028.74954-3-jefflexu@linux.alibaba.com
Acked-by: David Howells <dhowells@redhat.com>
Signed-off-by: Gao Xiang <hsiangkao@linux.alibaba.com>
2022-04-25 20:21:24 +08:00
|
|
|
if (!req) {
|
|
|
|
|
xa_unlock(&cache->reqs);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
msg = &req->msg;
|
|
|
|
|
n = msg->len;
|
|
|
|
|
|
|
|
|
|
if (n > buflen) {
|
|
|
|
|
xa_unlock(&cache->reqs);
|
|
|
|
|
return -EMSGSIZE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
xas_clear_mark(&xas, CACHEFILES_REQ_NEW);
|
2022-08-25 10:09:45 +08:00
|
|
|
cache->req_id_next = xas.xa_index + 1;
|
cachefiles: fix slab-use-after-free in cachefiles_ondemand_get_fd()
We got the following issue in a fuzz test of randomly issuing the restore
command:
==================================================================
BUG: KASAN: slab-use-after-free in cachefiles_ondemand_daemon_read+0x609/0xab0
Write of size 4 at addr ffff888109164a80 by task ondemand-04-dae/4962
CPU: 11 PID: 4962 Comm: ondemand-04-dae Not tainted 6.8.0-rc7-dirty #542
Call Trace:
kasan_report+0x94/0xc0
cachefiles_ondemand_daemon_read+0x609/0xab0
vfs_read+0x169/0xb50
ksys_read+0xf5/0x1e0
Allocated by task 626:
__kmalloc+0x1df/0x4b0
cachefiles_ondemand_send_req+0x24d/0x690
cachefiles_create_tmpfile+0x249/0xb30
cachefiles_create_file+0x6f/0x140
cachefiles_look_up_object+0x29c/0xa60
cachefiles_lookup_cookie+0x37d/0xca0
fscache_cookie_state_machine+0x43c/0x1230
[...]
Freed by task 626:
kfree+0xf1/0x2c0
cachefiles_ondemand_send_req+0x568/0x690
cachefiles_create_tmpfile+0x249/0xb30
cachefiles_create_file+0x6f/0x140
cachefiles_look_up_object+0x29c/0xa60
cachefiles_lookup_cookie+0x37d/0xca0
fscache_cookie_state_machine+0x43c/0x1230
[...]
==================================================================
Following is the process that triggers the issue:
mount | daemon_thread1 | daemon_thread2
------------------------------------------------------------
cachefiles_ondemand_init_object
cachefiles_ondemand_send_req
REQ_A = kzalloc(sizeof(*req) + data_len)
wait_for_completion(&REQ_A->done)
cachefiles_daemon_read
cachefiles_ondemand_daemon_read
REQ_A = cachefiles_ondemand_select_req
cachefiles_ondemand_get_fd
copy_to_user(_buffer, msg, n)
process_open_req(REQ_A)
------ restore ------
cachefiles_ondemand_restore
xas_for_each(&xas, req, ULONG_MAX)
xas_set_mark(&xas, CACHEFILES_REQ_NEW);
cachefiles_daemon_read
cachefiles_ondemand_daemon_read
REQ_A = cachefiles_ondemand_select_req
write(devfd, ("copen %u,%llu", msg->msg_id, size));
cachefiles_ondemand_copen
xa_erase(&cache->reqs, id)
complete(&REQ_A->done)
kfree(REQ_A)
cachefiles_ondemand_get_fd(REQ_A)
fd = get_unused_fd_flags
file = anon_inode_getfile
fd_install(fd, file)
load = (void *)REQ_A->msg.data;
load->fd = fd;
// load UAF !!!
This issue is caused by issuing a restore command when the daemon is still
alive, which results in a request being processed multiple times thus
triggering a UAF. So to avoid this problem, add an additional reference
count to cachefiles_req, which is held while waiting and reading, and then
released when the waiting and reading is over.
Note that since there is only one reference count for waiting, we need to
avoid the same request being completed multiple times, so we can only
complete the request if it is successfully removed from the xarray.
Fixes: e73fa11a356c ("cachefiles: add restore command to recover inflight ondemand read requests")
Suggested-by: Hou Tao <houtao1@huawei.com>
Signed-off-by: Baokun Li <libaokun1@huawei.com>
Link: https://lore.kernel.org/r/20240522114308.2402121-4-libaokun@huaweicloud.com
Acked-by: Jeff Layton <jlayton@kernel.org>
Reviewed-by: Jia Zhu <zhujia.zj@bytedance.com>
Reviewed-by: Jingbo Xu <jefflexu@linux.alibaba.com>
Signed-off-by: Christian Brauner <brauner@kernel.org>
2024-05-22 19:42:59 +08:00
|
|
|
refcount_inc(&req->ref);
|
2024-05-22 19:43:00 +08:00
|
|
|
cachefiles_grab_object(req->object, cachefiles_obj_get_read_req);
|
cachefiles: notify the user daemon when looking up cookie
Fscache/CacheFiles used to serve as a local cache for a remote
networking fs. A new on-demand read mode will be introduced for
CacheFiles, which can boost the scenario where on-demand read semantics
are needed, e.g. container image distribution.
The essential difference between these two modes is seen when a cache
miss occurs: In the original mode, the netfs will fetch the data from
the remote server and then write it to the cache file; in on-demand
read mode, fetching the data and writing it into the cache is delegated
to a user daemon.
As the first step, notify the user daemon when looking up cookie. In
this case, an anonymous fd is sent to the user daemon, through which the
user daemon can write the fetched data to the cache file. Since the user
daemon may move the anonymous fd around, e.g. through dup(), an object
ID uniquely identifying the cache file is also attached.
Also add one advisory flag (FSCACHE_ADV_WANT_CACHE_SIZE) suggesting that
the cache file size shall be retrieved at runtime. This helps the
scenario where one cache file contains multiple netfs files, e.g. for
the purpose of deduplication. In this case, netfs itself has no idea the
size of the cache file, whilst the user daemon should give the hint on
it.
Signed-off-by: Jeffle Xu <jefflexu@linux.alibaba.com>
Link: https://lore.kernel.org/r/20220509074028.74954-3-jefflexu@linux.alibaba.com
Acked-by: David Howells <dhowells@redhat.com>
Signed-off-by: Gao Xiang <hsiangkao@linux.alibaba.com>
2022-04-25 20:21:24 +08:00
|
|
|
xa_unlock(&cache->reqs);
|
|
|
|
|
|
|
|
|
|
if (msg->opcode == CACHEFILES_OP_OPEN) {
|
|
|
|
|
ret = cachefiles_ondemand_get_fd(req);
|
2023-11-20 12:14:20 +08:00
|
|
|
if (ret) {
|
|
|
|
|
cachefiles_ondemand_set_object_close(req->object);
|
2024-05-22 19:43:01 +08:00
|
|
|
goto out;
|
2023-11-20 12:14:20 +08:00
|
|
|
}
|
cachefiles: notify the user daemon when looking up cookie
Fscache/CacheFiles used to serve as a local cache for a remote
networking fs. A new on-demand read mode will be introduced for
CacheFiles, which can boost the scenario where on-demand read semantics
are needed, e.g. container image distribution.
The essential difference between these two modes is seen when a cache
miss occurs: In the original mode, the netfs will fetch the data from
the remote server and then write it to the cache file; in on-demand
read mode, fetching the data and writing it into the cache is delegated
to a user daemon.
As the first step, notify the user daemon when looking up cookie. In
this case, an anonymous fd is sent to the user daemon, through which the
user daemon can write the fetched data to the cache file. Since the user
daemon may move the anonymous fd around, e.g. through dup(), an object
ID uniquely identifying the cache file is also attached.
Also add one advisory flag (FSCACHE_ADV_WANT_CACHE_SIZE) suggesting that
the cache file size shall be retrieved at runtime. This helps the
scenario where one cache file contains multiple netfs files, e.g. for
the purpose of deduplication. In this case, netfs itself has no idea the
size of the cache file, whilst the user daemon should give the hint on
it.
Signed-off-by: Jeffle Xu <jefflexu@linux.alibaba.com>
Link: https://lore.kernel.org/r/20220509074028.74954-3-jefflexu@linux.alibaba.com
Acked-by: David Howells <dhowells@redhat.com>
Signed-off-by: Gao Xiang <hsiangkao@linux.alibaba.com>
2022-04-25 20:21:24 +08:00
|
|
|
}
|
|
|
|
|
|
2024-05-22 19:43:01 +08:00
|
|
|
msg->msg_id = xas.xa_index;
|
2023-11-20 12:14:20 +08:00
|
|
|
msg->object_id = req->object->ondemand->ondemand_id;
|
|
|
|
|
|
cachefiles: notify the user daemon when looking up cookie
Fscache/CacheFiles used to serve as a local cache for a remote
networking fs. A new on-demand read mode will be introduced for
CacheFiles, which can boost the scenario where on-demand read semantics
are needed, e.g. container image distribution.
The essential difference between these two modes is seen when a cache
miss occurs: In the original mode, the netfs will fetch the data from
the remote server and then write it to the cache file; in on-demand
read mode, fetching the data and writing it into the cache is delegated
to a user daemon.
As the first step, notify the user daemon when looking up cookie. In
this case, an anonymous fd is sent to the user daemon, through which the
user daemon can write the fetched data to the cache file. Since the user
daemon may move the anonymous fd around, e.g. through dup(), an object
ID uniquely identifying the cache file is also attached.
Also add one advisory flag (FSCACHE_ADV_WANT_CACHE_SIZE) suggesting that
the cache file size shall be retrieved at runtime. This helps the
scenario where one cache file contains multiple netfs files, e.g. for
the purpose of deduplication. In this case, netfs itself has no idea the
size of the cache file, whilst the user daemon should give the hint on
it.
Signed-off-by: Jeffle Xu <jefflexu@linux.alibaba.com>
Link: https://lore.kernel.org/r/20220509074028.74954-3-jefflexu@linux.alibaba.com
Acked-by: David Howells <dhowells@redhat.com>
Signed-off-by: Gao Xiang <hsiangkao@linux.alibaba.com>
2022-04-25 20:21:24 +08:00
|
|
|
if (copy_to_user(_buffer, msg, n) != 0) {
|
|
|
|
|
ret = -EFAULT;
|
2024-05-22 19:43:01 +08:00
|
|
|
if (msg->opcode == CACHEFILES_OP_OPEN)
|
|
|
|
|
close_fd(((struct cachefiles_open *)msg->data)->fd);
|
2022-04-25 20:21:26 +08:00
|
|
|
}
|
2024-05-22 19:43:01 +08:00
|
|
|
out:
|
2024-05-22 19:43:00 +08:00
|
|
|
cachefiles_put_object(req->object, cachefiles_obj_put_read_req);
|
2024-05-22 19:43:01 +08:00
|
|
|
/* Remove error request and CLOSE request has no reply */
|
|
|
|
|
if (ret || msg->opcode == CACHEFILES_OP_CLOSE) {
|
|
|
|
|
xas_reset(&xas);
|
|
|
|
|
xas_lock(&xas);
|
|
|
|
|
if (xas_load(&xas) == req) {
|
|
|
|
|
req->error = ret;
|
|
|
|
|
complete(&req->done);
|
|
|
|
|
xas_store(&xas, NULL);
|
|
|
|
|
}
|
|
|
|
|
xas_unlock(&xas);
|
cachefiles: fix slab-use-after-free in cachefiles_ondemand_get_fd()
We got the following issue in a fuzz test of randomly issuing the restore
command:
==================================================================
BUG: KASAN: slab-use-after-free in cachefiles_ondemand_daemon_read+0x609/0xab0
Write of size 4 at addr ffff888109164a80 by task ondemand-04-dae/4962
CPU: 11 PID: 4962 Comm: ondemand-04-dae Not tainted 6.8.0-rc7-dirty #542
Call Trace:
kasan_report+0x94/0xc0
cachefiles_ondemand_daemon_read+0x609/0xab0
vfs_read+0x169/0xb50
ksys_read+0xf5/0x1e0
Allocated by task 626:
__kmalloc+0x1df/0x4b0
cachefiles_ondemand_send_req+0x24d/0x690
cachefiles_create_tmpfile+0x249/0xb30
cachefiles_create_file+0x6f/0x140
cachefiles_look_up_object+0x29c/0xa60
cachefiles_lookup_cookie+0x37d/0xca0
fscache_cookie_state_machine+0x43c/0x1230
[...]
Freed by task 626:
kfree+0xf1/0x2c0
cachefiles_ondemand_send_req+0x568/0x690
cachefiles_create_tmpfile+0x249/0xb30
cachefiles_create_file+0x6f/0x140
cachefiles_look_up_object+0x29c/0xa60
cachefiles_lookup_cookie+0x37d/0xca0
fscache_cookie_state_machine+0x43c/0x1230
[...]
==================================================================
Following is the process that triggers the issue:
mount | daemon_thread1 | daemon_thread2
------------------------------------------------------------
cachefiles_ondemand_init_object
cachefiles_ondemand_send_req
REQ_A = kzalloc(sizeof(*req) + data_len)
wait_for_completion(&REQ_A->done)
cachefiles_daemon_read
cachefiles_ondemand_daemon_read
REQ_A = cachefiles_ondemand_select_req
cachefiles_ondemand_get_fd
copy_to_user(_buffer, msg, n)
process_open_req(REQ_A)
------ restore ------
cachefiles_ondemand_restore
xas_for_each(&xas, req, ULONG_MAX)
xas_set_mark(&xas, CACHEFILES_REQ_NEW);
cachefiles_daemon_read
cachefiles_ondemand_daemon_read
REQ_A = cachefiles_ondemand_select_req
write(devfd, ("copen %u,%llu", msg->msg_id, size));
cachefiles_ondemand_copen
xa_erase(&cache->reqs, id)
complete(&REQ_A->done)
kfree(REQ_A)
cachefiles_ondemand_get_fd(REQ_A)
fd = get_unused_fd_flags
file = anon_inode_getfile
fd_install(fd, file)
load = (void *)REQ_A->msg.data;
load->fd = fd;
// load UAF !!!
This issue is caused by issuing a restore command when the daemon is still
alive, which results in a request being processed multiple times thus
triggering a UAF. So to avoid this problem, add an additional reference
count to cachefiles_req, which is held while waiting and reading, and then
released when the waiting and reading is over.
Note that since there is only one reference count for waiting, we need to
avoid the same request being completed multiple times, so we can only
complete the request if it is successfully removed from the xarray.
Fixes: e73fa11a356c ("cachefiles: add restore command to recover inflight ondemand read requests")
Suggested-by: Hou Tao <houtao1@huawei.com>
Signed-off-by: Baokun Li <libaokun1@huawei.com>
Link: https://lore.kernel.org/r/20240522114308.2402121-4-libaokun@huaweicloud.com
Acked-by: Jeff Layton <jlayton@kernel.org>
Reviewed-by: Jia Zhu <zhujia.zj@bytedance.com>
Reviewed-by: Jingbo Xu <jefflexu@linux.alibaba.com>
Signed-off-by: Christian Brauner <brauner@kernel.org>
2024-05-22 19:42:59 +08:00
|
|
|
}
|
|
|
|
|
cachefiles_req_put(req);
|
2024-05-22 19:43:01 +08:00
|
|
|
return ret ? ret : n;
|
cachefiles: notify the user daemon when looking up cookie
Fscache/CacheFiles used to serve as a local cache for a remote
networking fs. A new on-demand read mode will be introduced for
CacheFiles, which can boost the scenario where on-demand read semantics
are needed, e.g. container image distribution.
The essential difference between these two modes is seen when a cache
miss occurs: In the original mode, the netfs will fetch the data from
the remote server and then write it to the cache file; in on-demand
read mode, fetching the data and writing it into the cache is delegated
to a user daemon.
As the first step, notify the user daemon when looking up cookie. In
this case, an anonymous fd is sent to the user daemon, through which the
user daemon can write the fetched data to the cache file. Since the user
daemon may move the anonymous fd around, e.g. through dup(), an object
ID uniquely identifying the cache file is also attached.
Also add one advisory flag (FSCACHE_ADV_WANT_CACHE_SIZE) suggesting that
the cache file size shall be retrieved at runtime. This helps the
scenario where one cache file contains multiple netfs files, e.g. for
the purpose of deduplication. In this case, netfs itself has no idea the
size of the cache file, whilst the user daemon should give the hint on
it.
Signed-off-by: Jeffle Xu <jefflexu@linux.alibaba.com>
Link: https://lore.kernel.org/r/20220509074028.74954-3-jefflexu@linux.alibaba.com
Acked-by: David Howells <dhowells@redhat.com>
Signed-off-by: Gao Xiang <hsiangkao@linux.alibaba.com>
2022-04-25 20:21:24 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
typedef int (*init_req_fn)(struct cachefiles_req *req, void *private);
|
|
|
|
|
|
|
|
|
|
static int cachefiles_ondemand_send_req(struct cachefiles_object *object,
|
|
|
|
|
enum cachefiles_opcode opcode,
|
|
|
|
|
size_t data_len,
|
|
|
|
|
init_req_fn init_req,
|
|
|
|
|
void *private)
|
|
|
|
|
{
|
|
|
|
|
struct cachefiles_cache *cache = object->volume->cache;
|
2023-11-20 12:14:20 +08:00
|
|
|
struct cachefiles_req *req = NULL;
|
cachefiles: notify the user daemon when looking up cookie
Fscache/CacheFiles used to serve as a local cache for a remote
networking fs. A new on-demand read mode will be introduced for
CacheFiles, which can boost the scenario where on-demand read semantics
are needed, e.g. container image distribution.
The essential difference between these two modes is seen when a cache
miss occurs: In the original mode, the netfs will fetch the data from
the remote server and then write it to the cache file; in on-demand
read mode, fetching the data and writing it into the cache is delegated
to a user daemon.
As the first step, notify the user daemon when looking up cookie. In
this case, an anonymous fd is sent to the user daemon, through which the
user daemon can write the fetched data to the cache file. Since the user
daemon may move the anonymous fd around, e.g. through dup(), an object
ID uniquely identifying the cache file is also attached.
Also add one advisory flag (FSCACHE_ADV_WANT_CACHE_SIZE) suggesting that
the cache file size shall be retrieved at runtime. This helps the
scenario where one cache file contains multiple netfs files, e.g. for
the purpose of deduplication. In this case, netfs itself has no idea the
size of the cache file, whilst the user daemon should give the hint on
it.
Signed-off-by: Jeffle Xu <jefflexu@linux.alibaba.com>
Link: https://lore.kernel.org/r/20220509074028.74954-3-jefflexu@linux.alibaba.com
Acked-by: David Howells <dhowells@redhat.com>
Signed-off-by: Gao Xiang <hsiangkao@linux.alibaba.com>
2022-04-25 20:21:24 +08:00
|
|
|
XA_STATE(xas, &cache->reqs, 0);
|
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
|
|
if (!test_bit(CACHEFILES_ONDEMAND_MODE, &cache->flags))
|
|
|
|
|
return 0;
|
|
|
|
|
|
2023-11-20 12:14:20 +08:00
|
|
|
if (test_bit(CACHEFILES_DEAD, &cache->flags)) {
|
|
|
|
|
ret = -EIO;
|
|
|
|
|
goto out;
|
|
|
|
|
}
|
cachefiles: notify the user daemon when looking up cookie
Fscache/CacheFiles used to serve as a local cache for a remote
networking fs. A new on-demand read mode will be introduced for
CacheFiles, which can boost the scenario where on-demand read semantics
are needed, e.g. container image distribution.
The essential difference between these two modes is seen when a cache
miss occurs: In the original mode, the netfs will fetch the data from
the remote server and then write it to the cache file; in on-demand
read mode, fetching the data and writing it into the cache is delegated
to a user daemon.
As the first step, notify the user daemon when looking up cookie. In
this case, an anonymous fd is sent to the user daemon, through which the
user daemon can write the fetched data to the cache file. Since the user
daemon may move the anonymous fd around, e.g. through dup(), an object
ID uniquely identifying the cache file is also attached.
Also add one advisory flag (FSCACHE_ADV_WANT_CACHE_SIZE) suggesting that
the cache file size shall be retrieved at runtime. This helps the
scenario where one cache file contains multiple netfs files, e.g. for
the purpose of deduplication. In this case, netfs itself has no idea the
size of the cache file, whilst the user daemon should give the hint on
it.
Signed-off-by: Jeffle Xu <jefflexu@linux.alibaba.com>
Link: https://lore.kernel.org/r/20220509074028.74954-3-jefflexu@linux.alibaba.com
Acked-by: David Howells <dhowells@redhat.com>
Signed-off-by: Gao Xiang <hsiangkao@linux.alibaba.com>
2022-04-25 20:21:24 +08:00
|
|
|
|
|
|
|
|
req = kzalloc(sizeof(*req) + data_len, GFP_KERNEL);
|
2023-11-20 12:14:20 +08:00
|
|
|
if (!req) {
|
|
|
|
|
ret = -ENOMEM;
|
|
|
|
|
goto out;
|
|
|
|
|
}
|
cachefiles: notify the user daemon when looking up cookie
Fscache/CacheFiles used to serve as a local cache for a remote
networking fs. A new on-demand read mode will be introduced for
CacheFiles, which can boost the scenario where on-demand read semantics
are needed, e.g. container image distribution.
The essential difference between these two modes is seen when a cache
miss occurs: In the original mode, the netfs will fetch the data from
the remote server and then write it to the cache file; in on-demand
read mode, fetching the data and writing it into the cache is delegated
to a user daemon.
As the first step, notify the user daemon when looking up cookie. In
this case, an anonymous fd is sent to the user daemon, through which the
user daemon can write the fetched data to the cache file. Since the user
daemon may move the anonymous fd around, e.g. through dup(), an object
ID uniquely identifying the cache file is also attached.
Also add one advisory flag (FSCACHE_ADV_WANT_CACHE_SIZE) suggesting that
the cache file size shall be retrieved at runtime. This helps the
scenario where one cache file contains multiple netfs files, e.g. for
the purpose of deduplication. In this case, netfs itself has no idea the
size of the cache file, whilst the user daemon should give the hint on
it.
Signed-off-by: Jeffle Xu <jefflexu@linux.alibaba.com>
Link: https://lore.kernel.org/r/20220509074028.74954-3-jefflexu@linux.alibaba.com
Acked-by: David Howells <dhowells@redhat.com>
Signed-off-by: Gao Xiang <hsiangkao@linux.alibaba.com>
2022-04-25 20:21:24 +08:00
|
|
|
|
cachefiles: fix slab-use-after-free in cachefiles_ondemand_get_fd()
We got the following issue in a fuzz test of randomly issuing the restore
command:
==================================================================
BUG: KASAN: slab-use-after-free in cachefiles_ondemand_daemon_read+0x609/0xab0
Write of size 4 at addr ffff888109164a80 by task ondemand-04-dae/4962
CPU: 11 PID: 4962 Comm: ondemand-04-dae Not tainted 6.8.0-rc7-dirty #542
Call Trace:
kasan_report+0x94/0xc0
cachefiles_ondemand_daemon_read+0x609/0xab0
vfs_read+0x169/0xb50
ksys_read+0xf5/0x1e0
Allocated by task 626:
__kmalloc+0x1df/0x4b0
cachefiles_ondemand_send_req+0x24d/0x690
cachefiles_create_tmpfile+0x249/0xb30
cachefiles_create_file+0x6f/0x140
cachefiles_look_up_object+0x29c/0xa60
cachefiles_lookup_cookie+0x37d/0xca0
fscache_cookie_state_machine+0x43c/0x1230
[...]
Freed by task 626:
kfree+0xf1/0x2c0
cachefiles_ondemand_send_req+0x568/0x690
cachefiles_create_tmpfile+0x249/0xb30
cachefiles_create_file+0x6f/0x140
cachefiles_look_up_object+0x29c/0xa60
cachefiles_lookup_cookie+0x37d/0xca0
fscache_cookie_state_machine+0x43c/0x1230
[...]
==================================================================
Following is the process that triggers the issue:
mount | daemon_thread1 | daemon_thread2
------------------------------------------------------------
cachefiles_ondemand_init_object
cachefiles_ondemand_send_req
REQ_A = kzalloc(sizeof(*req) + data_len)
wait_for_completion(&REQ_A->done)
cachefiles_daemon_read
cachefiles_ondemand_daemon_read
REQ_A = cachefiles_ondemand_select_req
cachefiles_ondemand_get_fd
copy_to_user(_buffer, msg, n)
process_open_req(REQ_A)
------ restore ------
cachefiles_ondemand_restore
xas_for_each(&xas, req, ULONG_MAX)
xas_set_mark(&xas, CACHEFILES_REQ_NEW);
cachefiles_daemon_read
cachefiles_ondemand_daemon_read
REQ_A = cachefiles_ondemand_select_req
write(devfd, ("copen %u,%llu", msg->msg_id, size));
cachefiles_ondemand_copen
xa_erase(&cache->reqs, id)
complete(&REQ_A->done)
kfree(REQ_A)
cachefiles_ondemand_get_fd(REQ_A)
fd = get_unused_fd_flags
file = anon_inode_getfile
fd_install(fd, file)
load = (void *)REQ_A->msg.data;
load->fd = fd;
// load UAF !!!
This issue is caused by issuing a restore command when the daemon is still
alive, which results in a request being processed multiple times thus
triggering a UAF. So to avoid this problem, add an additional reference
count to cachefiles_req, which is held while waiting and reading, and then
released when the waiting and reading is over.
Note that since there is only one reference count for waiting, we need to
avoid the same request being completed multiple times, so we can only
complete the request if it is successfully removed from the xarray.
Fixes: e73fa11a356c ("cachefiles: add restore command to recover inflight ondemand read requests")
Suggested-by: Hou Tao <houtao1@huawei.com>
Signed-off-by: Baokun Li <libaokun1@huawei.com>
Link: https://lore.kernel.org/r/20240522114308.2402121-4-libaokun@huaweicloud.com
Acked-by: Jeff Layton <jlayton@kernel.org>
Reviewed-by: Jia Zhu <zhujia.zj@bytedance.com>
Reviewed-by: Jingbo Xu <jefflexu@linux.alibaba.com>
Signed-off-by: Christian Brauner <brauner@kernel.org>
2024-05-22 19:42:59 +08:00
|
|
|
refcount_set(&req->ref, 1);
|
cachefiles: notify the user daemon when looking up cookie
Fscache/CacheFiles used to serve as a local cache for a remote
networking fs. A new on-demand read mode will be introduced for
CacheFiles, which can boost the scenario where on-demand read semantics
are needed, e.g. container image distribution.
The essential difference between these two modes is seen when a cache
miss occurs: In the original mode, the netfs will fetch the data from
the remote server and then write it to the cache file; in on-demand
read mode, fetching the data and writing it into the cache is delegated
to a user daemon.
As the first step, notify the user daemon when looking up cookie. In
this case, an anonymous fd is sent to the user daemon, through which the
user daemon can write the fetched data to the cache file. Since the user
daemon may move the anonymous fd around, e.g. through dup(), an object
ID uniquely identifying the cache file is also attached.
Also add one advisory flag (FSCACHE_ADV_WANT_CACHE_SIZE) suggesting that
the cache file size shall be retrieved at runtime. This helps the
scenario where one cache file contains multiple netfs files, e.g. for
the purpose of deduplication. In this case, netfs itself has no idea the
size of the cache file, whilst the user daemon should give the hint on
it.
Signed-off-by: Jeffle Xu <jefflexu@linux.alibaba.com>
Link: https://lore.kernel.org/r/20220509074028.74954-3-jefflexu@linux.alibaba.com
Acked-by: David Howells <dhowells@redhat.com>
Signed-off-by: Gao Xiang <hsiangkao@linux.alibaba.com>
2022-04-25 20:21:24 +08:00
|
|
|
req->object = object;
|
|
|
|
|
init_completion(&req->done);
|
|
|
|
|
req->msg.opcode = opcode;
|
|
|
|
|
req->msg.len = sizeof(struct cachefiles_msg) + data_len;
|
|
|
|
|
|
|
|
|
|
ret = init_req(req, private);
|
|
|
|
|
if (ret)
|
|
|
|
|
goto out;
|
|
|
|
|
|
|
|
|
|
do {
|
|
|
|
|
/*
|
|
|
|
|
* Stop enqueuing the request when daemon is dying. The
|
|
|
|
|
* following two operations need to be atomic as a whole.
|
|
|
|
|
* 1) check cache state, and
|
|
|
|
|
* 2) enqueue request if cache is alive.
|
|
|
|
|
* Otherwise the request may be enqueued after xarray has been
|
|
|
|
|
* flushed, leaving the orphan request never being completed.
|
|
|
|
|
*
|
|
|
|
|
* CPU 1 CPU 2
|
|
|
|
|
* ===== =====
|
|
|
|
|
* test CACHEFILES_DEAD bit
|
|
|
|
|
* set CACHEFILES_DEAD bit
|
|
|
|
|
* flush requests in the xarray
|
|
|
|
|
* enqueue the request
|
|
|
|
|
*/
|
|
|
|
|
xas_lock(&xas);
|
|
|
|
|
|
|
|
|
|
if (test_bit(CACHEFILES_DEAD, &cache->flags)) {
|
|
|
|
|
xas_unlock(&xas);
|
|
|
|
|
ret = -EIO;
|
|
|
|
|
goto out;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* coupled with the barrier in cachefiles_flush_reqs() */
|
|
|
|
|
smp_mb();
|
|
|
|
|
|
2023-11-20 12:14:20 +08:00
|
|
|
if (opcode == CACHEFILES_OP_CLOSE &&
|
2023-11-20 12:14:18 +08:00
|
|
|
!cachefiles_ondemand_object_is_open(object)) {
|
2023-11-20 12:14:19 +08:00
|
|
|
WARN_ON_ONCE(object->ondemand->ondemand_id == 0);
|
2022-04-25 20:21:26 +08:00
|
|
|
xas_unlock(&xas);
|
|
|
|
|
ret = -EIO;
|
|
|
|
|
goto out;
|
|
|
|
|
}
|
|
|
|
|
|
cachefiles: notify the user daemon when looking up cookie
Fscache/CacheFiles used to serve as a local cache for a remote
networking fs. A new on-demand read mode will be introduced for
CacheFiles, which can boost the scenario where on-demand read semantics
are needed, e.g. container image distribution.
The essential difference between these two modes is seen when a cache
miss occurs: In the original mode, the netfs will fetch the data from
the remote server and then write it to the cache file; in on-demand
read mode, fetching the data and writing it into the cache is delegated
to a user daemon.
As the first step, notify the user daemon when looking up cookie. In
this case, an anonymous fd is sent to the user daemon, through which the
user daemon can write the fetched data to the cache file. Since the user
daemon may move the anonymous fd around, e.g. through dup(), an object
ID uniquely identifying the cache file is also attached.
Also add one advisory flag (FSCACHE_ADV_WANT_CACHE_SIZE) suggesting that
the cache file size shall be retrieved at runtime. This helps the
scenario where one cache file contains multiple netfs files, e.g. for
the purpose of deduplication. In this case, netfs itself has no idea the
size of the cache file, whilst the user daemon should give the hint on
it.
Signed-off-by: Jeffle Xu <jefflexu@linux.alibaba.com>
Link: https://lore.kernel.org/r/20220509074028.74954-3-jefflexu@linux.alibaba.com
Acked-by: David Howells <dhowells@redhat.com>
Signed-off-by: Gao Xiang <hsiangkao@linux.alibaba.com>
2022-04-25 20:21:24 +08:00
|
|
|
xas.xa_index = 0;
|
|
|
|
|
xas_find_marked(&xas, UINT_MAX, XA_FREE_MARK);
|
|
|
|
|
if (xas.xa_node == XAS_RESTART)
|
|
|
|
|
xas_set_err(&xas, -EBUSY);
|
|
|
|
|
xas_store(&xas, req);
|
|
|
|
|
xas_clear_mark(&xas, XA_FREE_MARK);
|
|
|
|
|
xas_set_mark(&xas, CACHEFILES_REQ_NEW);
|
|
|
|
|
xas_unlock(&xas);
|
|
|
|
|
} while (xas_nomem(&xas, GFP_KERNEL));
|
|
|
|
|
|
|
|
|
|
ret = xas_error(&xas);
|
|
|
|
|
if (ret)
|
|
|
|
|
goto out;
|
|
|
|
|
|
|
|
|
|
wake_up_all(&cache->daemon_pollwq);
|
|
|
|
|
wait_for_completion(&req->done);
|
|
|
|
|
ret = req->error;
|
cachefiles: fix slab-use-after-free in cachefiles_ondemand_get_fd()
We got the following issue in a fuzz test of randomly issuing the restore
command:
==================================================================
BUG: KASAN: slab-use-after-free in cachefiles_ondemand_daemon_read+0x609/0xab0
Write of size 4 at addr ffff888109164a80 by task ondemand-04-dae/4962
CPU: 11 PID: 4962 Comm: ondemand-04-dae Not tainted 6.8.0-rc7-dirty #542
Call Trace:
kasan_report+0x94/0xc0
cachefiles_ondemand_daemon_read+0x609/0xab0
vfs_read+0x169/0xb50
ksys_read+0xf5/0x1e0
Allocated by task 626:
__kmalloc+0x1df/0x4b0
cachefiles_ondemand_send_req+0x24d/0x690
cachefiles_create_tmpfile+0x249/0xb30
cachefiles_create_file+0x6f/0x140
cachefiles_look_up_object+0x29c/0xa60
cachefiles_lookup_cookie+0x37d/0xca0
fscache_cookie_state_machine+0x43c/0x1230
[...]
Freed by task 626:
kfree+0xf1/0x2c0
cachefiles_ondemand_send_req+0x568/0x690
cachefiles_create_tmpfile+0x249/0xb30
cachefiles_create_file+0x6f/0x140
cachefiles_look_up_object+0x29c/0xa60
cachefiles_lookup_cookie+0x37d/0xca0
fscache_cookie_state_machine+0x43c/0x1230
[...]
==================================================================
Following is the process that triggers the issue:
mount | daemon_thread1 | daemon_thread2
------------------------------------------------------------
cachefiles_ondemand_init_object
cachefiles_ondemand_send_req
REQ_A = kzalloc(sizeof(*req) + data_len)
wait_for_completion(&REQ_A->done)
cachefiles_daemon_read
cachefiles_ondemand_daemon_read
REQ_A = cachefiles_ondemand_select_req
cachefiles_ondemand_get_fd
copy_to_user(_buffer, msg, n)
process_open_req(REQ_A)
------ restore ------
cachefiles_ondemand_restore
xas_for_each(&xas, req, ULONG_MAX)
xas_set_mark(&xas, CACHEFILES_REQ_NEW);
cachefiles_daemon_read
cachefiles_ondemand_daemon_read
REQ_A = cachefiles_ondemand_select_req
write(devfd, ("copen %u,%llu", msg->msg_id, size));
cachefiles_ondemand_copen
xa_erase(&cache->reqs, id)
complete(&REQ_A->done)
kfree(REQ_A)
cachefiles_ondemand_get_fd(REQ_A)
fd = get_unused_fd_flags
file = anon_inode_getfile
fd_install(fd, file)
load = (void *)REQ_A->msg.data;
load->fd = fd;
// load UAF !!!
This issue is caused by issuing a restore command when the daemon is still
alive, which results in a request being processed multiple times thus
triggering a UAF. So to avoid this problem, add an additional reference
count to cachefiles_req, which is held while waiting and reading, and then
released when the waiting and reading is over.
Note that since there is only one reference count for waiting, we need to
avoid the same request being completed multiple times, so we can only
complete the request if it is successfully removed from the xarray.
Fixes: e73fa11a356c ("cachefiles: add restore command to recover inflight ondemand read requests")
Suggested-by: Hou Tao <houtao1@huawei.com>
Signed-off-by: Baokun Li <libaokun1@huawei.com>
Link: https://lore.kernel.org/r/20240522114308.2402121-4-libaokun@huaweicloud.com
Acked-by: Jeff Layton <jlayton@kernel.org>
Reviewed-by: Jia Zhu <zhujia.zj@bytedance.com>
Reviewed-by: Jingbo Xu <jefflexu@linux.alibaba.com>
Signed-off-by: Christian Brauner <brauner@kernel.org>
2024-05-22 19:42:59 +08:00
|
|
|
cachefiles_req_put(req);
|
2023-11-20 12:14:20 +08:00
|
|
|
return ret;
|
cachefiles: notify the user daemon when looking up cookie
Fscache/CacheFiles used to serve as a local cache for a remote
networking fs. A new on-demand read mode will be introduced for
CacheFiles, which can boost the scenario where on-demand read semantics
are needed, e.g. container image distribution.
The essential difference between these two modes is seen when a cache
miss occurs: In the original mode, the netfs will fetch the data from
the remote server and then write it to the cache file; in on-demand
read mode, fetching the data and writing it into the cache is delegated
to a user daemon.
As the first step, notify the user daemon when looking up cookie. In
this case, an anonymous fd is sent to the user daemon, through which the
user daemon can write the fetched data to the cache file. Since the user
daemon may move the anonymous fd around, e.g. through dup(), an object
ID uniquely identifying the cache file is also attached.
Also add one advisory flag (FSCACHE_ADV_WANT_CACHE_SIZE) suggesting that
the cache file size shall be retrieved at runtime. This helps the
scenario where one cache file contains multiple netfs files, e.g. for
the purpose of deduplication. In this case, netfs itself has no idea the
size of the cache file, whilst the user daemon should give the hint on
it.
Signed-off-by: Jeffle Xu <jefflexu@linux.alibaba.com>
Link: https://lore.kernel.org/r/20220509074028.74954-3-jefflexu@linux.alibaba.com
Acked-by: David Howells <dhowells@redhat.com>
Signed-off-by: Gao Xiang <hsiangkao@linux.alibaba.com>
2022-04-25 20:21:24 +08:00
|
|
|
out:
|
2023-11-20 12:14:20 +08:00
|
|
|
/* Reset the object to close state in error handling path.
|
|
|
|
|
* If error occurs after creating the anonymous fd,
|
|
|
|
|
* cachefiles_ondemand_fd_release() will set object to close.
|
|
|
|
|
*/
|
|
|
|
|
if (opcode == CACHEFILES_OP_OPEN)
|
|
|
|
|
cachefiles_ondemand_set_object_close(object);
|
cachefiles: notify the user daemon when looking up cookie
Fscache/CacheFiles used to serve as a local cache for a remote
networking fs. A new on-demand read mode will be introduced for
CacheFiles, which can boost the scenario where on-demand read semantics
are needed, e.g. container image distribution.
The essential difference between these two modes is seen when a cache
miss occurs: In the original mode, the netfs will fetch the data from
the remote server and then write it to the cache file; in on-demand
read mode, fetching the data and writing it into the cache is delegated
to a user daemon.
As the first step, notify the user daemon when looking up cookie. In
this case, an anonymous fd is sent to the user daemon, through which the
user daemon can write the fetched data to the cache file. Since the user
daemon may move the anonymous fd around, e.g. through dup(), an object
ID uniquely identifying the cache file is also attached.
Also add one advisory flag (FSCACHE_ADV_WANT_CACHE_SIZE) suggesting that
the cache file size shall be retrieved at runtime. This helps the
scenario where one cache file contains multiple netfs files, e.g. for
the purpose of deduplication. In this case, netfs itself has no idea the
size of the cache file, whilst the user daemon should give the hint on
it.
Signed-off-by: Jeffle Xu <jefflexu@linux.alibaba.com>
Link: https://lore.kernel.org/r/20220509074028.74954-3-jefflexu@linux.alibaba.com
Acked-by: David Howells <dhowells@redhat.com>
Signed-off-by: Gao Xiang <hsiangkao@linux.alibaba.com>
2022-04-25 20:21:24 +08:00
|
|
|
kfree(req);
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int cachefiles_ondemand_init_open_req(struct cachefiles_req *req,
|
|
|
|
|
void *private)
|
|
|
|
|
{
|
|
|
|
|
struct cachefiles_object *object = req->object;
|
|
|
|
|
struct fscache_cookie *cookie = object->cookie;
|
|
|
|
|
struct fscache_volume *volume = object->volume->vcookie;
|
|
|
|
|
struct cachefiles_open *load = (void *)req->msg.data;
|
|
|
|
|
size_t volume_key_size, cookie_key_size;
|
|
|
|
|
void *volume_key, *cookie_key;
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Volume key is a NUL-terminated string. key[0] stores strlen() of the
|
|
|
|
|
* string, followed by the content of the string (excluding '\0').
|
|
|
|
|
*/
|
|
|
|
|
volume_key_size = volume->key[0] + 1;
|
|
|
|
|
volume_key = volume->key + 1;
|
|
|
|
|
|
|
|
|
|
/* Cookie key is binary data, which is netfs specific. */
|
|
|
|
|
cookie_key_size = cookie->key_len;
|
|
|
|
|
cookie_key = fscache_get_key(cookie);
|
|
|
|
|
|
|
|
|
|
if (!(object->cookie->advice & FSCACHE_ADV_WANT_CACHE_SIZE)) {
|
|
|
|
|
pr_err("WANT_CACHE_SIZE is needed for on-demand mode\n");
|
|
|
|
|
return -EINVAL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
load->volume_key_size = volume_key_size;
|
|
|
|
|
load->cookie_key_size = cookie_key_size;
|
|
|
|
|
memcpy(load->data, volume_key, volume_key_size);
|
|
|
|
|
memcpy(load->data + volume_key_size, cookie_key, cookie_key_size);
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2022-04-25 20:21:26 +08:00
|
|
|
static int cachefiles_ondemand_init_close_req(struct cachefiles_req *req,
|
|
|
|
|
void *private)
|
|
|
|
|
{
|
|
|
|
|
struct cachefiles_object *object = req->object;
|
|
|
|
|
|
2023-11-20 12:14:18 +08:00
|
|
|
if (!cachefiles_ondemand_object_is_open(object))
|
2022-04-25 20:21:26 +08:00
|
|
|
return -ENOENT;
|
|
|
|
|
|
2022-04-25 20:21:29 +08:00
|
|
|
trace_cachefiles_ondemand_close(object, &req->msg);
|
2022-04-25 20:21:26 +08:00
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2022-04-25 20:21:27 +08:00
|
|
|
struct cachefiles_read_ctx {
|
|
|
|
|
loff_t off;
|
|
|
|
|
size_t len;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static int cachefiles_ondemand_init_read_req(struct cachefiles_req *req,
|
|
|
|
|
void *private)
|
|
|
|
|
{
|
|
|
|
|
struct cachefiles_object *object = req->object;
|
|
|
|
|
struct cachefiles_read *load = (void *)req->msg.data;
|
|
|
|
|
struct cachefiles_read_ctx *read_ctx = private;
|
|
|
|
|
|
|
|
|
|
load->off = read_ctx->off;
|
|
|
|
|
load->len = read_ctx->len;
|
2022-04-25 20:21:29 +08:00
|
|
|
trace_cachefiles_ondemand_read(object, &req->msg, load);
|
2022-04-25 20:21:27 +08:00
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
cachefiles: notify the user daemon when looking up cookie
Fscache/CacheFiles used to serve as a local cache for a remote
networking fs. A new on-demand read mode will be introduced for
CacheFiles, which can boost the scenario where on-demand read semantics
are needed, e.g. container image distribution.
The essential difference between these two modes is seen when a cache
miss occurs: In the original mode, the netfs will fetch the data from
the remote server and then write it to the cache file; in on-demand
read mode, fetching the data and writing it into the cache is delegated
to a user daemon.
As the first step, notify the user daemon when looking up cookie. In
this case, an anonymous fd is sent to the user daemon, through which the
user daemon can write the fetched data to the cache file. Since the user
daemon may move the anonymous fd around, e.g. through dup(), an object
ID uniquely identifying the cache file is also attached.
Also add one advisory flag (FSCACHE_ADV_WANT_CACHE_SIZE) suggesting that
the cache file size shall be retrieved at runtime. This helps the
scenario where one cache file contains multiple netfs files, e.g. for
the purpose of deduplication. In this case, netfs itself has no idea the
size of the cache file, whilst the user daemon should give the hint on
it.
Signed-off-by: Jeffle Xu <jefflexu@linux.alibaba.com>
Link: https://lore.kernel.org/r/20220509074028.74954-3-jefflexu@linux.alibaba.com
Acked-by: David Howells <dhowells@redhat.com>
Signed-off-by: Gao Xiang <hsiangkao@linux.alibaba.com>
2022-04-25 20:21:24 +08:00
|
|
|
int cachefiles_ondemand_init_object(struct cachefiles_object *object)
|
|
|
|
|
{
|
|
|
|
|
struct fscache_cookie *cookie = object->cookie;
|
|
|
|
|
struct fscache_volume *volume = object->volume->vcookie;
|
|
|
|
|
size_t volume_key_size, cookie_key_size, data_len;
|
|
|
|
|
|
2024-01-19 20:49:34 +00:00
|
|
|
if (!object->ondemand)
|
|
|
|
|
return 0;
|
|
|
|
|
|
cachefiles: notify the user daemon when looking up cookie
Fscache/CacheFiles used to serve as a local cache for a remote
networking fs. A new on-demand read mode will be introduced for
CacheFiles, which can boost the scenario where on-demand read semantics
are needed, e.g. container image distribution.
The essential difference between these two modes is seen when a cache
miss occurs: In the original mode, the netfs will fetch the data from
the remote server and then write it to the cache file; in on-demand
read mode, fetching the data and writing it into the cache is delegated
to a user daemon.
As the first step, notify the user daemon when looking up cookie. In
this case, an anonymous fd is sent to the user daemon, through which the
user daemon can write the fetched data to the cache file. Since the user
daemon may move the anonymous fd around, e.g. through dup(), an object
ID uniquely identifying the cache file is also attached.
Also add one advisory flag (FSCACHE_ADV_WANT_CACHE_SIZE) suggesting that
the cache file size shall be retrieved at runtime. This helps the
scenario where one cache file contains multiple netfs files, e.g. for
the purpose of deduplication. In this case, netfs itself has no idea the
size of the cache file, whilst the user daemon should give the hint on
it.
Signed-off-by: Jeffle Xu <jefflexu@linux.alibaba.com>
Link: https://lore.kernel.org/r/20220509074028.74954-3-jefflexu@linux.alibaba.com
Acked-by: David Howells <dhowells@redhat.com>
Signed-off-by: Gao Xiang <hsiangkao@linux.alibaba.com>
2022-04-25 20:21:24 +08:00
|
|
|
/*
|
|
|
|
|
* CacheFiles will firstly check the cache file under the root cache
|
|
|
|
|
* directory. If the coherency check failed, it will fallback to
|
|
|
|
|
* creating a new tmpfile as the cache file. Reuse the previously
|
|
|
|
|
* allocated object ID if any.
|
|
|
|
|
*/
|
2023-11-20 12:14:18 +08:00
|
|
|
if (cachefiles_ondemand_object_is_open(object))
|
cachefiles: notify the user daemon when looking up cookie
Fscache/CacheFiles used to serve as a local cache for a remote
networking fs. A new on-demand read mode will be introduced for
CacheFiles, which can boost the scenario where on-demand read semantics
are needed, e.g. container image distribution.
The essential difference between these two modes is seen when a cache
miss occurs: In the original mode, the netfs will fetch the data from
the remote server and then write it to the cache file; in on-demand
read mode, fetching the data and writing it into the cache is delegated
to a user daemon.
As the first step, notify the user daemon when looking up cookie. In
this case, an anonymous fd is sent to the user daemon, through which the
user daemon can write the fetched data to the cache file. Since the user
daemon may move the anonymous fd around, e.g. through dup(), an object
ID uniquely identifying the cache file is also attached.
Also add one advisory flag (FSCACHE_ADV_WANT_CACHE_SIZE) suggesting that
the cache file size shall be retrieved at runtime. This helps the
scenario where one cache file contains multiple netfs files, e.g. for
the purpose of deduplication. In this case, netfs itself has no idea the
size of the cache file, whilst the user daemon should give the hint on
it.
Signed-off-by: Jeffle Xu <jefflexu@linux.alibaba.com>
Link: https://lore.kernel.org/r/20220509074028.74954-3-jefflexu@linux.alibaba.com
Acked-by: David Howells <dhowells@redhat.com>
Signed-off-by: Gao Xiang <hsiangkao@linux.alibaba.com>
2022-04-25 20:21:24 +08:00
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
volume_key_size = volume->key[0] + 1;
|
|
|
|
|
cookie_key_size = cookie->key_len;
|
|
|
|
|
data_len = sizeof(struct cachefiles_open) +
|
|
|
|
|
volume_key_size + cookie_key_size;
|
|
|
|
|
|
|
|
|
|
return cachefiles_ondemand_send_req(object, CACHEFILES_OP_OPEN,
|
|
|
|
|
data_len, cachefiles_ondemand_init_open_req, NULL);
|
|
|
|
|
}
|
2022-04-25 20:21:26 +08:00
|
|
|
|
|
|
|
|
void cachefiles_ondemand_clean_object(struct cachefiles_object *object)
|
|
|
|
|
{
|
|
|
|
|
cachefiles_ondemand_send_req(object, CACHEFILES_OP_CLOSE, 0,
|
|
|
|
|
cachefiles_ondemand_init_close_req, NULL);
|
|
|
|
|
}
|
2022-04-25 20:21:27 +08:00
|
|
|
|
2023-11-20 12:14:19 +08:00
|
|
|
int cachefiles_ondemand_init_obj_info(struct cachefiles_object *object,
|
|
|
|
|
struct cachefiles_volume *volume)
|
|
|
|
|
{
|
|
|
|
|
if (!cachefiles_in_ondemand_mode(volume->cache))
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
object->ondemand = kzalloc(sizeof(struct cachefiles_ondemand_info),
|
|
|
|
|
GFP_KERNEL);
|
|
|
|
|
if (!object->ondemand)
|
|
|
|
|
return -ENOMEM;
|
|
|
|
|
|
|
|
|
|
object->ondemand->object = object;
|
2023-11-20 12:14:20 +08:00
|
|
|
INIT_WORK(&object->ondemand->ondemand_work, ondemand_object_worker);
|
2023-11-20 12:14:19 +08:00
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void cachefiles_ondemand_deinit_obj_info(struct cachefiles_object *object)
|
|
|
|
|
{
|
|
|
|
|
kfree(object->ondemand);
|
|
|
|
|
object->ondemand = NULL;
|
|
|
|
|
}
|
|
|
|
|
|
2022-04-25 20:21:27 +08:00
|
|
|
int cachefiles_ondemand_read(struct cachefiles_object *object,
|
|
|
|
|
loff_t pos, size_t len)
|
|
|
|
|
{
|
|
|
|
|
struct cachefiles_read_ctx read_ctx = {pos, len};
|
|
|
|
|
|
|
|
|
|
return cachefiles_ondemand_send_req(object, CACHEFILES_OP_READ,
|
|
|
|
|
sizeof(struct cachefiles_read),
|
|
|
|
|
cachefiles_ondemand_init_read_req, &read_ctx);
|
|
|
|
|
}
|