Whamcloud - gitweb
LU-9855 lustre: replace LPROCFS_CLIMP_CHECK() 56/36956/6
authorMr NeilBrown <neilb@suse.de>
Mon, 9 Dec 2019 05:33:46 +0000 (16:33 +1100)
committerOleg Drokin <green@whamcloud.com>
Fri, 14 Feb 2020 05:50:44 +0000 (05:50 +0000)
The usage pattern for LPROCFS_CLIMP_CHECK() is clumsy.
It must be paired with LPROCFS_CLIMP_EXIT(), but
not doing this does not produce a compile-time error.
The 'import' should not be dereferenced before the CHECK, or
used after the EXIT, but sometimes it is.

Replace it with a structure macro/statement:

 with_obd_imp_lock(obd, imp, rc) {
     statements;
 }

statements are protected by the semaphore and only run if imp can be
set to a non-NULL pointer.
rc can be changed by the statements, and should be returned
afterwards as it may have been set to -ENODEV.

Errors fixed with this patch:
- some code tested u.cli.cl_import no-NULL even after
  LPROCFS_CLIMP_CHECK()
- some code dereferences cl_import before calling
  LPROCFS_CLIMP_CHECK()
- short_io_bytes_store() and max_procs_in_flight_store() don't access
  the import, so don't need LPROCFS_CLIMP_CHECK
- lprocfs_import_seq_write() set count to an error before 'goto out'
  which would free memory of length "count+1".
- lprocfs_import_seq_write() also called ptlrpc_recover_import()
  on the imp *after* dropping the semaphore.

Signed-off-by: Mr NeilBrown <neilb@suse.de>
Change-Id: If9d5eb452157d7f76796f690569ef13fec111d76
Reviewed-on: https://review.whamcloud.com/36956
Tested-by: jenkins <devops@whamcloud.com>
Reviewed-by: Andreas Dilger <adilger@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
Reviewed-by: James Simmons <jsimmons@infradead.org>
Reviewed-by: Shaun Tancheff <shaun.tancheff@hpe.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
lustre/include/lprocfs_status.h
lustre/mdc/lproc_mdc.c
lustre/mgc/mgc_request.c
lustre/obdclass/lprocfs_status.c
lustre/osc/lproc_osc.c
lustre/osp/lproc_osp.c
lustre/ptlrpc/lproc_ptlrpc.c

