Whamcloud - gitweb
LU-9859 libcfs: move tgt_descs to standard Linux bitmaps.
[fs/lustre-release.git] / lustre / lod / lproc_lod.c
index 8297ae3..c4a4572 100644 (file)
 
 #ifdef CONFIG_PROC_FS
 
+static ssize_t dom_stripesize_show(struct kobject *kobj,
+                                  struct attribute *attr,
+                                  char *buf)
+{
+       struct dt_device *dt = container_of(kobj, struct dt_device, dd_kobj);
+       struct lod_device *lod = dt2lod_dev(dt);
+
+       return snprintf(buf, PAGE_SIZE, "%u\n",
+                       lod->lod_dom_stripesize_max_kb << 10);
+}
+
+static inline int dom_stripesize_max_kb_update(struct lod_device *lod,
+                                              __u64 val)
+{
+       /* 1GB is the limit */
+       if (val > (1ULL << 20))
+               return -ERANGE;
+
+       if (val > 0) {
+               if (val < LOD_DOM_MIN_SIZE_KB) {
+                       LCONSOLE_INFO("Increasing provided stripe size to a minimum value %u\n",
+                                     LOD_DOM_MIN_SIZE_KB);
+                       val = LOD_DOM_MIN_SIZE_KB;
+               } else if (val & (LOD_DOM_MIN_SIZE_KB - 1)) {
+                       val &= ~(LOD_DOM_MIN_SIZE_KB - 1);
+                       LCONSOLE_WARN("Changing provided stripe size to %llu (a multiple of minimum %u)\n",
+                                     val, LOD_DOM_MIN_SIZE_KB);
+               }
+       }
+       spin_lock(&lod->lod_lsfs_lock);
+       lod->lod_dom_stripesize_max_kb = val;
+       lod_dom_stripesize_recalc(lod);
+       spin_unlock(&lod->lod_lsfs_lock);
+       return 0;
+}
+
+static ssize_t dom_stripesize_store(struct kobject *kobj,
+                                   struct attribute *attr,
+                                   const char *buffer, size_t count)
+{
+       struct dt_device *dt = container_of(kobj, struct dt_device, dd_kobj);
+       struct lod_device *lod = dt2lod_dev(dt);
+       u64 val;
+       int rc;
+
+       rc = sysfs_memparse(buffer, count, &val, "B");
+       if (rc < 0)
+               return rc;
+
+       rc = dom_stripesize_max_kb_update(lod, val >> 10);
+       if (rc)
+               return rc;
+       return count;
+}
+
+/* Old attribute name is still supported */
+LUSTRE_RW_ATTR(dom_stripesize);
+
 /**
- * Show DoM default stripe size.
+ * Show DoM maximum allowed stripe size.
  */
-static ssize_t dom_stripesize_show(struct kobject *kobj, struct attribute *attr,
-                                  char *buf)
+static ssize_t dom_stripesize_max_kb_show(struct kobject *kobj,
+                                         struct attribute *attr,
+                                         char *buf)
 {
-       struct dt_device *dt = container_of(kobj, struct dt_device,
-                                           dd_kobj);
+       struct dt_device *dt = container_of(kobj, struct dt_device, dd_kobj);
        struct lod_device *lod = dt2lod_dev(dt);
 
-       return snprintf(buf, PAGE_SIZE, "%u\n", lod->lod_dom_max_stripesize);
+       return snprintf(buf, PAGE_SIZE, "%u\n",
+                       lod->lod_dom_stripesize_max_kb);
 }
 
 /**
- * Set DoM default stripe size.
+ * Set DoM maximum allowed stripe size.
  */
-static ssize_t dom_stripesize_store(struct kobject *kobj,
-                                   struct attribute *attr, const char *buffer,
-                                   size_t count)
+static ssize_t dom_stripesize_max_kb_store(struct kobject *kobj,
+                                          struct attribute *attr,
+                                          const char *buffer, size_t count)
 {
-       struct dt_device *dt = container_of(kobj, struct dt_device,
-                                           dd_kobj);
+       struct dt_device *dt = container_of(kobj, struct dt_device, dd_kobj);
        struct lod_device *lod = dt2lod_dev(dt);
-       char tbuf[22] = "";
-       s64 val;
+       u64 val;
        int rc;
 
-       if (count > (sizeof(tbuf) - 1))
-               return -EINVAL;
-
-       memcpy(tbuf, buffer, count);
+       rc = sysfs_memparse(buffer, count, &val, "KiB");
+       if (rc < 0)
+               return rc;
 
-       rc = lu_str_to_s64(tbuf, count, &val, '1');
+       rc = dom_stripesize_max_kb_update(lod, val >> 10);
        if (rc)
                return rc;
+       return count;
+}
+LUSTRE_RW_ATTR(dom_stripesize_max_kb);
 
-       if (val < 0)
-               return -ERANGE;
+/**
+ * Show DoM default stripe size.
+ */
+static ssize_t dom_stripesize_cur_kb_show(struct kobject *kobj,
+                                         struct attribute *attr,
+                                         char *buf)
+{
+       struct dt_device *dt = container_of(kobj, struct dt_device, dd_kobj);
+       struct lod_device *lod = dt2lod_dev(dt);
 
-       /* 1GB is the limit */
-       if (val > (1ULL << 30))
-               return -ERANGE;
+       return snprintf(buf, PAGE_SIZE, "%u\n", lod->lod_dom_stripesize_cur_kb);
+}
 
-       if (val > 0) {
-               if (val < LOV_MIN_STRIPE_SIZE) {
-                       LCONSOLE_INFO("Increasing provided stripe size to "
-                                     "a minimum value %u\n",
-                                     LOV_MIN_STRIPE_SIZE);
-                       val = LOV_MIN_STRIPE_SIZE;
-               } else if (val & (LOV_MIN_STRIPE_SIZE - 1)) {
-                       val &= ~(LOV_MIN_STRIPE_SIZE - 1);
-                       LCONSOLE_WARN("Changing provided stripe size to %llu "
-                                     "(a multiple of minimum %u)\n",
-                                     val, LOV_MIN_STRIPE_SIZE);
-               }
+LUSTRE_RO_ATTR(dom_stripesize_cur_kb);
+
+/**
+ * Show DoM threshold.
+ */
+static ssize_t dom_threshold_free_mb_show(struct kobject *kobj,
+                                         struct attribute *attr, char *buf)
+{
+       struct dt_device *dt = container_of(kobj, struct dt_device, dd_kobj);
+       struct lod_device *lod = dt2lod_dev(dt);
+
+       return snprintf(buf, PAGE_SIZE, "%llu\n",
+                       lod->lod_dom_threshold_free_mb);
+}
+
+/**
+ * Set DoM default stripe size.
+ */
+static ssize_t dom_threshold_free_mb_store(struct kobject *kobj,
+                                          struct attribute *attr,
+                                          const char *buffer, size_t count)
+{
+       struct dt_device *dt = container_of(kobj, struct dt_device, dd_kobj);
+       struct lod_device *lod = dt2lod_dev(dt);
+       u64 val;
+       int rc;
+       char *pct;
+
+       pct = strnchr(buffer, count, '%');
+       if (pct) {
+               rc = string_to_size(&val, buffer, pct - buffer);
+               if (rc < 0)
+                       return rc;
+               val = mult_frac(lod->lod_lsfs_total_mb,
+                               min_t(unsigned int, val, 100), 100);
+       } else {
+               rc = sysfs_memparse(buffer, count, &val, "MiB");
+               if (rc < 0)
+                       return rc;
+               val >>= 20;
        }
 
-       lod->lod_dom_max_stripesize = val;
+       spin_lock(&lod->lod_lsfs_lock);
+       lod->lod_dom_threshold_free_mb = val;
+       lod_dom_stripesize_recalc(lod);
+       spin_unlock(&lod->lod_lsfs_lock);
 
        return count;
 }
 
-LUSTRE_RW_ATTR(dom_stripesize);
+LUSTRE_RW_ATTR(dom_threshold_free_mb);
 
 static ssize_t stripesize_show(struct kobject *kobj, struct attribute *attr,
                               char *buf)
@@ -126,22 +222,13 @@ static ssize_t stripesize_store(struct kobject *kobj, struct attribute *attr,
        struct dt_device *dt = container_of(kobj, struct dt_device,
                                            dd_kobj);
        struct lod_device *lod = dt2lod_dev(dt);
-       char tbuf[22] = "";
-       s64 val;
+       u64 val;
        int rc;
 
-       if (count > (sizeof(tbuf) - 1))
-               return -EINVAL;
-
-       memcpy(tbuf, buffer, count);
-
-       rc = lu_str_to_s64(tbuf, count, &val, '1');
-       if (rc)
+       rc = sysfs_memparse(buffer, count, &val, "B");
+       if (rc < 0)
                return rc;
 
-       if (val < 0)
-               return -ERANGE;
-
        lod_fix_desc_stripe_size(&val);
        lod->lod_ost_descs.ltd_lov_desc.ld_default_stripe_size = val;
 
@@ -453,8 +540,8 @@ static ssize_t qos_prio_free_show(struct kobject *kobj,
  * Set QoS free space priority parameter.
  *
  * Set the relative priority of free OST space compared to OST load when OSTs
- * are space imbalanced.  See lod_qos_priofree_seq_show() for description of
- * this parameter.  See lod_qos_thresholdrr_seq_write() and lq_threshold_rr to
+ * are space imbalanced.  See qos_priofree_show() for description of
+ * this parameter.  See qos_threshold_rr_store() and lq_threshold_rr to
  * determine what constitutes "space imbalanced" OSTs.
  */
 static ssize_t __qos_prio_free_store(struct kobject *kobj,
@@ -502,9 +589,9 @@ LUSTRE_RW_ATTR(qos_prio_free);
 /**
  * Show threshold for "same space on all OSTs" rule.
  */
-static ssize_t __qos_thresholdrr_show(struct kobject *kobj,
-                                   struct attribute *attr, char *buf,
-                                   bool is_mdt)
+static ssize_t __qos_threshold_rr_show(struct kobject *kobj,
+                                      struct attribute *attr, char *buf,
+                                      bool is_mdt)
 {
        struct dt_device *dt = container_of(kobj, struct dt_device,
                                            dd_kobj);
@@ -516,16 +603,16 @@ static ssize_t __qos_thresholdrr_show(struct kobject *kobj,
                       (ltd->ltd_qos.lq_threshold_rr * 100 + 255) >> 8);
 }
 
-static ssize_t mdt_qos_thresholdrr_show(struct kobject *kobj,
-                                       struct attribute *attr, char *buf)
+static ssize_t mdt_qos_threshold_rr_show(struct kobject *kobj,
+                                        struct attribute *attr, char *buf)
 {
-       return __qos_thresholdrr_show(kobj, attr, buf, true);
+       return __qos_threshold_rr_show(kobj, attr, buf, true);
 }
 
-static ssize_t lod_qos_thresholdrr_show(struct kobject *kobj,
-                                       struct attribute *attr, char *buf)
+static ssize_t qos_threshold_rr_show(struct kobject *kobj,
+                                    struct attribute *attr, char *buf)
 {
-       return __qos_thresholdrr_show(kobj, attr, buf, false);
+       return __qos_threshold_rr_show(kobj, attr, buf, false);
 }
 
 /**
@@ -537,20 +624,31 @@ static ssize_t lod_qos_thresholdrr_show(struct kobject *kobj,
  * space so that more full OSTs are chosen less often, otherwise use the
  * round-robin allocator for efficiency and performance.
  */
-static ssize_t __qos_thresholdrr_store(struct kobject *kobj,
-                                      struct attribute *attr,
-                                      const char *buffer, size_t count,
-                                      bool is_mdt)
+static ssize_t __qos_threshold_rr_store(struct kobject *kobj,
+                                       struct attribute *attr,
+                                       const char *buffer, size_t count,
+                                       bool is_mdt)
 {
        struct dt_device *dt = container_of(kobj, struct dt_device,
                                            dd_kobj);
        struct lod_device *lod = dt2lod_dev(dt);
        struct lu_tgt_descs *ltd = is_mdt ? &lod->lod_mdt_descs :
                                            &lod->lod_ost_descs;
+       char buf[6], *tmp;
        unsigned int val;
        int rc;
 
-       rc = kstrtouint(buffer, 0, &val);
+       /* "100%\n\0" should be largest string */
+       if (count >= sizeof(buf))
+               return -ERANGE;
+
+       strncpy(buf, buffer, sizeof(buf));
+       buf[sizeof(buf) - 1] = '\0';
+       tmp = strchr(buf, '%');
+       if (tmp)
+               *tmp = '\0';
+
+       rc = kstrtouint(buf, 0, &val);
        if (rc)
                return rc;
 
@@ -562,22 +660,22 @@ static ssize_t __qos_thresholdrr_store(struct kobject *kobj,
        return count;
 }
 
-static ssize_t mdt_qos_thresholdrr_store(struct kobject *kobj,
-                                        struct attribute *attr,
-                                        const char *buffer, size_t count)
+static ssize_t mdt_qos_threshold_rr_store(struct kobject *kobj,
+                                         struct attribute *attr,
+                                         const char *buffer, size_t count)
 {
-       return __qos_thresholdrr_store(kobj, attr, buffer, count, true);
+       return __qos_threshold_rr_store(kobj, attr, buffer, count, true);
 }
 
-static ssize_t lod_qos_thresholdrr_store(struct kobject *kobj,
-                                        struct attribute *attr,
-                                        const char *buffer, size_t count)
+static ssize_t qos_threshold_rr_store(struct kobject *kobj,
+                                     struct attribute *attr,
+                                     const char *buffer, size_t count)
 {
-       return __qos_thresholdrr_store(kobj, attr, buffer, count, false);
+       return __qos_threshold_rr_store(kobj, attr, buffer, count, false);
 }
 
-LUSTRE_RW_ATTR(mdt_qos_thresholdrr);
-LUSTRE_RW_ATTR(lod_qos_thresholdrr);
+LUSTRE_RW_ATTR(mdt_qos_threshold_rr);
+LUSTRE_RW_ATTR(qos_threshold_rr);
 
 /**
  * Show expiration period used to refresh cached statfs data, which
@@ -679,20 +777,20 @@ LUSTRE_RW_ATTR(qos_maxage);
 
 static void *lod_tgts_seq_start(struct seq_file *p, loff_t *pos, bool is_mdt)
 {
-       struct obd_device *dev = p->private;
-       struct lod_device *lod = lu2lod_dev(dev->obd_lu_dev);
+       struct obd_device *obd = p->private;
+       struct lod_device *lod = lu2lod_dev(obd->obd_lu_dev);
        struct lu_tgt_descs *ltd = is_mdt ? &lod->lod_mdt_descs :
                                            &lod->lod_ost_descs;
 
-       LASSERT(dev != NULL);
+       LASSERT(obd != NULL);
 
        lod_getref(ltd); /* released in lod_tgts_seq_stop */
-       if (*pos >= ltd->ltd_tgt_bitmap->size)
+       if (*pos >= ltd->ltd_tgts_size)
                return NULL;
 
-       *pos = find_next_bit(ltd->ltd_tgt_bitmap->data,
-                            ltd->ltd_tgt_bitmap->size, *pos);
-       if (*pos < ltd->ltd_tgt_bitmap->size)
+       *pos = find_next_bit(ltd->ltd_tgt_bitmap,
+                            ltd->ltd_tgts_size, *pos);
+       if (*pos < ltd->ltd_tgts_size)
                return LTD_TGT(ltd, *pos);
        else
                return NULL;
@@ -710,12 +808,12 @@ static void *lod_osts_seq_start(struct seq_file *p, loff_t *pos)
 
 static void lod_tgts_seq_stop(struct seq_file *p, void *v, bool is_mdt)
 {
-       struct obd_device *dev = p->private;
-       struct lod_device *lod = lu2lod_dev(dev->obd_lu_dev);
+       struct obd_device *obd = p->private;
+       struct lod_device *lod = lu2lod_dev(obd->obd_lu_dev);
        struct lu_tgt_descs *ltd = is_mdt ? &lod->lod_mdt_descs :
                                            &lod->lod_ost_descs;
 
-       LASSERT(dev != NULL);
+       LASSERT(obd != NULL);
        lod_putref(lod, ltd);
 }
 
@@ -732,17 +830,17 @@ static void lod_osts_seq_stop(struct seq_file *p, void *v)
 static void *lod_tgts_seq_next(struct seq_file *p, void *v, loff_t *pos,
                               bool is_mdt)
 {
-       struct obd_device *dev = p->private;
-       struct lod_device *lod = lu2lod_dev(dev->obd_lu_dev);
+       struct obd_device *obd = p->private;
+       struct lod_device *lod = lu2lod_dev(obd->obd_lu_dev);
        struct lu_tgt_descs *ltd = is_mdt ? &lod->lod_mdt_descs :
                                            &lod->lod_ost_descs;
 
-       if (*pos >= ltd->ltd_tgt_bitmap->size - 1)
+       if (*pos >= ltd->ltd_tgts_size - 1)
                return NULL;
 
-       *pos = find_next_bit(ltd->ltd_tgt_bitmap->data,
-                            ltd->ltd_tgt_bitmap->size, *pos + 1);
-       if (*pos < ltd->ltd_tgt_bitmap->size)
+       *pos = find_next_bit(ltd->ltd_tgt_bitmap,
+                            ltd->ltd_tgts_size, *pos + 1);
+       if (*pos < ltd->ltd_tgts_size)
                return LTD_TGT(ltd, *pos);
        else
                return NULL;
@@ -876,6 +974,50 @@ static ssize_t lmv_failout_store(struct kobject *kobj, struct attribute *attr,
 }
 LUSTRE_RW_ATTR(lmv_failout);
 
+char *mdt_hash_name[] = { "none",
+                         LMV_HASH_NAME_ALL_CHARS,
+                         LMV_HASH_NAME_FNV_1A_64,
+                         LMV_HASH_NAME_CRUSH,
+};
+
+static ssize_t mdt_hash_show(struct kobject *kobj, struct attribute *attr,
+                            char *buf)
+{
+       struct dt_device *dt = container_of(kobj, struct dt_device, dd_kobj);
+       struct lod_device *lod = dt2lod_dev(dt);
+
+       return snprintf(buf, PAGE_SIZE, "%s\n",
+               mdt_hash_name[lod->lod_mdt_descs.ltd_lmv_desc.ld_pattern]);
+}
+
+static ssize_t mdt_hash_store(struct kobject *kobj, struct attribute *attr,
+                             const char *buffer, size_t count)
+{
+       struct dt_device *dt = container_of(kobj, struct dt_device, dd_kobj);
+       struct lod_device *lod = dt2lod_dev(dt);
+       char *hash;
+       int len;
+       int i;
+
+       hash = kstrndup(buffer, count, GFP_KERNEL);
+       if (!hash)
+               return -ENOMEM;
+
+       len = strcspn(hash, "\n ");
+       hash[len] = '\0';
+       for (i = LMV_HASH_TYPE_ALL_CHARS; i < LMV_HASH_TYPE_MAX; i++) {
+               if (!strcmp(hash, mdt_hash_name[i])) {
+                       lod->lod_mdt_descs.ltd_lmv_desc.ld_pattern = i;
+                       kfree(hash);
+                       return count;
+               }
+       }
+       kfree(hash);
+
+       return -EINVAL;
+}
+LUSTRE_RW_ATTR(mdt_hash);
+
 static struct lprocfs_vars lprocfs_lod_obd_vars[] = {
        { NULL }
 };
@@ -898,6 +1040,9 @@ static const struct file_operations lod_proc_target_fops = {
 
 static struct attribute *lod_attrs[] = {
        &lustre_attr_dom_stripesize.attr,
+       &lustre_attr_dom_stripesize_max_kb.attr,
+       &lustre_attr_dom_stripesize_cur_kb.attr,
+       &lustre_attr_dom_threshold_free_mb.attr,
        &lustre_attr_stripesize.attr,
        &lustre_attr_stripeoffset.attr,
        &lustre_attr_stripecount.attr,
@@ -908,14 +1053,15 @@ static struct attribute *lod_attrs[] = {
        &lustre_attr_numobd.attr,
        &lustre_attr_qos_maxage.attr,
        &lustre_attr_qos_prio_free.attr,
-       &lustre_attr_lod_qos_thresholdrr.attr,
+       &lustre_attr_qos_threshold_rr.attr,
        &lustre_attr_mdt_stripecount.attr,
        &lustre_attr_mdt_stripetype.attr,
        &lustre_attr_mdt_activeobd.attr,
        &lustre_attr_mdt_numobd.attr,
        &lustre_attr_mdt_qos_maxage.attr,
        &lustre_attr_mdt_qos_prio_free.attr,
-       &lustre_attr_mdt_qos_thresholdrr.attr,
+       &lustre_attr_mdt_qos_threshold_rr.attr,
+       &lustre_attr_mdt_hash.attr,
        NULL,
 };
 
@@ -1041,8 +1187,7 @@ void lod_procfs_fini(struct lod_device *lod)
                kobject_put(lov);
        }
 
-       if (!IS_ERR_OR_NULL(lod->lod_debugfs))
-               ldebugfs_remove(&lod->lod_debugfs);
+       debugfs_remove_recursive(lod->lod_debugfs);
 
        if (obd->obd_proc_entry) {
                lprocfs_remove(&obd->obd_proc_entry);