Commit 357a18d0 authored by Jia Zhu's avatar Jia Zhu Committed by Christian Brauner

cachefiles: introduce object ondemand state

Previously, @ondemand_id field was used not only to identify ondemand
state of the object, but also to represent the index of the xarray.
This commit introduces @state field to decouple the role of @ondemand_id
and adds helpers to access it.
Signed-off-by: default avatarJia Zhu <zhujia.zj@bytedance.com>
Link: https://lore.kernel.org/r/20231120041422.75170-2-zhujia.zj@bytedance.comReviewed-by: default avatarJingbo Xu <jefflexu@linux.alibaba.com>
Reviewed-by: default avatarDavid Howells <dhowells@redhat.com>
Signed-off-by: default avatarChristian Brauner <brauner@kernel.org>
parent b85ea95d
...@@ -44,6 +44,11 @@ struct cachefiles_volume { ...@@ -44,6 +44,11 @@ struct cachefiles_volume {
struct dentry *fanout[256]; /* Fanout subdirs */ struct dentry *fanout[256]; /* Fanout subdirs */
}; };
enum cachefiles_object_state {
CACHEFILES_ONDEMAND_OBJSTATE_CLOSE, /* Anonymous fd closed by daemon or initial state */
CACHEFILES_ONDEMAND_OBJSTATE_OPEN, /* Anonymous fd associated with object is available */
};
/* /*
* Backing file state. * Backing file state.
*/ */
...@@ -62,6 +67,7 @@ struct cachefiles_object { ...@@ -62,6 +67,7 @@ struct cachefiles_object {
#define CACHEFILES_OBJECT_USING_TMPFILE 0 /* Have an unlinked tmpfile */ #define CACHEFILES_OBJECT_USING_TMPFILE 0 /* Have an unlinked tmpfile */
#ifdef CONFIG_CACHEFILES_ONDEMAND #ifdef CONFIG_CACHEFILES_ONDEMAND
int ondemand_id; int ondemand_id;
enum cachefiles_object_state state;
#endif #endif
}; };
...@@ -296,6 +302,21 @@ extern void cachefiles_ondemand_clean_object(struct cachefiles_object *object); ...@@ -296,6 +302,21 @@ extern void cachefiles_ondemand_clean_object(struct cachefiles_object *object);
extern int cachefiles_ondemand_read(struct cachefiles_object *object, extern int cachefiles_ondemand_read(struct cachefiles_object *object,
loff_t pos, size_t len); loff_t pos, size_t len);
#define CACHEFILES_OBJECT_STATE_FUNCS(_state, _STATE) \
static inline bool \
cachefiles_ondemand_object_is_##_state(const struct cachefiles_object *object) \
{ \
return object->state == CACHEFILES_ONDEMAND_OBJSTATE_##_STATE; \
} \
\
static inline void \
cachefiles_ondemand_set_object_##_state(struct cachefiles_object *object) \
{ \
object->state = CACHEFILES_ONDEMAND_OBJSTATE_##_STATE; \
}
CACHEFILES_OBJECT_STATE_FUNCS(open, OPEN);
CACHEFILES_OBJECT_STATE_FUNCS(close, CLOSE);
#else #else
static inline ssize_t cachefiles_ondemand_daemon_read(struct cachefiles_cache *cache, static inline ssize_t cachefiles_ondemand_daemon_read(struct cachefiles_cache *cache,
char __user *_buffer, size_t buflen) char __user *_buffer, size_t buflen)
......
...@@ -15,6 +15,7 @@ static int cachefiles_ondemand_fd_release(struct inode *inode, ...@@ -15,6 +15,7 @@ static int cachefiles_ondemand_fd_release(struct inode *inode,
xa_lock(&cache->reqs); xa_lock(&cache->reqs);
object->ondemand_id = CACHEFILES_ONDEMAND_ID_CLOSED; object->ondemand_id = CACHEFILES_ONDEMAND_ID_CLOSED;
cachefiles_ondemand_set_object_close(object);
/* /*
* Flush all pending READ requests since their completion depends on * Flush all pending READ requests since their completion depends on
...@@ -176,6 +177,8 @@ int cachefiles_ondemand_copen(struct cachefiles_cache *cache, char *args) ...@@ -176,6 +177,8 @@ int cachefiles_ondemand_copen(struct cachefiles_cache *cache, char *args)
set_bit(FSCACHE_COOKIE_NO_DATA_TO_READ, &cookie->flags); set_bit(FSCACHE_COOKIE_NO_DATA_TO_READ, &cookie->flags);
trace_cachefiles_ondemand_copen(req->object, id, size); trace_cachefiles_ondemand_copen(req->object, id, size);
cachefiles_ondemand_set_object_open(req->object);
out: out:
complete(&req->done); complete(&req->done);
return ret; return ret;
...@@ -363,7 +366,8 @@ static int cachefiles_ondemand_send_req(struct cachefiles_object *object, ...@@ -363,7 +366,8 @@ static int cachefiles_ondemand_send_req(struct cachefiles_object *object,
/* coupled with the barrier in cachefiles_flush_reqs() */ /* coupled with the barrier in cachefiles_flush_reqs() */
smp_mb(); smp_mb();
if (opcode != CACHEFILES_OP_OPEN && object->ondemand_id <= 0) { if (opcode != CACHEFILES_OP_OPEN &&
!cachefiles_ondemand_object_is_open(object)) {
WARN_ON_ONCE(object->ondemand_id == 0); WARN_ON_ONCE(object->ondemand_id == 0);
xas_unlock(&xas); xas_unlock(&xas);
ret = -EIO; ret = -EIO;
...@@ -430,18 +434,11 @@ static int cachefiles_ondemand_init_close_req(struct cachefiles_req *req, ...@@ -430,18 +434,11 @@ static int cachefiles_ondemand_init_close_req(struct cachefiles_req *req,
void *private) void *private)
{ {
struct cachefiles_object *object = req->object; struct cachefiles_object *object = req->object;
int object_id = object->ondemand_id;
/* if (!cachefiles_ondemand_object_is_open(object))
* It's possible that object id is still 0 if the cookie looking up
* phase failed before OPEN request has ever been sent. Also avoid
* sending CLOSE request for CACHEFILES_ONDEMAND_ID_CLOSED, which means
* anon_fd has already been closed.
*/
if (object_id <= 0)
return -ENOENT; return -ENOENT;
req->msg.object_id = object_id; req->msg.object_id = object->ondemand_id;
trace_cachefiles_ondemand_close(object, &req->msg); trace_cachefiles_ondemand_close(object, &req->msg);
return 0; return 0;
} }
...@@ -460,7 +457,7 @@ static int cachefiles_ondemand_init_read_req(struct cachefiles_req *req, ...@@ -460,7 +457,7 @@ static int cachefiles_ondemand_init_read_req(struct cachefiles_req *req,
int object_id = object->ondemand_id; int object_id = object->ondemand_id;
/* Stop enqueuing requests when daemon has closed anon_fd. */ /* Stop enqueuing requests when daemon has closed anon_fd. */
if (object_id <= 0) { if (!cachefiles_ondemand_object_is_open(object)) {
WARN_ON_ONCE(object_id == 0); WARN_ON_ONCE(object_id == 0);
pr_info_once("READ: anonymous fd closed prematurely.\n"); pr_info_once("READ: anonymous fd closed prematurely.\n");
return -EIO; return -EIO;
...@@ -485,7 +482,7 @@ int cachefiles_ondemand_init_object(struct cachefiles_object *object) ...@@ -485,7 +482,7 @@ int cachefiles_ondemand_init_object(struct cachefiles_object *object)
* creating a new tmpfile as the cache file. Reuse the previously * creating a new tmpfile as the cache file. Reuse the previously
* allocated object ID if any. * allocated object ID if any.
*/ */
if (object->ondemand_id > 0) if (cachefiles_ondemand_object_is_open(object))
return 0; return 0;
volume_key_size = volume->key[0] + 1; volume_key_size = volume->key[0] + 1;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment