mirror of
https://github.com/tbsdtv/linux_media.git
synced 2025-07-23 20:51:03 +02:00
cachefiles: document on-demand read mode
Document new user interface introduced by on-demand read mode. Signed-off-by: Jeffle Xu <jefflexu@linux.alibaba.com> Link: https://lore.kernel.org/r/20220509074028.74954-9-jefflexu@linux.alibaba.com Acked-by: David Howells <dhowells@redhat.com> Signed-off-by: Gao Xiang <hsiangkao@linux.alibaba.com>
This commit is contained in:
@@ -28,6 +28,7 @@ Cache on Already Mounted Filesystem
|
|||||||
|
|
||||||
(*) Debugging.
|
(*) Debugging.
|
||||||
|
|
||||||
|
(*) On-demand Read.
|
||||||
|
|
||||||
|
|
||||||
Overview
|
Overview
|
||||||
@@ -482,3 +483,180 @@ the control file. For example::
|
|||||||
echo $((1|4|8)) >/sys/module/cachefiles/parameters/debug
|
echo $((1|4|8)) >/sys/module/cachefiles/parameters/debug
|
||||||
|
|
||||||
will turn on all function entry debugging.
|
will turn on all function entry debugging.
|
||||||
|
|
||||||
|
|
||||||
|
On-demand Read
|
||||||
|
==============
|
||||||
|
|
||||||
|
When working in its original mode, CacheFiles serves as a local cache for a
|
||||||
|
remote networking fs - while in on-demand read mode, CacheFiles 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.
|
||||||
|
|
||||||
|
``CONFIG_CACHEFILES_ONDEMAND`` should be enabled to support on-demand read mode.
|
||||||
|
|
||||||
|
|
||||||
|
Protocol Communication
|
||||||
|
----------------------
|
||||||
|
|
||||||
|
The on-demand read mode uses a simple protocol for communication between kernel
|
||||||
|
and user daemon. The protocol can be modeled as::
|
||||||
|
|
||||||
|
kernel --[request]--> user daemon --[reply]--> kernel
|
||||||
|
|
||||||
|
CacheFiles will send requests to the user daemon when needed. The user daemon
|
||||||
|
should poll the devnode ('/dev/cachefiles') to check if there's a pending
|
||||||
|
request to be processed. A POLLIN event will be returned when there's a pending
|
||||||
|
request.
|
||||||
|
|
||||||
|
The user daemon then reads the devnode to fetch a request to process. It should
|
||||||
|
be noted that each read only gets one request. When it has finished processing
|
||||||
|
the request, the user daemon should write the reply to the devnode.
|
||||||
|
|
||||||
|
Each request starts with a message header of the form::
|
||||||
|
|
||||||
|
struct cachefiles_msg {
|
||||||
|
__u32 msg_id;
|
||||||
|
__u32 opcode;
|
||||||
|
__u32 len;
|
||||||
|
__u32 object_id;
|
||||||
|
__u8 data[];
|
||||||
|
};
|
||||||
|
|
||||||
|
where:
|
||||||
|
|
||||||
|
* ``msg_id`` is a unique ID identifying this request among all pending
|
||||||
|
requests.
|
||||||
|
|
||||||
|
* ``opcode`` indicates the type of this request.
|
||||||
|
|
||||||
|
* ``object_id`` is a unique ID identifying the cache file operated on.
|
||||||
|
|
||||||
|
* ``data`` indicates the payload of this request.
|
||||||
|
|
||||||
|
* ``len`` indicates the whole length of this request, including the
|
||||||
|
header and following type-specific payload.
|
||||||
|
|
||||||
|
|
||||||
|
Turning on On-demand Mode
|
||||||
|
-------------------------
|
||||||
|
|
||||||
|
An optional parameter becomes available to the "bind" command::
|
||||||
|
|
||||||
|
bind [ondemand]
|
||||||
|
|
||||||
|
When the "bind" command is given no argument, it defaults to the original mode.
|
||||||
|
When it is given the "ondemand" argument, i.e. "bind ondemand", on-demand read
|
||||||
|
mode will be enabled.
|
||||||
|
|
||||||
|
|
||||||
|
The OPEN Request
|
||||||
|
----------------
|
||||||
|
|
||||||
|
When the netfs opens a cache file for the first time, a request with the
|
||||||
|
CACHEFILES_OP_OPEN opcode, a.k.a an OPEN request will be sent to the user
|
||||||
|
daemon. The payload format is of the form::
|
||||||
|
|
||||||
|
struct cachefiles_open {
|
||||||
|
__u32 volume_key_size;
|
||||||
|
__u32 cookie_key_size;
|
||||||
|
__u32 fd;
|
||||||
|
__u32 flags;
|
||||||
|
__u8 data[];
|
||||||
|
};
|
||||||
|
|
||||||
|
where:
|
||||||
|
|
||||||
|
* ``data`` contains the volume_key followed directly by the cookie_key.
|
||||||
|
The volume key is a NUL-terminated string; the cookie key is binary
|
||||||
|
data.
|
||||||
|
|
||||||
|
* ``volume_key_size`` indicates the size of the volume key in bytes.
|
||||||
|
|
||||||
|
* ``cookie_key_size`` indicates the size of the cookie key in bytes.
|
||||||
|
|
||||||
|
* ``fd`` indicates an anonymous fd referring to the cache file, through
|
||||||
|
which the user daemon can perform write/llseek file operations on the
|
||||||
|
cache file.
|
||||||
|
|
||||||
|
|
||||||
|
The user daemon can use the given (volume_key, cookie_key) pair to distinguish
|
||||||
|
the requested cache file. With the given anonymous fd, the user daemon can
|
||||||
|
fetch the data and write it to the cache file in the background, even when
|
||||||
|
kernel has not triggered a cache miss yet.
|
||||||
|
|
||||||
|
Be noted that each cache file has a unique object_id, while it may have multiple
|
||||||
|
anonymous fds. The user daemon may duplicate anonymous fds from the initial
|
||||||
|
anonymous fd indicated by the @fd field through dup(). Thus each object_id can
|
||||||
|
be mapped to multiple anonymous fds, while the usr daemon itself needs to
|
||||||
|
maintain the mapping.
|
||||||
|
|
||||||
|
When implementing a user daemon, please be careful of RLIMIT_NOFILE,
|
||||||
|
``/proc/sys/fs/nr_open`` and ``/proc/sys/fs/file-max``. Typically these needn't
|
||||||
|
be huge since they're related to the number of open device blobs rather than
|
||||||
|
open files of each individual filesystem.
|
||||||
|
|
||||||
|
The user daemon should reply the OPEN request by issuing a "copen" (complete
|
||||||
|
open) command on the devnode::
|
||||||
|
|
||||||
|
copen <msg_id>,<cache_size>
|
||||||
|
|
||||||
|
where:
|
||||||
|
|
||||||
|
* ``msg_id`` must match the msg_id field of the OPEN request.
|
||||||
|
|
||||||
|
* When >= 0, ``cache_size`` indicates the size of the cache file;
|
||||||
|
when < 0, ``cache_size`` indicates any error code encountered by the
|
||||||
|
user daemon.
|
||||||
|
|
||||||
|
|
||||||
|
The CLOSE Request
|
||||||
|
-----------------
|
||||||
|
|
||||||
|
When a cookie withdrawn, a CLOSE request (opcode CACHEFILES_OP_CLOSE) will be
|
||||||
|
sent to the user daemon. This tells the user daemon to close all anonymous fds
|
||||||
|
associated with the given object_id. The CLOSE request has no extra payload,
|
||||||
|
and shouldn't be replied.
|
||||||
|
|
||||||
|
|
||||||
|
The READ Request
|
||||||
|
----------------
|
||||||
|
|
||||||
|
When a cache miss is encountered in on-demand read mode, CacheFiles will send a
|
||||||
|
READ request (opcode CACHEFILES_OP_READ) to the user daemon. This tells the user
|
||||||
|
daemon to fetch the contents of the requested file range. The payload is of the
|
||||||
|
form::
|
||||||
|
|
||||||
|
struct cachefiles_read {
|
||||||
|
__u64 off;
|
||||||
|
__u64 len;
|
||||||
|
};
|
||||||
|
|
||||||
|
where:
|
||||||
|
|
||||||
|
* ``off`` indicates the starting offset of the requested file range.
|
||||||
|
|
||||||
|
* ``len`` indicates the length of the requested file range.
|
||||||
|
|
||||||
|
|
||||||
|
When it receives a READ request, the user daemon should fetch the requested data
|
||||||
|
and write it to the cache file identified by object_id.
|
||||||
|
|
||||||
|
When it has finished processing the READ request, the user daemon should reply
|
||||||
|
by using the CACHEFILES_IOC_READ_COMPLETE ioctl on one of the anonymous fds
|
||||||
|
associated with the object_id given in the READ request. The ioctl is of the
|
||||||
|
form::
|
||||||
|
|
||||||
|
ioctl(fd, CACHEFILES_IOC_READ_COMPLETE, msg_id);
|
||||||
|
|
||||||
|
where:
|
||||||
|
|
||||||
|
* ``fd`` is one of the anonymous fds associated with the object_id
|
||||||
|
given.
|
||||||
|
|
||||||
|
* ``msg_id`` must match the msg_id field of the READ request.
|
||||||
|
Reference in New Issue
Block a user