+/**
+ * Show if the OFD enforces T10PI checksum.
+ *
+ * \param[in] m seq_file handle
+ * \param[in] data unused for single entry
+ *
+ * \retval 0 on success
+ * \retval negative value on error
+ */
+static ssize_t checksum_t10pi_enforce_show(struct kobject *kobj,
+ struct attribute *attr,
+ char *buf)
+{
+ struct obd_device *obd = container_of(kobj, struct obd_device,
+ obd_kset.kobj);
+ struct ofd_device *ofd = ofd_dev(obd->obd_lu_dev);
+
+ return sprintf(buf, "%u\n", ofd->ofd_checksum_t10pi_enforce);
+}
+
+/**
+ * Force specific T10PI checksum modes to be enabled
+ *
+ * If T10PI *is* supported in hardware, allow only the supported T10PI type
+ * to be used. If T10PI is *not* supported by the OSD, setting the enforce
+ * parameter forces all T10PI types to be enabled (even if slower) for
+ * testing.
+ *
+ * The final determination of which algorithm to be used depends whether
+ * the client supports T10PI or not, and is handled at client connect time.
+ *
+ * \param[in] file proc file
+ * \param[in] buffer string which represents mode
+ * 1: set T10PI checksums enforced
+ * 0: unset T10PI checksums enforced
+ * \param[in] count \a buffer length
+ * \param[in] off unused for single entry
+ *
+ * \retval \a count on success
+ * \retval negative number on error
+ */
+static ssize_t checksum_t10pi_enforce_store(struct kobject *kobj,
+ struct attribute *attr,
+ const char *buffer, size_t count)
+{
+ struct obd_device *obd = container_of(kobj, struct obd_device,
+ obd_kset.kobj);
+ struct ofd_device *ofd = ofd_dev(obd->obd_lu_dev);
+ bool enforce;
+ int rc;
+
+ rc = kstrtobool(buffer, &enforce);
+ if (rc)
+ return rc;
+
+ spin_lock(&ofd->ofd_flags_lock);
+ ofd->ofd_checksum_t10pi_enforce = enforce;
+ spin_unlock(&ofd->ofd_flags_lock);
+ return count;
+}
+LUSTRE_RW_ATTR(checksum_t10pi_enforce);
+
+#if LUSTRE_VERSION_CODE < OBD_OCD_VERSION(2, 14, 53, 0)
+static bool max_file_warned;
+static bool rd_cache_warned;
+static bool wr_cache_warned;
+
+static ssize_t read_cache_enable_show(struct kobject *kobj,
+ struct attribute *attr,
+ char *buf)
+{
+ struct obd_device *obd = container_of(kobj, struct obd_device,
+ obd_kset.kobj);
+ struct ofd_device *ofd = ofd_dev(obd->obd_lu_dev);
+
+ if (!rd_cache_warned) {
+ rd_cache_warned = true;
+ pr_info("ofd: 'obdfilter.*.read_cache_enabled' is deprecated, use 'osd-*.read_cache_enabled' instead\n");
+ }
+
+ if (!ofd->ofd_read_cache_enable)
+ return -EOPNOTSUPP;
+
+ return lustre_attr_show(&ofd->ofd_osd->dd_kobj,
+ ofd->ofd_read_cache_enable, buf);
+}
+
+static ssize_t read_cache_enable_store(struct kobject *kobj,
+ struct attribute *attr,
+ const char *buffer, size_t count)
+{
+ struct obd_device *obd = container_of(kobj, struct obd_device,
+ obd_kset.kobj);
+ struct ofd_device *ofd = ofd_dev(obd->obd_lu_dev);
+
+ if (!rd_cache_warned) {
+ rd_cache_warned = true;
+ pr_info("ofd: 'obdfilter.*.read_cache_enabled' is deprecated, use 'osd-*.read_cache_enabled' instead\n");
+ }
+
+ if (!ofd->ofd_read_cache_enable)
+ return -EOPNOTSUPP;
+
+ return lustre_attr_store(&ofd->ofd_osd->dd_kobj,
+ ofd->ofd_read_cache_enable, buffer, count);
+}
+LUSTRE_RW_ATTR(read_cache_enable);
+
+static ssize_t readcache_max_filesize_show(struct kobject *kobj,
+ struct attribute *attr,
+ char *buf)
+{
+ struct obd_device *obd = container_of(kobj, struct obd_device,
+ obd_kset.kobj);
+ struct ofd_device *ofd = ofd_dev(obd->obd_lu_dev);
+
+ if (!max_file_warned) {
+ max_file_warned = true;
+ pr_info("ofd: 'obdfilter.*.readcache_max_filesize' is deprecated, use 'osd-*.readcache_max_filesize' instead\n");
+ }
+
+ if (!ofd->ofd_read_cache_max_filesize)
+ return -EOPNOTSUPP;
+
+ return lustre_attr_show(&ofd->ofd_osd->dd_kobj,
+ ofd->ofd_read_cache_max_filesize, buf);
+}
+
+static ssize_t readcache_max_filesize_store(struct kobject *kobj,
+ struct attribute *attr,
+ const char *buffer, size_t count)
+{
+ struct obd_device *obd = container_of(kobj, struct obd_device,
+ obd_kset.kobj);
+ struct ofd_device *ofd = ofd_dev(obd->obd_lu_dev);
+
+ if (!max_file_warned) {
+ max_file_warned = true;
+ pr_info("ofd: 'obdfilter.*.readcache_max_filesize' is deprecated, use 'osd-*.readcache_max_filesize' instead\n");
+ }
+
+ if (!ofd->ofd_read_cache_max_filesize)
+ return -EOPNOTSUPP;
+
+ return lustre_attr_store(&ofd->ofd_osd->dd_kobj,
+ ofd->ofd_read_cache_max_filesize,
+ buffer, count);
+}
+LUSTRE_RW_ATTR(readcache_max_filesize);
+
+static ssize_t writethrough_cache_enable_show(struct kobject *kobj,
+ struct attribute *attr,
+ char *buf)
+{
+ struct obd_device *obd = container_of(kobj, struct obd_device,
+ obd_kset.kobj);
+ struct ofd_device *ofd = ofd_dev(obd->obd_lu_dev);
+
+ if (!wr_cache_warned) {
+ wr_cache_warned = true;
+ pr_info("ofd: 'obdfilter.*.writethrough_cache_enabled' is deprecated, use 'osd-*.writethrough_cache_enabled' instead\n");
+ }
+
+ if (!ofd->ofd_write_cache_enable)
+ return -EOPNOTSUPP;
+
+ return lustre_attr_show(&ofd->ofd_osd->dd_kobj,
+ ofd->ofd_write_cache_enable, buf);
+}
+
+static ssize_t writethrough_cache_enable_store(struct kobject *kobj,
+ struct attribute *attr,
+ const char *buffer, size_t count)
+{
+ struct obd_device *obd = container_of(kobj, struct obd_device,
+ obd_kset.kobj);
+ struct ofd_device *ofd = ofd_dev(obd->obd_lu_dev);
+
+ if (!ofd->ofd_write_cache_enable)
+ return -EOPNOTSUPP;
+
+ return lustre_attr_store(&ofd->ofd_osd->dd_kobj,
+ ofd->ofd_write_cache_enable,
+ buffer, count);
+}
+LUSTRE_RW_ATTR(writethrough_cache_enable);
+#endif