Whamcloud - gitweb
A solid part of the MDS request processing infrastructure.
authorbraam <braam>
Fri, 28 Dec 2001 04:41:15 +0000 (04:41 +0000)
committerbraam <braam>
Fri, 28 Dec 2001 04:41:15 +0000 (04:41 +0000)
  - 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.

14 files changed:
lustre/demos/config.sh
lustre/include/linux/lustre_idl.h [new file with mode: 0644]
lustre/include/linux/lustre_lib.h [new file with mode: 0644]
lustre/include/linux/lustre_mds.h [new file with mode: 0644]
lustre/include/linux/obd_class.h
lustre/include/linux/obdfs.h
lustre/lib/mds_pack.c [new file with mode: 0644]
lustre/mds/Makefile.am [new file with mode: 0644]
lustre/mds/handler.c [new file with mode: 0644]
lustre/obdclass/pack.c [new file with mode: 0644]
lustre/obdfs/super.c
lustre/utils/Makefile.am
lustre/utils/obdctl.c
lustre/utils/parser.c

index 3fdd5ba..4d19a29 100644 (file)
@@ -25,8 +25,8 @@ OBDMAJ=186
 
 # If LOOPDEV is empty, then it is assumed that BASEDEV is a real block device
 # that doesn't mind being overwritten - don't use a partition with data on it!!
-LOOPDEV=""
-BASEDEV="/dev/hda6"
+LOOPDEV="/dev/loop0"
+BASEDEV="/dev/loop0"
 
 # The following are mount points for the filesystems during the test.
 MNTOBD="/mnt/obd"
diff --git a/lustre/include/linux/lustre_idl.h b/lustre/include/linux/lustre_idl.h
new file mode 100644 (file)
index 0000000..201939b
--- /dev/null
@@ -0,0 +1,379 @@
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
+ *
+ * Copyright (C) 2001 Cluster File Systems, Inc.
+ */
+
+#ifndef __LUSTRE_IDL_H__
+#define __LUSTRE_IDL_H__
+#ifdef __KERNEL__
+#include <linux/ioctl.h>
+#include <asm/types.h>
+
+#include <linux/types.h>
+#else 
+#define __KERNEL__
+#include <linux/list.h>
+#undef __KERNEL__
+#include <stdint.h>
+#endif
+/* 
+ * this file contains all data structures used in Lustre interfaces:
+ * - obdo and obd_request records
+ * - mds_request records
+ * - ioctl's
+ */ 
+
+/* 
+ *   OBDO & OBD request records
+ */
+
+typedef uint64_t        obd_id;
+typedef uint64_t        obd_gr;
+typedef uint64_t        obd_time;
+typedef uint64_t        obd_size;
+typedef uint64_t        obd_off;
+typedef uint64_t        obd_blocks;
+typedef uint32_t        obd_blksize;
+typedef uint32_t        obd_mode;
+typedef uint32_t        obd_uid;
+typedef uint32_t        obd_gid;
+typedef uint32_t        obd_rdev;
+typedef uint32_t        obd_flag;
+typedef uint32_t        obd_count;
+
+#define OBD_FL_INLINEDATA       (0x00000001UL)  
+#define OBD_FL_OBDMDEXISTS      (0x00000002UL)
+
+#define OBD_INLINESZ    60
+#define OBD_OBDMDSZ     60
+/* Note: 64-bit types are 64-bit aligned in structure */
+struct obdo {
+        obd_id                  o_id;
+        obd_gr                  o_gr;
+        obd_time                o_atime;
+        obd_time                o_mtime;
+        obd_time                o_ctime;
+        obd_size                o_size;
+        obd_blocks              o_blocks;
+        obd_blksize             o_blksize;
+        obd_mode                o_mode;
+        obd_uid                 o_uid;
+        obd_gid                 o_gid;
+        obd_flag                o_flags;
+        obd_flag                o_obdflags;
+        obd_count               o_nlink;
+        obd_count               o_generation;
+        obd_flag                o_valid;        /* hot fields in this obdo */
+        char                    o_inline[OBD_INLINESZ];
+        char                    o_obdmd[OBD_OBDMDSZ];
+        struct list_head        o_list;
+        struct obd_ops          *o_op;
+};
+
+#define OBD_MD_FLALL    (~0UL)
+#define OBD_MD_FLID     (0x00000001UL)
+#define OBD_MD_FLATIME  (0x00000002UL)
+#define OBD_MD_FLMTIME  (0x00000004UL)
+#define OBD_MD_FLCTIME  (0x00000008UL)
+#define OBD_MD_FLSIZE   (0x00000010UL)
+#define OBD_MD_FLBLOCKS (0x00000020UL)
+#define OBD_MD_FLBLKSZ  (0x00000040UL)
+#define OBD_MD_FLMODE   (0x00000080UL)
+#define OBD_MD_FLTYPE   (0x00000100UL)
+#define OBD_MD_FLUID    (0x00000200UL)
+#define OBD_MD_FLGID    (0x00000400UL)
+#define OBD_MD_FLFLAGS  (0x00000800UL)
+#define OBD_MD_FLOBDFLG (0x00001000UL)
+#define OBD_MD_FLNLINK  (0x00002000UL)
+#define OBD_MD_FLGENER  (0x00004000UL)
+#define OBD_MD_FLINLINE (0x00008000UL)
+#define OBD_MD_FLOBDMD  (0x00010000UL)
+#define OBD_MD_FLNOTOBD (~(OBD_MD_FLOBDMD | OBD_MD_FLOBDFLG | OBD_MD_FLBLOCKS))
+
+
+/* 
+ *   MDS REQ RECORDS
+ */
+
+
+#define MDS_TYPE_REQ 1
+#define MDS_TYPE_REP 2
+#define MDS_TYPE_ERR 3
+
+struct mds_req_hdr { 
+       __u32 opc;
+       __u64 seqno;
+       __u32 status;
+       __u32 type;
+};
+
+struct lustre_fid { 
+       __u64 id;
+       __u32 generation;
+       __u32 f_type;
+};
+
+struct mds_req {
+       struct lustre_fid        fid1;
+       struct lustre_fid        fid2;
+        char                      *name;
+        int                        namelen;
+        char                      *tgt;
+        int                        tgtlen;
+        __u32                       valid;
+        __u32                      mode;
+        __u32                       uid;
+        __u32                       gid;
+        __u64                       size;
+        __u32                       mtime;
+        __u32                       ctime;
+        __u32                       atime;
+        __u32                       flags;
+        __u32                       major;
+        __u32                       minor;
+        __u32                       ino;
+        __u32                       generation;
+};
+
+struct mds_rep_hdr { 
+       __u32 opc;
+       __u64 seqno;
+       __u32 status;
+       __u32 type;
+};
+
+struct mds_rep {
+       struct lustre_fid        fid1;
+       struct lustre_fid        fid2;
+        char                      *name;
+        int                        namelen;
+        char                      *tgt;
+        int                        tgtlen;
+        __u32                       valid;
+        __u32                      mode;
+        __u32                       uid;
+        __u32                       gid;
+        __u64                       size;
+        __u32                       mtime;
+        __u32                       ctime;
+        __u32                       atime;
+        __u32                       flags;
+        __u32                       major;
+        __u32                       minor;
+        __u32                       ino;
+        __u32                       generation;
+};
+
+/* 
+ *   OBD IOCTLS
+ */
+
+
+#define OBD_IOCTL_VERSION 0x00010001
+
+struct obd_ioctl_data { 
+       uint32_t ioc_len;
+       uint32_t ioc_version;
+        uint32_t ioc_conn1;
+        uint32_t ioc_conn2;
+       struct obdo ioc_obdo1;
+       struct obdo ioc_obdo2;
+        obd_size         ioc_count;
+        obd_off          ioc_offset;
+       uint32_t         ioc_dev;
+
+       /* buffers the kernel will treat as user pointers */
+       uint32_t ioc_plen1;
+       char    *ioc_pbuf1;
+       uint32_t ioc_plen2;
+       char    *ioc_pbuf2;
+
+       /* two inline buffers */
+       uint32_t ioc_inllen1;
+       char    *ioc_inlbuf1;
+       uint32_t ioc_inllen2;
+       char    *ioc_inlbuf2;
+
+       char    ioc_bulk[0];
+};
+
+struct obd_ioctl_hdr { 
+       uint32_t ioc_len;
+       uint32_t ioc_version;
+};
+
+static inline int obd_ioctl_packlen(struct obd_ioctl_data *data)
+{
+       int len = sizeof(struct obd_ioctl_data);
+       len += size_round(data->ioc_inllen1);
+       len += size_round(data->ioc_inllen2);
+       return len;
+}
+
+static inline int obd_ioctl_is_invalid(struct obd_ioctl_data *data)
+{
+       if (data->ioc_len > (1<<30)) { 
+               printk("OBD ioctl: ioc_len larger than 1<<30\n");
+               return 1;
+       }
+       if (data->ioc_inllen1 > (1<<30)) { 
+               printk("OBD ioctl: ioc_inllen1 larger than 1<<30\n");
+               return 1;
+       }
+       if (data->ioc_inllen2 > (1<<30)) { 
+               printk("OBD ioctl: ioc_inllen2 larger than 1<<30\n");
+               return 1;
+       }
+       if (data->ioc_inlbuf1 && !data->ioc_inllen1) {
+               printk("OBD ioctl: inlbuf1 pointer but 0 length\n");
+               return 1;
+       }
+       if (data->ioc_inlbuf2 && !data->ioc_inllen2) {
+               printk("OBD ioctl: inlbuf2 pointer but 0 length\n");
+               return 1;
+       }
+       if (data->ioc_pbuf1 && !data->ioc_plen1) {
+               printk("OBD ioctl: pbuf1 pointer but 0 length\n");
+               return 1;
+       }
+       if (data->ioc_pbuf2 && !data->ioc_plen2) {
+               printk("OBD ioctl: pbuf2 pointer but 0 length\n");
+               return 1;
+       }
+       if (obd_ioctl_packlen(data) != data->ioc_len ) {
+               printk("OBD ioctl: packlen exceeds ioc_len\n");
+               return 1;
+       }
+       if (data->ioc_inllen1 && 
+           data->ioc_bulk[data->ioc_inllen1 - 1] != '\0') { 
+               printk("OBD ioctl: inlbuf1 not 0 terminated\n");
+               return 1;
+       }
+       if (data->ioc_inllen2 && 
+           data->ioc_bulk[size_round(data->ioc_inllen1) + data->ioc_inllen2 - 1] != '\0') { 
+               printk("OBD ioctl: inlbuf2 not 0 terminated\n");
+               return 1;
+       }
+       return 0;
+}
+
+#ifndef __KERNEL__
+static inline int obd_ioctl_pack(struct obd_ioctl_data *data, char **pbuf, int max)
+{
+       char *ptr;
+       struct obd_ioctl_data *overlay;
+       data->ioc_len = obd_ioctl_packlen(data);
+       data->ioc_version = OBD_IOCTL_VERSION;
+
+       if (*pbuf && obd_ioctl_packlen(data) > max) 
+               return 1;
+       if (*pbuf == NULL) { 
+               *pbuf = malloc(data->ioc_len);
+       }
+       if (!*pbuf)
+               return 1;
+       overlay = (struct obd_ioctl_data *)*pbuf;
+       memcpy(*pbuf, data, sizeof(*data));
+
+       ptr = overlay->ioc_bulk;
+       if (data->ioc_inlbuf1)
+               LOGL(data->ioc_inlbuf1, data->ioc_inllen1, ptr);
+       if (data->ioc_inlbuf2)
+               LOGL(data->ioc_inlbuf2, data->ioc_inllen2, ptr);
+       if (obd_ioctl_is_invalid(overlay))
+               return 1;
+
+       return 0;
+}
+#else
+
+
+/* buffer MUST be at least the size of obd_ioctl_hdr */
+static inline int obd_ioctl_getdata(char *buf, char *end, void *arg)
+{
+       struct obd_ioctl_hdr *hdr;
+       struct obd_ioctl_data *data;
+       int err;
+       ENTRY;
+
+       hdr = (struct obd_ioctl_hdr *)buf;
+       data = (struct obd_ioctl_data *)buf;
+
+       err = copy_from_user(buf, (void *)arg, sizeof(*hdr));
+       if ( err ) {
+               EXIT;
+               return err;
+       }
+
+       if (hdr->ioc_version != OBD_IOCTL_VERSION) { 
+               printk("OBD: version mismatch kernel vs application\n");
+               return -EINVAL;
+       }
+
+       if (hdr->ioc_len + buf >= end) { 
+               printk("OBD: user buffer exceeds kernel buffer\n");
+               return -EINVAL;
+       }
+
+
+       if (hdr->ioc_len < sizeof(struct obd_ioctl_data)) { 
+               printk("OBD: user buffer too small for ioctl\n");
+               return -EINVAL;
+       }
+
+       err = copy_from_user(buf, (void *)arg, hdr->ioc_len);
+       if ( err ) {
+               EXIT;
+               return err;
+       }
+
+       if (obd_ioctl_is_invalid(data)) { 
+               printk("OBD: ioctl not correctly formatted\n");
+               return -EINVAL;
+       }
+
+       if (data->ioc_inllen1) { 
+               data->ioc_inlbuf1 = &data->ioc_bulk[0];
+       }
+
+       if (data->ioc_inllen2) { 
+               data->ioc_inlbuf2 = &data->ioc_bulk[0] + size_round(data->ioc_inllen1);
+       }
+
+       EXIT;
+       return 0;
+}
+#endif
+
+
+#define OBD_IOC_CREATE                 _IOR ('f',  3, long)
+#define OBD_IOC_SETUP                  _IOW ('f',  4, long)
+#define OBD_IOC_CLEANUP                _IO  ('f',  5      )
+#define OBD_IOC_DESTROY                _IOW ('f',  6, long)
+#define OBD_IOC_PREALLOCATE            _IOWR('f',  7, long)
+#define OBD_IOC_DEC_USE_COUNT          _IO  ('f',  8      )
+#define OBD_IOC_SETATTR                _IOW ('f',  9, long)
+#define OBD_IOC_GETATTR                _IOR ('f', 10, long)
+#define OBD_IOC_READ                   _IOWR('f', 11, long)
+#define OBD_IOC_WRITE                  _IOWR('f', 12, long)
+#define OBD_IOC_CONNECT                _IOR ('f', 13, long)
+#define OBD_IOC_DISCONNECT             _IOW ('f', 14, long)
+#define OBD_IOC_STATFS                 _IOWR('f', 15, long)
+#define OBD_IOC_SYNC                   _IOR ('f', 16, long)
+#define OBD_IOC_READ2                  _IOWR('f', 17, long)
+#define OBD_IOC_FORMAT                 _IOWR('f', 18, long)
+#define OBD_IOC_PARTITION              _IOWR('f', 19, long)
+#define OBD_IOC_ATTACH                 _IOWR('f', 20, long)
+#define OBD_IOC_DETACH                 _IOWR('f', 21, long)
+#define OBD_IOC_COPY                   _IOWR('f', 22, long)
+#define OBD_IOC_MIGR                   _IOWR('f', 23, long)
+#define OBD_IOC_PUNCH                  _IOWR('f', 24, long)
+#define OBD_IOC_DEVICE                 _IOWR('f', 25, long)
+
+#define OBD_IOC_DEC_FS_USE_COUNT       _IO  ('f', 32      )
+
+
+
+
+#endif
diff --git a/lustre/include/linux/lustre_lib.h b/lustre/include/linux/lustre_lib.h
new file mode 100644 (file)
index 0000000..cda3eca
--- /dev/null
@@ -0,0 +1,124 @@
+#ifndef _LUSTRE_LIB_H
+#define _LUSTRE_LIB_H
+
+#include <asm/types.h>
+
+#ifndef __KERNEL__
+# include <string.h>
+#endif
+
+#undef MIN
+#define MIN(a,b) (((a)<(b)) ? (a): (b))
+#undef MAX
+#define MAX(a,b) (((a)>(b)) ? (a): (b))
+#define MKSTR(ptr) ((ptr))? (ptr) : ""
+
+static inline int size_round (int val)
+{
+       return (val + 3) & (~0x3);
+}
+
+static inline size_t round_strlen(char *fset)
+{
+       return size_round(strlen(fset) + 1);
+}
+
+#ifdef __KERNEL__
+static inline char *strdup(char *str)
+{
+       char *tmp = kmalloc(strlen(str) + 1, GFP_KERNEL);
+       if (tmp)
+               memcpy(tmp, str, strlen(str) + 1);
+               
+       return NULL;
+}
+#endif
+
+#ifdef __KERNEL__
+# define NTOH__u32(var) le32_to_cpu(var)
+# define NTOH__u64(var) le64_to_cpu(var)
+# define HTON__u32(var) cpu_to_le32(var)
+# define HTON__u64(var) cpu_to_le64(var)
+#else
+# include <glib.h>
+# define NTOH__u32(var) GUINT32_FROM_LE(var)
+# define NTOH__u64(var) GUINT64_FROM_LE(var)
+# define HTON__u32(var) GUINT32_TO_LE(var)
+# define HTON__u64(var) GUINT64_TO_LE(var)
+#endif
+
+/* 
+ * copy sizeof(type) bytes from pointer to var and move ptr forward.
+ * return EFAULT if pointer goes beyond end
+ */
+#define UNLOGV(var,type,ptr,end)                \
+do {                                            \
+        var = *(type *)ptr;                     \
+        ptr += sizeof(type);                    \
+        if (ptr > end )                         \
+                return -EFAULT;                 \
+} while (0)
+
+/* the following two macros convert to little endian */
+/* type MUST be __u32 or __u64 */
+#define LUNLOGV(var,type,ptr,end)               \
+do {                                            \
+        var = NTOH##type(*(type *)ptr);         \
+        ptr += sizeof(type);                    \
+        if (ptr > end )                         \
+                return -EFAULT;                 \
+} while (0)
+
+/* now log values */
+#define LOGV(var,type,ptr)                      \
+do {                                            \
+        *((type *)ptr) = var;                   \
+        ptr += sizeof(type);                    \
+} while (0)
+
+/* and in network order */
+#define LLOGV(var,type,ptr)                     \
+do {                                            \
+        *((type *)ptr) = HTON##type(var);       \
+        ptr += sizeof(type);                    \
+} while (0)
+
+
+/* 
+ * set var to point at (type *)ptr, move ptr forward with sizeof(type)
+ * return from function with EFAULT if ptr goes beyond end
+ */
+#define UNLOGP(var,type,ptr,end)                \
+do {                                            \
+        var = (type *)ptr;                      \
+        ptr += sizeof(type);                    \
+        if (ptr > end )                         \
+                return -EFAULT;                 \
+} while (0)
+
+#define LOGP(var,type,ptr)                      \
+do {                                            \
+        memcpy(ptr, var, sizeof(type));         \
+        ptr += sizeof(type);                    \
+} while (0)
+
+/* 
+ * set var to point at (char *)ptr, move ptr forward by size_round(len);
+ * return from function with EFAULT if ptr goes beyond end
+ */
+#define UNLOGL(var,type,len,ptr,end)            \
+do {                                            \
+        var = (type *)ptr;                      \
+        ptr += size_round(len * sizeof(type));  \
+        if (ptr > end )                         \
+                return -EFAULT;                 \
+} while (0)
+
+
+#define LOGL(var,len,ptr)                               \
+do {                                                    \
+        memcpy((char *)ptr, (const char *)var, len);    \
+        ptr += size_round(len);                         \
+} while (0)
+
+#endif /* _LUSTRE_LIB_H */
diff --git a/lustre/include/linux/lustre_mds.h b/lustre/include/linux/lustre_mds.h
new file mode 100644 (file)
index 0000000..3465630
--- /dev/null
@@ -0,0 +1,75 @@
+#ifndef _LUSTRE_MDS_H
+#define _LUSTRE_MDS_H
+
+#include <linux/obd_support.h>
+
+
+struct mds_run_ctxt { 
+       struct vfsmount *pwdmnt;
+       struct dentry   *pwd;
+       mm_segment_t     fs;
+};
+
+#define MDS_UNMOUNT 1
+#define LUSTRE_MDS_NAME "mds"
+
+struct mds_obd {
+       char *mds_fstype;
+       struct task_struct *mds_thread;
+       wait_queue_head_t mds_waitq;
+       wait_queue_head_t mds_done_waitq;
+       struct timer_list *mds_timer;
+       int mds_interval; 
+       int mds_flags;
+       struct list_head mds_reqs;
+        struct super_block * mds_sb;
+       struct vfsmount *mds_vfsmnt;
+       struct mds_run_ctxt  mds_ctxt;
+       spinlock_t mds_lock;
+       __u64 mds_lastino;
+       struct file_operations *mds_fop; 
+       struct inode_operations *mds_iop;
+       struct address_space_operations *mds_aops;
+};
+
+#define MDS_GETATTR   1
+#define MDS_SETATTR  2
+#define MDS_OPEN     3
+#define MDS_CREATE   4
+#define MDS_LINK     5
+#define MDS_SYMLINK  6
+#define MDS_MKNOD    7
+#define MDS_MKDIR    8
+#define MDS_UNLINK   9
+#define MDS_RMDIR   10
+#define MDS_RENAME  11
+
+struct mds_request { 
+       struct list_head *rq_list;
+       struct mds_obd *rq_obd;
+       int rq_status;
+
+       char *rq_reqbuf;
+       int rq_reqlen;
+       struct mds_req_hdr *rq_reqhdr;
+       struct mds_req *rq_req;
+
+       char *rq_repbuf;
+       int rq_replen;
+       struct mds_rep_hdr *rq_rephdr;
+       struct mds_rep *rq_rep;
+
+       wait_queue_head_t rq_wait_for_mds_rep;
+};
+
+
+/* mds/mds_pack.c */
+int mds_pack_req(char *name, int namelen, char *tgt, int tgtlen, struct mds_req_hdr **hdr, struct mds_req **req, int *len, char **buf);
+int mds_unpack_req(char *buf, int len, struct mds_req_hdr **hdr, struct mds_req **req);
+int mds_pack_rep(char *name, int namelen, char *tgt, int tgtlen, struct mds_rep_hdr **hdr, struct mds_rep **rep, int *len, char **buf);
+int mds_unpack_rep(char *buf, int len, struct mds_rep_hdr **hdr, struct mds_rep **rep);
+
+
+#endif
+
+
index 706996a..8a34b09 100644 (file)
 #include <linux/types.h>
 #include <linux/fs.h>
 #include <linux/time.h>
+
+#include <linux/lustre_lib.h>
+#include <linux/lustre_idl.h>
 #include <linux/obd.h>
 
 #include <linux/obd_ext2.h>
 #include <linux/obd_filter.h>
+#include <linux/lustre_mds.h>
 #include <linux/obd_snap.h>
 #include <linux/obd_trace.h>
 /* #include <linux/obd_fc.h> */
 #endif
 
 
-/*
- *  ======== OBD type Declarations ===========
- */
-#define MIN(a,b) (((a)<(b)) ? (a): (b))
-#define MAX(a,b) (((a)>(b)) ? (a): (b))
-#define MKSTR(ptr) ((ptr))? (ptr) : ""
 
-static inline int size_round(int val)
-{
-       return (val + 3) & (~0x3);
-}
 
-static inline size_t round_strlen(char *str)
-{
-       return size_round(strlen(str) + 1);
-}
 
-#ifdef __KERNEL__
-static inline char *strdup(char *str)
-{
-       char *tmp = kmalloc(strlen(str) + 1, GFP_KERNEL);
-       if (tmp)
-               memcpy(tmp, str, strlen(str) + 1);
-               
-       return NULL;
-}
-#endif
-/* 
- * copy sizeof(type) bytes from pointer to var and move ptr forward.
- * return EFAULT if pointer goes beyond end
- */
-#define UNLOGV(var,type,ptr,end) do {var = *(type *)ptr; ptr += sizeof(type); if (ptr > end ) return -EFAULT;} while (0)
-
-
-/* the following two macros convert to little endian */
-/* type must be 32 or 64 */
-#define LUNLOGV(var,type,ptr,end)                \
-do {                                            \
-        var = le_to_cpu##type(*(type *)ptr);         \
-        ptr += sizeof(type);                    \
-        if (ptr > end )                         \
-                return -EFAULT;                 \
-} while (0)
-
-/* now log values */
-#define LOGV(var,type,ptr)                      \
-do {                                            \
-        *((type *)ptr) = var;                   \
-        ptr += sizeof(type);                    \
-} while (0)
-
-/* and in network order */
-#define LLOGV(var,type,ptr)                     \
-do {                                            \
-        *((type *)ptr) = cpu_to_le##type(var);  \
-        ptr += sizeof(type);                    \
-} while (0)
-
-/* 
- * set var to point at (type *)ptr, move ptr forward with sizeof(type)
- * return from function with EFAULT if ptr goes beyond end
- */
-#define UNLOGP(var,type,ptr,end) do {var = (type *)ptr; ptr += sizeof(type); if (ptr > end ) return -EFAULT; } while (0)
-
-/* 
- * set var to point at (char *)ptr, move ptr forward by size_round(len);
- * return from function with EFAULT if ptr goes beyond end
- */
-#define UNLOGL(var,type,len,ptr,end) do {var = (type *)ptr; ptr += size_round(len * sizeof(type)); if (ptr > end ) return -EFAULT; } while (0)
-
-
-#define LOGL(var,len,ptr) do {memcpy((char *)ptr, (const char *)var, len); ptr += size_round(len);} while (0)
-
-typedef uint64_t        obd_id;
-typedef uint64_t        obd_gr;
-typedef uint64_t        obd_time;
-typedef uint64_t        obd_size;
-typedef uint64_t        obd_off;
-typedef uint64_t        obd_blocks;
-typedef uint32_t        obd_blksize;
-typedef uint32_t        obd_mode;
-typedef uint32_t        obd_uid;
-typedef uint32_t        obd_gid;
-typedef uint32_t        obd_rdev;
-typedef uint32_t        obd_flag;
-typedef uint32_t        obd_count;
-
-
-
-#define OBD_FL_INLINEDATA       (0x00000001UL)  
-#define OBD_FL_OBDMDEXISTS      (0x00000002UL)
-
-#define OBD_INLINESZ    60
-#define OBD_OBDMDSZ     60
-/* Note: 64-bit types are 64-bit aligned in structure */
-struct obdo {
-        obd_id                  o_id;
-        obd_gr                  o_gr;
-        obd_time                o_atime;
-        obd_time                o_mtime;
-        obd_time                o_ctime;
-        obd_size                o_size;
-        obd_blocks              o_blocks;
-        obd_blksize             o_blksize;
-        obd_mode                o_mode;
-        obd_uid                 o_uid;
-        obd_gid                 o_gid;
-        obd_flag                o_flags;
-        obd_flag                o_obdflags;
-        obd_count               o_nlink;
-        obd_count               o_generation;
-        obd_flag                o_valid;        /* hot fields in this obdo */
-        char                    o_inline[OBD_INLINESZ];
-        char                    o_obdmd[OBD_OBDMDSZ];
-        struct list_head        o_list;
-        struct obd_ops          *o_op;
-};
-
-
-struct obd_ioctl_data { 
-       uint32_t ioc_len;
-       uint32_t ioc_version;
-        uint32_t ioc_conn1;
-        uint32_t ioc_conn2;
-       struct obdo ioc_obdo1;
-       struct obdo ioc_obdo2;
-        obd_size         ioc_count;
-        obd_off          ioc_offset;
-       uint32_t         ioc_dev;
-
-       /* buffers the kernel will treat as user pointers */
-       uint32_t ioc_plen1;
-       char    *ioc_pbuf1;
-       uint32_t ioc_plen2;
-       char    *ioc_pbuf2;
-
-       /* two inline buffers */
-       uint32_t ioc_inllen1;
-       char    *ioc_inlbuf1;
-       uint32_t ioc_inllen2;
-       char    *ioc_inlbuf2;
-
-       char    ioc_bulk[0];
-};
-
-#define OBD_MD_FLALL    (~0UL)
-#define OBD_MD_FLID     (0x00000001UL)
-#define OBD_MD_FLATIME  (0x00000002UL)
-#define OBD_MD_FLMTIME  (0x00000004UL)
-#define OBD_MD_FLCTIME  (0x00000008UL)
-#define OBD_MD_FLSIZE   (0x00000010UL)
-#define OBD_MD_FLBLOCKS (0x00000020UL)
-#define OBD_MD_FLBLKSZ  (0x00000040UL)
-#define OBD_MD_FLMODE   (0x00000080UL)
-#define OBD_MD_FLTYPE   (0x00000100UL)
-#define OBD_MD_FLUID    (0x00000200UL)
-#define OBD_MD_FLGID    (0x00000400UL)
-#define OBD_MD_FLFLAGS  (0x00000800UL)
-#define OBD_MD_FLOBDFLG (0x00001000UL)
-#define OBD_MD_FLNLINK  (0x00002000UL)
-#define OBD_MD_FLGENER  (0x00004000UL)
-#define OBD_MD_FLINLINE (0x00008000UL)
-#define OBD_MD_FLOBDMD  (0x00010000UL)
-#define OBD_MD_FLNOTOBD (~(OBD_MD_FLOBDMD | OBD_MD_FLOBDFLG | OBD_MD_FLBLOCKS))
 
 /*
  *  ======== OBD Device Declarations ===========
@@ -241,6 +84,7 @@ struct obd_device {
         union {
                 struct ext2_obd ext2;
                 struct filter_obd filter;
+                struct mds_obd mds;
                 struct raid1_obd raid1;
                 struct snap_obd snap;
                struct trace_obd trace;
@@ -300,6 +144,16 @@ struct obd_ops {
                          obd_id *startid, obd_gr group, void *data);
 };
 
+struct obd_request {
+       struct obdo *oa;
+       struct obd_conn *conn;
+       __u32 plen1;
+       char *pbuf1;
+};
+
+
+
+
 #define OBT(dev)        dev->obd_type->typ_ops
 #define OBP(dev,op)     dev->obd_type->typ_ops->o_ ## op
 
@@ -642,188 +496,6 @@ int gen_copy_data(struct obd_conn *dst_conn, struct obdo *dst,
 
 #endif
 
-/*
- *  ======== OBD IOCL Declarations ===========
- */
-
-#define OBD_IOCTL_VERSION 0x00010001
-
-struct obd_ioctl_hdr { 
-       uint32_t ioc_len;
-       uint32_t ioc_version;
-};
-
-static inline int obd_ioctl_packlen(struct obd_ioctl_data *data)
-{
-       int len = sizeof(struct obd_ioctl_data);
-       len += size_round(data->ioc_inllen1);
-       len += size_round(data->ioc_inllen2);
-       return len;
-}
-
-static inline int obd_ioctl_is_invalid(struct obd_ioctl_data *data)
-{
-       if (data->ioc_len > (1<<30)) { 
-               printk("OBD ioctl: ioc_len larger than 1<<30\n");
-               return 1;
-       }
-       if (data->ioc_inllen1 > (1<<30)) { 
-               printk("OBD ioctl: ioc_inllen1 larger than 1<<30\n");
-               return 1;
-       }
-       if (data->ioc_inllen2 > (1<<30)) { 
-               printk("OBD ioctl: ioc_inllen2 larger than 1<<30\n");
-               return 1;
-       }
-       if (data->ioc_inlbuf1 && !data->ioc_inllen1) {
-               printk("OBD ioctl: inlbuf1 pointer but 0 length\n");
-               return 1;
-       }
-       if (data->ioc_inlbuf2 && !data->ioc_inllen2) {
-               printk("OBD ioctl: inlbuf2 pointer but 0 length\n");
-               return 1;
-       }
-       if (data->ioc_pbuf1 && !data->ioc_plen1) {
-               printk("OBD ioctl: pbuf1 pointer but 0 length\n");
-               return 1;
-       }
-       if (data->ioc_pbuf2 && !data->ioc_plen2) {
-               printk("OBD ioctl: pbuf2 pointer but 0 length\n");
-               return 1;
-       }
-       if (obd_ioctl_packlen(data) != data->ioc_len ) {
-               printk("OBD ioctl: packlen exceeds ioc_len\n");
-               return 1;
-       }
-       if (data->ioc_inllen1 && 
-           data->ioc_bulk[data->ioc_inllen1 - 1] != '\0') { 
-               printk("OBD ioctl: inlbuf1 not 0 terminated\n");
-               return 1;
-       }
-       if (data->ioc_inllen2 && 
-           data->ioc_bulk[size_round(data->ioc_inllen1) + data->ioc_inllen2 - 1] != '\0') { 
-               printk("OBD ioctl: inlbuf2 not 0 terminated\n");
-               return 1;
-       }
-       return 0;
-}
-
-#ifndef __KERNEL__
-static inline int obd_ioctl_pack(struct obd_ioctl_data *data, char **pbuf, int max)
-{
-       char *ptr;
-       struct obd_ioctl_data *overlay;
-       data->ioc_len = obd_ioctl_packlen(data);
-       data->ioc_version = OBD_IOCTL_VERSION;
-
-       if (*pbuf && obd_ioctl_packlen(data) > max) 
-               return 1;
-       if (*pbuf == NULL) { 
-               *pbuf = malloc(data->ioc_len);
-       }
-       if (!*pbuf)
-               return 1;
-       overlay = (struct obd_ioctl_data *)*pbuf;
-       memcpy(*pbuf, data, sizeof(*data));
-
-       ptr = overlay->ioc_bulk;
-       if (data->ioc_inlbuf1)
-               LOGL(data->ioc_inlbuf1, data->ioc_inllen1, ptr);
-       if (data->ioc_inlbuf2)
-               LOGL(data->ioc_inlbuf2, data->ioc_inllen2, ptr);
-       if (obd_ioctl_is_invalid(overlay))
-               return 1;
-
-       return 0;
-}
-#else
-
-
-/* buffer MUST be at least the size of obd_ioctl_hdr */
-static inline int obd_ioctl_getdata(char *buf, char *end, void *arg)
-{
-       struct obd_ioctl_hdr *hdr;
-       struct obd_ioctl_data *data;
-       int err;
-       ENTRY;
-
-       hdr = (struct obd_ioctl_hdr *)buf;
-       data = (struct obd_ioctl_data *)buf;
-
-       err = copy_from_user(buf, (void *)arg, sizeof(*hdr));
-       if ( err ) {
-               EXIT;
-               return err;
-       }
-
-       if (hdr->ioc_version != OBD_IOCTL_VERSION) { 
-               printk("OBD: version mismatch kernel vs application\n");
-               return -EINVAL;
-       }
-
-       if (hdr->ioc_len + buf >= end) { 
-               printk("OBD: user buffer exceeds kernel buffer\n");
-               return -EINVAL;
-       }
-
-
-       if (hdr->ioc_len < sizeof(struct obd_ioctl_data)) { 
-               printk("OBD: user buffer too small for ioctl\n");
-               return -EINVAL;
-       }
-
-       err = copy_from_user(buf, (void *)arg, hdr->ioc_len);
-       if ( err ) {
-               EXIT;
-               return err;
-       }
-
-       if (obd_ioctl_is_invalid(data)) { 
-               printk("OBD: ioctl not correctly formatted\n");
-               return -EINVAL;
-       }
-
-       if (data->ioc_inllen1) { 
-               data->ioc_inlbuf1 = &data->ioc_bulk[0];
-       }
-
-       if (data->ioc_inllen2) { 
-               data->ioc_inlbuf2 = &data->ioc_bulk[0] + size_round(data->ioc_inllen1);
-       }
-
-       EXIT;
-       return 0;
-}
-#endif
-
-
-#define OBD_IOC_CREATE                 _IOR ('f',  3, long)
-#define OBD_IOC_SETUP                  _IOW ('f',  4, long)
-#define OBD_IOC_CLEANUP                _IO  ('f',  5      )
-#define OBD_IOC_DESTROY                _IOW ('f',  6, long)
-#define OBD_IOC_PREALLOCATE            _IOWR('f',  7, long)
-#define OBD_IOC_DEC_USE_COUNT          _IO  ('f',  8      )
-#define OBD_IOC_SETATTR                _IOW ('f',  9, long)
-#define OBD_IOC_GETATTR                _IOR ('f', 10, long)
-#define OBD_IOC_READ                   _IOWR('f', 11, long)
-#define OBD_IOC_WRITE                  _IOWR('f', 12, long)
-#define OBD_IOC_CONNECT                _IOR ('f', 13, long)
-#define OBD_IOC_DISCONNECT             _IOW ('f', 14, long)
-#define OBD_IOC_STATFS                 _IOWR('f', 15, long)
-#define OBD_IOC_SYNC                   _IOR ('f', 16, long)
-#define OBD_IOC_READ2                  _IOWR('f', 17, long)
-#define OBD_IOC_FORMAT                 _IOWR('f', 18, long)
-#define OBD_IOC_PARTITION              _IOWR('f', 19, long)
-#define OBD_IOC_ATTACH                 _IOWR('f', 20, long)
-#define OBD_IOC_DETACH                 _IOWR('f', 21, long)
-#define OBD_IOC_COPY                   _IOWR('f', 22, long)
-#define OBD_IOC_MIGR                   _IOWR('f', 23, long)
-#define OBD_IOC_PUNCH                  _IOWR('f', 24, long)
-#define OBD_IOC_DEVICE                 _IOWR('f', 25, long)
-
-#define OBD_IOC_DEC_FS_USE_COUNT       _IO  ('f', 32      )
-
-
 /* sysctl.c */
 extern void obd_sysctl_init (void);
 extern void obd_sysctl_clean (void);
index 4c839ee..57fc191 100644 (file)
@@ -23,7 +23,7 @@ struct obdfs_pgrq {
         struct page             *rq_page;       /* page to be written */
 };
 
-struct list_head obdfs_super_list;       /* list of all OBDFS superblocks */
+extern struct list_head obdfs_super_list;       /* list of all OBDFS superblocks */
 
 
 
diff --git a/lustre/lib/mds_pack.c b/lustre/lib/mds_pack.c
new file mode 100644 (file)
index 0000000..da1c3dd
--- /dev/null
@@ -0,0 +1,191 @@
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
+ *
+ *  Copyright (C) 2001 Cluster File Systems, Inc. <braam@clusterfs.com>
+ *
+ *   This file is part of InterMezzo, http://www.inter-mezzo.org.
+ *
+ *   InterMezzo is free software; you can redistribute it and/or
+ *   modify it under the terms of version 2 of the GNU General Public
+ *   License as published by the Free Software Foundation.
+ *
+ *   InterMezzo is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with InterMezzo; if not, write to the Free Software
+ *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Unpacking of KML records
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/major.h>
+#include <linux/sched.h>
+#include <linux/lp.h>
+#include <linux/slab.h>
+#include <linux/ioport.h>
+#include <linux/fcntl.h>
+#include <linux/delay.h>
+#include <linux/skbuff.h>
+#include <linux/proc_fs.h>
+#include <linux/vmalloc.h>
+#include <linux/fs.h>
+#include <linux/poll.h>
+#include <linux/init.h>
+#include <linux/list.h>
+#include <asm/io.h>
+#include <asm/segment.h>
+#include <asm/system.h>
+#include <asm/poll.h>
+#include <asm/uaccess.h>
+
+#include <linux/obd_support.h>
+#include <linux/lustre_lib.h>
+#include <linux/lustre_idl.h>
+
+
+int mds_pack_req(char *name, int namelen, char *tgt, int tgtlen, 
+                struct mds_req_hdr **hdr, struct mds_req **req, 
+                int *len, char **buf)
+{
+       char *ptr;
+
+       *len = sizeof(**hdr) + size_round(namelen) + sizeround(tgtlen) + 
+               sizeof(**req); 
+
+       *buf = kmalloc(*len, GFP_KERNEL);
+       if (!*buf) {
+               EXIT;
+               return -ENOMEM;
+       }
+
+       memset(*buf, 0, *len); 
+       *hdr = (struct mds_req_hdr *)(*buf);
+       *req = (struct mds_req *)(*buf + sizeof(**hdr));
+       ptr = *buf + sizeof(**hdr) + sizeof(**req);
+
+       (*hdr)->type =  MDS_TYPE_REQ;
+
+       (*req)->namelen = NTOH_u32(namelen);
+       if (name) { 
+               LOGL(name, namelen, ptr); 
+       } 
+
+       (*req)->tgtlen = NTOH_u32(tgtlen);
+       if (tgt) { 
+               LOGL(tgt, tgtlen, ptr);
+       }
+       return 0;
+}
+
+
+int mds_unpack_req(char *buf, int len, 
+                  struct mds_req_hdr **hdr, struct mds_req **req)
+{
+       if (len < sizeof(**hdr) + sizeof(**req)) { 
+               EXIT;
+               return -EINVAL;
+       }
+
+       *hdr = (struct mds_req_hdr *) (buf);
+       *req = (struct mds_req *) (buf + sizeof(**hdr));
+       (*req)->namelen = NTOH_u32((*req)->namelen); 
+       (*req)->tgtlen = NTOH_u32((*req)->namelen); 
+
+       if (len < sizeof(**hdr) + sizeof(**req) + (*req)->namelen + 
+           (*req)->tgtlen ) { 
+               EXIT;
+               return -EINVAL;
+       }
+
+       if ((*req)->namelen) { 
+               (*req)->name = buf + sizeof(**hdr) + sizeof(**req);
+       } else { 
+               (*req)->name = NULL;
+       }
+
+       if ((*req)->tgtlen) { 
+               (*req)->tgt = buf + sizeof(**hdr) + sizeof(**req) + 
+                       sizerount((*req)->namelen);
+       } else { 
+               (*req)->tgt = NULL;
+       }
+
+       EXIT;
+       return 0;
+}
+
+int mds_pack_rep(char *name, int namelen, char *tgt, int tgtlen, 
+                struct mds_rep_hdr **hdr, struct mds_rep **rep, 
+                int *len, char **buf)
+{
+       char *ptr;
+
+       *len = sizeof(**hdr) + size_round(namelen) + sizeround(tgtlen) + 
+               sizeof(**rep); 
+
+       *buf = kmalloc(*len, GFP_KERNEL);
+       if (!*buf) {
+               EXIT;
+               return -ENOMEM;
+       }
+
+       memset(*buf, 0, *len); 
+       *hdr = (struct mds_rep_hdr *)(*buf);
+       *rep = (struct mds_rep *)(*buf + sizeof(**hdr));
+       ptr = *buf + sizeof(**hdr) + sizeof(**rep);
+
+       (*rep)->namelen = NTOH_u32(namelen);
+       if (name) { 
+               LOGL(name, namelen, ptr); 
+       } 
+
+       (*rep)->tgtlen = NTOH_u32(tgtlen);
+       if (tgt) { 
+               LOGL(tgt, tgtlen, ptr);
+       }
+       return 0;
+}
+
+
+int mds_unpack_rep(char *buf, int len, 
+                  struct mds_rep_hdr **hdr, struct mds_rep **rep)
+{
+       if (len < sizeof(**hdr) + sizeof(**rep)) { 
+               EXIT;
+               return -EINVAL;
+       }
+
+       *hdr = (struct mds_rep_hdr *) (buf);
+       *rep = (struct mds_rep *) (buf + sizeof(**hdr));
+       (*rep)->namelen = NTOH_u32((*rep)->namelen); 
+       (*rep)->tgtlen = NTOH_u32((*rep)->namelen); 
+
+       if (len < sizeof(**hdr) + sizeof(**rep) + (*rep)->namelen + 
+           (*rep)->tgtlen ) { 
+               EXIT;
+               return -EINVAL;
+       }
+
+       if ((*rep)->namelen) { 
+               (*rep)->name = buf + sizeof(**hdr) + sizeof(**rep);
+       } else { 
+               (*rep)->name = NULL;
+       }
+
+       if ((*rep)->tgtlen) { 
+               (*rep)->tgt = buf + sizeof(**hdr) + sizeof(**rep) + 
+                       sizerount((*rep)->namelen);
+       } else { 
+               (*rep)->tgt = NULL;
+       }
+
+       EXIT;
+       return 0;
+}
diff --git a/lustre/mds/Makefile.am b/lustre/mds/Makefile.am
new file mode 100644 (file)
index 0000000..4f1864d
--- /dev/null
@@ -0,0 +1,16 @@
+# 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
+
diff --git a/lustre/mds/handler.c b/lustre/mds/handler.c
new file mode 100644 (file)
index 0000000..2380d69
--- /dev/null
@@ -0,0 +1,391 @@
+/*
+ *  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);
diff --git a/lustre/obdclass/pack.c b/lustre/obdclass/pack.c
new file mode 100644 (file)
index 0000000..07ad20a
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ *  pack.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
+ *
+ *  
+ */
+
+
+#include <linux/mm.h>
+#include <linux/pagemap.h>
+#include <linux/fs.h>
+#include <linux/sched.h>
+#include <asm/uaccess.h>
+
+#include <linux/obd_support.h>
+#include <linux/obd_class.h>
+#include <linux/obd_lib.h>
+
+
+void obd_req_pack(char **buf, int max, struct obd_req *req)
+{
+       char *ptr;
+
+       ptr = *buf;
+
+       LOGP(ptr, struct obdo, obd req->oa);
+       LOGP(ptr, struct obd_conn, obd req->obd);
+
+}
index 72926c0..f67764c 100644 (file)
@@ -36,7 +36,7 @@
 #include <linux/obdfs.h>
 
 struct list_head obdfs_super_list;
