Whamcloud - gitweb
LU-14291 lustre: only include nrs headers when needed
[fs/lustre-release.git] / lustre / ldlm / ldlm_resource.c
index e439ffb..ea6e751 100644 (file)
@@ -39,6 +39,7 @@
 #include <lustre_dlm.h>
 #include <lustre_fid.h>
 #include <obd_class.h>
+#include <libcfs/linux/linux-hash.h>
 #include "ldlm_internal.h"
 
 struct kmem_cache *ldlm_resource_slab, *ldlm_lock_slab;
@@ -372,6 +373,61 @@ static ssize_t lru_size_store(struct kobject *kobj, struct attribute *attr,
 }
 LUSTRE_RW_ATTR(lru_size);
 
+static ssize_t lru_cancel_batch_show(struct kobject *kobj,
+                                struct attribute *attr, char *buf)
+{
+       struct ldlm_namespace *ns = container_of(kobj, struct ldlm_namespace,
+                                                ns_kobj);
+
+       return snprintf(buf, sizeof(buf) - 1, "%u\n", ns->ns_cancel_batch);
+}
+
+static ssize_t lru_cancel_batch_store(struct kobject *kobj,
+                                 struct attribute *attr,
+                                 const char *buffer, size_t count)
+{
+       struct ldlm_namespace *ns = container_of(kobj, struct ldlm_namespace,
+                                                ns_kobj);
+       unsigned long tmp;
+
+       if (kstrtoul(buffer, 10, &tmp))
+               return -EINVAL;
+
+       ns->ns_cancel_batch = (unsigned int)tmp;
+
+       return count;
+}
+LUSTRE_RW_ATTR(lru_cancel_batch);
+
+static ssize_t ns_recalc_pct_show(struct kobject *kobj,
+                                 struct attribute *attr, char *buf)
+{
+       struct ldlm_namespace *ns = container_of(kobj, struct ldlm_namespace,
+                                                ns_kobj);
+
+       return snprintf(buf, sizeof(buf) - 1, "%u\n", ns->ns_recalc_pct);
+}
+
+static ssize_t ns_recalc_pct_store(struct kobject *kobj,
+                                  struct attribute *attr,
+                                  const char *buffer, size_t count)
+{
+       struct ldlm_namespace *ns = container_of(kobj, struct ldlm_namespace,
+                                                ns_kobj);
+       unsigned long tmp;
+
+       if (kstrtoul(buffer, 10, &tmp))
+               return -EINVAL;
+
+       if (tmp > 100)
+               return -ERANGE;
+
+       ns->ns_recalc_pct = (unsigned int)tmp;
+
+       return count;
+}
+LUSTRE_RW_ATTR(ns_recalc_pct);
+
 static ssize_t lru_max_age_show(struct kobject *kobj, struct attribute *attr,
                                char *buf)
 {
@@ -623,7 +679,9 @@ static struct attribute *ldlm_ns_attrs[] = {
        &lustre_attr_resource_count.attr,
        &lustre_attr_lock_count.attr,
        &lustre_attr_lock_unused_count.attr,
+       &lustre_attr_ns_recalc_pct.attr,
        &lustre_attr_lru_size.attr,
+       &lustre_attr_lru_cancel_batch.attr,
        &lustre_attr_lru_max_age.attr,
        &lustre_attr_early_lock_cancel.attr,
        &lustre_attr_dirty_age_limit.attr,
@@ -839,19 +897,21 @@ struct ldlm_namespace *ldlm_namespace_new(struct obd_device *obd, char *name,
 
        rc = ldlm_get_ref();
        if (rc) {
-               CERROR("ldlm_get_ref failed: %d\n", rc);
-               RETURN(NULL);
+               CERROR("%s: ldlm_get_ref failed: rc = %d\n", name, rc);
+               RETURN(ERR_PTR(rc));
        }
 
        if (ns_type >= ARRAY_SIZE(ldlm_ns_hash_defs) ||
            ldlm_ns_hash_defs[ns_type].nsd_bkt_bits == 0) {
-               CERROR("Unknown type %d for ns %s\n", ns_type, name);
-               GOTO(out_ref, NULL);
+               rc = -EINVAL;
+               CERROR("%s: unknown namespace type %d: rc = %d\n",
+                      name, ns_type, rc);
+               GOTO(out_ref, rc);
        }
 
        OBD_ALLOC_PTR(ns);
        if (!ns)
-               GOTO(out_ref, NULL);
+               GOTO(out_ref, rc = -ENOMEM);
 
        ns->ns_rs_hash = cfs_hash_create(name,
                                         ldlm_ns_hash_defs[ns_type].nsd_all_bits,
@@ -865,15 +925,15 @@ struct ldlm_namespace *ldlm_namespace_new(struct obd_device *obd, char *name,
                                         CFS_HASH_BIGNAME |
                                         CFS_HASH_SPIN_BKTLOCK |
                                         CFS_HASH_NO_ITEMREF);
-       if (ns->ns_rs_hash == NULL)
-               GOTO(out_ns, NULL);
+       if (!ns->ns_rs_hash)
+               GOTO(out_ns, rc = -ENOMEM);
 
        ns->ns_bucket_bits = ldlm_ns_hash_defs[ns_type].nsd_all_bits -
                             ldlm_ns_hash_defs[ns_type].nsd_bkt_bits;
 
        OBD_ALLOC_PTR_ARRAY_LARGE(ns->ns_rs_buckets, 1 << ns->ns_bucket_bits);
        if (!ns->ns_rs_buckets)
-               goto out_hash;
+               GOTO(out_hash, rc = -ENOMEM);
 
        for (idx = 0; idx < (1 << ns->ns_bucket_bits); idx++) {
                struct ldlm_ns_bucket *nsb = &ns->ns_rs_buckets[idx];
@@ -889,7 +949,7 @@ struct ldlm_namespace *ldlm_namespace_new(struct obd_device *obd, char *name,
        ns->ns_client = client;
        ns->ns_name = kstrdup(name, GFP_KERNEL);
        if (!ns->ns_name)
-               goto out_hash;
+               GOTO(out_hash, rc = -ENOMEM);
 
        INIT_LIST_HEAD(&ns->ns_list_chain);
        INIT_LIST_HEAD(&ns->ns_unused_list);
@@ -904,6 +964,8 @@ struct ldlm_namespace *ldlm_namespace_new(struct obd_device *obd, char *name,
        ns->ns_max_parallel_ast   = LDLM_DEFAULT_PARALLEL_AST_LIMIT;
        ns->ns_nr_unused          = 0;
        ns->ns_max_unused         = LDLM_DEFAULT_LRU_SIZE;
+       ns->ns_cancel_batch       = LDLM_DEFAULT_LRU_SHRINK_BATCH;
+       ns->ns_recalc_pct         = LDLM_DEFAULT_SLV_RECALC_PCT;
        ns->ns_max_age            = ktime_set(LDLM_DEFAULT_MAX_ALIVE, 0);
        ns->ns_ctime_age_limit    = LDLM_CTIME_AGE_LIMIT;
        ns->ns_dirty_age_limit    = ktime_set(LDLM_DIRTY_AGE_LIMIT, 0);
@@ -917,20 +979,20 @@ struct ldlm_namespace *ldlm_namespace_new(struct obd_device *obd, char *name,
 
        rc = ldlm_namespace_sysfs_register(ns);
        if (rc) {
-               CERROR("Can't initialize ns sysfs, rc %d\n", rc);
+               CERROR("%s: cannot initialize ns sysfs: rc = %d\n", name, rc);
                GOTO(out_hash, rc);
        }
 
        rc = ldlm_namespace_debugfs_register(ns);
        if (rc) {
-               CERROR("Can't initialize ns proc, rc %d\n", rc);
+               CERROR("%s: cannot initialize ns proc: rc = %d\n", name, rc);
                GOTO(out_sysfs, rc);
        }
 
        idx = ldlm_namespace_nr_read(client);
        rc = ldlm_pool_init(&ns->ns_pool, ns, idx, client);
        if (rc) {
-               CERROR("Can't initialize lock pool, rc %d\n", rc);
+               CERROR("%s: cannot initialize lock pool, rc = %d\n", name, rc);
                GOTO(out_proc, rc);
        }
 
@@ -949,7 +1011,7 @@ out_ns:
         OBD_FREE_PTR(ns);
 out_ref:
        ldlm_put_ref();
-       RETURN(NULL);
+       RETURN(ERR_PTR(rc));
 }
 EXPORT_SYMBOL(ldlm_namespace_new);
 
@@ -1564,7 +1626,7 @@ static void __ldlm_resource_add_lock(struct ldlm_resource *res,
                list_add(&lock->l_res_link, head);
 
        if (res->lr_type == LDLM_IBITS)
-               ldlm_inodebits_add_lock(res, head, lock);
+               ldlm_inodebits_add_lock(res, head, lock, tail);
 
        ldlm_resource_dump(D_INFO, res);
 }
@@ -1596,6 +1658,11 @@ void ldlm_resource_insert_lock_after(struct ldlm_lock *original,
 
 /**
  * Insert a lock into resource before the specified lock.
+ *
+ * IBITS waiting locks are to be inserted to the ibit lists as well, and only
+ * the insert-after operation is supported for them, because the set of bits
+ * of the previous and the new locks must match. Therefore, get the previous
+ * lock and insert after.
  */
 void ldlm_resource_insert_lock_before(struct ldlm_lock *original,
                                       struct ldlm_lock *new)