@@ -105,6 +105,8 @@ enum dax_device_flags {
DAXDEV_WRITE_CACHE,
/* flag to check if device supports synchronous flush */
DAXDEV_SYNC,
+ /* flag to indicate device capable of poison recovery */
+ DAXDEV_RECOVERY,
};
/**
@@ -227,6 +229,38 @@ bool dax_alive(struct dax_device *dax_dev)
}
EXPORT_SYMBOL_GPL(dax_alive);
+/* set by driver */
+/* for md: set if any participant target has the capability */
+void set_dax_recovery(struct dax_device *dax_dev)
+{
+ set_bit(DAXDEV_RECOVERY, &dax_dev->flags);
+}
+EXPORT_SYMBOL_GPL(set_dax_recovery);
+
+/* query by dax, and md drivers, and .... */
+/* can be true for md raid, but untrue for a target within */
+bool dax_recovery_capable(struct dax_device *dax_dev)
+{
+ return test_bit(DAXDEV_RECOVERY, &dax_dev->flags);
+}
+EXPORT_SYMBOL_GPL(dax_recovery_capable);
+
+/* requested by fs */
+/* can be true for md raid, and ought to be true for the target
+ * because kaddr ought to fall into the target which complained
+ * about BB and only pmem do that. however in theory, this could
+ * be true for md but untrue for a target strip
+ */
+int dax_prep_recovery(struct dax_device *dax_dev, void **kaddr)
+{
+ if (dax_recovery_capable(dax_dev)) {
+ set_bit(DAXDEV_RECOVERY, (unsigned long *)kaddr);
+ return 0;
+ }
+ return -EINVAL;
+}
+EXPORT_SYMBOL_GPL(dax_prep_recovery);
+
/*
* Note, rcu is not protecting the liveness of dax_dev, rcu is ensuring
* that any fault handlers or operations that might have seen
@@ -506,6 +506,7 @@ static int pmem_attach_disk(struct device *dev,
if (rc)
goto out_cleanup_dax;
dax_write_cache(dax_dev, nvdimm_has_cache(nd_region));
+ set_dax_recovery(dax_dev);
pmem->dax_dev = dax_dev;
rc = device_add_disk(dev, disk, pmem_attribute_groups);
@@ -49,6 +49,9 @@ void kill_dax(struct dax_device *dax_dev);
void dax_write_cache(struct dax_device *dax_dev, bool wc);
bool dax_write_cache_enabled(struct dax_device *dax_dev);
bool __dax_synchronous(struct dax_device *dax_dev);
+void set_dax_recovery(struct dax_device *dax_dev);
+bool dax_recovery_capable(struct dax_device *dax_dev);
+int dax_prep_recovery(struct dax_device *dax_dev, void **kaddr);
static inline bool dax_synchronous(struct dax_device *dax_dev)
{
return __dax_synchronous(dax_dev);
Introduce dax device flag DAXDEV_RECOVERY to indicate a device that is capable of recoverying from media poison. For MD raid DAX devices, the capability is allowed for partial device as oppose to the entire device. And the final poison detection and repair rely on the provisioning base drivers. Signed-off-by: Jane Chu <jane.chu@oracle.com> --- drivers/dax/super.c | 34 ++++++++++++++++++++++++++++++++++ drivers/nvdimm/pmem.c | 1 + include/linux/dax.h | 3 +++ 3 files changed, 38 insertions(+)