# 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"
--- /dev/null
+/* -*- 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
--- /dev/null
+#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 */
--- /dev/null
+#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
+
+
#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 ===========
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;
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
#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);
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 */
--- /dev/null
+/* -*- 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;
+}
--- /dev/null
+# 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
+
--- /dev/null
+/*
+ * 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(¤t->sigmask_lock);
+ sigfillset(¤t->blocked);
+ recalc_sigpending(current);
+ spin_unlock_irq(¤t->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);
--- /dev/null
+/*
+ * 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);
+
+}
#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;
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
#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>
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;
#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 *);
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 */
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);