-struct address_space_operations obdfs_aops;
+extern struct address_space_operations obdfs_aops;
 struct super_operations obdfs_super_operations;
 long obdfs_cache_count = 0;
 long obdfs_mutex_start = 0;
index 90007fc..2e8010b 100644 (file)
@@ -1,10 +1,10 @@
 bin_SCRIPTS = obdcontrol
 EXTRA_DIST = $(bin_SCRIPTS)
 
-CFLAGS:=-g -I. -I../include -Wall
+CFLAGS:=-g -I. -I/usr/include/glib-1.2 -I/usr/lib/glib/include -I../include -Wall
 KFLAGS:=
 CPPFLAGS :=
-LDADD := -lreadline -ltermcap -lefence
+LDADD := -lreadline -ltermcap -lefence
 bin_PROGRAMS = obdctl
 obdctl_SOURCES = parser.c obdctl.c
 
index eebb238..4be1b2e 100644 (file)
@@ -6,7 +6,8 @@
 #include <sys/stat.h>
 #include <stdio.h>
 #define printk printf
-#include <linux/obd_class.h>
+#include <linux/lustre_lib.h>
+#include <linux/lustre_idl.h>
 #include <unistd.h>
 #include <sys/un.h>
 #include <sys/time.h>
@@ -261,19 +262,20 @@ static int jt_setup(int argc, char **argv)
                data.ioc_inlbuf2 = argv[2];
        }
 