index 0853a51..feed2bd 100644 (file)
@@ -660,17 +660,14 @@ extern int lprocfs_single_release(struct inode *, struct file *);
 extern int lprocfs_seq_release(struct inode *, struct file *);
 
 /* You must use these macros when you want to refer to
- * the import in a client obd_device for a lprocfs entry */
-#define LPROCFS_CLIMP_CHECK(obd) do {           \
-        typecheck(struct obd_device *, obd);    \
-       down_read(&(obd)->u.cli.cl_sem);    \
-        if ((obd)->u.cli.cl_import == NULL) {   \
-            up_read(&(obd)->u.cli.cl_sem); \
-             return -ENODEV;                    \
-        }                                       \
-} while(0)
-#define LPROCFS_CLIMP_EXIT(obd)                 \
-       up_read(&(obd)->u.cli.cl_sem);
+ * the import in a client obd_device for a lprocfs entry
+ */
+#define with_imp_locked(__obd, __imp, __rc)                            \
+       for (down_read(&(__obd)->u.cli.cl_sem),                         \
+            __imp = (__obd)->u.cli.cl_import,                          \
+            __rc = __imp ? 0 : -ENODEV;                                \
+            __imp ? 1 : (up_read(&(__obd)->u.cli.cl_sem), 0);          \
+            __imp = NULL)
 
 /* write the name##_seq_show function, call LDEBUGFS_SEQ_FOPS_RO for read-only
  * debugfs entries; otherwise, you will define name##_seq_write function also
index cf21905..f5bae91 100644 (file)
@@ -43,11 +43,11 @@ static ssize_t active_show(struct kobject *kobj, struct attribute *attr,
 {
        struct obd_device *dev = container_of(kobj, struct obd_device,
                                              obd_kset.kobj);
+       struct obd_import *imp;
        ssize_t len;
 
-       LPROCFS_CLIMP_CHECK(dev);
-       len = sprintf(buf, "%d\n", !dev->u.cli.cl_import->imp_deactive);
-       LPROCFS_CLIMP_EXIT(dev);
+       with_imp_locked(dev, imp, len)
+               len = sprintf(buf, "%d\n", !imp->imp_deactive);
        return len;
 }
 
index 943ee3a..077f740 100644 (file)
@@ -546,15 +546,20 @@ int lprocfs_mgc_rd_ir_state(struct seq_file *m, void *data)
        struct obd_import       *imp;
        struct obd_connect_data *ocd;
        struct config_llog_data *cld;
+       int rc = 0;
 
        ENTRY;
        LASSERT(obd);
-       LPROCFS_CLIMP_CHECK(obd);
-       imp = obd->u.cli.cl_import;
-       ocd = &imp->imp_connect_data;
+       with_imp_locked(obd, imp, rc) {
+               ocd = &imp->imp_connect_data;
+
+               seq_printf(m, "imperative_recovery: %s\n",
+                          OCD_HAS_FLAG(ocd, IMP_RECOV) ?
+                          "ENABLED" : "DISABLED");
+       }
+       if (rc)
+               RETURN(rc);
 
-       seq_printf(m, "imperative_recovery: %s\n",
-                  OCD_HAS_FLAG(ocd, IMP_RECOV) ? "ENABLED" : "DISABLED");
        seq_printf(m, "client_state:\n");
 
        spin_lock(&config_list_lock);
@@ -567,7 +572,6 @@ int lprocfs_mgc_rd_ir_state(struct seq_file *m, void *data)
        }
        spin_unlock(&config_list_lock);
 
-       LPROCFS_CLIMP_EXIT(obd);
        RETURN(0);
 }
 
index 7b8aff9..717c272 100644 (file)
@@ -516,17 +516,18 @@ ssize_t conn_uuid_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;
        struct ptlrpc_connection *conn;
        ssize_t count;
 
-       LPROCFS_CLIMP_CHECK(obd);
-       conn = obd->u.cli.cl_import->imp_connection;
-       if (conn && obd->u.cli.cl_import)
-               count = sprintf(buf, "%s\n", conn->c_remote_uuid.uuid);
-       else
-               count = sprintf(buf, "%s\n", "<none>");
+       with_imp_locked(obd, imp, count) {
+               conn = imp->imp_connection;
+               if (conn)
+                       count = sprintf(buf, "%s\n", conn->c_remote_uuid.uuid);
+               else
+                       count = sprintf(buf, "%s\n", "<none>");
+       }
 
-       LPROCFS_CLIMP_EXIT(obd);
        return count;
 }
 EXPORT_SYMBOL(conn_uuid_show);
@@ -539,13 +540,12 @@ int lprocfs_server_uuid_seq_show(struct seq_file *m, void *data)
        int rc = 0;
 
        LASSERT(obd != NULL);
-       LPROCFS_CLIMP_CHECK(obd);
-       imp = obd->u.cli.cl_import;
-       imp_state_name = ptlrpc_import_state_name(imp->imp_state);
-       seq_printf(m, "%s\t%s%s\n", obd2cli_tgt(obd), imp_state_name,
-                  imp->imp_deactive ? "\tDEACTIVATED" : "");
+       with_imp_locked(obd, imp, rc) {
+               imp_state_name = ptlrpc_import_state_name(imp->imp_state);
+               seq_printf(m, "%s\t%s%s\n", obd2cli_tgt(obd), imp_state_name,
+                          imp->imp_deactive ? "\tDEACTIVATED" : "");
+       }
 
-       LPROCFS_CLIMP_EXIT(obd);
        return rc;
 }
 EXPORT_SYMBOL(lprocfs_server_uuid_seq_show);
@@ -913,22 +913,19 @@ obd_connect_data_seqprint(struct seq_file *m, struct obd_connect_data *ocd)
                           ocd->ocd_maxmodrpcs);
 }
 
-int lprocfs_import_seq_show(struct seq_file *m, void *data)
+static void lprocfs_import_seq_show_locked(struct seq_file *m,
+                                          struct obd_device *obd,
+                                          struct obd_import *imp)
 {
        char nidstr[LNET_NIDSTR_SIZE];
        struct lprocfs_counter ret;
        struct lprocfs_counter_header *header;
-       struct obd_device *obd = (struct obd_device *)data;
-       struct obd_import *imp;
        struct obd_import_conn *conn;
        struct obd_connect_data *ocd;
        int j;
        int k;
        int rw = 0;
 
-       LASSERT(obd != NULL);
-       LPROCFS_CLIMP_CHECK(obd);
-       imp = obd->u.cli.cl_import;
        ocd = &imp->imp_connect_data;
 
        seq_printf(m, "import:\n"
@@ -977,7 +974,7 @@ int lprocfs_import_seq_show(struct seq_file *m, void *data)
        spin_unlock(&imp->imp_lock);
 
        if (!obd->obd_svc_stats)
-               goto out_climp;
+               return;
 
        header = &obd->obd_svc_stats->ls_cnt_header[PTLRPC_REQWAIT_CNTR];
        lprocfs_stats_collect(obd->obd_svc_stats, PTLRPC_REQWAIT_CNTR, &ret);
@@ -1042,10 +1039,18 @@ int lprocfs_import_seq_show(struct seq_file *m, void *data)
                                           k / j, (100 * k / j) % 100);
                }
        }
+}
 
-out_climp:
-       LPROCFS_CLIMP_EXIT(obd);
-       return 0;
+int lprocfs_import_seq_show(struct seq_file *m, void *data)
+{
+       struct obd_device *obd = (struct obd_device *)data;
+       struct obd_import *imp;
+       int rv;
+
+       LASSERT(obd != NULL);
+       with_imp_locked(obd, imp, rv)
+               lprocfs_import_seq_show_locked(m, obd, imp);
+       return rv;
 }
 EXPORT_SYMBOL(lprocfs_import_seq_show);
 
@@ -1054,26 +1059,25 @@ int lprocfs_state_seq_show(struct seq_file *m, void *data)
        struct obd_device *obd = (struct obd_device *)data;
        struct obd_import *imp;
        int j, k;
+       int rc;
 
        LASSERT(obd != NULL);
-       LPROCFS_CLIMP_CHECK(obd);
-       imp = obd->u.cli.cl_import;
-
-       seq_printf(m, "current_state: %s\n",
-                  ptlrpc_import_state_name(imp->imp_state));
-       seq_printf(m, "state_history:\n");
-       k = imp->imp_state_hist_idx;
-       for (j = 0; j < IMP_STATE_HIST_LEN; j++) {
-               struct import_state_hist *ish =
-                       &imp->imp_state_hist[(k + j) % IMP_STATE_HIST_LEN];
-               if (ish->ish_state == 0)
-                       continue;
-               seq_printf(m, " - [ %lld, %s ]\n", (s64)ish->ish_time,
-                          ptlrpc_import_state_name(ish->ish_state));
+       with_imp_locked(obd, imp, rc) {
+               seq_printf(m, "current_state: %s\n",
+                          ptlrpc_import_state_name(imp->imp_state));
+               seq_printf(m, "state_history:\n");
+               k = imp->imp_state_hist_idx;
+               for (j = 0; j < IMP_STATE_HIST_LEN; j++) {
+                       struct import_state_hist *ish =
+                               &imp->imp_state_hist[(k + j) % IMP_STATE_HIST_LEN];
+                       if (ish->ish_state == 0)
+                               continue;
+                       seq_printf(m, " - [ %lld, %s ]\n", (s64)ish->ish_time,
+                                  ptlrpc_import_state_name(ish->ish_state));
+               }
        }
 
-       LPROCFS_CLIMP_EXIT(obd);
-       return 0;
+       return rc;
 }
 EXPORT_SYMBOL(lprocfs_state_seq_show);
 
@@ -1088,17 +1092,15 @@ int lprocfs_at_hist_helper(struct seq_file *m, struct adaptive_timeout *at)
 EXPORT_SYMBOL(lprocfs_at_hist_helper);
 
 /* See also ptlrpc_lprocfs_timeouts_show_seq */
