File handlers do not need to pin modules indefinitely or during active live update sessions. The VFS 'struct file' pins the file handler's module via f_op->owner during active sessions, making dynamic reference counting unnecessary for handlers. When a file is preserved, the live update core obtains a 'struct file' via fdget(). As long as the file is kept open within the live update session, the module is pinned by the VFS and cannot be unloaded. Similarly, during deserialization, file handlers are matched based on the compatible string. Because the handler list is protected by luo_file_handler_lock, there is no race that requires dynamic module refcounting. Removing these module references ensures that modules implementing file handlers can be unloaded when no longer providing active files. Suggested-by: David Matlack Signed-off-by: Pasha Tatashin --- kernel/liveupdate/luo_file.c | 28 +++++++--------------------- 1 file changed, 7 insertions(+), 21 deletions(-) diff --git a/kernel/liveupdate/luo_file.c b/kernel/liveupdate/luo_file.c index 96fdd5790dcc..b124fd747841 100644 --- a/kernel/liveupdate/luo_file.c +++ b/kernel/liveupdate/luo_file.c @@ -836,7 +836,6 @@ void luo_file_set_destroy(struct luo_file_set *file_set) int liveupdate_register_file_handler(struct liveupdate_file_handler *fh) { struct liveupdate_file_handler *fh_iter; - int err; if (!liveupdate_enabled()) return -EOPNOTSUPP; @@ -861,17 +860,11 @@ int liveupdate_register_file_handler(struct liveupdate_file_handler *fh) if (!strcmp(fh_iter->compatible, fh->compatible)) { pr_err("File handler registration failed: Compatible string '%s' already registered.\n", fh->compatible); - err = -EEXIST; - goto err_resume; + luo_session_resume(); + return -EEXIST; } } - /* Pin the module implementing the handler */ - if (!try_module_get(fh->ops->owner)) { - err = -EAGAIN; - goto err_resume; - } - INIT_LIST_HEAD(&ACCESS_PRIVATE(fh, flb_list)); init_rwsem(&ACCESS_PRIVATE(fh, flb_lock)); INIT_LIST_HEAD(&ACCESS_PRIVATE(fh, list)); @@ -882,10 +875,6 @@ int liveupdate_register_file_handler(struct liveupdate_file_handler *fh) liveupdate_test_register(fh); return 0; - -err_resume: - luo_session_resume(); - return err; } /** @@ -907,8 +896,6 @@ int liveupdate_register_file_handler(struct liveupdate_file_handler *fh) */ int liveupdate_unregister_file_handler(struct liveupdate_file_handler *fh) { - int err = -EBUSY; - if (!liveupdate_enabled()) return -EOPNOTSUPP; @@ -918,19 +905,18 @@ int liveupdate_unregister_file_handler(struct liveupdate_file_handler *fh) goto err_register; scoped_guard(rwsem_write, &luo_file_handler_lock) { - if (!list_empty(&ACCESS_PRIVATE(fh, flb_list))) - goto err_resume; + if (!list_empty(&ACCESS_PRIVATE(fh, flb_list))) { + luo_session_resume(); + goto err_register; + } list_del(&ACCESS_PRIVATE(fh, list)); } - module_put(fh->ops->owner); luo_session_resume(); return 0; -err_resume: - luo_session_resume(); err_register: liveupdate_test_register(fh); - return err; + return -EBUSY; } -- 2.53.0.851.ga537e3e6e9-goog