Whamcloud - gitweb
LU-12542 handles: discard h_owner in favour of h_ops 39/35739/3
authorNeilBrown <neilb@suse.com>
Fri, 9 Aug 2019 00:02:43 +0000 (20:02 -0400)
committerOleg Drokin <green@whamcloud.com>
Thu, 15 Aug 2019 07:55:48 +0000 (07:55 +0000)
lustre_handles assigned a 64bit unique identifier (a 'cookie') to
objects of various types and stored them in a hash table, allowing
them to be accessed by the cookie.

There is a facility for type checking by recording an 'owner' for each
object, and checking the owner on lookup. Unfortunately this is not
used - owner is always zero for the client.

Each object also contains an h_ops pointer which can be used to
reliably identify an owner.

So discard h_owner, pass and 'ops' pointer to class_handle2object(),
and only return objects for which the h_ops matches.

Note: this h_owner is now quiet different from the similar h_owner
in the server code.  When the server code is merged the "med" pointer
should be stored in the "mfd" and validated separately.

This reduces the size of the portals_handle by one pointer, which
benefits various other structures including struct ldlm_lock which can
be very populous and so is best keep small.

Change-Id: I9cf2b32f8b0ea7c188888301fb6130818b3d5ae9
Signed-off-by: NeilBrown <neilb@suse.com>
Reviewed-on: https://review.whamcloud.com/35739
Tested-by: jenkins <devops@whamcloud.com>
Reviewed-by: Andreas Dilger <adilger@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
lustre/include/lustre_handles.h
lustre/ldlm/ldlm_lock.c
lustre/mdt/mdt_internal.h
lustre/mdt/mdt_open.c
lustre/obdclass/genops.c
lustre/obdclass/lustre_handles.c

index feab792..bbbefad 100644 (file)
@@ -61,8 +61,7 @@ struct portals_handle_ops {
 struct portals_handle {
        struct list_head                h_link;
        __u64                           h_cookie;
-       const void                     *h_owner;
-       struct portals_handle_ops      *h_ops;
+       const struct portals_handle_ops *h_ops;
 
        /* newly added fields to handle the RCU issue. -jxiong */
        struct rcu_head                 h_rcu;
@@ -75,9 +74,9 @@ struct portals_handle {
 
 /* Add a handle to the hash table */
 void class_handle_hash(struct portals_handle *,
-                      struct portals_handle_ops *ops);
+                      const struct portals_handle_ops *ops);
 void class_handle_unhash(struct portals_handle *);
-void *class_handle2object(__u64 cookie, const void *owner);
+void *class_handle2object(u64 cookie, const struct portals_handle_ops *ops);
 void class_handle_free_cb(struct rcu_head *rcu);
 int class_handle_init(void);
 void class_handle_cleanup(void);
index 12ffa08..73d522f 100644 (file)
@@ -587,7 +587,7 @@ struct ldlm_lock *__ldlm_handle2lock(const struct lustre_handle *handle,
 
        LASSERT(handle);
 
-       lock = class_handle2object(handle->cookie, NULL);
+       lock = class_handle2object(handle->cookie, &lock_handle_ops);
        if (lock == NULL)
                RETURN(NULL);
 
index 9c21885..79eaf99 100644 (file)
@@ -66,6 +66,8 @@ struct mdt_object;
 struct mdt_file_data {
        /**  portals handle must be first */
        struct portals_handle   mfd_open_handle;
+       /* export data of portals_handle */
+       const struct mdt_export_data    *mfd_owner;
        /** open mode provided by client */
        u64                     mfd_open_flags;
        /** protected by med_open_lock */
index b7c5691..33db7d8 100644 (file)
@@ -49,7 +49,7 @@ static void mdt_mfd_get(void *mfdp)
 {
 }
 
-static struct portals_handle_ops mfd_open_handle_ops = {
+static const struct portals_handle_ops mfd_open_handle_ops = {
        .hop_addref = mdt_mfd_get,
        .hop_free   = NULL,
 };
@@ -64,7 +64,7 @@ struct mdt_file_data *mdt_mfd_new(const struct mdt_export_data *med)
        OBD_ALLOC_PTR(mfd);
        if (mfd != NULL) {
                INIT_LIST_HEAD_RCU(&mfd->mfd_open_handle.h_link);
-               mfd->mfd_open_handle.h_owner = med;
+               mfd->mfd_owner = med;
                INIT_LIST_HEAD(&mfd->mfd_list);
                class_handle_hash(&mfd->mfd_open_handle, &mfd_open_handle_ops);
        }
@@ -86,9 +86,9 @@ struct mdt_file_data *mdt_open_handle2mfd(struct mdt_export_data *med,
        ENTRY;
 
        LASSERT(open_handle != NULL);
-       mfd = class_handle2object(open_handle->cookie, med);
+       mfd = class_handle2object(open_handle->cookie, &mfd_open_handle_ops);
        /* during dw/setattr replay the mfd can be found by old handle */
-       if (mfd == NULL && is_replay_or_resent) {
+       if ((!mfd || mfd->mfd_owner != med) && is_replay_or_resent) {
                list_for_each_entry(mfd, &med->med_open_head, mfd_list) {
                        if (mfd->mfd_open_handle_old.cookie ==
                            open_handle->cookie)
index aac82d2..32a4727 100644 (file)
@@ -927,6 +927,8 @@ out:
        RETURN(rc);
 }
 
+static struct portals_handle_ops export_handle_ops;
+
 /* map connection to client */
 struct obd_export *class_conn2export(struct lustre_handle *conn)
 {
@@ -944,7 +946,7 @@ struct obd_export *class_conn2export(struct lustre_handle *conn)
         }
 
        CDEBUG(D_INFO, "looking for export cookie %#llx\n", conn->cookie);
-       export = class_handle2object(conn->cookie, NULL);
+       export = class_handle2object(conn->cookie, &export_handle_ops);
        RETURN(export);
 }
 EXPORT_SYMBOL(class_conn2export);
index 4da1823..f790f7d 100644 (file)
@@ -60,7 +60,7 @@ static struct handle_bucket {
  * global (per-node) hash-table.
  */
 void class_handle_hash(struct portals_handle *h,
-                      struct portals_handle_ops *ops)
+                      const struct portals_handle_ops *ops)
 {
        struct handle_bucket *bucket;
 
@@ -135,7 +135,7 @@ void class_handle_unhash(struct portals_handle *h)
 }
 EXPORT_SYMBOL(class_handle_unhash);
 
-void *class_handle2object(__u64 cookie, const void *owner)
+void *class_handle2object(u64 cookie, const struct portals_handle_ops *ops)
 {
        struct handle_bucket *bucket;
        struct portals_handle *h;
@@ -153,7 +153,7 @@ void *class_handle2object(__u64 cookie, const void *owner)
 
        rcu_read_lock();
        list_for_each_entry_rcu(h, &bucket->head, h_link) {
-               if (h->h_cookie != cookie || h->h_owner != owner)
+               if (h->h_cookie != cookie || h->h_ops != ops)
                        continue;
 
                spin_lock(&h->h_lock);