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)
"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) {
}
}
}
+ if(abort_on_failure) {
+ ceph_abort();
+ }
return reinterpret_cast<void*>(tr);
#else
return reinterpret_cast<void*>(0);
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);
!(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 {
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;
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,
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);