+static ssize_t idle_timeout_show(struct kobject *kobj, struct attribute *attr,
+ char *buf)
+{
+ struct obd_device *obd = container_of(kobj, struct obd_device,
+ obd_kset.kobj);
+ struct obd_import *imp;
+ int ret;
+
+ with_imp_locked(obd, imp, ret)
+ ret = sprintf(buf, "%u\n", imp->imp_idle_timeout);
+
+ return ret;
+}
+
+static ssize_t idle_timeout_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 obd_import *imp;
+ struct ptlrpc_request *req;
+ unsigned int idle_debug = 0;
+ unsigned int val;
+ int rc;
+
+ if (strncmp(buffer, "debug", 5) == 0) {
+ idle_debug = D_CONSOLE;
+ } else if (strncmp(buffer, "nodebug", 6) == 0) {
+ idle_debug = D_HA;
+ } else {
+ rc = kstrtouint(buffer, 10, &val);
+ if (rc)
+ return rc;
+
+ if (val > CONNECTION_SWITCH_MAX)
+ return -ERANGE;
+ }
+
+ with_imp_locked(obd, imp, rc) {
+ if (idle_debug) {
+ imp->imp_idle_debug = idle_debug;
+ } else {
+ if (!val) {
+ /* initiate the connection if it's in IDLE state */
+ req = ptlrpc_request_alloc(imp,
+ &RQF_OST_STATFS);
+ if (req != NULL)
+ ptlrpc_req_finished(req);
+ }
+ imp->imp_idle_timeout = val;
+ }
+ }
+
+ return count;
+}
+LUSTRE_RW_ATTR(idle_timeout);
+
+static ssize_t idle_connect_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 obd_import *imp;
+ struct ptlrpc_request *req;
+ int rc;
+
+ with_imp_locked(obd, imp, rc) {
+ /* to initiate the connection if it's in IDLE state */
+ req = ptlrpc_request_alloc(imp, &RQF_OST_STATFS);
+ if (req)
+ ptlrpc_req_finished(req);
+ ptlrpc_pinger_force(imp);
+ }
+
+ return rc ?: count;
+}
+LUSTRE_WO_ATTR(idle_connect);
+
+static ssize_t grant_shrink_show(struct kobject *kobj, struct attribute *attr,
+ char *buf)
+{
+ struct obd_device *obd = container_of(kobj, struct obd_device,
+ obd_kset.kobj);
+ struct obd_import *imp;
+ ssize_t len;
+
+ with_imp_locked(obd, imp, len)
+ len = scnprintf(buf, PAGE_SIZE, "%d\n",
+ !imp->imp_grant_shrink_disabled &&
+ OCD_HAS_FLAG(&imp->imp_connect_data,
+ GRANT_SHRINK));
+
+ return len;
+}
+
+static ssize_t grant_shrink_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 obd_import *imp;
+ bool val;
+ int rc;
+
+ if (obd == NULL)
+ return 0;
+
+ rc = kstrtobool(buffer, &val);
+ if (rc)
+ return rc;
+
+ with_imp_locked(obd, imp, rc) {
+ spin_lock(&imp->imp_lock);
+ imp->imp_grant_shrink_disabled = !val;
+ spin_unlock(&imp->imp_lock);
+ }
+
+ return rc ?: count;
+}
+LUSTRE_RW_ATTR(grant_shrink);
+