Whamcloud - gitweb
Landing b_lock_replay so that Phil can use my ldlm iterators and whatnot for his
[fs/lustre-release.git] / lustre / ldlm / ldlm_resource.c
index 5434363..bdb3449 100644 (file)
@@ -23,40 +23,50 @@ static struct proc_dir_entry *ldlm_ns_proc_dir = NULL;
 int ldlm_proc_setup(struct obd_device *obd)
 {
         ENTRY;
-
-        if (obd->obd_proc_entry == NULL)
-                RETURN(-EINVAL);
-
-        ldlm_ns_proc_dir = proc_mkdir("namespaces", obd->obd_proc_entry);
-        if (ldlm_ns_proc_dir == NULL) {
-                CERROR("Couldn't create /proc/lustre/ldlm/namespaces\n");
-                RETURN(-EPERM);
-        }
+        LASSERT(ldlm_ns_proc_dir == NULL);
+        ldlm_ns_proc_dir=obd->obd_type->typ_procroot;
         RETURN(0);
 }
 
 void ldlm_proc_cleanup(struct obd_device *obd)
 {
-        proc_lustre_remove_obd_entry("namespaces", obd);
+        ldlm_ns_proc_dir = NULL;
 }
 
-/* FIXME: This can go away when we start to really use lprocfs */
-static int lprocfs_ll_rd(char *page, char **start, off_t off,
-                         int count, int *eof, void *data)
+#define MAX_STRING_SIZE 100
+void ldlm_proc_namespace(struct ldlm_namespace *ns)
 {
-        int len;
-        __u64 *temp = (__u64 *)data;
+        struct lprocfs_vars lock_vars[2];
+        char lock_names[MAX_STRING_SIZE+1];
+
+        memset(lock_vars, 0, sizeof(lock_vars));
+        snprintf(lock_names, MAX_STRING_SIZE, "%s/resource_count", ns->ns_name);
+        lock_names[MAX_STRING_SIZE] = '\0';
+        lock_vars[0].name = lock_names;
+        lock_vars[0].read_fptr = lprocfs_ll_rd;
+        lock_vars[0].write_fptr = NULL;
+        lock_vars[0].data = &ns->ns_resources;
+        lprocfs_add_vars(ldlm_ns_proc_dir, lock_vars, 0);
+
+        memset(lock_vars, 0, sizeof(lock_vars));
+        snprintf(lock_names, MAX_STRING_SIZE, "%s/lock_count", ns->ns_name);
+        lock_names[MAX_STRING_SIZE] = '\0';
+        lock_vars[0].name = lock_names;
+        lock_vars[0].read_fptr = lprocfs_ll_rd;
+        lock_vars[0].write_fptr = NULL;
+        lock_vars[0].data = &ns->ns_locks;
+        lprocfs_add_vars(ldlm_ns_proc_dir, lock_vars, 0);
 
-        len = snprintf(page, count, "%Lu\n", *temp);
-
-        return len;
 }
+#undef MAX_STRING_SIZE
 