-int lprocfs_timeouts_seq_show(struct seq_file *m, void *data)
+static void lprocfs_timeouts_seq_show_locked(struct seq_file *m,
+                                            struct obd_device *obd,
+                                            struct obd_import *imp)
 {
-       struct obd_device *obd = (struct obd_device *)data;
-       struct obd_import *imp;
        unsigned int cur, worst;
        time64_t now, worstt;
        int i;
 
        LASSERT(obd != NULL);
-       LPROCFS_CLIMP_CHECK(obd);
-       imp = obd->u.cli.cl_import;
 
        now = ktime_get_real_seconds();
 
@@ -1125,9 +1127,17 @@ int lprocfs_timeouts_seq_show(struct seq_file *m, void *data)
                           (s64)(now - worstt));
                lprocfs_at_hist_helper(m, &imp->imp_at.iat_service_estimate[i]);
        }
+}
 
-       LPROCFS_CLIMP_EXIT(obd);
-       return 0;
+int lprocfs_timeouts_seq_show(struct seq_file *m, void *data)
+{
+       struct obd_device *obd = (struct obd_device *)data;
+       struct obd_import *imp;
+       int rc;
+
+       with_imp_locked(obd, imp, rc)
+               lprocfs_timeouts_seq_show_locked(m, obd, imp);
+       return rc;
 }
 EXPORT_SYMBOL(lprocfs_timeouts_seq_show);
 
