Version:  2.0.40 2.2.26 2.4.37 2.6.39 3.0 3.1 3.2 3.3 3.4 3.5 3.6 3.7 3.8 3.9 3.10 3.11 3.12 3.13 3.14 3.15

Linux/drivers/staging/lustre/lustre/obdclass/obd_mount.c

  1 /*
  2  * GPL HEADER START
  3  *
  4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  5  *
  6  * This program is free software; you can redistribute it and/or modify
  7  * it under the terms of the GNU General Public License version 2 only,
  8  * as published by the Free Software Foundation.
  9  *
 10  * This program is distributed in the hope that it will be useful, but
 11  * WITHOUT ANY WARRANTY; without even the implied warranty of
 12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 13  * General Public License version 2 for more details (a copy is included
 14  * in the LICENSE file that accompanied this code).
 15  *
 16  * You should have received a copy of the GNU General Public License
 17  * version 2 along with this program; If not, see
 18  * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
 19  *
 20  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
 21  * CA 95054 USA or visit www.sun.com if you need additional information or
 22  * have any questions.
 23  *
 24  * GPL HEADER END
 25  */
 26 /*
 27  * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
 28  * Use is subject to license terms.
 29  *
 30  * Copyright (c) 2011, 2012, Intel Corporation.
 31  */
 32 /*
 33  * This file is part of Lustre, http://www.lustre.org/
 34  * Lustre is a trademark of Sun Microsystems, Inc.
 35  *
 36  * lustre/obdclass/obd_mount.c
 37  *
 38  * Client mount routines
 39  *
 40  * Author: Nathan Rutman <nathan@clusterfs.com>
 41  */
 42 
 43 
 44 #define DEBUG_SUBSYSTEM S_CLASS
 45 #define D_MOUNT (D_SUPER|D_CONFIG/*|D_WARNING */)
 46 #define PRINT_CMD CDEBUG
 47 
 48 #include <obd.h>
 49 #include <lvfs.h>
 50 #include <obd_class.h>
 51 #include <lustre/lustre_user.h>
 52 #include <lustre_log.h>
 53 #include <lustre_disk.h>
 54 #include <lustre_param.h>
 55 
 56 static int (*client_fill_super)(struct super_block *sb,
 57                                 struct vfsmount *mnt);
 58 
 59 static void (*kill_super_cb)(struct super_block *sb);
 60 
 61 /**************** config llog ********************/
 62 
 63 /** Get a config log from the MGS and process it.
 64  * This func is called for both clients and servers.
 65  * Continue to process new statements appended to the logs
 66  * (whenever the config lock is revoked) until lustre_end_log
 67  * is called.
 68  * @param sb The superblock is used by the MGC to write to the local copy of
 69  *   the config log
 70  * @param logname The name of the llog to replicate from the MGS
 71  * @param cfg Since the same mgc may be used to follow multiple config logs
 72  *   (e.g. ost1, ost2, client), the config_llog_instance keeps the state for
 73  *   this log, and is added to the mgc's list of logs to follow.
 74  */
 75 int lustre_process_log(struct super_block *sb, char *logname,
 76                      struct config_llog_instance *cfg)
 77 {
 78         struct lustre_cfg *lcfg;
 79         struct lustre_cfg_bufs *bufs;
 80         struct lustre_sb_info *lsi = s2lsi(sb);
 81         struct obd_device *mgc = lsi->lsi_mgc;
 82         int rc;
 83 
 84         LASSERT(mgc);
 85         LASSERT(cfg);
 86 
 87         OBD_ALLOC_PTR(bufs);
 88         if (bufs == NULL)
 89                 return -ENOMEM;
 90 
 91         /* mgc_process_config */
 92         lustre_cfg_bufs_reset(bufs, mgc->obd_name);
 93         lustre_cfg_bufs_set_string(bufs, 1, logname);
 94         lustre_cfg_bufs_set(bufs, 2, cfg, sizeof(*cfg));
 95         lustre_cfg_bufs_set(bufs, 3, &sb, sizeof(sb));
 96         lcfg = lustre_cfg_new(LCFG_LOG_START, bufs);
 97         rc = obd_process_config(mgc, sizeof(*lcfg), lcfg);
 98         lustre_cfg_free(lcfg);
 99 
100         OBD_FREE_PTR(bufs);
101 
102         if (rc == -EINVAL)
103                 LCONSOLE_ERROR_MSG(0x15b, "%s: The configuration from log '%s'"
104                                    "failed from the MGS (%d).  Make sure this "
105                                    "client and the MGS are running compatible "
106                                    "versions of Lustre.\n",
107                                    mgc->obd_name, logname, rc);
108 
109         if (rc)
110                 LCONSOLE_ERROR_MSG(0x15c, "%s: The configuration from log '%s' "
111                                    "failed (%d). This may be the result of "
112                                    "communication errors between this node and "
113                                    "the MGS, a bad configuration, or other "
114                                    "errors. See the syslog for more "
115                                    "information.\n", mgc->obd_name, logname,
116                                    rc);
117 
118         /* class_obd_list(); */
119         return rc;
120 }
121 EXPORT_SYMBOL(lustre_process_log);
122 
123 /* Stop watching this config log for updates */
124 int lustre_end_log(struct super_block *sb, char *logname,
125                        struct config_llog_instance *cfg)
126 {
127         struct lustre_cfg *lcfg;
128         struct lustre_cfg_bufs bufs;
129         struct lustre_sb_info *lsi = s2lsi(sb);
130         struct obd_device *mgc = lsi->lsi_mgc;
131         int rc;
132 
133         if (!mgc)
134                 return -ENOENT;
135 
136         /* mgc_process_config */
137         lustre_cfg_bufs_reset(&bufs, mgc->obd_name);
138         lustre_cfg_bufs_set_string(&bufs, 1, logname);
139         if (cfg)
140                 lustre_cfg_bufs_set(&bufs, 2, cfg, sizeof(*cfg));
141         lcfg = lustre_cfg_new(LCFG_LOG_END, &bufs);
142         rc = obd_process_config(mgc, sizeof(*lcfg), lcfg);
143         lustre_cfg_free(lcfg);
144         return rc;
145 }
146 EXPORT_SYMBOL(lustre_end_log);
147 
148 /**************** obd start *******************/
149 
150 /** lustre_cfg_bufs are a holdover from 1.4; we can still set these up from
151  * lctl (and do for echo cli/srv.
152  */
153 int do_lcfg(char *cfgname, lnet_nid_t nid, int cmd,
154             char *s1, char *s2, char *s3, char *s4)
155 {
156         struct lustre_cfg_bufs bufs;
157         struct lustre_cfg    * lcfg = NULL;
158         int rc;
159 
160         CDEBUG(D_TRACE, "lcfg %s %#x %s %s %s %s\n", cfgname,
161                cmd, s1, s2, s3, s4);
162 
163         lustre_cfg_bufs_reset(&bufs, cfgname);
164         if (s1)
165                 lustre_cfg_bufs_set_string(&bufs, 1, s1);
166         if (s2)
167                 lustre_cfg_bufs_set_string(&bufs, 2, s2);
168         if (s3)
169                 lustre_cfg_bufs_set_string(&bufs, 3, s3);
170         if (s4)
171                 lustre_cfg_bufs_set_string(&bufs, 4, s4);
172 
173         lcfg = lustre_cfg_new(cmd, &bufs);
174         lcfg->lcfg_nid = nid;
175         rc = class_process_config(lcfg);
176         lustre_cfg_free(lcfg);
177         return(rc);
178 }
179 EXPORT_SYMBOL(do_lcfg);
180 
181 /** Call class_attach and class_setup.  These methods in turn call
182  * obd type-specific methods.
183  */
184 int lustre_start_simple(char *obdname, char *type, char *uuid,
185                         char *s1, char *s2, char *s3, char *s4)
186 {
187         int rc;
188         CDEBUG(D_MOUNT, "Starting obd %s (typ=%s)\n", obdname, type);
189 
190         rc = do_lcfg(obdname, 0, LCFG_ATTACH, type, uuid, 0, 0);
191         if (rc) {
192                 CERROR("%s attach error %d\n", obdname, rc);
193                 return rc;
194         }
195         rc = do_lcfg(obdname, 0, LCFG_SETUP, s1, s2, s3, s4);
196         if (rc) {
197                 CERROR("%s setup error %d\n", obdname, rc);
198                 do_lcfg(obdname, 0, LCFG_DETACH, 0, 0, 0, 0);
199         }
200         return rc;
201 }
202 
203 DEFINE_MUTEX(mgc_start_lock);
204 
205 /** Set up a mgc obd to process startup logs
206  *
207  * \param sb [in] super block of the mgc obd
208  *
209  * \retval 0 success, otherwise error code
210  */
211 int lustre_start_mgc(struct super_block *sb)
212 {
213         struct obd_connect_data *data = NULL;
214         struct lustre_sb_info *lsi = s2lsi(sb);
215         struct obd_device *obd;
216         struct obd_export *exp;
217         struct obd_uuid *uuid;
218         class_uuid_t uuidc;
219         lnet_nid_t nid;
220         char *mgcname = NULL, *niduuid = NULL, *mgssec = NULL;
221         char *ptr;
222         int recov_bk;
223         int rc = 0, i = 0, j, len;
224 
225         LASSERT(lsi->lsi_lmd);
226 
227         /* Find the first non-lo MGS nid for our MGC name */
228         if (IS_SERVER(lsi)) {
229                 /* mount -o mgsnode=nid */
230                 ptr = lsi->lsi_lmd->lmd_mgs;
231                 if (lsi->lsi_lmd->lmd_mgs &&
232                     (class_parse_nid(lsi->lsi_lmd->lmd_mgs, &nid, &ptr) == 0)) {
233                         i++;
234                 } else if (IS_MGS(lsi)) {
235                         lnet_process_id_t id;
236                         while ((rc = LNetGetId(i++, &id)) != -ENOENT) {
237                                 if (LNET_NETTYP(LNET_NIDNET(id.nid)) == LOLND)
238                                         continue;
239                                 nid = id.nid;
240                                 i++;
241                                 break;
242                         }
243                 }
244         } else { /* client */
245                 /* Use nids from mount line: uml1,1@elan:uml2,2@elan:/lustre */
246                 ptr = lsi->lsi_lmd->lmd_dev;
247                 if (class_parse_nid(ptr, &nid, &ptr) == 0)
248                         i++;
249         }
250         if (i == 0) {
251                 CERROR("No valid MGS nids found.\n");
252                 return -EINVAL;
253         }
254 
255         mutex_lock(&mgc_start_lock);
256 
257         len = strlen(LUSTRE_MGC_OBDNAME) + strlen(libcfs_nid2str(nid)) + 1;
258         OBD_ALLOC(mgcname, len);
259         OBD_ALLOC(niduuid, len + 2);
260         if (!mgcname || !niduuid)
261                 GOTO(out_free, rc = -ENOMEM);
262         sprintf(mgcname, "%s%s", LUSTRE_MGC_OBDNAME, libcfs_nid2str(nid));
263 
264         mgssec = lsi->lsi_lmd->lmd_mgssec ? lsi->lsi_lmd->lmd_mgssec : "";
265 
266         OBD_ALLOC_PTR(data);
267         if (data == NULL)
268                 GOTO(out_free, rc = -ENOMEM);
269 
270         obd = class_name2obd(mgcname);
271         if (obd && !obd->obd_stopping) {
272                 rc = obd_set_info_async(NULL, obd->obd_self_export,
273                                         strlen(KEY_MGSSEC), KEY_MGSSEC,
274                                         strlen(mgssec), mgssec, NULL);
275                 if (rc)
276                         GOTO(out_free, rc);
277 
278                 /* Re-using an existing MGC */
279                 atomic_inc(&obd->u.cli.cl_mgc_refcount);
280 
281                 /* IR compatibility check, only for clients */
282                 if (lmd_is_client(lsi->lsi_lmd)) {
283                         int has_ir;
284                         int vallen = sizeof(*data);
285                         __u32 *flags = &lsi->lsi_lmd->lmd_flags;
286 
287                         rc = obd_get_info(NULL, obd->obd_self_export,
288                                           strlen(KEY_CONN_DATA), KEY_CONN_DATA,
289                                           &vallen, data, NULL);
290                         LASSERT(rc == 0);
291                         has_ir = OCD_HAS_FLAG(data, IMP_RECOV);
292                         if (has_ir ^ !(*flags & LMD_FLG_NOIR)) {
293                                 /* LMD_FLG_NOIR is for test purpose only */
294                                 LCONSOLE_WARN(
295                                     "Trying to mount a client with IR setting "
296                                     "not compatible with current mgc. "
297                                     "Force to use current mgc setting that is "
298                                     "IR %s.\n",
299                                     has_ir ? "enabled" : "disabled");
300                                 if (has_ir)
301                                         *flags &= ~LMD_FLG_NOIR;
302                                 else
303                                         *flags |= LMD_FLG_NOIR;
304                         }
305                 }
306 
307                 recov_bk = 0;
308                 /* If we are restarting the MGS, don't try to keep the MGC's
309                    old connection, or registration will fail. */
310                 if (IS_MGS(lsi)) {
311                         CDEBUG(D_MOUNT, "New MGS with live MGC\n");
312                         recov_bk = 1;
313                 }
314 
315                 /* Try all connections, but only once (again).
316                    We don't want to block another target from starting
317                    (using its local copy of the log), but we do want to connect
318                    if at all possible. */
319                 recov_bk++;
320                 CDEBUG(D_MOUNT, "%s: Set MGC reconnect %d\n", mgcname,recov_bk);
321                 rc = obd_set_info_async(NULL, obd->obd_self_export,
322                                         sizeof(KEY_INIT_RECOV_BACKUP),
323                                         KEY_INIT_RECOV_BACKUP,
324                                         sizeof(recov_bk), &recov_bk, NULL);
325                 GOTO(out, rc = 0);
326         }
327 
328         CDEBUG(D_MOUNT, "Start MGC '%s'\n", mgcname);
329 
330         /* Add the primary nids for the MGS */
331         i = 0;
332         sprintf(niduuid, "%s_%x", mgcname, i);
333         if (IS_SERVER(lsi)) {
334                 ptr = lsi->lsi_lmd->lmd_mgs;
335                 if (IS_MGS(lsi)) {
336                         /* Use local nids (including LO) */
337                         lnet_process_id_t id;
338                         while ((rc = LNetGetId(i++, &id)) != -ENOENT) {
339                                 rc = do_lcfg(mgcname, id.nid,
340                                              LCFG_ADD_UUID, niduuid, 0,0,0);
341                         }
342                 } else {
343                         /* Use mgsnode= nids */
344                         /* mount -o mgsnode=nid */
345                         if (lsi->lsi_lmd->lmd_mgs) {
346                                 ptr = lsi->lsi_lmd->lmd_mgs;
347                         } else if (class_find_param(ptr, PARAM_MGSNODE,
348                                                     &ptr) != 0) {
349                                 CERROR("No MGS nids given.\n");
350                                 GOTO(out_free, rc = -EINVAL);
351                         }
352                         while (class_parse_nid(ptr, &nid, &ptr) == 0) {
353                                 rc = do_lcfg(mgcname, nid,
354                                              LCFG_ADD_UUID, niduuid, 0,0,0);
355                                 i++;
356                         }
357                 }
358         } else { /* client */
359                 /* Use nids from mount line: uml1,1@elan:uml2,2@elan:/lustre */
360                 ptr = lsi->lsi_lmd->lmd_dev;
361                 while (class_parse_nid(ptr, &nid, &ptr) == 0) {
362                         rc = do_lcfg(mgcname, nid,
363                                      LCFG_ADD_UUID, niduuid, 0,0,0);
364                         i++;
365                         /* Stop at the first failover nid */
366                         if (*ptr == ':')
367                                 break;
368                 }
369         }
370         if (i == 0) {
371                 CERROR("No valid MGS nids found.\n");
372                 GOTO(out_free, rc = -EINVAL);
373         }
374         lsi->lsi_lmd->lmd_mgs_failnodes = 1;
375 
376         /* Random uuid for MGC allows easier reconnects */
377         OBD_ALLOC_PTR(uuid);
378         ll_generate_random_uuid(uuidc);
379         class_uuid_unparse(uuidc, uuid);
380 
381         /* Start the MGC */
382         rc = lustre_start_simple(mgcname, LUSTRE_MGC_NAME,
383                                  (char *)uuid->uuid, LUSTRE_MGS_OBDNAME,
384                                  niduuid, 0, 0);
385         OBD_FREE_PTR(uuid);
386         if (rc)
387                 GOTO(out_free, rc);
388 
389         /* Add any failover MGS nids */
390         i = 1;
391         while (ptr && ((*ptr == ':' ||
392                class_find_param(ptr, PARAM_MGSNODE, &ptr) == 0))) {
393                 /* New failover node */
394                 sprintf(niduuid, "%s_%x", mgcname, i);
395                 j = 0;
396                 while (class_parse_nid_quiet(ptr, &nid, &ptr) == 0) {
397                         j++;
398                         rc = do_lcfg(mgcname, nid,
399                                      LCFG_ADD_UUID, niduuid, 0,0,0);
400                         if (*ptr == ':')
401                                 break;
402                 }
403                 if (j > 0) {
404                         rc = do_lcfg(mgcname, 0, LCFG_ADD_CONN,
405                                      niduuid, 0, 0, 0);
406                         i++;
407                 } else {
408                         /* at ":/fsname" */
409                         break;
410                 }
411         }
412         lsi->lsi_lmd->lmd_mgs_failnodes = i;
413 
414         obd = class_name2obd(mgcname);
415         if (!obd) {
416                 CERROR("Can't find mgcobd %s\n", mgcname);
417                 GOTO(out_free, rc = -ENOTCONN);
418         }
419 
420         rc = obd_set_info_async(NULL, obd->obd_self_export,
421                                 strlen(KEY_MGSSEC), KEY_MGSSEC,
422                                 strlen(mgssec), mgssec, NULL);
423         if (rc)
424                 GOTO(out_free, rc);
425 
426         /* Keep a refcount of servers/clients who started with "mount",
427            so we know when we can get rid of the mgc. */
428         atomic_set(&obd->u.cli.cl_mgc_refcount, 1);
429 
430         /* Try all connections, but only once. */
431         recov_bk = 1;
432         rc = obd_set_info_async(NULL, obd->obd_self_export,
433                                 sizeof(KEY_INIT_RECOV_BACKUP),
434                                 KEY_INIT_RECOV_BACKUP,
435                                 sizeof(recov_bk), &recov_bk, NULL);
436         if (rc)
437                 /* nonfatal */
438                 CWARN("can't set %s %d\n", KEY_INIT_RECOV_BACKUP, rc);
439 
440         /* We connect to the MGS at setup, and don't disconnect until cleanup */
441         data->ocd_connect_flags = OBD_CONNECT_VERSION | OBD_CONNECT_AT |
442                                   OBD_CONNECT_FULL20 | OBD_CONNECT_IMP_RECOV |
443                                   OBD_CONNECT_LVB_TYPE;
444 
445 #if LUSTRE_VERSION_CODE < OBD_OCD_VERSION(3, 2, 50, 0)
446         data->ocd_connect_flags |= OBD_CONNECT_MNE_SWAB;
447 #else
448 #warning "LU-1644: Remove old OBD_CONNECT_MNE_SWAB fixup and imp_need_mne_swab"
449 #endif
450 
451         if (lmd_is_client(lsi->lsi_lmd) &&
452             lsi->lsi_lmd->lmd_flags & LMD_FLG_NOIR)
453                 data->ocd_connect_flags &= ~OBD_CONNECT_IMP_RECOV;
454         data->ocd_version = LUSTRE_VERSION_CODE;
455         rc = obd_connect(NULL, &exp, obd, &(obd->obd_uuid), data, NULL);
456         if (rc) {
457                 CERROR("connect failed %d\n", rc);
458                 GOTO(out, rc);
459         }
460 
461         obd->u.cli.cl_mgc_mgsexp = exp;
462 
463 out:
464         /* Keep the mgc info in the sb. Note that many lsi's can point
465            to the same mgc.*/
466         lsi->lsi_mgc = obd;
467 out_free:
468         mutex_unlock(&mgc_start_lock);
469 
470         if (data)
471                 OBD_FREE_PTR(data);
472         if (mgcname)
473                 OBD_FREE(mgcname, len);
474         if (niduuid)
475                 OBD_FREE(niduuid, len + 2);
476         return rc;
477 }
478 
479 static int lustre_stop_mgc(struct super_block *sb)
480 {
481         struct lustre_sb_info *lsi = s2lsi(sb);
482         struct obd_device *obd;
483         char *niduuid = 0, *ptr = 0;
484         int i, rc = 0, len = 0;
485 
486         if (!lsi)
487                 return -ENOENT;
488         obd = lsi->lsi_mgc;
489         if (!obd)
490                 return -ENOENT;
491         lsi->lsi_mgc = NULL;
492 
493         mutex_lock(&mgc_start_lock);
494         LASSERT(atomic_read(&obd->u.cli.cl_mgc_refcount) > 0);
495         if (!atomic_dec_and_test(&obd->u.cli.cl_mgc_refcount)) {
496                 /* This is not fatal, every client that stops
497                    will call in here. */
498                 CDEBUG(D_MOUNT, "mgc still has %d references.\n",
499                        atomic_read(&obd->u.cli.cl_mgc_refcount));
500                 GOTO(out, rc = -EBUSY);
501         }
502 
503         /* The MGC has no recoverable data in any case.
504          * force shutdown set in umount_begin */
505         obd->obd_no_recov = 1;
506 
507         if (obd->u.cli.cl_mgc_mgsexp) {
508                 /* An error is not fatal, if we are unable to send the
509                    disconnect mgs ping evictor cleans up the export */
510                 rc = obd_disconnect(obd->u.cli.cl_mgc_mgsexp);
511                 if (rc)
512                         CDEBUG(D_MOUNT, "disconnect failed %d\n", rc);
513         }
514 
515         /* Save the obdname for cleaning the nid uuids, which are
516            obdname_XX */
517         len = strlen(obd->obd_name) + 6;
518         OBD_ALLOC(niduuid, len);
519         if (niduuid) {
520                 strcpy(niduuid, obd->obd_name);
521                 ptr = niduuid + strlen(niduuid);
522         }
523 
524         rc = class_manual_cleanup(obd);
525         if (rc)
526                 GOTO(out, rc);
527 
528         /* Clean the nid uuids */
529         if (!niduuid)
530                 GOTO(out, rc = -ENOMEM);
531 
532         for (i = 0; i < lsi->lsi_lmd->lmd_mgs_failnodes; i++) {
533                 sprintf(ptr, "_%x", i);
534                 rc = do_lcfg(LUSTRE_MGC_OBDNAME, 0, LCFG_DEL_UUID,
535                              niduuid, 0, 0, 0);
536                 if (rc)
537                         CERROR("del MDC UUID %s failed: rc = %d\n",
538                                niduuid, rc);
539         }
540 out:
541         if (niduuid)
542                 OBD_FREE(niduuid, len);
543 
544         /* class_import_put will get rid of the additional connections */
545         mutex_unlock(&mgc_start_lock);
546         return rc;
547 }
548 
549 /***************** lustre superblock **************/
550 
551 struct lustre_sb_info *lustre_init_lsi(struct super_block *sb)
552 {
553         struct lustre_sb_info *lsi;
554 
555         OBD_ALLOC_PTR(lsi);
556         if (!lsi)
557                 return NULL;
558         OBD_ALLOC_PTR(lsi->lsi_lmd);
559         if (!lsi->lsi_lmd) {
560                 OBD_FREE_PTR(lsi);
561                 return NULL;
562         }
563 
564         lsi->lsi_lmd->lmd_exclude_count = 0;
565         lsi->lsi_lmd->lmd_recovery_time_soft = 0;
566         lsi->lsi_lmd->lmd_recovery_time_hard = 0;
567         s2lsi_nocast(sb) = lsi;
568         /* we take 1 extra ref for our setup */
569         atomic_set(&lsi->lsi_mounts, 1);
570 
571         /* Default umount style */
572         lsi->lsi_flags = LSI_UMOUNT_FAILOVER;
573 
574         return lsi;
575 }
576 
577 static int lustre_free_lsi(struct super_block *sb)
578 {
579         struct lustre_sb_info *lsi = s2lsi(sb);
580 
581         LASSERT(lsi != NULL);
582         CDEBUG(D_MOUNT, "Freeing lsi %p\n", lsi);
583 
584         /* someone didn't call server_put_mount. */
585         LASSERT(atomic_read(&lsi->lsi_mounts) == 0);
586 
587         if (lsi->lsi_lmd != NULL) {
588                 if (lsi->lsi_lmd->lmd_dev != NULL)
589                         OBD_FREE(lsi->lsi_lmd->lmd_dev,
590                                  strlen(lsi->lsi_lmd->lmd_dev) + 1);
591                 if (lsi->lsi_lmd->lmd_profile != NULL)
592                         OBD_FREE(lsi->lsi_lmd->lmd_profile,
593                                  strlen(lsi->lsi_lmd->lmd_profile) + 1);
594                 if (lsi->lsi_lmd->lmd_mgssec != NULL)
595                         OBD_FREE(lsi->lsi_lmd->lmd_mgssec,
596                                  strlen(lsi->lsi_lmd->lmd_mgssec) + 1);
597                 if (lsi->lsi_lmd->lmd_opts != NULL)
598                         OBD_FREE(lsi->lsi_lmd->lmd_opts,
599                                  strlen(lsi->lsi_lmd->lmd_opts) + 1);
600                 if (lsi->lsi_lmd->lmd_exclude_count)
601                         OBD_FREE(lsi->lsi_lmd->lmd_exclude,
602                                  sizeof(lsi->lsi_lmd->lmd_exclude[0]) *
603                                  lsi->lsi_lmd->lmd_exclude_count);
604                 if (lsi->lsi_lmd->lmd_mgs != NULL)
605                         OBD_FREE(lsi->lsi_lmd->lmd_mgs,
606                                  strlen(lsi->lsi_lmd->lmd_mgs) + 1);
607                 if (lsi->lsi_lmd->lmd_osd_type != NULL)
608                         OBD_FREE(lsi->lsi_lmd->lmd_osd_type,
609                                  strlen(lsi->lsi_lmd->lmd_osd_type) + 1);
610                 if (lsi->lsi_lmd->lmd_params != NULL)
611                         OBD_FREE(lsi->lsi_lmd->lmd_params, 4096);
612 
613                 OBD_FREE(lsi->lsi_lmd, sizeof(*lsi->lsi_lmd));
614         }
615 
616         LASSERT(lsi->lsi_llsbi == NULL);
617         OBD_FREE(lsi, sizeof(*lsi));
618         s2lsi_nocast(sb) = NULL;
619 
620         return 0;
621 }
622 
623 /* The lsi has one reference for every server that is using the disk -
624    e.g. MDT, MGS, and potentially MGC */
625 int lustre_put_lsi(struct super_block *sb)
626 {
627         struct lustre_sb_info *lsi = s2lsi(sb);
628 
629         LASSERT(lsi != NULL);
630 
631         CDEBUG(D_MOUNT, "put %p %d\n", sb, atomic_read(&lsi->lsi_mounts));
632         if (atomic_dec_and_test(&lsi->lsi_mounts)) {
633                 if (IS_SERVER(lsi) && lsi->lsi_osd_exp) {
634                         lu_device_put(&lsi->lsi_dt_dev->dd_lu_dev);
635                         lsi->lsi_osd_exp->exp_obd->obd_lvfs_ctxt.dt = NULL;
636                         lsi->lsi_dt_dev = NULL;
637                         obd_disconnect(lsi->lsi_osd_exp);
638                         /* wait till OSD is gone */
639                         obd_zombie_barrier();
640                 }
641                 lustre_free_lsi(sb);
642                 return 1;
643         }
644         return 0;
645 }
646 
647 /*** SERVER NAME ***
648  * <FSNAME><SEPERATOR><TYPE><INDEX>
649  * FSNAME is between 1 and 8 characters (inclusive).
650  *      Excluded characters are '/' and ':'
651  * SEPERATOR is either ':' or '-'
652  * TYPE: "OST", "MDT", etc.
653  * INDEX: Hex representation of the index
654  */
655 
656 /** Get the fsname ("lustre") from the server name ("lustre-OST003F").
657  * @param [in] svname server name including type and index
658  * @param [out] fsname Buffer to copy filesystem name prefix into.
659  *  Must have at least 'strlen(fsname) + 1' chars.
660  * @param [out] endptr if endptr isn't NULL it is set to end of fsname
661  * rc < 0  on error
662  */
663 int server_name2fsname(const char *svname, char *fsname, const char **endptr)
664 {
665         const char *dash;
666 
667         dash = svname + strnlen(svname, 8); /* max fsname length is 8 */
668         for (; dash > svname && *dash != '-' && *dash != ':'; dash--)
669                 ;
670         if (dash == svname)
671                 return -EINVAL;
672 
673         if (fsname != NULL) {
674                 strncpy(fsname, svname, dash - svname);
675                 fsname[dash - svname] = '\0';
676         }
677 
678         if (endptr != NULL)
679                 *endptr = dash;
680 
681         return 0;
682 }
683 EXPORT_SYMBOL(server_name2fsname);
684 
685 /**
686  * Get service name (svname) from string
687  * rc < 0 on error
688  * if endptr isn't NULL it is set to end of fsname *
689  */
690 int server_name2svname(const char *label, char *svname, const char **endptr,
691                        size_t svsize)
692 {
693         int rc;
694         const char *dash;
695 
696         /* We use server_name2fsname() just for parsing */
697         rc = server_name2fsname(label, NULL, &dash);
698         if (rc != 0)
699                 return rc;
700 
701         if (endptr != NULL)
702                 *endptr = dash;
703 
704         if (strlcpy(svname, dash + 1, svsize) >= svsize)
705                 return -E2BIG;
706 
707         return 0;
708 }
709 EXPORT_SYMBOL(server_name2svname);
710 
711 
712 /* Get the index from the obd name.
713    rc = server type, or
714    rc < 0  on error
715    if endptr isn't NULL it is set to end of name */
716 int server_name2index(const char *svname, __u32 *idx, const char **endptr)
717 {
718         unsigned long index;
719         int rc;
720         const char *dash;
721 
722         /* We use server_name2fsname() just for parsing */
723         rc = server_name2fsname(svname, NULL, &dash);
724         if (rc != 0)
725                 return rc;
726 
727         dash++;
728 
729         if (strncmp(dash, "MDT", 3) == 0)
730                 rc = LDD_F_SV_TYPE_MDT;
731         else if (strncmp(dash, "OST", 3) == 0)
732                 rc = LDD_F_SV_TYPE_OST;
733         else
734                 return -EINVAL;
735 
736         dash += 3;
737 
738         if (strncmp(dash, "all", 3) == 0) {
739                 if (endptr != NULL)
740                         *endptr = dash + 3;
741                 return rc | LDD_F_SV_ALL;
742         }
743 
744         index = simple_strtoul(dash, (char **)endptr, 16);
745         if (idx != NULL)
746                 *idx = index;
747 
748         /* Account for -mdc after index that is possible when specifying mdt */
749         if (endptr != NULL && strncmp(LUSTRE_MDC_NAME, *endptr + 1,
750                                       sizeof(LUSTRE_MDC_NAME)-1) == 0)
751                 *endptr += sizeof(LUSTRE_MDC_NAME);
752 
753         return rc;
754 }
755 EXPORT_SYMBOL(server_name2index);
756 
757 /*************** mount common between server and client ***************/
758 
759 /* Common umount */
760 int lustre_common_put_super(struct super_block *sb)
761 {
762         int rc;
763 
764         CDEBUG(D_MOUNT, "dropping sb %p\n", sb);
765 
766         /* Drop a ref to the MGC */
767         rc = lustre_stop_mgc(sb);
768         if (rc && (rc != -ENOENT)) {
769                 if (rc != -EBUSY) {
770                         CERROR("Can't stop MGC: %d\n", rc);
771                         return rc;
772                 }
773                 /* BUSY just means that there's some other obd that
774                    needs the mgc.  Let him clean it up. */
775                 CDEBUG(D_MOUNT, "MGC still in use\n");
776         }
777         /* Drop a ref to the mounted disk */
778         lustre_put_lsi(sb);
779         lu_types_stop();
780         return rc;
781 }
782 EXPORT_SYMBOL(lustre_common_put_super);
783 
784 static void lmd_print(struct lustre_mount_data *lmd)
785 {
786         int i;
787 
788         PRINT_CMD(D_MOUNT, "  mount data:\n");
789         if (lmd_is_client(lmd))
790                 PRINT_CMD(D_MOUNT, "profile: %s\n", lmd->lmd_profile);
791         PRINT_CMD(D_MOUNT, "device:  %s\n", lmd->lmd_dev);
792         PRINT_CMD(D_MOUNT, "flags:   %x\n", lmd->lmd_flags);
793 
794         if (lmd->lmd_opts)
795                 PRINT_CMD(D_MOUNT, "options: %s\n", lmd->lmd_opts);
796 
797         if (lmd->lmd_recovery_time_soft)
798                 PRINT_CMD(D_MOUNT, "recovery time soft: %d\n",
799                           lmd->lmd_recovery_time_soft);
800 
801         if (lmd->lmd_recovery_time_hard)
802                 PRINT_CMD(D_MOUNT, "recovery time hard: %d\n",
803                           lmd->lmd_recovery_time_hard);
804 
805         for (i = 0; i < lmd->lmd_exclude_count; i++) {
806                 PRINT_CMD(D_MOUNT, "exclude %d:  OST%04x\n", i,
807                           lmd->lmd_exclude[i]);
808         }
809 }
810 
811 /* Is this server on the exclusion list */
812 int lustre_check_exclusion(struct super_block *sb, char *svname)
813 {
814         struct lustre_sb_info *lsi = s2lsi(sb);
815         struct lustre_mount_data *lmd = lsi->lsi_lmd;
816         __u32 index;
817         int i, rc;
818 
819         rc = server_name2index(svname, &index, NULL);
820         if (rc != LDD_F_SV_TYPE_OST)
821                 /* Only exclude OSTs */
822                 return 0;
823 
824         CDEBUG(D_MOUNT, "Check exclusion %s (%d) in %d of %s\n", svname,
825                index, lmd->lmd_exclude_count, lmd->lmd_dev);
826 
827         for(i = 0; i < lmd->lmd_exclude_count; i++) {
828                 if (index == lmd->lmd_exclude[i]) {
829                         CWARN("Excluding %s (on exclusion list)\n", svname);
830                         return 1;
831                 }
832         }
833         return 0;
834 }
835 
836 /* mount -v  -o exclude=lustre-OST0001:lustre-OST0002 -t lustre ... */
837 static int lmd_make_exclusion(struct lustre_mount_data *lmd, const char *ptr)
838 {
839         const char *s1 = ptr, *s2;
840         __u32 index, *exclude_list;
841         int rc = 0, devmax;
842 
843         /* The shortest an ost name can be is 8 chars: -OST0000.
844            We don't actually know the fsname at this time, so in fact
845            a user could specify any fsname. */
846         devmax = strlen(ptr) / 8 + 1;
847 
848         /* temp storage until we figure out how many we have */
849         OBD_ALLOC(exclude_list, sizeof(index) * devmax);
850         if (!exclude_list)
851                 return -ENOMEM;
852 
853         /* we enter this fn pointing at the '=' */
854         while (*s1 && *s1 != ' ' && *s1 != ',') {
855                 s1++;
856                 rc = server_name2index(s1, &index, &s2);
857                 if (rc < 0) {
858                         CERROR("Can't parse server name '%s': rc = %d\n",
859                                s1, rc);
860                         break;
861                 }
862                 if (rc == LDD_F_SV_TYPE_OST)
863                         exclude_list[lmd->lmd_exclude_count++] = index;
864                 else
865                         CDEBUG(D_MOUNT, "ignoring exclude %.*s: type = %#x\n",
866                                (uint)(s2-s1), s1, rc);
867                 s1 = s2;
868                 /* now we are pointing at ':' (next exclude)
869                    or ',' (end of excludes) */
870                 if (lmd->lmd_exclude_count >= devmax)
871                         break;
872         }
873         if (rc >= 0) /* non-err */
874                 rc = 0;
875 
876         if (lmd->lmd_exclude_count) {
877                 /* permanent, freed in lustre_free_lsi */
878                 OBD_ALLOC(lmd->lmd_exclude, sizeof(index) *
879                           lmd->lmd_exclude_count);
880                 if (lmd->lmd_exclude) {
881                         memcpy(lmd->lmd_exclude, exclude_list,
882                                sizeof(index) * lmd->lmd_exclude_count);
883                 } else {
884                         rc = -ENOMEM;
885                         lmd->lmd_exclude_count = 0;
886                 }
887         }
888         OBD_FREE(exclude_list, sizeof(index) * devmax);
889         return rc;
890 }
891 
892 static int lmd_parse_mgssec(struct lustre_mount_data *lmd, char *ptr)
893 {
894         char   *tail;
895         int     length;
896 
897         if (lmd->lmd_mgssec != NULL) {
898                 OBD_FREE(lmd->lmd_mgssec, strlen(lmd->lmd_mgssec) + 1);
899                 lmd->lmd_mgssec = NULL;
900         }
901 
902         tail = strchr(ptr, ',');
903         if (tail == NULL)
904                 length = strlen(ptr);
905         else
906                 length = tail - ptr;
907 
908         OBD_ALLOC(lmd->lmd_mgssec, length + 1);
909         if (lmd->lmd_mgssec == NULL)
910                 return -ENOMEM;
911 
912         memcpy(lmd->lmd_mgssec, ptr, length);
913         lmd->lmd_mgssec[length] = '\0';
914         return 0;
915 }
916 
917 static int lmd_parse_string(char **handle, char *ptr)
918 {
919         char   *tail;
920         int     length;
921 
922         if ((handle == NULL) || (ptr == NULL))
923                 return -EINVAL;
924 
925         if (*handle != NULL) {
926                 OBD_FREE(*handle, strlen(*handle) + 1);
927                 *handle = NULL;
928         }
929 
930         tail = strchr(ptr, ',');
931         if (tail == NULL)
932                 length = strlen(ptr);
933         else
934                 length = tail - ptr;
935 
936         OBD_ALLOC(*handle, length + 1);
937         if (*handle == NULL)
938                 return -ENOMEM;
939 
940         memcpy(*handle, ptr, length);
941         (*handle)[length] = '\0';
942 
943         return 0;
944 }
945 
946 /* Collect multiple values for mgsnid specifiers */
947 static int lmd_parse_mgs(struct lustre_mount_data *lmd, char **ptr)
948 {
949         lnet_nid_t nid;
950         char *tail = *ptr;
951         char *mgsnid;
952         int   length;
953         int   oldlen = 0;
954 
955         /* Find end of nidlist */
956         while (class_parse_nid_quiet(tail, &nid, &tail) == 0) {}
957         length = tail - *ptr;
958         if (length == 0) {
959                 LCONSOLE_ERROR_MSG(0x159, "Can't parse NID '%s'\n", *ptr);
960                 return -EINVAL;
961         }
962 
963         if (lmd->lmd_mgs != NULL)
964                 oldlen = strlen(lmd->lmd_mgs) + 1;
965 
966         OBD_ALLOC(mgsnid, oldlen + length + 1);
967         if (mgsnid == NULL)
968                 return -ENOMEM;
969 
970         if (lmd->lmd_mgs != NULL) {
971                 /* Multiple mgsnid= are taken to mean failover locations */
972                 memcpy(mgsnid, lmd->lmd_mgs, oldlen);
973                 mgsnid[oldlen - 1] = ':';
974                 OBD_FREE(lmd->lmd_mgs, oldlen);
975         }
976         memcpy(mgsnid + oldlen, *ptr, length);
977         mgsnid[oldlen + length] = '\0';
978         lmd->lmd_mgs = mgsnid;
979         *ptr = tail;
980 
981         return 0;
982 }
983 
984 /** Parse mount line options
985  * e.g. mount -v -t lustre -o abort_recov uml1:uml2:/lustre-client /mnt/lustre
986  * dev is passed as device=uml1:/lustre by mount.lustre
987  */
988 static int lmd_parse(char *options, struct lustre_mount_data *lmd)
989 {
990         char *s1, *s2, *devname = NULL;
991         struct lustre_mount_data *raw = (struct lustre_mount_data *)options;
992         int rc = 0;
993 
994         LASSERT(lmd);
995         if (!options) {
996                 LCONSOLE_ERROR_MSG(0x162, "Missing mount data: check that "
997                                    "/sbin/mount.lustre is installed.\n");
998                 return -EINVAL;
999         }
1000 
1001         /* Options should be a string - try to detect old lmd data */
1002         if ((raw->lmd_magic & 0xffffff00) == (LMD_MAGIC & 0xffffff00)) {
1003                 LCONSOLE_ERROR_MSG(0x163, "You're using an old version of "
1004                                    "/sbin/mount.lustre.  Please install "
1005                                    "version %s\n", LUSTRE_VERSION_STRING);
1006                 return -EINVAL;
1007         }
1008         lmd->lmd_magic = LMD_MAGIC;
1009 
1010         OBD_ALLOC(lmd->lmd_params, 4096);
1011         if (lmd->lmd_params == NULL)
1012                 return -ENOMEM;
1013         lmd->lmd_params[0] = '\0';
1014 
1015         /* Set default flags here */
1016 
1017         s1 = options;
1018         while (*s1) {
1019                 int clear = 0;
1020                 int time_min = OBD_RECOVERY_TIME_MIN;
1021 
1022                 /* Skip whitespace and extra commas */
1023                 while (*s1 == ' ' || *s1 == ',')
1024                         s1++;
1025 
1026                 /* Client options are parsed in ll_options: eg. flock,
1027                    user_xattr, acl */
1028 
1029                 /* Parse non-ldiskfs options here. Rather than modifying
1030                    ldiskfs, we just zero these out here */
1031                 if (strncmp(s1, "abort_recov", 11) == 0) {
1032                         lmd->lmd_flags |= LMD_FLG_ABORT_RECOV;
1033                         clear++;
1034                 } else if (strncmp(s1, "recovery_time_soft=", 19) == 0) {
1035                         lmd->lmd_recovery_time_soft = max_t(int,
1036                                 simple_strtoul(s1 + 19, NULL, 10), time_min);
1037                         clear++;
1038                 } else if (strncmp(s1, "recovery_time_hard=", 19) == 0) {
1039                         lmd->lmd_recovery_time_hard = max_t(int,
1040                                 simple_strtoul(s1 + 19, NULL, 10), time_min);
1041                         clear++;
1042                 } else if (strncmp(s1, "noir", 4) == 0) {
1043                         lmd->lmd_flags |= LMD_FLG_NOIR; /* test purpose only. */
1044                         clear++;
1045                 } else if (strncmp(s1, "nosvc", 5) == 0) {
1046                         lmd->lmd_flags |= LMD_FLG_NOSVC;
1047                         clear++;
1048                 } else if (strncmp(s1, "nomgs", 5) == 0) {
1049                         lmd->lmd_flags |= LMD_FLG_NOMGS;
1050                         clear++;
1051                 } else if (strncmp(s1, "noscrub", 7) == 0) {
1052                         lmd->lmd_flags |= LMD_FLG_NOSCRUB;
1053                         clear++;
1054                 } else if (strncmp(s1, PARAM_MGSNODE,
1055                                    sizeof(PARAM_MGSNODE) - 1) == 0) {
1056                         s2 = s1 + sizeof(PARAM_MGSNODE) - 1;
1057                         /* Assume the next mount opt is the first
1058                            invalid nid we get to. */
1059                         rc = lmd_parse_mgs(lmd, &s2);
1060                         if (rc)
1061                                 goto invalid;
1062                         clear++;
1063                 } else if (strncmp(s1, "writeconf", 9) == 0) {
1064                         lmd->lmd_flags |= LMD_FLG_WRITECONF;
1065                         clear++;
1066                 } else if (strncmp(s1, "update", 6) == 0) {
1067                         lmd->lmd_flags |= LMD_FLG_UPDATE;
1068                         clear++;
1069                 } else if (strncmp(s1, "virgin", 6) == 0) {
1070                         lmd->lmd_flags |= LMD_FLG_VIRGIN;
1071                         clear++;
1072                 } else if (strncmp(s1, "noprimnode", 10) == 0) {
1073                         lmd->lmd_flags |= LMD_FLG_NO_PRIMNODE;
1074                         clear++;
1075                 } else if (strncmp(s1, "mgssec=", 7) == 0) {
1076                         rc = lmd_parse_mgssec(lmd, s1 + 7);
1077                         if (rc)
1078                                 goto invalid;
1079                         clear++;
1080                 /* ost exclusion list */
1081                 } else if (strncmp(s1, "exclude=", 8) == 0) {
1082                         rc = lmd_make_exclusion(lmd, s1 + 7);
1083                         if (rc)
1084                                 goto invalid;
1085                         clear++;
1086                 } else if (strncmp(s1, "mgs", 3) == 0) {
1087                         /* We are an MGS */
1088                         lmd->lmd_flags |= LMD_FLG_MGS;
1089                         clear++;
1090                 } else if (strncmp(s1, "svname=", 7) == 0) {
1091                         rc = lmd_parse_string(&lmd->lmd_profile, s1 + 7);
1092                         if (rc)
1093                                 goto invalid;
1094                         clear++;
1095                 } else if (strncmp(s1, "param=", 6) == 0) {
1096                         int length;
1097                         char *tail = strchr(s1 + 6, ',');
1098                         if (tail == NULL)
1099                                 length = strlen(s1);
1100                         else
1101                                 length = tail - s1;
1102                         length -= 6;
1103                         strncat(lmd->lmd_params, s1 + 6, length);
1104                         strcat(lmd->lmd_params, " ");
1105                         clear++;
1106                 } else if (strncmp(s1, "osd=", 4) == 0) {
1107                         rc = lmd_parse_string(&lmd->lmd_osd_type, s1 + 4);
1108                         if (rc)
1109                                 goto invalid;
1110                         clear++;
1111                 }
1112                 /* Linux 2.4 doesn't pass the device, so we stuck it at the
1113                    end of the options. */
1114                 else if (strncmp(s1, "device=", 7) == 0) {
1115                         devname = s1 + 7;
1116                         /* terminate options right before device.  device
1117                            must be the last one. */
1118                         *s1 = '\0';
1119                         break;
1120                 }
1121 
1122                 /* Find next opt */
1123                 s2 = strchr(s1, ',');
1124                 if (s2 == NULL) {
1125                         if (clear)
1126                                 *s1 = '\0';
1127                         break;
1128                 }
1129                 s2++;
1130                 if (clear)
1131                         memmove(s1, s2, strlen(s2) + 1);
1132                 else
1133                         s1 = s2;
1134         }
1135 
1136         if (!devname) {
1137                 LCONSOLE_ERROR_MSG(0x164, "Can't find the device name "
1138                                    "(need mount option 'device=...')\n");
1139                 goto invalid;
1140         }
1141 
1142         s1 = strstr(devname, ":/");
1143         if (s1) {
1144                 ++s1;
1145                 lmd->lmd_flags |= LMD_FLG_CLIENT;
1146                 /* Remove leading /s from fsname */
1147                 while (*++s1 == '/') ;
1148                 /* Freed in lustre_free_lsi */
1149                 OBD_ALLOC(lmd->lmd_profile, strlen(s1) + 8);
1150                 if (!lmd->lmd_profile)
1151                         return -ENOMEM;
1152                 sprintf(lmd->lmd_profile, "%s-client", s1);
1153         }
1154 
1155         /* Freed in lustre_free_lsi */
1156         OBD_ALLOC(lmd->lmd_dev, strlen(devname) + 1);
1157         if (!lmd->lmd_dev)
1158                 return -ENOMEM;
1159         strcpy(lmd->lmd_dev, devname);
1160 
1161         /* Save mount options */
1162         s1 = options + strlen(options) - 1;
1163         while (s1 >= options && (*s1 == ',' || *s1 == ' '))
1164                 *s1-- = 0;
1165         if (*options != 0) {
1166                 /* Freed in lustre_free_lsi */
1167                 OBD_ALLOC(lmd->lmd_opts, strlen(options) + 1);
1168                 if (!lmd->lmd_opts)
1169                         return -ENOMEM;
1170                 strcpy(lmd->lmd_opts, options);
1171         }
1172 
1173         lmd_print(lmd);
1174         lmd->lmd_magic = LMD_MAGIC;
1175 
1176         return rc;
1177 
1178 invalid:
1179         CERROR("Bad mount options %s\n", options);
1180         return -EINVAL;
1181 }
1182 
1183 struct lustre_mount_data2 {
1184         void *lmd2_data;
1185         struct vfsmount *lmd2_mnt;
1186 };
1187 
1188 /** This is the entry point for the mount call into Lustre.
1189  * This is called when a server or client is mounted,
1190  * and this is where we start setting things up.
1191  * @param data Mount options (e.g. -o flock,abort_recov)
1192  */
1193 int lustre_fill_super(struct super_block *sb, void *data, int silent)
1194 {
1195         struct lustre_mount_data *lmd;
1196         struct lustre_mount_data2 *lmd2 = data;
1197         struct lustre_sb_info *lsi;
1198         int rc;
1199 
1200         CDEBUG(D_MOUNT|D_VFSTRACE, "VFS Op: sb %p\n", sb);
1201 
1202         lsi = lustre_init_lsi(sb);
1203         if (!lsi)
1204                 return -ENOMEM;
1205         lmd = lsi->lsi_lmd;
1206 
1207         /*
1208          * Disable lockdep during mount, because mount locking patterns are
1209          * `special'.
1210          */
1211         lockdep_off();
1212 
1213         /*
1214          * LU-639: the obd cleanup of last mount may not finish yet, wait here.
1215          */
1216         obd_zombie_barrier();
1217 
1218         /* Figure out the lmd from the mount options */
1219         if (lmd_parse((char *)(lmd2->lmd2_data), lmd)) {
1220                 lustre_put_lsi(sb);
1221                 GOTO(out, rc = -EINVAL);
1222         }
1223 
1224         if (lmd_is_client(lmd)) {
1225                 CDEBUG(D_MOUNT, "Mounting client %s\n", lmd->lmd_profile);
1226                 if (!client_fill_super) {
1227                         LCONSOLE_ERROR_MSG(0x165, "Nothing registered for "
1228                                            "client mount! Is the 'lustre' "
1229                                            "module loaded?\n");
1230                         lustre_put_lsi(sb);
1231                         rc = -ENODEV;
1232                 } else {
1233                         rc = lustre_start_mgc(sb);
1234                         if (rc) {
1235                                 lustre_put_lsi(sb);
1236                                 GOTO(out, rc);
1237                         }
1238                         /* Connect and start */
1239                         /* (should always be ll_fill_super) */
1240                         rc = (*client_fill_super)(sb, lmd2->lmd2_mnt);
1241                         /* c_f_s will call lustre_common_put_super on failure */
1242                 }
1243         } else {
1244                 CERROR("This is client-side-only module, "
1245                        "cannot handle server mount.\n");
1246                 rc = -EINVAL;
1247         }
1248 
1249         /* If error happens in fill_super() call, @lsi will be killed there.
1250          * This is why we do not put it here. */
1251         GOTO(out, rc);
1252 out:
1253         if (rc) {
1254                 CERROR("Unable to mount %s (%d)\n",
1255                        s2lsi(sb) ? lmd->lmd_dev : "", rc);
1256         } else {
1257                 CDEBUG(D_SUPER, "Mount %s complete\n",
1258                        lmd->lmd_dev);
1259         }
1260         lockdep_on();
1261         return rc;
1262 }
1263 
1264 
1265 /* We can't call ll_fill_super by name because it lives in a module that
1266    must be loaded after this one. */
1267 void lustre_register_client_fill_super(int (*cfs)(struct super_block *sb,
1268                                                   struct vfsmount *mnt))
1269 {
1270         client_fill_super = cfs;
1271 }
1272 EXPORT_SYMBOL(lustre_register_client_fill_super);
1273 
1274 void lustre_register_kill_super_cb(void (*cfs)(struct super_block *sb))
1275 {
1276         kill_super_cb = cfs;
1277 }
1278 EXPORT_SYMBOL(lustre_register_kill_super_cb);
1279 
1280 /***************** FS registration ******************/
1281 struct dentry *lustre_mount(struct file_system_type *fs_type, int flags,
1282                                 const char *devname, void *data)
1283 {
1284         struct lustre_mount_data2 lmd2 = { data, NULL };
1285 
1286         return mount_nodev(fs_type, flags, &lmd2, lustre_fill_super);
1287 }
1288 
1289 void lustre_kill_super(struct super_block *sb)
1290 {
1291         struct lustre_sb_info *lsi = s2lsi(sb);
1292 
1293         if (kill_super_cb && lsi && !IS_SERVER(lsi))
1294                 (*kill_super_cb)(sb);
1295 
1296         kill_anon_super(sb);
1297 }
1298 
1299 /** Register the "lustre" fs type
1300  */
1301 struct file_system_type lustre_fs_type = {
1302         .owner  = THIS_MODULE,
1303         .name    = "lustre",
1304         .mount  = lustre_mount,
1305         .kill_sb      = lustre_kill_super,
1306         .fs_flags     = FS_BINARY_MOUNTDATA | FS_REQUIRES_DEV |
1307                         FS_HAS_FIEMAP | FS_RENAME_DOES_D_MOVE,
1308 };
1309 
1310 int lustre_register_fs(void)
1311 {
1312         return register_filesystem(&lustre_fs_type);
1313 }
1314 
1315 int lustre_unregister_fs(void)
1316 {
1317         return unregister_filesystem(&lustre_fs_type);
1318 }
1319 

This page was automatically generated by LXR 0.3.1 (source).  •  Linux is a registered trademark of Linus Torvalds  •  Contact us