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...@bytedance.com>
---
 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

--
Linux-cachefs mailing list
Linux-cachefs@redhat.com
https://listman.redhat.com/mailman/listinfo/linux-cachefs

Reply via email to