+#define LDLM_MAX_UNUSED 20
 struct ldlm_namespace *ldlm_namespace_new(char *name, __u32 client)
 {
         struct ldlm_namespace *ns = NULL;
         struct list_head *bucket;
-        struct proc_dir_entry *proc_entry;
+
+       
 
         OBD_ALLOC(ns, sizeof(*ns));
         if (!ns) {
@@ -90,20 +100,14 @@ struct ldlm_namespace *ldlm_namespace_new(char *name, __u32 client)
              bucket--)
                 INIT_LIST_HEAD(bucket);
 
+        INIT_LIST_HEAD(&ns->ns_unused_list);
+        ns->ns_nr_unused = 0;
+        ns->ns_max_unused = LDLM_MAX_UNUSED;
+
         spin_lock(&ldlm_namespace_lock);
         list_add(&ns->ns_list_chain, &ldlm_namespace_list);
         spin_unlock(&ldlm_namespace_lock);
-
-        ns->ns_proc_dir = proc_mkdir(ns->ns_name, ldlm_ns_proc_dir);
-        if (ns->ns_proc_dir == NULL)
-                CERROR("Unable to create proc directory for namespace.\n");
-        proc_entry = create_proc_entry("resource_count", 0444, ns->ns_proc_dir);
-        proc_entry->read_proc = lprocfs_ll_rd;
-        proc_entry->data = &ns->ns_resources;
-        proc_entry = create_proc_entry("lock_count", 0444, ns->ns_proc_dir);
-        proc_entry->read_proc = lprocfs_ll_rd;
-        proc_entry->data = &ns->ns_locks;
-
+        ldlm_proc_namespace(ns);
         RETURN(ns);
 
  out:
@@ -120,9 +124,9 @@ struct ldlm_namespace *ldlm_namespace_new(char *name, __u32 client)
 
 extern struct ldlm_lock *ldlm_lock_get(struct ldlm_lock *lock);
 
-/* If 'local' is true, don't try to tell the server, just cleanup. */
+/* If 'local_only' is true, don't try to tell the server, just cleanup. */
 static void cleanup_resource(struct ldlm_resource *res, struct list_head *q,
-                             int local)
+                             int local_only)
 {
         struct list_head *tmp, *pos;
         int rc = 0, client = res->lr_namespace->ns_client;
@@ -133,16 +137,19 @@ static void cleanup_resource(struct ldlm_resource *res, struct list_head *q,
                 lock = list_entry(tmp, struct ldlm_lock, l_res_link);
                 LDLM_LOCK_GET(lock);
 
+                /* At shutdown time, don't call the cancellation callback */
+                lock->l_flags |= LDLM_FL_CANCEL;
+
                 if (client) {
                         struct lustre_handle lockh;
                         ldlm_lock2handle(lock, &lockh);
-                        if (!local) {
+                        if (!local_only) {
                                 rc = ldlm_cli_cancel(&lockh);
                                 if (rc)
                                         CERROR("ldlm_cli_cancel: %d\n", rc);
                         }
                         /* Force local cleanup on errors, too. */
-                        if (local || rc != ELDLM_OK)
+                        if (local_only || rc != ELDLM_OK)
                                 ldlm_lock_cancel(lock);
                 } else {
                         LDLM_DEBUG(lock, "Freeing a lock still held by a "
@@ -155,7 +162,7 @@ static void cleanup_resource(struct ldlm_resource *res, struct list_head *q,
         }
 }
 
-int ldlm_namespace_cleanup(struct ldlm_namespace *ns, int local)
+int ldlm_namespace_cleanup(struct ldlm_namespace *ns, int local_only)
 {
         int i;
 
@@ -167,11 +174,16 @@ int ldlm_namespace_cleanup(struct ldlm_namespace *ns, int local)
                         res = list_entry(tmp, struct ldlm_resource, lr_hash);
                         ldlm_resource_getref(res);
 
-                        cleanup_resource(res, &res->lr_granted, local);
-                        cleanup_resource(res, &res->lr_converting, local);
-                        cleanup_resource(res, &res->lr_waiting, local);
+                        cleanup_resource(res, &res->lr_granted, local_only);
+                        cleanup_resource(res, &res->lr_converting, local_only);
+                        cleanup_resource(res, &res->lr_waiting, local_only);
 
-                        if (!ldlm_resource_put(res)) {
+                        /* XXX this is a bit counter-intuitive and should
+                         * probably be cleaner: don't force cleanup if we're
+                         * local_only (which is only used by recovery).  We
+                         * probably still have outstanding lock refs which
+                         * reference these resources. -phil */
+                        if (!ldlm_resource_put(res) && !local_only) {
                                 CERROR("Resource refcount nonzero (%d) after "
                                        "lock cleanup; forcing cleanup.\n",
                                        atomic_read(&res->lr_refcount));
@@ -194,9 +206,7 @@ int ldlm_namespace_free(struct ldlm_namespace *ns)
 
         spin_lock(&ldlm_namespace_lock);
         list_del(&ns->ns_list_chain);
-        remove_proc_entry("resource_count", ns->ns_proc_dir);
-        remove_proc_entry("lock_count", ns->ns_proc_dir);
-        remove_proc_entry(ns->ns_name, ldlm_ns_proc_dir);
+
         spin_unlock(&ldlm_namespace_lock);
 
         ldlm_namespace_cleanup(ns, 0);