Whamcloud - gitweb
LU-836 ldiskfs: require ldiskfs filesystem has journal
[fs/lustre-release.git] / lustre / mds / handler.c
1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2  * vim:expandtab:shiftwidth=8:tabstop=8:
3  *
4  * GPL HEADER START
5  *
6  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License version 2 only,
10  * as published by the Free Software Foundation.
11  *
12  * This program is distributed in the hope that it will be useful, but
13  * WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * General Public License version 2 for more details (a copy is included
16  * in the LICENSE file that accompanied this code).
17  *
18  * You should have received a copy of the GNU General Public License
19  * version 2 along with this program; If not, see
20  * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
21  *
22  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
23  * CA 95054 USA or visit www.sun.com if you need additional information or
24  * have any questions.
25  *
26  * GPL HEADER END
27  */
28 /*
29  * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
30  * Use is subject to license terms.
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/mds/handler.c
37  *
38  * Author: Peter Braam <braam@clusterfs.com>
39  * Author: Andreas Dilger <adilger@clusterfs.com>
40  * Author: Phil Schwan <phil@clusterfs.com>
41  * Author: Mike Shaver <shaver@clusterfs.com>
42  */
43
44 #define DEBUG_SUBSYSTEM S_MDS
45
46 #include <lustre_mds.h>
47 #include <linux/module.h>
48 #include <linux/init.h>
49 #include <linux/fs.h>
50 #include <linux/jbd.h>
51 #include <linux/smp_lock.h>
52 #include <linux/buffer_head.h>
53 #include <linux/workqueue.h>
54 #include <linux/mount.h>
55
56 #include <lustre_acl.h>
57 #include <obd_class.h>
58 #include <lustre_dlm.h>
59 #include <obd_lov.h>
60 #include <lustre_fsfilt.h>
61 #include <lprocfs_status.h>
62 #include <lustre_disk.h>
63 #include <lustre_param.h>
64
65 #include "mds_internal.h"
66
67 __u32 mds_max_ost_index=0xFFFF;
68 CFS_MODULE_PARM(mds_max_ost_index, "i", int, 0444,
69                 "maximal OST index");
70
71 static int mds_lov_presetup (struct mds_obd *mds, struct lustre_cfg *lcfg)
72 {
73         int rc = 0;
74         ENTRY;
75
76         if (lcfg->lcfg_bufcount >= 4 && LUSTRE_CFG_BUFLEN(lcfg, 3) > 0) {
77                 class_uuid_t uuid;
78
79                 ll_generate_random_uuid(uuid);
80                 class_uuid_unparse(uuid, &mds->mds_lov_uuid);
81
82                 OBD_ALLOC(mds->mds_profile, LUSTRE_CFG_BUFLEN(lcfg, 3));
83                 if (mds->mds_profile == NULL)
84                         RETURN(-ENOMEM);
85
86                 strncpy(mds->mds_profile, lustre_cfg_string(lcfg, 3),
87                         LUSTRE_CFG_BUFLEN(lcfg, 3));
88         }
89         RETURN(rc);
90 }
91
92 static int mds_lov_clean(struct obd_device *obd)
93 {
94         struct mds_obd *mds = &obd->u.mds;
95         struct obd_device *osc = mds->mds_lov_obd;
96         ENTRY;
97
98         if (mds->mds_profile) {
99                 class_del_profile(mds->mds_profile);
100                 OBD_FREE(mds->mds_profile, strlen(mds->mds_profile) + 1);
101                 mds->mds_profile = NULL;
102         }
103
104         /* There better be a lov */
105         if (!osc)
106                 RETURN(0);
107         if (IS_ERR(osc))
108                 RETURN(PTR_ERR(osc));
109
110         obd_register_observer(osc, NULL);
111
112         /* Give lov our same shutdown flags */
113         osc->obd_force = obd->obd_force;
114         osc->obd_fail = obd->obd_fail;
115
116         /* Cleanup the lov */
117         obd_disconnect(mds->mds_lov_exp);
118         class_manual_cleanup(osc);
119
120         RETURN(0);
121 }
122
123 static int mds_postsetup(struct obd_device *obd)
124 {
125         struct mds_obd *mds = &obd->u.mds;
126         struct llog_ctxt *ctxt;
127         int rc = 0;
128         ENTRY;
129
130         rc = llog_setup(obd, &obd->obd_olg, LLOG_CONFIG_ORIG_CTXT, obd, 0, NULL,
131                         &llog_lvfs_ops);
132         if (rc)
133                 RETURN(rc);
134
135         rc = llog_setup(obd, &obd->obd_olg, LLOG_LOVEA_ORIG_CTXT, obd, 0, NULL,
136                         &llog_lvfs_ops);
137         if (rc)
138                 GOTO(err_llog, rc);
139
140         mds_changelog_llog_init(obd, obd);
141
142         if (mds->mds_profile) {
143                 struct lustre_profile *lprof;
144                 /* The profile defines which osc and mdc to connect to, for a
145                    client.  We reuse that here to figure out the name of the
146                    lov to use (and ignore lprof->lp_md).
147                    The profile was set in the config log with
148                    LCFG_MOUNTOPT profilenm oscnm mdcnm */
149                 lprof = class_get_profile(mds->mds_profile);
150                 if (lprof == NULL) {
151                         CERROR("No profile found: %s\n", mds->mds_profile);
152                         GOTO(err_cleanup, rc = -ENOENT);
153                 }
154                 rc = mds_lov_connect(obd, lprof->lp_dt);
155                 if (rc)
156                         GOTO(err_cleanup, rc);
157         }
158
159         RETURN(rc);
160
161 err_cleanup:
162         mds_lov_clean(obd);
163         ctxt = llog_get_context(obd, LLOG_LOVEA_ORIG_CTXT);
164         if (ctxt)
165                 llog_cleanup(ctxt);
166 err_llog:
167         ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
168         if (ctxt)
169                 llog_cleanup(ctxt);
170         return rc;
171 }
172
173 int mds_postrecov(struct obd_device *obd)
174 {
175         int rc = 0;
176         ENTRY;
177
178         if (obd->obd_fail)
179                 RETURN(0);
180
181         LASSERT(!obd->obd_recovering);
182         /* clean PENDING dir */
183 #if 0
184         if (strncmp(obd->obd_name, MDD_OBD_NAME, strlen(MDD_OBD_NAME)))
185                 rc = mds_cleanup_pending(obd);
186                 if (rc < 0)
187                         GOTO(out, rc);
188 #endif
189         /* FIXME Does target_finish_recovery really need this to block? */
190         /* Notify the LOV, which will in turn call mds_notify for each tgt */
191         /* This means that we have to hack obd_notify to think we're obd_set_up
192            during mds_lov_connect. */
193         obd_notify(obd->u.mds.mds_lov_obd, NULL,
194                    obd->obd_async_recov ? OBD_NOTIFY_SYNC_NONBLOCK :
195                    OBD_NOTIFY_SYNC, NULL);
196
197         RETURN(rc);
198 }
199
200 /* We need to be able to stop an mds_lov_synchronize */
201 static int mds_lov_early_clean(struct obd_device *obd)
202 {
203         struct mds_obd *mds = &obd->u.mds;
204         struct obd_device *osc = mds->mds_lov_obd;
205
206         if (!osc || (!obd->obd_force && !obd->obd_fail))
207                 return(0);
208
209         CDEBUG(D_HA, "abort inflight\n");
210         return (obd_precleanup(osc, OBD_CLEANUP_EARLY));
211 }
212
213 static int mds_precleanup(struct obd_device *obd, enum obd_cleanup_stage stage)
214 {
215         struct mds_obd *mds = &obd->u.mds;
216         struct llog_ctxt *ctxt;
217         int rc = 0;
218         ENTRY;
219
220         switch (stage) {
221         case OBD_CLEANUP_EARLY:
222                 break;
223         case OBD_CLEANUP_EXPORTS:
224                 mds_lov_early_clean(obd);
225                 cfs_down_write(&mds->mds_notify_lock);
226                 mds_lov_disconnect(obd);
227                 mds_lov_clean(obd);
228                 ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
229                 if (ctxt)
230                         llog_cleanup(ctxt);
231                 ctxt = llog_get_context(obd, LLOG_LOVEA_ORIG_CTXT);
232                 if (ctxt)
233                         llog_cleanup(ctxt);
234                 rc = obd_llog_finish(obd, 0);
235                 mds->mds_lov_exp = NULL;
236                 cfs_up_write(&mds->mds_notify_lock);
237                 break;
238         }
239         RETURN(rc);
240 }
241
242 /* Look up an entry by inode number. */
243 /* this function ONLY returns valid dget'd dentries with an initialized inode
244    or errors */
245 static struct dentry *mds_lvfs_fid2dentry(__u64 id, __u32 gen, __u64 gr,
246                                           void *data)
247 {
248         struct fsfilt_fid  fid;
249         struct obd_device *obd = (struct obd_device *)data;
250
251         if (id == 0)
252                 RETURN(ERR_PTR(-ESTALE));
253
254         fid.ino = id;
255         fid.gen = gen;
256
257         RETURN(fsfilt_fid2dentry(obd, obd->u.mds.mds_obt.obt_vfsmnt, &fid, 0));
258 }
259
260
261 struct lvfs_callback_ops mds_lvfs_ops = {
262         l_fid2dentry:     mds_lvfs_fid2dentry,
263 };
264
265 static int mds_init_ctxt(struct obd_device *obd, struct vfsmount *mnt)
266 {
267         struct mds_obd *mds = &obd->u.mds;
268         int rc;
269
270         mds->mds_obt.obt_vfsmnt = mnt;
271         /* why not mnt->mnt_sb instead of mnt->mnt_root->d_inode->i_sb? */
272         obd->u.obt.obt_sb = mnt->mnt_root->d_inode->i_sb;
273         obd->u.obt.obt_magic = OBT_MAGIC;
274         rc = fsfilt_setup(obd, obd->u.obt.obt_sb);
275         if (rc)
276                 return rc;
277
278         OBD_SET_CTXT_MAGIC(&obd->obd_lvfs_ctxt);
279         obd->obd_lvfs_ctxt.pwdmnt = mnt;
280         obd->obd_lvfs_ctxt.pwd = mnt->mnt_root;
281         obd->obd_lvfs_ctxt.fs = get_ds();
282         obd->obd_lvfs_ctxt.cb_ops = mds_lvfs_ops;
283         return 0;
284 }
285
286 /*mds still need lov setup here*/
287 static int mds_cmd_setup(struct obd_device *obd, struct lustre_cfg *lcfg)
288 {
289         struct mds_obd *mds = &obd->u.mds;
290         struct lvfs_run_ctxt saved;
291         const char     *dev;
292         struct vfsmount *mnt;
293         struct lustre_sb_info *lsi;
294         struct lustre_mount_info *lmi;
295         struct dentry  *dentry;
296         int rc = 0;
297         ENTRY;
298
299         CDEBUG(D_INFO, "obd %s setup \n", obd->obd_name);
300         if (strncmp(obd->obd_name, MDD_OBD_NAME, strlen(MDD_OBD_NAME)))
301                 RETURN(0);
302
303         if (lcfg->lcfg_bufcount < 5) {
304                 CERROR("invalid arg for setup %s\n", MDD_OBD_NAME);
305                 RETURN(-EINVAL);
306         }
307         dev = lustre_cfg_string(lcfg, 4);
308         lmi = server_get_mount(dev);
309         LASSERT(lmi != NULL);
310
311         lsi = s2lsi(lmi->lmi_sb);
312         mnt = lmi->lmi_mnt;
313         /* FIXME: MDD LOV initialize objects.
314          * we need only lmi here but not get mount
315          * OSD did mount already, so put mount back
316          */
317         cfs_atomic_dec(&lsi->lsi_mounts);
318         mntput(mnt);
319         cfs_init_rwsem(&mds->mds_notify_lock);
320
321         obd->obd_fsops = fsfilt_get_ops(MT_STR(lsi->lsi_ldd));
322         rc = mds_init_ctxt(obd, mnt);
323         if (rc)
324                 GOTO(err_putfs, rc);
325
326         push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
327         dentry = simple_mkdir(cfs_fs_pwd(current->fs), mnt, "OBJECTS", 0777, 1);
328         if (IS_ERR(dentry)) {
329                 rc = PTR_ERR(dentry);
330                 CERROR("cannot create OBJECTS directory: rc = %d\n", rc);
331                 GOTO(err_pop, rc);
332         }
333         mds->mds_objects_dir = dentry;
334
335         rc = mds_lov_init_objids(obd);
336         if (rc != 0) {
337                CERROR("cannot init lov objid rc = %d\n", rc);
338                GOTO(err_objects, rc );
339         }
340
341         rc = mds_lov_presetup(mds, lcfg);
342         if (rc < 0)
343                 GOTO(err_objects, rc);
344
345         /* Don't wait for mds_postrecov trying to clear orphans */
346         obd->obd_async_recov = 1;
347         rc = mds_postsetup(obd);
348         /* Bug 11557 - allow async abort_recov start
349            FIXME can remove most of this obd_async_recov plumbing
350         obd->obd_async_recov = 0;
351         */
352
353         if (rc)
354                 GOTO(err_objects, rc);
355
356         pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
357         RETURN(0);
358
359 err_objects:
360         dput(mds->mds_objects_dir);
361 err_pop:
362         pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
363 err_putfs:
364         fsfilt_put_ops(obd->obd_fsops);
365         return rc;
366 }
367
368 static int mds_cmd_cleanup(struct obd_device *obd)
369 {
370         struct mds_obd *mds = &obd->u.mds;
371         struct lvfs_run_ctxt saved;
372         int rc = 0;
373         ENTRY;
374
375         mds->mds_lov_exp = NULL;
376
377         if (obd->obd_fail)
378                 LCONSOLE_WARN("%s: shutting down for failover; client state "
379                               "will be preserved.\n", obd->obd_name);
380
381         if (strncmp(obd->obd_name, MDD_OBD_NAME, strlen(MDD_OBD_NAME)))
382                 RETURN(0);
383
384         push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
385
386         mds_lov_destroy_objids(obd);
387
388         if (mds->mds_objects_dir != NULL) {
389                 l_dput(mds->mds_objects_dir);
390                 mds->mds_objects_dir = NULL;
391         }
392
393         ll_vfs_dq_off(obd->u.obt.obt_sb, 0);
394         shrink_dcache_sb(mds->mds_obt.obt_sb);
395         fsfilt_put_ops(obd->obd_fsops);
396
397         pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
398         RETURN(rc);
399 }
400
401 #if 0
402 static int mds_cmd_health_check(struct obd_device *obd)
403 {
404         return 0;
405 }
406 #endif
407 static struct obd_ops mds_cmd_obd_ops = {
408         .o_owner           = THIS_MODULE,
409         .o_setup           = mds_cmd_setup,
410         .o_cleanup         = mds_cmd_cleanup,
411         .o_precleanup      = mds_precleanup,
412         .o_create          = mds_obd_create,
413         .o_destroy         = mds_obd_destroy,
414         .o_llog_init       = mds_llog_init,
415         .o_llog_finish     = mds_llog_finish,
416         .o_notify          = mds_notify,
417         .o_postrecov       = mds_postrecov,
418         //   .o_health_check    = mds_cmd_health_check,
419 };
420
421 quota_interface_t *mds_quota_interface_ref;
422 extern quota_interface_t mds_quota_interface;
423
424 static int __init mds_cmd_init(void)
425 {
426         struct lprocfs_static_vars lvars;
427         int rc;
428
429         cfs_request_module("%s", "lquota");
430         mds_quota_interface_ref = PORTAL_SYMBOL_GET(mds_quota_interface);
431         rc = lquota_init(mds_quota_interface_ref);
432         if (rc) {
433                 if (mds_quota_interface_ref)
434                         PORTAL_SYMBOL_PUT(mds_quota_interface);
435                 return rc;
436         }
437         init_obd_quota_ops(mds_quota_interface_ref, &mds_cmd_obd_ops);
438
439         lprocfs_mds_init_vars(&lvars);
440         class_register_type(&mds_cmd_obd_ops, NULL, lvars.module_vars,
441                             LUSTRE_MDS_NAME, NULL);
442
443         return 0;
444 }
445
446 static void /*__exit*/ mds_cmd_exit(void)
447 {
448         lquota_exit(mds_quota_interface_ref);
449         if (mds_quota_interface_ref)
450                 PORTAL_SYMBOL_PUT(mds_quota_interface);
451
452         class_unregister_type(LUSTRE_MDS_NAME);
453 }
454
455 EXPORT_SYMBOL(mds_quota_interface_ref);
456 MODULE_AUTHOR("Sun Microsystems, Inc. <http://www.lustre.org/>");
457 MODULE_DESCRIPTION("Lustre Metadata Server (MDS)");
458 MODULE_LICENSE("GPL");
459
460 module_init(mds_cmd_init);
461 module_exit(mds_cmd_exit);