[prev in list] [next in list] [prev in thread] [next in thread] 

List:       lustre-cvs
Subject:    [Lustre-cvs] CVS: obd/mds Makefile.am,NONE,1.1 handler.c,NONE,1.1
From:       "Peter J. Braam" <braam () users ! sourceforge ! net>
Date:       2001-12-28 4:41:17
[Download RAW message or body]

Update of /cvsroot/lustre/obd/mds
In directory usw-pr-cvs1:/tmp/cvs-serv5726/mds

Added Files:
	Makefile.am handler.c 
Log Message:
A solid part of the MDS request processing infrastructure. 
  - packing/unpacking and definition of requests
  - a server daemon
  - getattr call coded

Lustre idl file created:
  - move all interface definitions here
  - that's ioctl's, mds requests/replies & obd requests/replies

Makefiles:
  - configure.in can handle user mode linux now

utils:
  - fixed the obdctl library to support old version of readline.





--- NEW FILE ---
# Copyright (C) 2001  Cluster File Systems, Inc.
#
# This code is issued under the GNU General Public License.
# See the file COPYING in this distribution

MODULE = mds
modulefs_DATA = mds.o
EXTRA_PROGRAMS = mds

mds_pack.c: 
	ln -s ../lib/mds_pack.c .

mds_SOURCES = mds_pack.c handler.c 

include $(top_srcdir)/Rules


--- NEW FILE ---
/*
 *  linux/fs/ext2_obd/ext2_obd.c
 *
 * Copyright (C) 2001  Cluster File Systems, Inc.
 *
 * This code is issued under the GNU General Public License.
 * See the file COPYING in this distribution
 *
 * by Peter Braam <braam@clusterfs.com>
 */

#define EXPORT_SYMTAB

#include <linux/version.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/stat.h>
#include <linux/locks.h>
#include <linux/ext2_fs.h>
#include <linux/quotaops.h>
#include <asm/unistd.h>
#include <linux/obd_support.h>
#include <linux/obd.h>
#include <linux/lustre_lib.h>
#include <linux/lustre_idl.h>
#include <linux/lustre_mds.h>
#include <linux/obd_class.h>


static struct dentry *mds_fid2dentry(struct mds_obd *mds, struct lustre_fid *fid)
{
	struct dentry *de;
	struct inode *inode;

	inode = iget(mds->mds_sb, fid->id);
	if (!inode) { 
		EXIT;
	}

	de = d_alloc_root(inode);
	if (!de) { 
		iput(inode);
		EXIT;
		return NULL;
	}

	de->d_inode = inode;
	return de;
}

int mds_getattr(struct mds_request *req)
{
	struct dentry *de = mds_fid2dentry(req->rq_obd, &req->rq_req->fid1);
	struct inode *inode;
	struct mds_rep *rep = req->rq_rep;
	int rc;
	
	rc = mds_pack_rep(NULL, 0, NULL, 0, &req->rq_rephdr, &req->rq_rep, 
			  &req->rq_replen, &req->rq_repbuf);
	if (rc) { 
		EXIT;
		printk("mds: out of memory\n");
		req->rq_status = -ENOMEM;
		return -ENOMEM;
	}

	req->rq_rephdr->seqno = req->rq_reqhdr->seqno;

	if (!de) { 
		EXIT;
		req->rq_rephdr->status = -ENOENT;
		return 0;
	}

	inode = de->d_inode;
	rep->atime = inode->i_atime;
	rep->ctime = inode->i_ctime;
	rep->mtime = inode->i_mtime;
	rep->uid = inode->i_uid;
	rep->gid = inode->i_gid;
	rep->size = inode->i_size;
	rep->mode = inode->i_mode;

	return 0;
}

int mds_reply(struct mds_request *req)
{
	ENTRY;
	kfree(req->rq_reqbuf);
	req->rq_reqbuf = NULL; 
	wake_up_interruptible(&req->rq_wait_for_mds_rep); 
	EXIT;
	return 0;
}