@@ -1136,16 +1146,19 @@ int lprocfs_connect_flags_seq_show(struct seq_file *m, void *data)
        struct obd_device *obd = data;
        __u64 flags;
        __u64 flags2;
+       struct obd_import *imp;
+       int rc;
 
-       LPROCFS_CLIMP_CHECK(obd);
-       flags = obd->u.cli.cl_import->imp_connect_data.ocd_connect_flags;
-       flags2 = obd->u.cli.cl_import->imp_connect_data.ocd_connect_flags2;
-       seq_printf(m, "flags=%#llx\n", flags);
-       seq_printf(m, "flags2=%#llx\n", flags2);
-       obd_connect_seq_flags2str(m, flags, flags2, "\n");
-       seq_printf(m, "\n");
-       LPROCFS_CLIMP_EXIT(obd);
-       return 0;
+       with_imp_locked(obd, imp, rc) {
+               flags = imp->imp_connect_data.ocd_connect_flags;
+               flags2 = imp->imp_connect_data.ocd_connect_flags2;
+               seq_printf(m, "flags=%#llx\n", flags);
+               seq_printf(m, "flags2=%#llx\n", flags2);
+               obd_connect_seq_flags2str(m, flags, flags2, "\n");
+               seq_printf(m, "\n");
+       }
+
+       return rc;
 }
 EXPORT_SYMBOL(lprocfs_connect_flags_seq_show);
 
