#include <linux/types.h>
#include <linux/fs.h>
#include <linux/time.h>
-#include <linux/obd.h>
-#include <linux/obd_ext2.h>
-#include <linux/obd_filter.h>
-#include <linux/obd_snap.h>
-#include <linux/obd_trace.h>
-/* #include <linux/obd_fc.h> */
-#include <linux/obd_raid1.h>
-#include <linux/obd_rpc.h>
+#include <linux/lustre_lib.h>
+#include <linux/lustre_idl.h>
+#include <linux/obd.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_FLUID (0x00000100UL)
-#define OBD_MD_FLGID (0x00000200UL)
-#define OBD_MD_FLFLAGS (0x00000400UL)
-#define OBD_MD_FLOBDFLG (0x00000800UL)
-#define OBD_MD_FLNLINK (0x00001000UL)
-#define OBD_MD_FLGENER (0x00002000UL)
-#define OBD_MD_FLINLINE (0x00004000UL)
-#define OBD_MD_FLOBDMD (0x00008000UL)
-#define OBD_MD_FLNOTOBD (~(OBD_MD_FLOBDMD | OBD_MD_FLOBDFLG | OBD_MD_FLBLOCKS))
-
/*
* ======== OBD Device Declarations ===========
*/
-
-
-#define OBD_PSDEV_MAJOR 186
#define MAX_OBD_DEVICES 8
#define MAX_MULTI 16
-
-
extern struct obd_device obd_dev[MAX_OBD_DEVICES];
-
#define OBD_ATTACHED 0x1
#define OBD_SET_UP 0x2
__u8 _uuid[16]; /* uuid obd device names */
} obd_devicename;
+#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> */
+#include <linux/obd_raid1.h>
+#include <linux/obd_ost.h>
#ifdef __KERNEL__
/* corresponds to one of the obdx */
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;
- /* struct fc_obd fc; */
+ struct ost_obd ost;
+ struct osc_obd osc;
} u;
};
obd_size count, obd_off offset);
int (*o_iterate)(struct obd_conn *conn, int (*)(obd_id, obd_gr, void *),
obd_id *startid, obd_gr group, void *data);
+ int (*o_dmaread)(struct obd_conn *conn, int count, struct obd_buf **dest,
+ struct obd_bufref **source);
+ int (*o_pre_dmawrite)(struct obd_conn *conn, int count, struct obd_buf **dstbufs,
+ struct obd_bufref **dest);
+ int (*o_dmawrite)(struct obd_conn *conn, int count, struct obd_buf **dstbufs,
+ struct obd_buf **dest);
};
+struct obd_request {
+ struct obdo *oa;
+ struct obd_conn *conn;
+ __u32 plen1;
+ char *pbuf1;
+};
+
+static inline int obd_check_conn(struct obd_conn *conn)
+{
+ struct obd_device *obd;
+ if (!conn) {
+ printk("obd_check_conn: NULL conn\n");
+ return -ENOTCONN;
+ }
+ obd = conn->oc_dev;
+ if (!obd) {
+ printk("obd_check_conn: NULL obd\n");
+ return -ENODEV;
+ }
+
+ if (!obd->obd_flags & OBD_ATTACHED ) {
+ printk("obd_check_conn: obd %d not attached\n", obd->obd_minor);
+ return -ENODEV;
+ }
+
+ if (!obd->obd_flags & OBD_SET_UP) {
+ printk("obd_check_conn: obd %d not setup\n", obd->obd_minor);
+ return -ENODEV;
+ }
+
+ if (!obd->obd_type) {
+ printk("obd_check_conn: obd %d not typed\n", obd->obd_minor);
+ return -ENODEV;
+ }
+
+ if (!obd->obd_type->typ_ops) {
+ printk("obd_check_conn: obd %d no operations\n", obd->obd_minor);
+ return -EOPNOTSUPP;
+ }
+ return 0;
+}
+
#define OBT(dev) dev->obd_type->typ_ops
#define OBP(dev,op) dev->obd_type->typ_ops->o_ ## op
+#define OBD_CHECK_OP(conn,op) do { \
+ int rc = obd_check_conn(conn);\
+ if (rc) { printk("obd: error in operation: " #op "\n"); return rc; }\
+ if (!OBP(conn->oc_dev,op)) { printk("obd_" #op ": dev %d no operation\n", conn->oc_dev->obd_minor); \
+ return -EOPNOTSUPP;\
+ }\
+} while (0)
+
+static inline int obd_get_info(struct obd_conn *conn, obd_count keylen, void *key,
+ obd_count *vallen, void **val)
+{
+ int rc;
+ OBD_CHECK_OP(conn,get_info);
+
+ rc = OBP(conn->oc_dev, get_info)(conn, keylen, key, vallen, val);
+ EXIT;
+ return rc;
+}
+
+static inline int obd_set_info(struct obd_conn *conn, obd_count keylen, void *key,
+ obd_count vallen, void *val)
+{
+ int rc;
+ OBD_CHECK_OP(conn,set_info);
+
+ rc = OBP(conn->oc_dev, set_info)(conn, keylen, key, vallen, val);
+ EXIT;
+ return rc;
+}
+
+static inline int obd_cleanup(struct obd_device *obd)
+{
+ struct obd_conn conn;
+ int rc;
+ conn.oc_dev = obd;
+
+ OBD_CHECK_OP((&conn),cleanup);
+
+ rc = OBP(conn.oc_dev, cleanup)(obd);
+ EXIT;
+ return rc;
+}
+
+static inline int obd_create(struct obd_conn *conn, struct obdo *obdo)
+{
+ int rc;
+ OBD_CHECK_OP(conn,create);
+
+ rc = OBP(conn->oc_dev, create)(conn, obdo);
+ EXIT;
+ return rc;
+}
+
+static inline int obd_destroy(struct obd_conn *conn, struct obdo *obdo)
+{
+ int rc;
+ OBD_CHECK_OP(conn,destroy);
+
+ rc = OBP(conn->oc_dev, destroy)(conn, obdo);
+ EXIT;
+ return rc;
+}
+
+static inline int obd_getattr(struct obd_conn *conn, struct obdo *obdo)
+{
+ int rc;
+ OBD_CHECK_OP(conn,getattr);
+
+ rc = OBP(conn->oc_dev, getattr)(conn, obdo);
+ EXIT;
+ return rc;
+}
+
+static inline int obd_setattr(struct obd_conn *conn, struct obdo *obdo)
+{
+ int rc;
+ OBD_CHECK_OP(conn,setattr);
+
+ rc = OBP(conn->oc_dev, setattr)(conn, obdo);
+ EXIT;
+ return rc;
+}
+
+static inline int obd_connect(struct obd_conn *conn)
+{
+ int rc;
+ OBD_CHECK_OP(conn,connect);
+
+ rc = OBP(conn->oc_dev, connect)(conn);
+ EXIT;
+ return rc;
+}
+
+static inline int obd_disconnect(struct obd_conn *conn)
+{
+ int rc;
+ OBD_CHECK_OP(conn,disconnect);
+
+ rc = OBP(conn->oc_dev, disconnect)(conn);
+ EXIT;
+ return rc;
+}
+
+static inline int obd_statfs(struct obd_conn *conn, struct statfs *buf)
+{
+ int rc;
+ OBD_CHECK_OP(conn,statfs);
+
+ rc = OBP(conn->oc_dev, statfs)(conn, buf);
+ EXIT;
+ return rc;
+}
+
+static inline int obd_punch(struct obd_conn *conn, struct obdo *tgt, obd_size count, obd_off offset)
+{
+ int rc;
+ OBD_CHECK_OP(conn,punch);
+
+ rc = OBP(conn->oc_dev, punch)(conn, tgt, count, offset);
+ EXIT;
+ return rc;
+}
+
+static inline int obd_brw(int rw, struct obd_conn *conn, obd_count num_oa,
+ struct obdo **oa, obd_count *oa_bufs, struct page **buf,
+ obd_size *count, obd_off *offset, obd_flag *flags)
+{
+ int rc;
+ OBD_CHECK_OP(conn,brw);
+
+ rc = OBP(conn->oc_dev, brw)(rw, conn, num_oa, oa, oa_bufs, buf,
+ count, offset, flags);
+ EXIT;
+ return rc;
+}
+
+
#endif
/* This value is not arbitrarily chosen. KIO_STATIC_PAGES from linux/iobuf.h */
kmem_cache_free(obdo_cachep, oa);
}
-
-
static __inline__ struct obdo *obdo_fromid(struct obd_conn *conn, obd_id id,
- obd_flag valid)
+ obd_mode mode, obd_flag valid)
{
struct obdo *oa;
int err;
}
oa->o_id = id;
+ oa->o_mode = mode;
oa->o_valid = valid;
if ((err = OBP(conn->oc_dev, getattr)(conn, oa))) {
obdo_free(oa);
static inline void iattr_from_obdo(struct iattr *attr, struct obdo *oa)
{
unsigned int ia_valid = oa->o_valid;
-
+
+ memset(attr, 0, sizeof(*attr));
if (ia_valid & OBD_MD_FLATIME) {
attr->ia_atime = oa->o_atime;
attr->ia_valid |= ATTR_ATIME;
#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);