int mds_error(struct mds_request *req)
{
	struct mds_rep_hdr *hdr;

	ENTRY;
	hdr = kmalloc(sizeof(*hdr), GFP_KERNEL);
	if (!hdr) { 
		EXIT;
		return -ENOMEM;
	}

	memset(hdr, 0, sizeof(*hdr));
	
	hdr->seqno = req->rq_reqhdr->seqno;
	hdr->status = req->rq_status; 
	hdr->type = MDS_TYPE_ERR;
	req->rq_repbuf = (char *)hdr;

	EXIT;
	return mds_reply(req);
}

//int mds_handle(struct mds_conn *conn, int len, char *buf)
int mds_handle(struct mds_request *req)
{
	int rc;
	struct mds_req_hdr *hdr;

	ENTRY;

	hdr = (struct mds_req_hdr *)req->rq_reqbuf;

	if (NTOH_u32(hdr->type) != MDS_TYPE_REQ) {
		printk("lustre_mds: wrong packet type sent %d\n",
		       NTOH_u32(hdr->type));
		rc = -EINVAL;
		goto out;
	}

	rc = mds_unpack_req(req->rq_reqbuf, req->rq_reqlen, 
			    &req->rq_reqhdr, &req->rq_req);
	if (rc) { 
		printk("lustre_mds: Invalid request\n");
		EXIT; 
		goto out;
	}

	switch (req->rq_reqhdr->opc) { 

	case MDS_GETATTR:
		CDEBUG(D_INODE, "getattr\n");
		rc = mds_getattr(req);
		break;

	case MDS_OPEN:
		return mds_getattr(req);

	case MDS_SETATTR:
		return mds_getattr(req);

	case MDS_CREATE:
		return mds_getattr(req);

	case MDS_MKDIR:
		return mds_getattr(req);

	case MDS_RMDIR:
		return mds_getattr(req);

	case MDS_SYMLINK:
		return mds_getattr(req);
 
	case MDS_LINK:
		return mds_getattr(req);
  
	case MDS_MKNOD:
		return mds_getattr(req);

	case MDS_UNLINK:
		return mds_getattr(req);

	case MDS_RENAME:
		return mds_getattr(req);

	default:
		return mds_error(req);
	}

out:
	if (rc) { 
		printk("mds: processing error %d\n", rc);
		mds_error(req);
	} else { 
		CDEBUG(D_INODE, "sending reply\n"); 
		mds_reply(req); 
	}

	return 0;
}


static void mds_timer_run(unsigned long __data)
{
	struct task_struct * p = (struct task_struct *) __data;

	wake_up_process(p);
}

int mds_main(void *arg)
{
	struct mds_obd *mds = (struct mds_obd *) arg;
	struct timer_list timer;

	lock_kernel();
	daemonize();
	spin_lock_irq(&current->sigmask_lock);
	sigfillset(&current->blocked);
	recalc_sigpending(current);
	spin_unlock_irq(&current->sigmask_lock);

	sprintf(current->comm, "lustre_mds");

	/* Set up an interval timer which can be used to trigger a
           wakeup after the interval expires */
	init_timer(&timer);
	timer.data = (unsigned long) current;
	timer.function = mds_timer_run;
	mds->mds_timer = &timer;

	/* Record that the  thread is running */
	mds->mds_thread = current;
	wake_up(&mds->mds_done_waitq); 

	printk(KERN_INFO "lustre_mds starting.  Commit interval %ld seconds\n",
			mds->mds_interval / HZ);

	/* XXX maintain a list of all managed devices: insert here */

	/* And now, wait forever for commit wakeup events. */
	while (1) {
		if (mds->mds_flags & MDS_UNMOUNT)
			break;


		wake_up(&mds->mds_done_waitq);
		interruptible_sleep_on(&mds->mds_waitq);

		CDEBUG(D_INODE, "lustre_mds wakes\n");
		CDEBUG(D_INODE, "pick up req here and continue\n"); 

		if (list_empty(&mds->mds_reqs)) { 
			CDEBUG(D_INODE, "woke because of timer\n"); 
		}
	}

	del_timer_sync(mds->mds_timer);

	/* XXX maintain a list of all managed devices: cleanup here */

	mds->mds_thread = NULL;
	wake_up(&mds->mds_done_waitq);
	printk("lustre_mds: exiting\n");
	return 0;
}