@@ -2445,7 +2458,8 @@ ssize_t lprocfs_obd_max_pages_per_rpc_seq_write(struct file *file,
        struct seq_file *m = file->private_data;
        struct obd_device *dev = m->private;
        struct client_obd *cli = &dev->u.cli;
-       struct obd_connect_data *ocd = &cli->cl_import->imp_connect_data;
+       struct obd_import *imp;
+       struct obd_connect_data *ocd;
        int chunk_mask, rc;
        s64 val;
 
@@ -2459,23 +2473,23 @@ ssize_t lprocfs_obd_max_pages_per_rpc_seq_write(struct file *file,
        if (val >= ONE_MB_BRW_SIZE)
                val >>= PAGE_SHIFT;
 
-       LPROCFS_CLIMP_CHECK(dev);
-
-       chunk_mask = ~((1 << (cli->cl_chunkbits - PAGE_SHIFT)) - 1);
-       /* max_pages_per_rpc must be chunk aligned */
-       val = (val + ~chunk_mask) & chunk_mask;
-       if (val == 0 || (ocd->ocd_brw_size != 0 &&
-                        val > ocd->ocd_brw_size >> PAGE_SHIFT)) {
-               LPROCFS_CLIMP_EXIT(dev);
-               return -ERANGE;
+       with_imp_locked(dev, imp, rc) {
+               ocd = &imp->imp_connect_data;
+               chunk_mask = ~((1 << (cli->cl_chunkbits - PAGE_SHIFT)) - 1);
+               /* max_pages_per_rpc must be chunk aligned */
+               val = (val + ~chunk_mask) & chunk_mask;
+               if (val == 0 || (ocd->ocd_brw_size != 0 &&
+                                val > ocd->ocd_brw_size >> PAGE_SHIFT)) {
+                       rc = -ERANGE;
+               } else {
+                       spin_lock(&cli->cl_loi_list_lock);
+                       cli->cl_max_pages_per_rpc = val;
+                       client_adjust_max_dirty(cli);
+                       spin_unlock(&cli->cl_loi_list_lock);
+               }
        }
-       spin_lock(&cli->cl_loi_list_lock);
-       cli->cl_max_pages_per_rpc = val;
-       client_adjust_max_dirty(cli);
-       spin_unlock(&cli->cl_loi_list_lock);
 
-       LPROCFS_CLIMP_EXIT(dev);
-       return count;
+       return rc ?: count;
 }
 EXPORT_SYMBOL(lprocfs_obd_max_pages_per_rpc_seq_write);
 
@@ -2510,8 +2524,6 @@ ssize_t short_io_bytes_store(struct kobject *kobj, struct attribute *attr,
        if (count >= sizeof(kernbuf))
                return -EINVAL;
 
-       LPROCFS_CLIMP_CHECK(dev);
-
        memcpy(kernbuf, buffer, count);
        kernbuf[count] = '\0';
        rc = lu_str_to_s64(kernbuf, count, &val, '1');
@@ -2531,7 +2543,6 @@ ssize_t short_io_bytes_store(struct kobject *kobj, struct attribute *attr,
        spin_unlock(&cli->cl_loi_list_lock);
 
 out:
-       LPROCFS_CLIMP_EXIT(dev);
        return rc;
 }
 EXPORT_SYMBOL(short_io_bytes_store);
index 387ec7d..b934243 100644 (file)
@@ -46,11 +46,12 @@ static ssize_t active_show(struct kobject *kobj, struct attribute *attr,
 {
        struct obd_device *dev = container_of(kobj, struct obd_device,
                                              obd_kset.kobj);
+       struct obd_import *imp;
        int rc;
 
-       LPROCFS_CLIMP_CHECK(dev);
-       rc = sprintf(buf, "%d\n", !dev->u.cli.cl_import->imp_deactive);
-       LPROCFS_CLIMP_EXIT(dev);
+       with_imp_locked(dev, imp, rc)
+               rc = sprintf(buf, "%d\n", !imp->imp_deactive);
+
        return rc;
 }
 
@@ -111,8 +112,6 @@ static ssize_t max_rpcs_in_flight_store(struct kobject *kobj,
        if (val == 0 || val > OSC_MAX_RIF_MAX)
                return -ERANGE;
 
-       LPROCFS_CLIMP_CHECK(dev);
-
        adding = (int)val - cli->cl_max_rpcs_in_flight;
        req_count = atomic_read(&osc_pool_req_count);
        if (adding > 0 && req_count < osc_reqpool_maxreqcount) {
@@ -132,7 +131,6 @@ static ssize_t max_rpcs_in_flight_store(struct kobject *kobj,
        client_adjust_max_dirty(cli);
        spin_unlock(&cli->cl_loi_list_lock);
 
-       LPROCFS_CLIMP_EXIT(dev);
        return count;
 }
 LUSTRE_RW_ATTR(max_rpcs_in_flight);
@@ -284,6 +282,7 @@ static ssize_t osc_cur_grant_bytes_seq_write(struct file *file,
        struct seq_file *m = file->private_data;
        struct obd_device *obd = m->private;
        struct client_obd *cli = &obd->u.cli;
+       struct obd_import *imp;
        char kernbuf[22] = "";
        u64 val;
        int rc;
@@ -311,10 +310,9 @@ static ssize_t osc_cur_grant_bytes_seq_write(struct file *file,
 
        spin_unlock(&cli->cl_loi_list_lock);
 
-       LPROCFS_CLIMP_CHECK(obd);
-       if (cli->cl_import->imp_state == LUSTRE_IMP_FULL)
-               rc = osc_shrink_grant_to_target(cli, val);
-       LPROCFS_CLIMP_EXIT(obd);
+       with_imp_locked(obd, imp, rc)
+               if (imp->imp_state == LUSTRE_IMP_FULL)
+                       rc = osc_shrink_grant_to_target(cli, val);
 
        return rc ? rc : count;
 }
@@ -625,12 +623,11 @@ static ssize_t idle_timeout_show(struct kobject *kobj, struct attribute *attr,
 {
        struct obd_device *obd = container_of(kobj, struct obd_device,
                                              obd_kset.kobj);
-       struct client_obd *cli = &obd->u.cli;
+       struct obd_import *imp;
        int ret;
 
-       LPROCFS_CLIMP_CHECK(obd);
-       ret = sprintf(buf, "%u\n", cli->cl_import->imp_idle_timeout);
-       LPROCFS_CLIMP_EXIT(obd);
+       with_imp_locked(obd, imp, ret)
+               ret = sprintf(buf, "%u\n", imp->imp_idle_timeout);
 
        return ret;
 }
@@ -640,7 +637,7 @@ static ssize_t idle_timeout_store(struct kobject *kobj, struct attribute *attr,
 {
        struct obd_device *dev = container_of(kobj, struct obd_device,
                                              obd_kset.kobj);
-       struct client_obd *cli = &dev->u.cli;
+       struct obd_import *imp;
        struct ptlrpc_request *req;
        unsigned int idle_debug = 0;
        unsigned int val;
@@ -659,20 +656,20 @@ static ssize_t idle_timeout_store(struct kobject *kobj, struct attribute *attr,
                        return -ERANGE;
        }
 
-       LPROCFS_CLIMP_CHECK(dev);
-       if (idle_debug) {
-               cli->cl_import->imp_idle_debug = idle_debug;
-       } else {
-               if (!val) {
-                       /* initiate the connection if it's in IDLE state */
-                       req = ptlrpc_request_alloc(cli->cl_import,
-                                                  &RQF_OST_STATFS);
-                       if (req != NULL)
-                               ptlrpc_req_finished(req);
+       with_imp_locked(dev, 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;
                }
-               cli->cl_import->imp_idle_timeout = val;
        }
-       LPROCFS_CLIMP_EXIT(dev);
 
        return count;
 }
@@ -683,18 +680,19 @@ static ssize_t idle_connect_store(struct kobject *kobj, struct attribute *attr,
 {
        struct obd_device *dev = container_of(kobj, struct obd_device,
                                              obd_kset.kobj);
-       struct client_obd *cli = &dev->u.cli;
+       struct obd_import *imp;
        struct ptlrpc_request *req;
+       int rc;
 
-       LPROCFS_CLIMP_CHECK(dev);
-       /* to initiate the connection if it's in IDLE state */
-       req = ptlrpc_request_alloc(cli->cl_import, &RQF_OST_STATFS);
-       if (req)
-               ptlrpc_req_finished(req);
-       ptlrpc_pinger_force(cli->cl_import);
-       LPROCFS_CLIMP_EXIT(dev);
+       with_imp_locked(dev, 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 count;
+       return rc ?: count;
 }
 LUSTRE_WO_ATTR(idle_connect);
 
@@ -706,12 +704,11 @@ static ssize_t grant_shrink_show(struct kobject *kobj, struct attribute *attr,
        struct obd_import *imp;
        ssize_t len;
 
-       LPROCFS_CLIMP_CHECK(obd);
-       imp = obd->u.cli.cl_import;
-       len = scnprintf(buf, PAGE_SIZE, "%d\n",
-                       !imp->imp_grant_shrink_disabled &&
-                       OCD_HAS_FLAG(&imp->imp_connect_data, GRANT_SHRINK));
-       LPROCFS_CLIMP_EXIT(obd);
+       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;
 }
@@ -732,16 +729,13 @@ static ssize_t grant_shrink_store(struct kobject *kobj, struct attribute *attr,
        if (rc)
                return rc;
 
-       LPROCFS_CLIMP_CHECK(dev);
-
-       imp = dev->u.cli.cl_import;
-       spin_lock(&imp->imp_lock);
-       imp->imp_grant_shrink_disabled = !val;
-       spin_unlock(&imp->imp_lock);
-
-       LPROCFS_CLIMP_EXIT(dev);
+       with_imp_locked(dev, imp, rc) {
+               spin_lock(&imp->imp_lock);
+               imp->imp_grant_shrink_disabled = !val;
+               spin_unlock(&imp->imp_lock);
+       }
 
-       return count;
+       return rc ?: count;
 }
 LUSTRE_RW_ATTR(grant_shrink);
 
index 2aa77f5..c0fc78d 100644 (file)
@@ -55,11 +55,11 @@ static ssize_t active_show(struct kobject *kobj, struct attribute *attr,
                                            dd_kobj);
        struct lu_device *lu = dt2lu_dev(dt);
        struct obd_device *obd = lu->ld_obd;
+       struct obd_import *imp;
        int rc;
 
-       LPROCFS_CLIMP_CHECK(obd);
-       rc = sprintf(buf, "%d\n", !obd->u.cli.cl_import->imp_deactive);
-       LPROCFS_CLIMP_EXIT(obd);
+       with_imp_locked(obd, imp, rc)
+               rc = sprintf(buf, "%d\n", !imp->imp_deactive);
        return rc;
 }
 
@@ -80,6 +80,7 @@ static ssize_t active_store(struct kobject *kobj, struct attribute *attr,
                                            dd_kobj);
        struct lu_device *lu = dt2lu_dev(dt);
        struct obd_device *obd = lu->ld_obd;
+       struct obd_import *imp;
        bool val;
        int rc;
 
@@ -87,16 +88,17 @@ static ssize_t active_store(struct kobject *kobj, struct attribute *attr,
        if (rc)
                return rc;
 
-       LPROCFS_CLIMP_CHECK(obd);
-       /* opposite senses */
-       if (obd->u.cli.cl_import->imp_deactive == val)
-               rc = ptlrpc_set_import_active(obd->u.cli.cl_import, val);
-       else
-               CDEBUG(D_CONFIG, "activate %u: ignoring repeat request\n",
-                      (unsigned int)val);
+       with_imp_locked(obd, imp, rc) {
+               /* opposite senses */
+               if (obd->u.cli.cl_import->imp_deactive == val)
+                       rc = ptlrpc_set_import_active(imp, val);
+               else
+                       CDEBUG(D_CONFIG,
+                              "activate %u: ignoring repeat request\n",
+                              (unsigned int)val);
+       }
 
-       LPROCFS_CLIMP_EXIT(obd);
-       return count;
+       return rc ?: count;
 }
 LUSTRE_RW_ATTR(active);
 
@@ -756,11 +758,11 @@ ssize_t ping_show(struct kobject *kobj, struct attribute *attr,
                                            dd_kobj);
        struct lu_device *lu = dt2lu_dev(dt);
        struct obd_device *obd = lu->ld_obd;
+       struct obd_import *imp;
        int rc;
 
-       LPROCFS_CLIMP_CHECK(obd);
-       rc = ptlrpc_obd_ping(obd);
-       LPROCFS_CLIMP_EXIT(obd);
+       with_imp_locked(obd, imp, rc)
+               rc = ptlrpc_obd_ping(obd);
 
        return rc;
 }
@@ -773,17 +775,18 @@ ssize_t osp_conn_uuid_show(struct kobject *kobj, struct attribute *attr,
                                            dd_kobj);
        struct lu_device *lu = dt2lu_dev(dt);
        struct obd_device *obd = lu->ld_obd;
+       struct obd_import *imp;
        struct ptlrpc_connection *conn;
        ssize_t count;
 
-       LPROCFS_CLIMP_CHECK(obd);
-       conn = obd->u.cli.cl_import->imp_connection;
-       if (conn && obd->u.cli.cl_import)
-               count = sprintf(buf, "%s\n", conn->c_remote_uuid.uuid);
-       else
-               count = sprintf(buf, "%s\n", "<none>");
+       with_imp_locked(obd, imp, count) {
+               conn = imp->imp_connection;
+               if (conn)
+                       count = sprintf(buf, "%s\n", conn->c_remote_uuid.uuid);
+               else
+                       count = sprintf(buf, "%s\n", "<none>");
+       }
 
-       LPROCFS_CLIMP_EXIT(obd);
        return count;
 }
 
index 3c58f5d..33824a7 100644 (file)
@@ -1320,13 +1320,16 @@ ssize_t ping_show(struct kobject *kobj, struct attribute *attr,
 {
        struct obd_device *obd = container_of(kobj, struct obd_device,
                                              obd_kset.kobj);
+       struct obd_import *imp;
        struct ptlrpc_request *req;
        int rc;
 
        ENTRY;
-       LPROCFS_CLIMP_CHECK(obd);
-       req = ptlrpc_prep_ping(obd->u.cli.cl_import);
-       LPROCFS_CLIMP_EXIT(obd);
+       with_imp_locked(obd, imp, rc)
+               req = ptlrpc_prep_ping(imp);
+
+       if (rc)
+               RETURN(rc);
        if (!req)
                RETURN(-ENOMEM);
 
@@ -1357,13 +1360,14 @@ lprocfs_import_seq_write(struct file *file, const char __user *buffer,
 {
        struct seq_file   *m    = file->private_data;
        struct obd_device *obd  = m->private;
-       struct obd_import *imp  = obd->u.cli.cl_import;
+       struct obd_import *imp;
        char *kbuf = NULL;
        char *uuid;
        char *ptr;
        int do_reconn = 1;
        const char prefix[] = "connection=";
        const int prefix_len = sizeof(prefix) - 1;
+       int rc = 0;
 
        if (count > PAGE_SIZE - 1 || count <= prefix_len)
                return -EINVAL;
@@ -1373,60 +1377,62 @@ lprocfs_import_seq_write(struct file *file, const char __user *buffer,
                return -ENOMEM;
 
        if (copy_from_user(kbuf, buffer, count))
-               GOTO(out, count = -EFAULT);
+               GOTO(out, rc = -EFAULT);
 
        kbuf[count] = 0;
 
        /* only support connection=uuid::instance now */
        if (strncmp(prefix, kbuf, prefix_len) != 0)
-               GOTO(out, count = -EINVAL);
-
-       LPROCFS_CLIMP_CHECK(obd);
-
-       uuid = kbuf + prefix_len;
-       ptr = strstr(uuid, "::");
-       if (ptr) {
-               u32 inst;
-               int rc;
-
-               *ptr = 0;
-               do_reconn = 0;
-               ptr += 2; /* Skip :: */
-               rc = kstrtouint(ptr, 10, &inst);
-               if (rc) {
-                       CERROR("config: wrong instance # %s\n", ptr);
-               } else if (inst != imp->imp_connect_data.ocd_instance) {
-                       CDEBUG(D_INFO, "IR: %s is connecting to an obsoleted "
-                              "target(%u/%u), reconnecting...\n",
-                              imp->imp_obd->obd_name,
-                              imp->imp_connect_data.ocd_instance, inst);
-                       do_reconn = 1;
-               } else {
-                       CDEBUG(D_INFO, "IR: %s has already been connecting to "
-                              "new target(%u)\n",
-                              imp->imp_obd->obd_name, inst);
+               GOTO(out, rc = -EINVAL);
+
+       with_imp_locked(obd, imp, rc) {
+               uuid = kbuf + prefix_len;
+               ptr = strstr(uuid, "::");
+               if (ptr) {
+                       u32 inst;
+                       int rc;
+
+                       *ptr = 0;
+                       do_reconn = 0;
+                       ptr += 2; /* Skip :: */
+                       rc = kstrtouint(ptr, 10, &inst);
+                       if (rc) {
+                               CERROR("config: wrong instance # %s\n", ptr);
+                       } else if (inst != imp->imp_connect_data.ocd_instance) {
+                               CDEBUG(D_INFO,
+                                      "IR: %s is connecting to an obsoleted target(%u/%u), reconnecting...\n",
+                                      imp->imp_obd->obd_name,
+                                      imp->imp_connect_data.ocd_instance,
+                                      inst);
+                               do_reconn = 1;
+                       } else {
+                               CDEBUG(D_INFO,
+                                      "IR: %s has already been connecting to "
+                                      "new target(%u)\n",
+                                      imp->imp_obd->obd_name, inst);
+                       }
                }
-       }
 
-       LPROCFS_CLIMP_EXIT(obd);
-       if (do_reconn)
-               ptlrpc_recover_import(imp, uuid, 1);
+               if (do_reconn)
+                       ptlrpc_recover_import(imp, uuid, 1);
+       }
 
 out:
        OBD_FREE(kbuf, count + 1);
-       return count;
+       return rc ?: count;
 }
 EXPORT_SYMBOL(lprocfs_import_seq_write);
 
 int lprocfs_pinger_recov_seq_show(struct seq_file *m, void *n)
 {
        struct obd_device *obd = m->private;
-       struct obd_import *imp = obd->u.cli.cl_import;
+       struct obd_import *imp;
+       int rc;
 
-       LPROCFS_CLIMP_CHECK(obd);
-       seq_printf(m, "%d\n", !imp->imp_no_pinger_recover);
-       LPROCFS_CLIMP_EXIT(obd);
-       return 0;
+       with_imp_locked(obd, imp, rc)
+               seq_printf(m, "%d\n", !imp->imp_no_pinger_recover);
+
+       return rc;
 }
 EXPORT_SYMBOL(lprocfs_pinger_recov_seq_show);
 
@@ -1436,8 +1442,7 @@ lprocfs_pinger_recov_seq_write(struct file *file, const char __user *buffer,
 {
        struct seq_file *m = file->private_data;
        struct obd_device *obd = m->private;
-       struct client_obd *cli = &obd->u.cli;
-       struct obd_import *imp = cli->cl_import;
+       struct obd_import *imp;
        bool val;
        int rc;
 
@@ -1445,11 +1450,12 @@ lprocfs_pinger_recov_seq_write(struct file *file, const char __user *buffer,
        if (rc < 0)
                return rc;
 
-       LPROCFS_CLIMP_CHECK(obd);
-       spin_lock(&imp->imp_lock);
-       imp->imp_no_pinger_recover = !val;
-       spin_unlock(&imp->imp_lock);
-       LPROCFS_CLIMP_EXIT(obd);
-       return count;
+       with_imp_locked(obd, imp, rc) {
+               spin_lock(&imp->imp_lock);
+               imp->imp_no_pinger_recover = !val;
+               spin_unlock(&imp->imp_lock);
+       }
+
+       return rc ?: count;
 }
 EXPORT_SYMBOL(lprocfs_pinger_recov_seq_write);