Whamcloud - gitweb
- first parts of lock management: module & resource hash +
authorbraam <braam>
Thu, 7 Mar 2002 23:41:09 +0000 (23:41 +0000)
committerbraam <braam>
Thu, 7 Mar 2002 23:41:09 +0000 (23:41 +0000)
  header file with data structures.

lustre/doc/Makefile.am
lustre/include/linux/lustre_dlm.h [new file with mode: 0644]
lustre/include/linux/obd_class.h
lustre/ldlm/Makefile.am [new file with mode: 0644]
lustre/ldlm/resource.c [new file with mode: 0644]

index 8ee9ed5..508c95d 100644 (file)
@@ -3,7 +3,7 @@
 # This code is issued under the GNU General Public License.
 # See the file COPYING in this distribution
 
-DOCS = OBD-HOWTO.sgml OLVM.txt figs notes.txt obdspec.sgml obdtrace_demo.txt
+DOCS = OBD-HOWTO.sgml OLVM.txt figs notes.txt obdtrace_demo.txt
 doc_DATA = $(DOCS) OBD-HOWTO.html OBD-HOWTO.txt
 CLEANFILES = OBD-HOWTO.html OBD-HOWTO.txt
 EXTRA_DIST = $(DOCS)
diff --git a/lustre/include/linux/lustre_dlm.h b/lustre/include/linux/lustre_dlm.h
new file mode 100644 (file)
index 0000000..ea9ae71
--- /dev/null
@@ -0,0 +1,130 @@
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
+ */
+
+#ifndef _LUSTRE_DLM_H__
+#define _LUSTRE_DLM_H__
+
+#include <linux/kp30.h>
+#include <linux/list.h>
+
+#define OBD_LDLM_DEVICENAME  "ldlm"
+
+typedef  int cluster_host;
+typedef  int cluster_pid;
+
+/* lock types */
+typedef enum  { 
+        LCK_EX,
+       LCK_PW,
+       LCK_PR,
+       LCK_CW,
+       LCK_CR,
+       LCK_NL
+} ldlm_mode_t;
+
+#define L2B(c) (1<<c)
+
+/* compatibility matrix */
+#define LCK_COMPAT_EX  L2B(LCK_NL)
+#define LCK_COMPAT_PW  (LCK_COMPAT_EX | L2B(LCK_CR))
+#define LCK_COMPAT_PR  (LCK_COMPAT_PW | L2B(LCK_PR))
+#define LCK_COMPAT_CW  (LCK_COMPAT_PW | L2B(LCK_CW))
+#define LCK_COMPAT_CR  (LCK_COMPAT_CW | L2B(LCK_PR) | L2B(LCK_PW))
+#define LCK_COMPAT_NL  (LCK_COMPAT_CR | L2B(LCK_EX))
+
+static ldlm_mode_t lck_compat_array[] = {
+       LCK_COMPAT_EX,
+       LCK_COMPAT_PW,
+       LCK_COMPAT_PR,
+       LCK_COMPAT_CW,
+       LCK_COMPAT_CR,
+       LCK_COMPAT_NL
+};
+
+static inline int lockmode_compat(ldlm_mode_t a, ldlm_mode_t b)
+{
+       if ( 0 <= a && a <= 5 ) { 
+              BUG();
+       }
+       if( 0 <= b && b <= 5 ) { 
+              BUG();
+       }
+    
+       return 1 && (lck_compat_array[a] & L2B(b));
+}
+
+/* 
+ * 
+ * cluster name spaces 
+ *
+ */
+
+#define DLM_OST_NAMESPACE 1
+#define DLM_MDS_NAMESPACE 2
+
+/* XXX 
+   - do we just separate this by security domains and use a prefix for 
+     multiple namespaces in the same domain? 
+   - 
+*/
+
+struct ldlm_namespace {
+       struct list_head      ns_link;      /* in the list of ns's */
+       __u32                 ns_id;        /* identifier of ns */
+       struct list_head     *ns_hash;      /* hash table for ns */
+       struct list_head      ns_root_list; /* all root resources in ns */
+};
+
+/* 
+ * 
+ * Resource hash table 
+ *
+ */
+
+#define RES_HASH_BITS 18
+#define RES_HASH_SIZE (1UL << RES_HASH_BITS)
+#define RES_HASH_MASK (RES_HASH_SIZE - 1)
+
+#define RES_NAME_SIZE 6
+#define RES_VERSION_SIZE 4
+
+struct ldlm_resource {
+       struct list_head      lr_hash;
+       struct list_head      lr_rootlink; /* link all root resources in NS */
+       struct ldlm_resource *lr_parent;   /* 0 for a root resource */
+       struct list_head      lr_children; /* list head for child resources */
+       struct list_head      lr_childof;  /* part of child list of parent */
+
+       struct list_head      lr_granted;
+       struct list_head      lr_converting;
+       struct list_head      lr_waiting;
+       ldlm_mode_t           lr_most_restr;
+       struct ldlm_resource *lr_root;
+       //XXX cluster_host          lr_master;
+       __u32                 lr_name[RES_NAME_SIZE];
+       __u32                 lr_version[RES_VERSION_SIZE];
+};
+
+struct ldlm_lock {
+       struct ldlm_resource *lb_resource;
+       struct ldlm_lock     *lb_parent;
+       struct list_head      lb_children;
+       struct list_head      lb_childof;
+       unsigned long         lb_id;
+       ldlm_mode_t           lb_req_mode;
+       ldlm_mode_t           lb_granted_mode;
+       void                 *lb_completion_ast;
+       void                 *lb_blocking_ast;
+       void                 *lb_event;
+       //XXX cluster_host    lb_holder;
+       __u32                 lb_version[RES_VERSION_SIZE];
+};
+
+struct ldlm_obd {
+        struct list_head ldlm_namespaces;
+};
+
+extern struct obd_ops ldlm_obd_ops;
+
+#endif
index 6420950..1ad5477 100644 (file)
@@ -68,6 +68,7 @@ typedef struct {
 #include <linux/obd_filter.h>
 #include <linux/lustre_mds.h>
 #include <linux/lustre_net.h>
+#include <linux/lustre_dlm.h>
 #include <linux/obd_snap.h>
 #include <linux/obd_trace.h>
 /* #include <linux/obd_fc.h> */
@@ -100,6 +101,7 @@ struct obd_device {
                struct trace_obd trace;
                 struct ost_obd ost;
                 struct osc_obd osc;
+                struct ldlm_obd ldlm;
         } u;
 };
 
