2 * linux/fs/ext2_obd/ext2_obd.c
4 * Copyright (C) 2001 Cluster File Systems, Inc.
6 * This code is issued under the GNU General Public License.
7 * See the file COPYING in this distribution
9 * by Peter Braam <braam@clusterfs.com>
14 #include <linux/version.h>
15 #include <linux/module.h>
17 #include <linux/stat.h>
18 #include <linux/locks.h>
19 #include <linux/ext2_fs.h>
20 #include <linux/quotaops.h>
21 #include <asm/unistd.h>
22 #include <linux/obd_support.h>
23 #include <linux/obd.h>
24 #include <linux/lustre_lib.h>
25 #include <linux/lustre_idl.h>
26 #include <linux/lustre_mds.h>
27 #include <linux/obd_class.h>
30 static struct dentry *mds_fid2dentry(struct mds_obd *mds, struct lustre_fid *fid)
35 inode = iget(mds->mds_sb, fid->id);
40 de = d_alloc_root(inode);
51 int mds_getattr(struct mds_request *req)
53 struct dentry *de = mds_fid2dentry(req->rq_obd, &req->rq_req->fid1);
55 struct mds_rep *rep = req->rq_rep;
58 rc = mds_pack_rep(NULL, 0, NULL, 0, &req->rq_rephdr, &req->rq_rep,
59 &req->rq_replen, &req->rq_repbuf);
62 printk("mds: out of memory\n");
63 req->rq_status = -ENOMEM;
67 req->rq_rephdr->seqno = req->rq_reqhdr->seqno;
71 req->rq_rephdr->status = -ENOENT;
76 rep->atime = inode->i_atime;
77 rep->ctime = inode->i_ctime;
78 rep->mtime = inode->i_mtime;
79 rep->uid = inode->i_uid;
80 rep->gid = inode->i_gid;
81 rep->size = inode->i_size;
82 rep->mode = inode->i_mode;
87 int mds_reply(struct mds_request *req)
90 kfree(req->rq_reqbuf);
91 req->rq_reqbuf = NULL;
92 wake_up_interruptible(&req->rq_wait_for_mds_rep);
97 int mds_error(struct mds_request *req)
99 struct mds_rep_hdr *hdr;
102 hdr = kmalloc(sizeof(*hdr), GFP_KERNEL);
108 memset(hdr, 0, sizeof(*hdr));
110 hdr->seqno = req->rq_reqhdr->seqno;
111 hdr->status = req->rq_status;
112 hdr->type = MDS_TYPE_ERR;
113 req->rq_repbuf = (char *)hdr;
116 return mds_reply(req);
119 //int mds_handle(struct mds_conn *conn, int len, char *buf)
120 int mds_handle(struct mds_request *req)
123 struct mds_req_hdr *hdr;
127 hdr = (struct mds_req_hdr *)req->rq_reqbuf;
129 if (NTOH_u32(hdr->type) != MDS_TYPE_REQ) {
130 printk("lustre_mds: wrong packet type sent %d\n",
131 NTOH_u32(hdr->type));
136 rc = mds_unpack_req(req->rq_reqbuf, req->rq_reqlen,
137 &req->rq_reqhdr, &req->rq_req);
139 printk("lustre_mds: Invalid request\n");
144 switch (req->rq_reqhdr->opc) {
147 CDEBUG(D_INODE, "getattr\n");
148 rc = mds_getattr(req);
152 return mds_getattr(req);
155 return mds_getattr(req);
158 return mds_getattr(req);
161 return mds_getattr(req);
164 return mds_getattr(req);
167 return mds_getattr(req);
170 return mds_getattr(req);
173 return mds_getattr(req);
176 return mds_getattr(req);
179 return mds_getattr(req);
182 return mds_error(req);
187 printk("mds: processing error %d\n", rc);
190 CDEBUG(D_INODE, "sending reply\n");
198 static void mds_timer_run(unsigned long __data)
200 struct task_struct * p = (struct task_struct *) __data;
205 int mds_main(void *arg)
207 struct mds_obd *mds = (struct mds_obd *) arg;
208 struct timer_list timer;
212 spin_lock_irq(¤t->sigmask_lock);
213 sigfillset(¤t->blocked);
214 recalc_sigpending(current);
215 spin_unlock_irq(¤t->sigmask_lock);
217 sprintf(current->comm, "lustre_mds");
219 /* Set up an interval timer which can be used to trigger a
220 wakeup after the interval expires */
222 timer.data = (unsigned long) current;
223 timer.function = mds_timer_run;
224 mds->mds_timer = &timer;
226 /* Record that the thread is running */
227 mds->mds_thread = current;
228 wake_up(&mds->mds_done_waitq);
230 printk(KERN_INFO "lustre_mds starting. Commit interval %ld seconds\n",
231 mds->mds_interval / HZ);
233 /* XXX maintain a list of all managed devices: insert here */
235 /* And now, wait forever for commit wakeup events. */
237 if (mds->mds_flags & MDS_UNMOUNT)
241 wake_up(&mds->mds_done_waitq);
242 interruptible_sleep_on(&mds->mds_waitq);
244 CDEBUG(D_INODE, "lustre_mds wakes\n");
245 CDEBUG(D_INODE, "pick up req here and continue\n");
247 if (list_empty(&mds->mds_reqs)) {
248 CDEBUG(D_INODE, "woke because of timer\n");
252 del_timer_sync(mds->mds_timer);
254 /* XXX maintain a list of all managed devices: cleanup here */
256 mds->mds_thread = NULL;
257 wake_up(&mds->mds_done_waitq);
258 printk("lustre_mds: exiting\n");
262 static void mds_stop_srv_thread(struct mds_obd *mds)
264 mds->mds_flags |= MDS_UNMOUNT;
266 while (mds->mds_thread) {
267 wake_up(&mds->mds_waitq);
268 sleep_on(&mds->mds_done_waitq);
272 static void mds_start_srv_thread(struct mds_obd *mds)
274 init_waitqueue_head(&mds->mds_waitq);
275 init_waitqueue_head(&mds->mds_done_waitq);
276 kernel_thread(mds_main, (void *)mds,
277 CLONE_VM | CLONE_FS | CLONE_FILES);
278 while (!mds->mds_thread)
279 sleep_on(&mds->mds_done_waitq);
282 /* mount the file system (secretly) */
283 static int mds_setup(struct obd_device *obddev, obd_count len,
287 struct obd_ioctl_data* data = buf;
288 struct mds_obd *mds = &obddev->u.mds;
289 struct vfsmount *mnt;
293 mnt = do_kern_mount(data->ioc_inlbuf2, 0,
294 data->ioc_inlbuf1, NULL);
301 mds->mds_sb = mnt->mnt_root->d_inode->i_sb;
302 if (!obddev->u.mds.mds_sb) {
307 INIT_LIST_HEAD(&mds->mds_reqs);
308 mds->mds_thread = NULL;
310 mds->mds_interval = 3 * HZ;
311 mds->mds_vfsmnt = mnt;
312 obddev->u.mds.mds_fstype = strdup(data->ioc_inlbuf2);
314 mds->mds_ctxt.pwdmnt = mnt;
315 mds->mds_ctxt.pwd = mnt->mnt_root;
316 mds->mds_ctxt.fs = KERNEL_DS;
318 spin_lock_init(&obddev->u.mds.fo_lock);
320 mds_start_srv_thread(mds);
327 static int mds_cleanup(struct obd_device * obddev)
329 struct super_block *sb;
330 struct mds_obd *mds = &obddev->u.mds;
334 if ( !(obddev->obd_flags & OBD_SET_UP) ) {
339 if ( !list_empty(&obddev->obd_gen_clients) ) {
340 printk(KERN_WARNING __FUNCTION__ ": still has clients!\n");
345 mds_stop_srv_thread(mds);
352 if (!list_empty(&mds->mds_reqs)) {
353 // XXX reply with errors and clean up
354 CDEBUG(D_INODE, "Request list not empty!\n");
358 mntput(mds->mds_vfsmnt);
360 kfree(mds->mds_fstype);
369 /* use obd ops to offer management infrastructure */
370 static struct obd_ops mds_obd_ops = {
372 o_cleanup: mds_cleanup,
375 static int __init mds_init(void)
377 printk(KERN_INFO "Lustre MDS v0.01, braam@clusterfs.com\n");
378 obd_register_type(&mds_obd_ops, LUSTRE_MDS_NAME);
381 static void __exit mds_exit(void)
383 obd_unregister_type(LUSTRE_MDS_NAME);
386 MODULE_AUTHOR("Peter J. Braam <braam@clusterfs.com>");
387 MODULE_DESCRIPTION("Lustre Metadata server module");
388 MODULE_LICENSE("GPL");
390 module_init(mds_init);
391 module_exit(mds_exit);