-       printf("attach len %d addr %p type %s data %s\n", data.ioc_len, buf, 
+       printf("setup len %d addr %p device %s type %s\n", data.ioc_len, buf, 
               MKSTR(data.ioc_inlbuf1), MKSTR(data.ioc_inlbuf2));
 
        if (obd_ioctl_pack(&data, &buf, max)) { 
                printf("invalid ioctl\n"); 
                return 1;
        }
-       printf("attach len %d addr %p raw %p type %s data %s and %s\n", data.ioc_len, buf, rawbuf,
-              MKSTR(data.ioc_inlbuf1), MKSTR(data.ioc_inlbuf2), &buf[516]);
+       printf("setup len %d addr %p raw %p device %s type %s\n", 
+              data.ioc_len, buf, rawbuf,
+              MKSTR(data.ioc_inlbuf1), MKSTR(data.ioc_inlbuf2));
 
        rc = ioctl(fd, OBD_IOC_SETUP , buf);
        if (rc < 0) {
-               printf("Attach: %x %s\n", OBD_IOC_SETUP, strerror(errno));
+               printf("setup: %x %s\n", OBD_IOC_SETUP, strerror(errno));
                return 1;
        }
        return 0;
index 63eb906..b08697e 100644 (file)
@@ -9,6 +9,7 @@
 #define        READLINE_LIBRARY
 #include <readline/readline.h>
 
+extern char **completion_matches __P((char *, rl_compentry_func_t *));
 extern void using_history(void);
 extern void stifle_history(int);
 extern void add_history(char *);
@@ -219,7 +220,7 @@ static char **command_completion(char * text, int start, int end)
        if (*(pos - 1) == ' ') match_tbl = table->pc_sub_cmd;
     }
 
-    return(rl_completion_matches(text, command_generator));
+    return(completion_matches(text, command_generator));
 }
 
 /* take a string and execute the function or print help */
@@ -272,8 +273,8 @@ void Parser_commands(void)
     stifle_history(HISTORY);
 
     rl_attempted_completion_function = 
-           (rl_completion_func_t *)command_completion;
-    rl_completion_entry_function = (rl_compentry_func_t *)command_generator;
+           (CPPFunction *)command_completion;
+    rl_completion_entry_function = (void *)command_generator;
     
     while(!done) {
        line = readline(parser_prompt);