#include <linux/types.h>
 #include <linux/debugfs.h>
+#include <linux/ratelimit.h>
 #include <linux/atomic.h>
 
 /*
        unsigned long reject_end;
 
        unsigned long count;
+       struct ratelimit_state ratelimit_state;
+       struct dentry *dname;
 };
 
-#define FAULT_ATTR_INITIALIZER {                               \
-               .interval = 1,                                  \
-               .times = ATOMIC_INIT(1),                        \
-               .require_end = ULONG_MAX,                       \
-               .stacktrace_depth = 32,                         \
-               .verbose = 2,                                   \
+#define FAULT_ATTR_INITIALIZER {                                       \
+               .interval = 1,                                          \
+               .times = ATOMIC_INIT(1),                                \
+               .require_end = ULONG_MAX,                               \
+               .stacktrace_depth = 32,                                 \
+               .ratelimit_state = RATELIMIT_STATE_INIT_DISABLED,       \
+               .verbose = 2,                                           \
+               .dname = NULL,                                          \
        }
 
 #define DECLARE_FAULT_ATTR(name) struct fault_attr name = FAULT_ATTR_INITIALIZER
 
 
 static void fail_dump(struct fault_attr *attr)
 {
-       if (attr->verbose > 0)
-               printk(KERN_NOTICE "FAULT_INJECTION: forcing a failure\n");
-       if (attr->verbose > 1)
-               dump_stack();
+       if (attr->verbose > 0 && __ratelimit(&attr->ratelimit_state)) {
+               printk(KERN_NOTICE "FAULT_INJECTION: forcing a failure.\n"
+                      "name %pd, interval %lu, probability %lu, "
+                      "space %d, times %d\n", attr->dname,
+                      attr->probability, attr->interval,
+                      atomic_read(&attr->space),
+                      atomic_read(&attr->times));
+               if (attr->verbose > 1)
+                       dump_stack();
+       }
 }
 
 #define atomic_dec_not_zero(v)         atomic_add_unless((v), -1, 0)
                goto fail;
        if (!debugfs_create_ul("verbose", mode, dir, &attr->verbose))
                goto fail;
+       if (!debugfs_create_u32("verbose_ratelimit_interval_ms", mode, dir,
+                               &attr->ratelimit_state.interval))
+               goto fail;
+       if (!debugfs_create_u32("verbose_ratelimit_burst", mode, dir,
+                               &attr->ratelimit_state.burst))
+               goto fail;
        if (!debugfs_create_bool("task-filter", mode, dir, &attr->task_filter))
                goto fail;
 
 
 #endif /* CONFIG_FAULT_INJECTION_STACKTRACE_FILTER */
 
+       attr->dname = dget(dir);
        return dir;
 fail:
        debugfs_remove_recursive(dir);