]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
ceph-fuse: perform cleanup if test_dentry_handling failed 45331/head
authorNikhilkumar Shelke <nshelke@redhat.com>
Wed, 2 Feb 2022 11:51:46 +0000 (17:21 +0530)
committerNikhilkumar Shelke <nshelke@redhat.com>
Fri, 11 Mar 2022 14:06:59 +0000 (19:36 +0530)
If remount failed due to some reason then ceph_abort() is
getting called which causes child process termination
without cleanup.
To fix this issue, ceph_abort() call moved after
performing cleanup.

Fixes: https://tracker.ceph.com/issues/54049
Signed-off-by: Nikhilkumar Shelke <nshelke@redhat.com>
(cherry picked from commit 8c778e79840f1aa9b9731e2ef20881da0d122fda)

src/ceph_fuse.cc
src/client/Client.cc
src/client/Client.h

index 5b2d370c49dc9fcd614544b1f8e90d4a44aa7fcf..115856f381cfd9cbfcd0bf7d8cee99b44677fce9 100644 (file)
@@ -204,7 +204,9 @@ int main(int argc, const char **argv, const char *envp[]) {
           "client_try_dentry_invalidate");
        bool can_invalidate_dentries =
           client_try_dentry_invalidate && ver < KERNEL_VERSION(3, 18, 0);
-       int tr = client->test_dentry_handling(can_invalidate_dentries);
+       auto test_result = client->test_dentry_handling(can_invalidate_dentries);
+       int tr = test_result.first;
+       bool abort_on_failure = test_result.second;
         bool client_die_on_failed_dentry_invalidate = g_conf().get_val<bool>(
           "client_die_on_failed_dentry_invalidate");
        if (tr != 0 && client_die_on_failed_dentry_invalidate) {
@@ -230,6 +232,9 @@ int main(int argc, const char **argv, const char *envp[]) {
            }
          }
        }
+       if(abort_on_failure) {
+         ceph_abort();
+       }
        return reinterpret_cast<void*>(tr);
 #else
        return reinterpret_cast<void*>(0);
index 86e01944f2e6b52a1a484565c2c08f976c7607dd..ff94e72efeea684d5302a1529362214db1f64df6 100644 (file)
@@ -4399,9 +4399,10 @@ void Client::remove_session_caps(MetaSession *s, int err)
   sync_cond.notify_all();
 }
 
-int Client::_do_remount(bool retry_on_error)
+std::pair<int, bool> Client::_do_remount(bool retry_on_error)
 {
   uint64_t max_retries = cct->_conf.get_val<uint64_t>("mds_max_retries_on_remount_failure");
+  bool abort_on_failure = false;
 
   errno = 0;
   int r = remount_cb(callback_handle);
@@ -4425,10 +4426,10 @@ int Client::_do_remount(bool retry_on_error)
       !(retry_on_error && (++retries_on_invalidate < max_retries));
     if (should_abort && !is_unmounting()) {
       lderr(cct) << "failed to remount for kernel dentry trimming; quitting!" << dendl;
-      ceph_abort();
+      abort_on_failure = true;
     }
   }
-  return r;
+  return std::make_pair(r, abort_on_failure);
 }
 
 class C_Client_Remount : public Context  {
@@ -11357,20 +11358,19 @@ int Client::ll_register_callbacks2(struct ceph_client_callback_args *args)
   return 0;
 }
 
-int Client::test_dentry_handling(bool can_invalidate)
+std::pair<int, bool> Client::test_dentry_handling(bool can_invalidate)
 {
-  int r = 0;
+  std::pair <int, bool> r(0, false);
 
   RWRef_t iref_reader(initialize_state, CLIENT_INITIALIZED);
   if (!iref_reader.is_state_satisfied())
-    return -CEPHFS_ENOTCONN;
+    return std::make_pair(-CEPHFS_ENOTCONN, false);
 
   can_invalidate_dentries = can_invalidate;
 
   if (can_invalidate_dentries) {
     ceph_assert(dentry_invalidate_cb);
     ldout(cct, 1) << "using dentry_invalidate_cb" << dendl;
-    r = 0;
   } else {
     ceph_assert(remount_cb);
     ldout(cct, 1) << "using remount_cb" << dendl;
index d7139983ef5e8b4361c5d41f273930b49fec8839..03a1326d5f0412bd4def9f0e81419678b39e076a 100644 (file)
@@ -655,7 +655,7 @@ public:
   void _ll_register_callbacks(struct ceph_client_callback_args *args);
   void ll_register_callbacks(struct ceph_client_callback_args *args); // deprecated
   int ll_register_callbacks2(struct ceph_client_callback_args *args);
-  int test_dentry_handling(bool can_invalidate);
+  std::pair<int, bool> test_dentry_handling(bool can_invalidate);
 
   const char** get_tracked_conf_keys() const override;
   void handle_conf_change(const ConfigProxy& conf,
@@ -1290,7 +1290,7 @@ private:
   int _release_fh(Fh *fh);
   void _put_fh(Fh *fh);
 
-  int _do_remount(bool retry_on_error);
+  std::pair<int, bool> _do_remount(bool retry_on_error);
 
   int _read_sync(Fh *f, uint64_t off, uint64_t len, bufferlist *bl, bool *checkeof);
   int _read_async(Fh *f, uint64_t off, uint64_t len, bufferlist *bl);