Split file object related logic out of the liveupdate implementation so it
can be reused by other kernel subsystems.

This is a preparatory change for enabling use of the luo infrastructure
outside of liveupdate. No functional change intended.

Signed-off-by: Stanislav Kinsburskii <[email protected]>
---
 include/linux/liveupdate.h       |    3 ++
 kernel/liveupdate/luo_file.c     |   55 ++++++++++++++++++++++++++++++++------
 kernel/liveupdate/luo_internal.h |    2 +
 kernel/liveupdate/luo_session.c  |    2 +
 4 files changed, 51 insertions(+), 11 deletions(-)

diff --git a/include/linux/liveupdate.h b/include/linux/liveupdate.h
index a7f6ee5b6771..0e6e0a1b1489 100644
--- a/include/linux/liveupdate.h
+++ b/include/linux/liveupdate.h
@@ -112,6 +112,9 @@ int liveupdate_reboot(void);
 int liveupdate_register_file_handler(struct liveupdate_file_handler *fh);
 int liveupdate_unregister_file_handler(struct liveupdate_file_handler *fh);
 
+int liveupdate_session_create(char *name, struct file **filep);
+void liveupdate_session_destroy(char *name, struct file *file);
+
 #else /* CONFIG_LIVEUPDATE */
 
 static inline bool liveupdate_enabled(void)
diff --git a/kernel/liveupdate/luo_file.c b/kernel/liveupdate/luo_file.c
index a32a777f6df8..e46aeb29ab4d 100644
--- a/kernel/liveupdate/luo_file.c
+++ b/kernel/liveupdate/luo_file.c
@@ -250,12 +250,11 @@ static bool luo_token_is_used(struct luo_file_set 
*file_set, u64 token)
  *         -ENOMEM on memory allocation failure.
  *         Other erros might be returned by .preserve().
  */
-int luo_preserve_file(struct luo_file_set *file_set, u64 token, int fd)
+static int luo_preserve_file(struct luo_file_set *file_set, u64 token, struct 
file *file)
 {
        struct liveupdate_file_op_args args = {0};
        struct liveupdate_file_handler *fh;
        struct luo_file *luo_file;
-       struct file *file;
        int err;
 
        if (luo_token_is_used(file_set, token))
@@ -264,13 +263,9 @@ int luo_preserve_file(struct luo_file_set *file_set, u64 
token, int fd)
        if (file_set->count == LUO_FILE_MAX)
                return -ENOSPC;
 
-       file = fget(fd);
-       if (!file)
-               return -EBADF;
-
        err = luo_alloc_files_mem(file_set);
        if (err)
-               goto  err_fput;
+               return err;
 
        err = -ENOENT;
        luo_list_for_each_private(fh, &luo_file_handler_list, list) {
@@ -313,8 +308,22 @@ int luo_preserve_file(struct luo_file_set *file_set, u64 
token, int fd)
        kfree(luo_file);
 err_free_files_mem:
        luo_free_files_mem(file_set);
-err_fput:
-       fput(file);
+
+       return err;
+}
+
+int luo_preserve_fd(struct luo_file_set *file_set, u64 token, int fd)
+{
+       struct file *file;
+       int err;
+
+       file = fget(fd);
+       if (!file)
+               return -EBADF;
+
+       err = luo_preserve_file(file_set, token, file);
+       if (err)
+               fput(file);
 
        return err;
 }
@@ -861,6 +870,34 @@ int liveupdate_register_file_handler(struct 
liveupdate_file_handler *fh)
        return err;
 }
 
+int liveupdate_session_create(char *name, struct file **filep)
+{
+       struct luo_session *session;
+       int err;
+
+       err = luo_session_create(name, filep);
+       if (err)
+               return err;
+
+       session = (*filep)->private_data;
+
+       /* Not need to guard here, session is not yet visible to others */
+       err = luo_preserve_file(&session->file_set, 0, *filep);
+       if (err)
+               goto err_preserve;
+
+       return 0;
+
+err_preserve:
+       fput(*filep);
+       return err;
+}
+
+void liveupdate_session_destroy(char *name, struct file *file)
+{
+       fput(file);
+}
+
 /**
  * liveupdate_unregister_file_handler - Unregister a liveupdate file handler
  * @fh: The file handler to unregister
diff --git a/kernel/liveupdate/luo_internal.h b/kernel/liveupdate/luo_internal.h
index c8973b543d1d..b14391f1514f 100644
--- a/kernel/liveupdate/luo_internal.h
+++ b/kernel/liveupdate/luo_internal.h
@@ -93,7 +93,7 @@ int luo_session_deserialize(void);
 bool luo_session_quiesce(void);
 void luo_session_resume(void);
 
-int luo_preserve_file(struct luo_file_set *file_set, u64 token, int fd);
+int luo_preserve_fd(struct luo_file_set *file_set, u64 token, int fd);
 void luo_file_unpreserve_files(struct luo_file_set *file_set);
 int luo_file_freeze(struct luo_file_set *file_set,
                    struct luo_file_set_ser *file_set_ser);
diff --git a/kernel/liveupdate/luo_session.c b/kernel/liveupdate/luo_session.c
index dbdbc3bd7929..641186d41a22 100644
--- a/kernel/liveupdate/luo_session.c
+++ b/kernel/liveupdate/luo_session.c
@@ -234,7 +234,7 @@ static int luo_session_preserve_fd(struct luo_session 
*session,
        int err;
 
        guard(mutex)(&session->mutex);
-       err = luo_preserve_file(&session->file_set, argp->token, argp->fd);
+       err = luo_preserve_fd(&session->file_set, argp->token, argp->fd);
        if (err)
                return err;
 



Reply via email to