]> git.apps.os.sepia.ceph.com Git - ceph-ci.git/commitdiff
client: always register callbacks before mount()
authorXiubo Li <xiubli@redhat.com>
Fri, 19 Mar 2021 08:28:57 +0000 (16:28 +0800)
committerXiubo Li <xiubli@redhat.com>
Thu, 8 Apr 2021 07:31:00 +0000 (15:31 +0800)
Add Client::ll_register_callbacks2() support and add a new register
callbacks API ceph_ll_register_callbacks2() support for libcephfs
library, at the same time bump the LIBCEPHFS_VER_EXTRA up to 3.

This can help get rid of the client_lock in ll_register_callbacks()
and later the inode lock patches can benefit from it.

Signed-off-by: Xiubo Li <xiubli@redhat.com>
src/client/Client.cc
src/client/Client.h
src/client/fuse_ll.cc
src/include/cephfs/libcephfs.h
src/libcephfs.cc
src/test/fs/test_ino_release_cb.cc

index 7a45461e8136884934a1dc3a721a2076372fa86e..7a8dee141d958c93ac7eb37d9b57556ee730af72 100644 (file)
@@ -11013,11 +11013,11 @@ int Client::ll_statfs(Inode *in, struct statvfs *stbuf, const UserPerm& perms)
   return statfs(0, stbuf, perms);
 }
 
-void Client::ll_register_callbacks(struct ceph_client_callback_args *args)
+void Client::_ll_register_callbacks(struct ceph_client_callback_args *args)
 {
   if (!args)
     return;
-  std::scoped_lock l(client_lock);
+
   ldout(cct, 10) << __func__ << " cb " << args->handle
                 << " invalidate_ino_cb " << args->ino_cb
                 << " invalidate_dentry_cb " << args->dentry_cb
@@ -11049,6 +11049,23 @@ void Client::ll_register_callbacks(struct ceph_client_callback_args *args)
     umask_cb = args->umask_cb;
 }
 
+// This is deprecated, use ll_register_callbacks2() instead.
+void Client::ll_register_callbacks(struct ceph_client_callback_args *args)
+{
+  ceph_assert(!is_mounting() && !is_mounted() && !is_unmounting());
+
+  _ll_register_callbacks(args);
+}
+
+int Client::ll_register_callbacks2(struct ceph_client_callback_args *args)
+{
+  if (is_mounting() || is_mounted() || is_unmounting())
+    return -CEPHFS_EBUSY;
+
+  _ll_register_callbacks(args);
+  return 0;
+}
+
 int Client::test_dentry_handling(bool can_invalidate)
 {
   int r = 0;
index 011ff1ad07b9a3bcbb638c1cc80c59f2b5fc48c4..c0bd0108e130a63e6305c07b90206e597ee9d818 100644 (file)
@@ -623,7 +623,9 @@ public:
   int ll_osdaddr(int osd, uint32_t *addr);
   int ll_osdaddr(int osd, char* buf, size_t size);
 
-  void ll_register_callbacks(struct ceph_client_callback_args *args);
+  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);
 
   const char** get_tracked_conf_keys() const override;
index c2141a00d7d270a584c032fb2445d9c47d26cb49..3dbd0eda0929e6591e13cbb565e13e3e7388720b 100644 (file)
@@ -1322,6 +1322,26 @@ int CephFuse::Handle::init(int argc, const char *argv[])
 
   ceph_assert(args.allocated);  // Checking fuse has realloc'd args so we can free newargv
   free(newargv);
+
+  struct ceph_client_callback_args cb_args = {
+    handle: this,
+    ino_cb: client->cct->_conf.get_val<bool>("fuse_use_invalidate_cb") ?
+      ino_invalidate_cb : NULL,
+    dentry_cb: dentry_invalidate_cb,
+    switch_intr_cb: switch_interrupt_cb,
+#if defined(__linux__)
+    remount_cb: remount_cb,
+#endif
+#if !defined(__APPLE__)
+    umask_cb: umask_cb,
+#endif
+  };
+  r = client->ll_register_callbacks2(&cb_args);
+  if (r) {
+    derr << "registering callbacks failed: " << r << dendl;
+    return r;
+  }
+
   return 0;
 }
 