static void mds_stop_srv_thread(struct mds_obd *mds)
{
	mds->mds_flags |= MDS_UNMOUNT;

	while (mds->mds_thread) {
		wake_up(&mds->mds_waitq);
		sleep_on(&mds->mds_done_waitq);
	}
}

static void mds_start_srv_thread(struct mds_obd *mds)
{
	init_waitqueue_head(&mds->mds_waitq);
	init_waitqueue_head(&mds->mds_done_waitq);
	kernel_thread(mds_main, (void *)mds, 
		      CLONE_VM | CLONE_FS | CLONE_FILES);
	while (!mds->mds_thread) 
		sleep_on(&mds->mds_done_waitq);
}

/* mount the file system (secretly) */
static int mds_setup(struct obd_device *obddev, obd_count len,
			void *buf)
			
{
	struct obd_ioctl_data* data = buf;
	struct mds_obd *mds = &obddev->u.mds;
	struct vfsmount *mnt;
	int err; 
        ENTRY;
	
	mnt = do_kern_mount(data->ioc_inlbuf2, 0, 
			    data->ioc_inlbuf1, NULL); 
	err = PTR_ERR(mnt);
	if (IS_ERR(mnt)) { 
		EXIT;
		return err;
	}

	mds->mds_sb = mnt->mnt_root->d_inode->i_sb;
  	if (!obddev->u.mds.mds_sb) {
  		EXIT;
  		return -ENODEV;
  	}

	INIT_LIST_HEAD(&mds->mds_reqs);
	mds->mds_thread = NULL;
	mds->mds_flags = 0;
	mds->mds_interval = 3 * HZ;
	mds->mds_vfsmnt = mnt;
	obddev->u.mds.mds_fstype = strdup(data->ioc_inlbuf2);

	mds->mds_ctxt.pwdmnt = mnt;
	mds->mds_ctxt.pwd = mnt->mnt_root;
	mds->mds_ctxt.fs = KERNEL_DS;

	spin_lock_init(&obddev->u.mds.fo_lock);

	mds_start_srv_thread(mds);

        MOD_INC_USE_COUNT;
        EXIT; 
        return 0;
} 

static int mds_cleanup(struct obd_device * obddev)
{
        struct super_block *sb;
	struct mds_obd *mds = &obddev->u.mds;

        ENTRY;

        if ( !(obddev->obd_flags & OBD_SET_UP) ) {
                EXIT;
                return 0;
        }

        if ( !list_empty(&obddev->obd_gen_clients) ) {
                printk(KERN_WARNING __FUNCTION__ ": still has clients!\n");
                EXIT;
                return -EBUSY;
        }

	mds_stop_srv_thread(mds);
        sb = mds->mds_sb;
        if (!mds->mds_sb){
                EXIT;
                return 0;
        }

	if (!list_empty(&mds->mds_reqs)) {
		// XXX reply with errors and clean up
		CDEBUG(D_INODE, "Request list not empty!\n");
	}

	unlock_kernel();
	mntput(mds->mds_vfsmnt); 
        mds->mds_sb = 0;
	kfree(mds->mds_fstype);
	lock_kernel();
	

        MOD_DEC_USE_COUNT;
        EXIT;
        return 0;
}

/* use obd ops to offer management infrastructure */
static struct obd_ops mds_obd_ops = {
        o_setup:       mds_setup,
        o_cleanup:     mds_cleanup,
};

static int __init mds_init(void)
{
        printk(KERN_INFO "Lustre MDS v0.01, braam@clusterfs.com\n");
        obd_register_type(&mds_obd_ops, LUSTRE_MDS_NAME);
}

static void __exit mds_exit(void)
{
	obd_unregister_type(LUSTRE_MDS_NAME);
}

MODULE_AUTHOR("Peter J. Braam <braam@clusterfs.com>");
MODULE_DESCRIPTION("Lustre Metadata server module");
MODULE_LICENSE("GPL");

module_init(mds_init);
module_exit(mds_exit);


_______________________________________________
Lustre-cvs mailing list
Lustre-cvs@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/lustre-cvs
[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic