+ lustre_hash_bucket_t *lhb;
+ int theta;
+ int i;
+ int c = 0;
+ int dist[8] = { 0, };
+
+ if (str == NULL || size == 0)
+ return 0;
+
+ read_lock(&lh->lh_rwlock);
+ theta = __lustre_hash_theta(lh);
+
+ c += snprintf(str + c, size - c, "%-36s ",lh->lh_name);
+ c += snprintf(str + c, size - c, "%5d ", lh->lh_cur_size);
+ c += snprintf(str + c, size - c, "%5d ", lh->lh_min_size);
+ c += snprintf(str + c, size - c, "%5d ", lh->lh_max_size);
+ c += snprintf(str + c, size - c, "%d.%03d ",
+ theta / 1000, theta % 1000);
+ c += snprintf(str + c, size - c, "%d.%03d ",
+ lh->lh_min_theta / 1000, lh->lh_min_theta % 1000);
+ c += snprintf(str + c, size - c, "%d.%03d ",
+ lh->lh_max_theta / 1000, lh->lh_max_theta % 1000);
+ c += snprintf(str + c, size - c, " 0x%02x ", lh->lh_flags);
+ c += snprintf(str + c, size - c, "%6d ",
+ atomic_read(&lh->lh_rehash_count));
+ c += snprintf(str + c, size - c, "%5d ",
+ atomic_read(&lh->lh_count));
+
+ /*
+ * The distribution is a summary of the chained hash depth in
+ * each of the lustre hash buckets. Each buckets lhb_count is
+ * divided by the hash theta value and used to generate a
+ * histogram of the hash distribution. A uniform hash will
+ * result in all hash buckets being close to the average thus
+ * only the first few entries in the histogram will be non-zero.
+ * If you hash function results in a non-uniform hash the will
+ * be observable by outlier bucks in the distribution histogram.
+ *
+ * Uniform hash distribution: 128/128/0/0/0/0/0/0
+ * Non-Uniform hash distribution: 128/125/0/0/0/0/2/1
+ */
+ lh_for_each_bucket(lh, lhb, i)
+ dist[MIN(fls(atomic_read(&lhb->lhb_count)/MAX(theta,1)),7)]++;
+
+ for (i = 0; i < 8; i++)
+ c += snprintf(str + c, size - c, "%d%c", dist[i],
+ (i == 7) ? '\n' : '/');
+
+ read_unlock(&lh->lh_rwlock);
+
+ return c;