Whamcloud - gitweb
LU-3319 procfs: fix symlink handling
[fs/lustre-release.git] / lustre / osc / osc_request.c
index 2b60765..076dcf6 100644 (file)
@@ -3091,9 +3091,10 @@ static int brw_queue_work(const struct lu_env *env, void *data)
 
 int osc_setup(struct obd_device *obd, struct lustre_cfg *lcfg)
 {
-       struct client_obd          *cli = &obd->u.cli;
-       void                       *handler;
-       int                        rc;
+       struct client_obd *cli = &obd->u.cli;
+       struct obd_type   *type;
+       void              *handler;
+       int                rc;
        ENTRY;
 
        rc = ptlrpcd_addref();
@@ -3119,10 +3120,32 @@ int osc_setup(struct obd_device *obd, struct lustre_cfg *lcfg)
                GOTO(out_ptlrpcd_work, rc);
 
        cli->cl_grant_shrink_interval = GRANT_SHRINK_INTERVAL;
+
 #ifdef LPROCFS
        obd->obd_vars = lprocfs_osc_obd_vars;
 #endif
-       if (lprocfs_seq_obd_setup(obd) == 0) {
+       /* If this is true then both client (osc) and server (osp) are on the
+        * same node. The osp layer if loaded first will register the osc proc
+        * directory. In that case this obd_device will be attached its proc
+        * tree to type->typ_procsym instead of obd->obd_type->typ_procroot. */
+       type = class_search_type(LUSTRE_OSP_NAME);
+       if (type && type->typ_procsym) {
+               obd->obd_proc_entry = lprocfs_seq_register(obd->obd_name,
+                                                          type->typ_procsym,
+                                                          obd->obd_vars, obd);
+               if (IS_ERR(obd->obd_proc_entry)) {
+                       rc = PTR_ERR(obd->obd_proc_entry);
+                       CERROR("error %d setting up lprocfs for %s\n", rc,
+                              obd->obd_name);
+                       obd->obd_proc_entry = NULL;
+               }
+       } else {
+               rc = lprocfs_seq_obd_setup(obd);
+       }
+
+       /* If the basic OSC proc tree construction succeeded then
+        * lets do the rest. */
+       if (rc == 0) {
                lproc_osc_attach_seqstat(obd);
                sptlrpc_lprocfs_cliobd_attach(obd);
                ptlrpc_lprocfs_register_obd(obd);
@@ -3140,7 +3163,7 @@ int osc_setup(struct obd_device *obd, struct lustre_cfg *lcfg)
 
        CFS_INIT_LIST_HEAD(&cli->cl_grant_shrink_list);
        ns_register_cancel(obd->obd_namespace, osc_cancel_weight);
-       RETURN(rc);
+       RETURN(0);
 
 out_ptlrpcd_work:
        if (cli->cl_writeback_work != NULL) {
@@ -3282,8 +3305,10 @@ extern struct lock_class_key osc_ast_guard_class;
 
 int __init osc_init(void)
 {
-        int rc;
-        ENTRY;
+       bool enable_proc = true;
+       struct obd_type *type;
+       int rc;
+       ENTRY;
 
         /* print an address of _any_ initialized kernel symbol from this
          * module, to allow debugging with gdb that doesn't support data
@@ -3294,11 +3319,15 @@ int __init osc_init(void)
        if (rc)
                RETURN(rc);
 
-       rc = class_register_type(&osc_obd_ops, NULL, NULL,
+       type = class_search_type(LUSTRE_OSP_NAME);
+       if (type != NULL && type->typ_procsym != NULL)
+               enable_proc = false;
+
+       rc = class_register_type(&osc_obd_ops, NULL, enable_proc, NULL,
 #ifndef HAVE_ONLY_PROCFS_SEQ
-                               NULL,
+                                NULL,
 #endif
-                               LUSTRE_OSC_NAME, &osc_device_type);
+                                LUSTRE_OSC_NAME, &osc_device_type);
         if (rc) {
                 lu_kmem_fini(osc_caches);
                 RETURN(rc);