+
+/**
+ * Show estimate of total amount of dirty data on clients.
+ *
+ * @kobj kobject embedded in obd_device
+ * @attr unused
+ * @buf buf used by sysfs to print out data
+ *
+ * Return: 0 on success
+ * negative value on error
+ */
+ssize_t tot_dirty_show(struct kobject *kobj, struct attribute *attr,
+ char *buf)
+{
+ struct obd_device *obd = container_of(kobj, struct obd_device,
+ obd_kset.kobj);
+ struct tg_grants_data *tgd;
+
+ tgd = &obd->u.obt.obt_lut->lut_tgd;
+ return scnprintf(buf, PAGE_SIZE, "%llu\n", tgd->tgd_tot_dirty);
+}
+EXPORT_SYMBOL(tot_dirty_show);
+
+/**
+ * Show total amount of space granted to clients.
+ *
+ * @kobj kobject embedded in obd_device
+ * @attr unused
+ * @buf buf used by sysfs to print out data
+ *
+ * Return: 0 on success
+ * negative value on error
+ */
+ssize_t tot_granted_show(struct kobject *kobj, struct attribute *attr,
+ char *buf)
+{
+ struct obd_device *obd = container_of(kobj, struct obd_device,
+ obd_kset.kobj);
+ struct tg_grants_data *tgd;
+
+ tgd = &obd->u.obt.obt_lut->lut_tgd;
+ return scnprintf(buf, PAGE_SIZE, "%llu\n", tgd->tgd_tot_granted);
+}
+EXPORT_SYMBOL(tot_granted_show);
+
+/**
+ * Show total amount of space used by IO in progress.
+ *
+ * @kobj kobject embedded in obd_device
+ * @attr unused
+ * @buf buf used by sysfs to print out data
+ *
+ * Return: 0 on success
+ * negative value on error
+ */
+ssize_t tot_pending_show(struct kobject *kobj, struct attribute *attr,
+ char *buf)
+{
+ struct obd_device *obd = container_of(kobj, struct obd_device,
+ obd_kset.kobj);
+ struct tg_grants_data *tgd;
+
+ tgd = &obd->u.obt.obt_lut->lut_tgd;
+ return scnprintf(buf, PAGE_SIZE, "%llu\n", tgd->tgd_tot_pending);
+}
+EXPORT_SYMBOL(tot_pending_show);
+
+/**
+ * Show if grants compatibility mode is disabled.
+ *
+ * When tgd_grant_compat_disable is set, we don't grant any space to clients
+ * not supporting OBD_CONNECT_GRANT_PARAM. Otherwise, space granted to such
+ * a client is inflated since it consumes PAGE_SIZE of grant space per
+ * block, (i.e. typically 4kB units), but underlaying file system might have
+ * block size bigger than page size, e.g. ZFS. See LU-2049 for details.
+ *
+ * @kobj kobject embedded in obd_device
+ * @attr unused
+ * @buf buf used by sysfs to print out data
+ *
+ * Return: string length of @buf output on success
+ */
+ssize_t grant_compat_disable_show(struct kobject *kobj, struct attribute *attr,
+ char *buf)
+{
+ struct obd_device *obd = container_of(kobj, struct obd_device,
+ obd_kset.kobj);
+ struct tg_grants_data *tgd = &obd->u.obt.obt_lut->lut_tgd;
+
+ return scnprintf(buf, PAGE_SIZE, "%u\n", tgd->tgd_grant_compat_disable);
+}
+EXPORT_SYMBOL(grant_compat_disable_show);
+
+/**
+ * Change grant compatibility mode.
+ *
+ * Setting tgd_grant_compat_disable prohibit any space granting to clients
+ * not supporting OBD_CONNECT_GRANT_PARAM. See details above.
+ *
+ * @kobj kobject embedded in obd_device
+ * @attr unused
+ * @buffer string which represents mode
+ * 1: disable compatibility mode
+ * 0: enable compatibility mode
+ * @count @buffer length
+ *
+ * Return: @count on success
+ * negative number on error
+ */
+ssize_t grant_compat_disable_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 tg_grants_data *tgd = &obd->u.obt.obt_lut->lut_tgd;
+ bool val;
+ int rc;
+
+ rc = kstrtobool(buffer, &val);
+ if (rc)
+ return rc;
+
+ tgd->tgd_grant_compat_disable = val;
+
+ return count;
+}
+EXPORT_SYMBOL(grant_compat_disable_store);