diff --git a/lustre/ldlm/Makefile.am b/lustre/ldlm/Makefile.am
new file mode 100644 (file)
index 0000000..a1a2074
--- /dev/null
@@ -0,0 +1,14 @@
+# Copyright (C) 2001  Cluster File Systems, Inc.
+#
+# This code is issued under the GNU General Public License.
+# See the file COPYING in this distribution
+
+DEFS:= 
+MODULE = llockd
+modulefs_DATA = llockd.o
+EXTRA_PROGRAMS = llockd
+
+llockd_SOURCES = resource.c
+
+include $(top_srcdir)/Rules
+
diff --git a/lustre/ldlm/resource.c b/lustre/ldlm/resource.c
new file mode 100644 (file)
index 0000000..078116a
--- /dev/null
@@ -0,0 +1,224 @@
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
+ *
+ * obd/ldlm/resource.c
+ *
+ * Copyright (C) 2002  Cluster File Systems, Inc.
+ *
+ * This code is issued under the GNU General Public License.
+ * See the file COPYING in this distribution
+ *
+ * by Cluster File Systems, Inc.
+ */
+
+#define EXPORT_SYMTAB
+
+#include <linux/version.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <asm/unistd.h>
+
+#define DEBUG_SUBSYSTEM S_LDLM
+
+#include <linux/obd_support.h>
+#include <linux/obd_class.h>
+
+#include <linux/lustre_dlm.h>
+
+static kmem_cache_t *ldlm_resource_slab;
+static kmem_cache_t *ldlm_lock_slab;
+
+struct ldlm_namespace *ldlm_namespace_find(struct obd_device *obddev, __u32 id)
+{
+       struct list_head *tmp;
+       struct ldlm_namespace *res;
+
+       res = NULL;
+       list_for_each(tmp, &obddev->u.ldlm.ldlm_namespaces) { 
+               struct ldlm_namespace *chk;
+               chk = list_entry(tmp, struct ldlm_namespace, ns_link);
+               
+               if ( chk->ns_id == id ) {
+                       res = chk;
+                       break;
+               }
+       }
+       return res;
+}
+
+static void res_hash_init(struct ldlm_namespace *name_space)
+{
+       struct list_head *res_hash;
+       struct list_head *bucket;
+
+       OBD_ALLOC(res_hash, sizeof(struct list_head) * RES_HASH_SIZE);
+       if (!res_hash)
+               BUG();
+
+       for (bucket = res_hash + RES_HASH_SIZE-1 ; bucket >= res_hash ;
+            bucket--) {
+               INIT_LIST_HEAD(bucket);
+       }
+
+       name_space->ns_hash = res_hash;
+}
+
+struct ldlm_namespace *ldlm_namespace_new(struct obd_device *obddev, __u32 id)
+{
+       struct ldlm_namespace *ns;
+
+       if (ldlm_namespace_find(obddev, id))
+               BUG();
+
+       OBD_ALLOC(ns, sizeof(*ns));
+       if (!ns)
+               BUG();
+
+       ns->ns_id = id;
+       INIT_LIST_HEAD(&ns->ns_root_list);
+       list_add(&ns->ns_link, &obddev->u.ldlm.ldlm_namespaces);
+
+       res_hash_init(ns); 
+       return ns;
+}
+
+__u32 ldlm_hash_fn(struct ldlm_resource *parent, __u32 *name)
+{
+       __u32 hash = 0;
+       int i;
+
+       for (i = 0; i < RES_NAME_SIZE; i++) {
+               hash += name[i];
+       }
+
+       hash += (__u32)((unsigned long)parent >> 4);
+
+       return (hash & RES_HASH_MASK);
+}
+
+struct ldlm_resource *ldlm_resource_find(struct ldlm_namespace *ns,
+                                        struct ldlm_resource *parent,
+                                        __u32 *name)
+{
+       struct list_head *bucket;
+       struct list_head *tmp = bucket;
+       struct ldlm_resource *res;
+
+       if (ns->ns_hash == NULL)
+               BUG();
+       bucket = ns->ns_hash + ldlm_hash_fn(parent, name);
+
+       res = NULL;
+       list_for_each(tmp, bucket) {
+               struct ldlm_resource *chk;
+               chk = list_entry(tmp, struct ldlm_resource, lr_hash);
+
+               if (memcmp(chk->lr_name, name, RES_NAME_SIZE * sizeof(__u32))){
+                       res = chk;
+                       break;
+               }
+       }
+                       
+       return res;
+}
+
+struct ldlm_resource *ldlm_resource_new(void)
+{
+       struct ldlm_resource *res;
+
+       res = kmem_cache_alloc(ldlm_resource_slab, SLAB_KERNEL);
+       if (res == NULL)
+               BUG();
+       memset(res, 0, sizeof(*res));
+
+       INIT_LIST_HEAD(&res->lr_children);
+       INIT_LIST_HEAD(&res->lr_granted);
+       INIT_LIST_HEAD(&res->lr_converting);
+       INIT_LIST_HEAD(&res->lr_waiting);
+
+       return res;
+}
+
+struct ldlm_resource *ldlm_resource_add(struct obd_device *obddev, __u32 id,
+                                       struct ldlm_resource *parent,
+                                       __u32 *name)
+{
+       struct ldlm_namespace *ns;
+       struct list_head *bucket;
+       struct ldlm_resource *res;
+
+       ns = ldlm_namespace_find(obddev, id);
+       if (ns == NULL || ns->ns_hash == NULL)
+               BUG();
+
+       bucket = ns->ns_hash + ldlm_hash_fn(parent, name);
+
+       if (ldlm_resource_find(ns, parent, name) != NULL)
+               BUG();
+
+       res = ldlm_resource_new();
+       if (!res)
+               BUG();
+
+       memcpy(res->lr_name, name, RES_NAME_SIZE * sizeof(__u32));
+       list_add(&res->lr_hash, bucket);
+       if (parent == NULL) {
+               res->lr_parent = res;
+               list_add(&res->lr_rootlink, &ns->ns_root_list);
+       } else {
+               res->lr_parent = parent;
+               list_add(&res->lr_childof, &parent->lr_children);
+       }
+
+       return res;
+}
+
+static int ldlm_obd_setup(struct obd_device *obddev, obd_count len, void *data)
+{
+       INIT_LIST_HEAD(&obddev->u.ldlm.ldlm_namespaces);
+
+       return 0;
+}
+
+struct obd_ops ldlm_obd_ops = {
+       o_setup:       ldlm_obd_setup,
+        o_connect:     gen_connect,
+        o_disconnect:  gen_disconnect,
+};
+
+static int __init ldlm_init(void)
+{
+        int rc = obd_register_type(&ldlm_obd_ops, OBD_LDLM_DEVICENAME);
+       if (rc != 0)
+               return rc;
+
+       ldlm_resource_slab = kmem_cache_create("ldlm_resources",
+                                              sizeof(struct ldlm_resource), 0,
+                                              SLAB_HWCACHE_ALIGN, NULL, NULL);
+       if (ldlm_resource_slab == NULL)
+               return -ENOMEM;
+
+       ldlm_lock_slab = kmem_cache_create("ldlm_locks",
+                                          sizeof(struct ldlm_lock), 0,
+                                          SLAB_HWCACHE_ALIGN, NULL, NULL);
+       if (ldlm_lock_slab == NULL) {
+               kmem_cache_destroy(ldlm_resource_slab);
+               return -ENOMEM;
+       }
+
+       return 0;
+}
+
+static void __exit ldlm_exit(void)
+{
+        obd_unregister_type(OBD_LDLM_DEVICENAME);
+       kmem_cache_destroy(ldlm_resource_slab);
+       kmem_cache_destroy(ldlm_lock_slab);
+}
+
+MODULE_AUTHOR("Cluster File Systems, Inc. <braam@clusterfs.com>");
+MODULE_DESCRIPTION("Lustre Lock Management Module v0.1");
+MODULE_LICENSE("GPL"); 
+
+module_init(ldlm_init);
+module_exit(ldlm_exit);