In on-demand read scenario, as long as the device connection
is not released, user daemon can restore the inflight request
by setting the request flag to CACHEFILES_REQ_NEW.
Signed-off-by: Jia Zhu <zhujia.zj@xxxxxxxxxxxxx>
---
fs/cachefiles/daemon.c | 1 +
fs/cachefiles/internal.h | 3 +++
fs/cachefiles/ondemand.c | 25 +++++++++++++++++++++++++
3 files changed, 29 insertions(+)
diff --git a/fs/cachefiles/daemon.c b/fs/cachefiles/daemon.c
index 5956bf10cb4b..280104171996 100644
--- a/fs/cachefiles/daemon.c
+++ b/fs/cachefiles/daemon.c
@@ -77,6 +77,7 @@ static const struct cachefiles_daemon_cmd
cachefiles_daemon_cmds[] = {
{ "tag", cachefiles_daemon_tag },
#ifdef CONFIG_CACHEFILES_ONDEMAND
{ "copen", cachefiles_ondemand_copen },
+ { "restore", cachefiles_ondemand_restore },
#endif
{ "", NULL }
};
diff --git a/fs/cachefiles/internal.h b/fs/cachefiles/internal.h
index 6cba2c6de2f9..402f552a9756 100644
--- a/fs/cachefiles/internal.h
+++ b/fs/cachefiles/internal.h
@@ -289,6 +289,9 @@ extern ssize_t
cachefiles_ondemand_daemon_read(struct cachefiles_cache *cache,
extern int cachefiles_ondemand_copen(struct cachefiles_cache *cache,
char *args);
+extern int cachefiles_ondemand_restore(struct cachefiles_cache *cache,
+ char *args);
+
extern int cachefiles_ondemand_init_object(struct cachefiles_object
*object);
extern void cachefiles_ondemand_clean_object(struct cachefiles_object
*object);
diff --git a/fs/cachefiles/ondemand.c b/fs/cachefiles/ondemand.c
index 2506e6d56965..0d0ed82f4814 100644
--- a/fs/cachefiles/ondemand.c
+++ b/fs/cachefiles/ondemand.c
@@ -174,6 +174,31 @@ int cachefiles_ondemand_copen(struct
cachefiles_cache *cache, char *args)
return ret;
}
+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;
+
+ if (test_bit(CACHEFILES_DEAD, &cache->flags))
+ return -EIO;
+
+ xas_lock(&xas);
+ /*
+ * Search the requests that being proceessed before
+ * the user daemon crashed.
+ * Set the CACHEFILES_REQ_NEW flag and user daemon will reprocess it.
+ */
+ xas_for_each(&xas, req, ULONG_MAX) {
+ if (!xas_get_mark(&xas, CACHEFILES_REQ_NEW))
+ xas_set_mark(&xas, CACHEFILES_REQ_NEW);
+ }
+ xas_unlock(&xas);
+ return 0;
+}
+
static int cachefiles_ondemand_get_fd(struct cachefiles_req *req)
{
struct cachefiles_object *object;
--
2.20.1