@@ -1363,22 +1383,6 @@ int CephFuse::Handle::start()
   fuse_session_add_chan(se, ch);
 #endif
 
-
-  struct ceph_client_callback_args args = {
-    handle: this,
-    ino_cb: client->cct->_conf.get_val<bool>("fuse_use_invalidate_cb") ?
-      ino_invalidate_cb : NULL,
-    dentry_cb: dentry_invalidate_cb,
-    switch_intr_cb: switch_interrupt_cb,
-#if defined(__linux__)
-    remount_cb: remount_cb,
-#endif
-#if !defined(__APPLE__)
-    umask_cb: umask_cb,
-#endif
-  };
-  client->ll_register_callbacks(&args);
-
   return 0;
 }
 
index d8042f5c5fee7ec99c3b3edf5691f4a4e497f78f..a7fd9b8f4fc3764d25ab81272df3df7754df3cfd 100644 (file)
@@ -39,7 +39,7 @@ extern "C" {
 
 #define LIBCEPHFS_VER_MAJOR 10
 #define LIBCEPHFS_VER_MINOR 0
-#define LIBCEPHFS_VER_EXTRA 2
+#define LIBCEPHFS_VER_EXTRA 3
 
 #define LIBCEPHFS_VERSION(maj, min, extra) ((maj << 16) + (min << 8) + extra)
 #define LIBCEPHFS_VERSION_CODE LIBCEPHFS_VERSION(LIBCEPHFS_VER_MAJOR, LIBCEPHFS_VER_MINOR, LIBCEPHFS_VER_EXTRA)
@@ -1955,6 +1955,9 @@ void ceph_finish_reclaim(struct ceph_mount_info *cmount);
 
 /**
  * Register a set of callbacks to be used with this cmount
+ *
+ * This is deprecated, use ceph_ll_register_callbacks2() instead.
+ *
  * @param cmount the ceph mount handle on which the cb's should be registerd
  * @param args   callback arguments to register with the cmount
  *
@@ -1964,6 +1967,19 @@ void ceph_finish_reclaim(struct ceph_mount_info *cmount);
 void ceph_ll_register_callbacks(struct ceph_mount_info *cmount,
                                struct ceph_client_callback_args *args);
 
+/**
+ * Register a set of callbacks to be used with this cmount
+ * @param cmount the ceph mount handle on which the cb's should be registerd
+ * @param args   callback arguments to register with the cmount
+ *
+ * Any fields set to NULL will be ignored. There currently is no way to
+ * unregister these callbacks, so this is a one-way change.
+ *
+ * Returns 0 on success or -EBUSY if the cmount is mounting or already mounted.
+ */
+int ceph_ll_register_callbacks2(struct ceph_mount_info *cmount,
+                               struct ceph_client_callback_args *args);
+
 /**
  * Get snapshot info
  *
index 8f88b387106c6446e507e18a0c2be6b006f6b733..cf38fb8b83c5c9a32b4f3a8b8d71faaf0152a897 100644 (file)
@@ -2075,11 +2075,17 @@ extern "C" void ceph_finish_reclaim(class ceph_mount_info *cmount)
   cmount->get_client()->finish_reclaim();
 }
 
+// This is deprecated, use ceph_ll_register_callbacks2 instead.
 extern "C" void ceph_ll_register_callbacks(class ceph_mount_info *cmount,
                                           struct ceph_client_callback_args *args)
 {
   cmount->get_client()->ll_register_callbacks(args);
+}
 
+extern "C" int ceph_ll_register_callbacks2(class ceph_mount_info *cmount,
+                                           struct ceph_client_callback_args *args)
+{
+  return cmount->get_client()->ll_register_callbacks2(args);
 }
 
 
index 7b3fc626073581c013cc9c3a2eebecd1cdaf42ca..0c53fea0a323914b18fe1b52673410aa330ba0cb 100644 (file)
@@ -56,7 +56,8 @@ int main(int argc, char *argv[])
 
        struct ceph_client_callback_args args = { 0 };
        args.ino_release_cb = cb;
-       ceph_ll_register_callbacks(cmount, &args);
+       ret = ceph_ll_register_callbacks2(cmount, &args);
+       assert(ret == 0);
 
        ret = ceph_mount(cmount, NULL);
        assert(ret >= 0);