work in sync.
- This is a fairly pervasive change to get away from "device
numbers".
- Introduce connection handles everywhere (treat these as
lustre_handles).
- On targets map UUID's to handles upon connect and use those handles
in the future.
AUTOMAKE_OPTIONS = foreign
# NOTE: keep extN before mds
-SUBDIRS = ldlm ptlrpc llite lib obdecho mdc osc extN mds ost
-SUBDIRS+= utils tests obdfilter obdclass obdfs demos doc scripts
+SUBDIRS = utils obdclass ldlm ptlrpc llite lib obdecho mdc osc extN mds ost
+SUBDIRS+= tests obdfilter obdfs demos doc scripts
EXTRA_DIST = BUGS FDL Rules include patches
# We get the version from the spec file.
};
int connmgr_connect(struct recovd_obd *mgr, struct ptlrpc_connection *conn);
-int connmgr_handle(struct obd_device *dev, struct ptlrpc_service *svc,
- struct ptlrpc_request *req);
+int connmgr_handle(struct ptlrpc_request *req);
void recovd_cli_fail(struct ptlrpc_client *cli);
void recovd_cli_manage(struct recovd_obd *mgr, struct ptlrpc_client *cli);
void recovd_cli_fixed(struct ptlrpc_client *cli);
struct obd_ioctl_data {
uint32_t ioc_len;
uint32_t ioc_version;
+
+ uint64_t ioc_addr;
+ uint64_t ioc_cookie;
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;
+ uint32_t ____padding;
/* buffers the kernel will treat as user pointers */
uint32_t ioc_plen1;
char *ioc_inlbuf1;
uint32_t ioc_inllen2;
char *ioc_inlbuf2;
+ uint32_t ioc_inllen3;
+ char *ioc_inlbuf3;
char ioc_bulk[0];
};
static inline int obd_ioctl_packlen(struct obd_ioctl_data *data)
{
- int len = sizeof(struct obd_ioctl_data);
+ int len = size_round(sizeof(struct obd_ioctl_data));
len += size_round(data->ioc_inllen1);
len += size_round(data->ioc_inllen2);
+ len += size_round(data->ioc_inllen3);
return len;
}
printk("OBD ioctl: ioc_inllen2 larger than 1<<30\n");
return 1;
}
+
+ if (data->ioc_inllen3 > (1<<30)) {
+ printk("OBD ioctl: ioc_inllen3 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;
printk("OBD ioctl: inlbuf2 pointer but 0 length\n");
return 1;
}
+ if (data->ioc_inlbuf3 && !data->ioc_inllen3) {
+ printk("OBD ioctl: inlbuf3 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;
printk("OBD ioctl: inllen2 set but NULL pointer\n");
return 1;
}
+ if (data->ioc_inllen3 && !data->ioc_inlbuf3) {
+ printk("OBD ioctl: inllen3 set but NULL pointer\n");
+ return 1;
+ }
+ */
if (data->ioc_plen1 && !data->ioc_pbuf1) {
printk("OBD ioctl: plen1 set but NULL pointer\n");
return 1;
printk("OBD ioctl: plen2 set but NULL pointer\n");
return 1;
}
- */
if (obd_ioctl_packlen(data) != data->ioc_len ) {
printk("OBD ioctl: packlen exceeds ioc_len\n");
return 1;
printk("OBD ioctl: inlbuf2 not 0 terminated\n");
return 1;
}
+ if (data->ioc_inllen3 &&
+ data->ioc_bulk[size_round(data->ioc_inllen1) + size_round(data->ioc_inllen2)
+ + data->ioc_inllen3 - 1] != '\0') {
+ printk("OBD ioctl: inlbuf3 not 0 terminated\n");
+ return 1;
+ }
return 0;
}
LOGL(data->ioc_inlbuf1, data->ioc_inllen1, ptr);
if (data->ioc_inlbuf2)
LOGL(data->ioc_inlbuf2, data->ioc_inllen2, ptr);
+ if (data->ioc_inlbuf3)
+ LOGL(data->ioc_inlbuf3, data->ioc_inllen3, ptr);
if (obd_ioctl_is_invalid(overlay))
return 1;
/* buffer MUST be at least the size of obd_ioctl_hdr */
-static inline int obd_ioctl_getdata(char *buf, char *end, void *arg)
+static inline int obd_ioctl_getdata(char *buf, int *len, void *arg)
{
struct obd_ioctl_hdr *hdr;
struct obd_ioctl_data *data;
return -EINVAL;
}
- if (hdr->ioc_len + buf >= end) {
+ if (hdr->ioc_len > *len) {
printk("OBD: user buffer exceeds kernel buffer\n");
return -EINVAL;
}
data->ioc_inlbuf2 = &data->ioc_bulk[0] + size_round(data->ioc_inllen1);
}
+ if (data->ioc_inllen3) {
+ data->ioc_inlbuf3 = &data->ioc_bulk[0] + size_round(data->ioc_inllen1) +
+ size_round(data->ioc_inllen2);
+ }
+
EXIT;
return 0;
}
#define OBD_IOC_BRW_WRITE _IOWR('f', 126, long)
#define OBD_IOC_NAME2DEV _IOWR('f', 127, long)
#define OBD_IOC_NEWDEV _IOWR('f', 128, long)
+#define OBD_IOC_LIST _IOWR('f', 129, long)
+#define OBD_IOC_UUID2DEV _IOWR('f', 130, long)
#define OBD_IOC_RECOVD_NEWCONN _IOWR('f', 131, long)
static inline struct mdc_obd *sbi2mdc(struct ll_sb_info *sbi)
{
- struct obd_device *obd = sbi->ll_mdc_conn.oc_dev;
+ struct obd_device *obd = gen_conn2obd(&sbi->ll_mdc_conn);
return &obd->u.mdc;
}
/* mdc/mdc_request.c */
static inline struct mdc_obd *mdc_conn2mdc(struct obd_conn *conn)
{
- return &conn->oc_dev->u.mdc;
+ return &gen_conn2obd(conn)->u.mdc;
}
int mdc_enqueue(struct obd_conn *conn, int lock_type, struct lookup_intent *it,
struct ptlrpc_connection *rq_connection;
struct ptlrpc_client *rq_client;
+ struct ptlrpc_service *rq_svc;
};
struct ptlrpc_bulk_page {
spinlock_t srv_lock;
struct list_head srv_reqs;
struct list_head srv_threads;
- int (*srv_handler)(struct obd_device *obddev,
- struct ptlrpc_service *svc,
- struct ptlrpc_request *req);
+ int (*srv_handler)(struct ptlrpc_request *req);
};
typedef void (*bulk_callback_t)(struct ptlrpc_bulk_desc *, void *);
-typedef int (*svc_handler_t)(struct obd_device *obddev,
- struct ptlrpc_service *svc,
- struct ptlrpc_request *req);
+typedef int (*svc_handler_t)(struct ptlrpc_request *req);
/* rpc/connection.c */
void ptlrpc_readdress_connection(struct ptlrpc_connection *conn, char *uuid);
#include <linux/lustre_idl.h>
-struct obd_conn_info {
- unsigned int conn_id; /* handle */
-};
-
struct obd_type {
struct list_head typ_chain;
struct obd_ops *typ_ops;
#define OBD_RUN_CTXT_MAGIC 0xC0FFEEAA
#define OBD_CTXT_DEBUG /* development-only debugging */
-
struct obd_run_ctxt {
struct vfsmount *pwdmnt;
struct dentry *pwd;
#endif
};
+
+
struct obd_conn {
+ __u64 addr;
+ __u64 cookie;
struct obd_device *oc_dev;
uint32_t oc_id;
};
-struct obd_devicename {
- uint32_t len;
- char *name;
- struct dentry *dentry; /* file system obd device names */
- __u8 _uuid[16]; /* uuid obd device names */
-};
-
-
/* Individual type definitions */
struct ext2_obd {
int snap_tableno;
};
-struct raid1_obd {
- unsigned int raid1_count; /* how many replicas */
- /* devices to replicate on */
- struct obd_device *raid1_devlist[MAX_RAID1];
- /* connections we make */
- struct obd_conn_info raid1_connections[MAX_RAID1];
- struct list_head raid1_clients; /* clients we have */
-};
#endif
struct ost_obd {
struct ptlrpc_service *ost_service;
- struct obd_device *ost_tgt; /* the exported OBD */
struct obd_conn ost_conn; /* the local connection to the OBD */
};
/* corresponds to one of the obd's */
struct obd_device {
struct obd_type *obd_type;
+
+ /* common and UUID name of this device */
char *obd_name;
__u8 obd_uuid[37];
int obd_minor;
int obd_flags;
- int obd_refcnt;
- struct obd_devicename obd_fsname;
struct proc_dir_entry *obd_proc_entry;
int obd_multi_count;
struct obd_conn obd_multi_conn[MAX_MULTI];
unsigned int obd_gen_last_id;
unsigned long obd_gen_prealloc_quota;
- struct list_head obd_gen_clients;
- struct list_head obd_req_list;
- wait_queue_head_t obd_req_waitq;
+ // struct obd_device *obd_target; /* for anything that simply layers */
+ struct list_head obd_exports;
+ struct list_head obd_imports;
struct ldlm_namespace *obd_namespace;
union {
struct ext2_obd ext2;
struct trace_obd trace;
struct lov_obd lov;
#if 0
- struct raid1_obd raid1;
struct snap_obd snap;
#endif
} u;
int (*o_detach)(struct obd_device *dev);
int (*o_setup) (struct obd_device *dev, obd_count len, void *data);
int (*o_cleanup)(struct obd_device *dev);
- int (*o_connect)(struct obd_conn *conn);
+ int (*o_connect)(struct obd_conn *conn, struct obd_device *src);
int (*o_disconnect)(struct obd_conn *conn);
int (*o_getattr)(struct obd_conn *conn, struct obdo *oa);
int (*o_open)(struct obd_conn *conn, struct obdo *oa);
int (*o_close)(struct obd_conn *conn, struct obdo *oa);
- int (*o_read)(struct obd_conn *conn, struct obdo *oa, char *buf,
- obd_size *count, obd_off offset);
- int (*o_write)(struct obd_conn *conn, struct obdo *oa, char *buf,
- obd_size *count, obd_off offset);
int (*o_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,
/*
* ======== OBD Device Declarations ===========
*/
-#define MAX_OBD_DEVICES 32
+#define MAX_OBD_DEVICES 128
extern struct obd_device obd_dev[MAX_OBD_DEVICES];
#define OBD_ATTACHED 0x1
#define OBD_BRW_CREATE 4
#ifdef __KERNEL__
+extern struct obd_export *gen_client(struct obd_conn *conn);
+extern struct obd_device *gen_conn2obd(struct obd_conn *conn);
+struct obd_export {
+ __u64 export_cookie;
+ struct lustre_handle export_import; /* client handle */
+ struct list_head export_chain;
+ struct obd_device *export_obd;
+ unsigned int export_id;
+ void *export_data; /* device specific data */
+};
+
+struct obd_import {
+ __u64 import_cookie;
+ struct lustre_handle import_export; /* client handle */
+ struct list_head import_chain;
+ struct obd_device *import_obd;
+ unsigned int import_id;
+ void *import_data; /* device specific data */
+};
+
+
struct obd_request {
struct obdo *oa;
struct obd_conn *conn;
char *pbuf1;
};
+
static inline int obd_check_conn(struct obd_conn *conn)
{
struct obd_device *obd;
if (!conn) {
- CERROR("obd_check_conn: NULL conn\n");
+ CERROR("NULL conn\n");
RETURN(-ENOTCONN);
}
- obd = conn->oc_dev;
+ obd = gen_conn2obd(conn);
if (!obd) {
- CERROR("obd_check_conn: NULL obd\n");
+ CERROR("NULL obd\n");
RETURN(-ENODEV);
}
if (!obd->obd_flags & OBD_ATTACHED ) {
- CERROR("obd_check_conn: obd %d not attached\n", obd->obd_minor);
+ CERROR("obd %d not attached\n", obd->obd_minor);
RETURN(-ENODEV);
}
if (!obd->obd_flags & OBD_SET_UP) {
- CERROR("obd_check_conn: obd %d not setup\n", obd->obd_minor);
+ CERROR("obd %d not setup\n", obd->obd_minor);
RETURN(-ENODEV);
}
if (!obd->obd_type) {
- CERROR("obd_check_conn: obd %d not typed\n", obd->obd_minor);
+ CERROR("obd %d not typed\n", obd->obd_minor);
RETURN(-ENODEV);
}
return 0;
}
+
#define OBT(dev) (dev)->obd_type
#define OBP(dev,op) (dev)->obd_type->typ_ops->o_ ## op
-#define OBD_CHECK_SETUP(conn) \
+#define OBD_CHECK_SETUP(conn, export) \
do { \
if (!(conn)) { \
CERROR("NULL connection\n"); \
RETURN(-EINVAL); \
} \
\
- if (!((conn)->oc_dev)) { \
- CERROR("NULL device\n"); \
+ export = gen_client(conn);\
+ if (!(export)) { \
+ CERROR("No export\n"); \
RETURN(-EINVAL); \
} \
\
- if ( !((conn)->oc_dev->obd_flags & OBD_SET_UP) ) { \
+ if ( !((export)->export_obd->obd_flags & OBD_SET_UP) ) { \
CERROR("Device %d not setup\n", \
- (conn)->oc_dev->obd_minor); \
+ (export)->export_obd->obd_minor); \
RETURN(-EINVAL); \
} \
} while (0)
-#define OBD_CHECK_OP(conn,op) \
+#define OBD_CHECK_DEVSETUP(obd) \
do { \
- int rc = obd_check_conn(conn); \
- if (rc) { \
- CERROR("obd: error in operation: " #op "\n"); \
- RETURN(rc); \
+ if (!(obd)) { \
+ CERROR("NULL device\n"); \
+ RETURN(-EINVAL); \
} \
- if (!OBP(conn->oc_dev,op)) { \
+ \
+ if ( !((obd)->obd_flags & OBD_SET_UP) ) { \
+ CERROR("Device %d not setup\n", \
+ (obd)->obd_minor); \
+ RETURN(-EINVAL); \
+ } \
+} while (0)
+
+#define OBD_CHECK_OP(obd,op) \
+do { \
+ if (!OBP((obd),op)) { \
CERROR("obd_" #op ": dev %d no operation\n", \
- conn->oc_dev->obd_minor); \
+ obd->obd_minor); \
RETURN(-EOPNOTSUPP); \
} \
} while (0)
void *key, obd_count *vallen, void **val)
{
int rc;
- OBD_CHECK_SETUP(conn);
- OBD_CHECK_OP(conn,get_info);
+ struct obd_export *export;
+ OBD_CHECK_SETUP(conn, export);
+ OBD_CHECK_OP(export->export_obd,get_info);
- rc = OBP(conn->oc_dev, get_info)(conn, keylen, key, vallen, val);
+ rc = OBP(export->export_obd, get_info)(conn, keylen, key, vallen, val);
RETURN(rc);
}
void *key, obd_count vallen, void *val)
{
int rc;
- OBD_CHECK_SETUP(conn);
- OBD_CHECK_OP(conn,set_info);
+ struct obd_export *export;
+ OBD_CHECK_SETUP(conn, export);
+ OBD_CHECK_OP(export->export_obd,set_info);
- rc = OBP(conn->oc_dev, set_info)(conn, keylen, key, vallen, val);
+ rc = OBP(export->export_obd, set_info)(conn, keylen, key, vallen, val);
RETURN(rc);
}
static inline int obd_setup(struct obd_device *obd, int datalen, void *data)
{
- struct obd_conn conn;
int rc;
- conn.oc_dev = obd;
- OBD_CHECK_OP((&conn),setup);
+ OBD_CHECK_OP(obd,setup);
- rc = OBP(conn.oc_dev, setup)(obd, datalen, data);
+ rc = OBP(obd, setup)(obd, datalen, data);
RETURN(rc);
}
static inline int obd_cleanup(struct obd_device *obd)
{
- struct obd_conn conn;
int rc;
- conn.oc_dev = obd;
- OBD_CHECK_SETUP(&conn);
- OBD_CHECK_OP((&conn),cleanup);
+ OBD_CHECK_DEVSETUP(obd);
+ OBD_CHECK_OP(obd,cleanup);
- rc = OBP(conn.oc_dev, cleanup)(obd);
+ rc = OBP(obd, cleanup)(obd);
RETURN(rc);
}
static inline int obd_create(struct obd_conn *conn, struct obdo *obdo)
{
int rc;
- OBD_CHECK_SETUP(conn);
- OBD_CHECK_OP(conn,create);
+ struct obd_export *export;
+ OBD_CHECK_SETUP(conn, export);
+ OBD_CHECK_OP(export->export_obd,create);
- rc = OBP(conn->oc_dev, create)(conn, obdo);
+ rc = OBP(export->export_obd, create)(conn, obdo);
RETURN(rc);
}
static inline int obd_destroy(struct obd_conn *conn, struct obdo *obdo)
{
int rc;
- OBD_CHECK_SETUP(conn);
- OBD_CHECK_OP(conn,destroy);
+ struct obd_export *export;
+ OBD_CHECK_SETUP(conn, export);
+ OBD_CHECK_OP(export->export_obd,destroy);
- rc = OBP(conn->oc_dev, destroy)(conn, obdo);
+ rc = OBP(export->export_obd, destroy)(conn, obdo);
RETURN(rc);
}
static inline int obd_getattr(struct obd_conn *conn, struct obdo *obdo)
{
int rc;
- OBD_CHECK_SETUP(conn);
- OBD_CHECK_OP(conn,getattr);
+ struct obd_export *export;
+ OBD_CHECK_SETUP(conn, export);
+ OBD_CHECK_OP(export->export_obd,getattr);
- rc = OBP(conn->oc_dev, getattr)(conn, obdo);
+ rc = OBP(export->export_obd, getattr)(conn, obdo);
RETURN(rc);
}
static inline int obd_close(struct obd_conn *conn, struct obdo *obdo)
{
int rc;
- OBD_CHECK_SETUP(conn);
- OBD_CHECK_OP(conn,close);
+ struct obd_export *export;
+ OBD_CHECK_SETUP(conn, export);
+ OBD_CHECK_OP(export->export_obd,close);
- rc = OBP(conn->oc_dev, close)(conn, obdo);
+ rc = OBP(export->export_obd, close)(conn, obdo);
RETURN(rc);
}
static inline int obd_open(struct obd_conn *conn, struct obdo *obdo)
{
int rc;
- OBD_CHECK_SETUP(conn);
- OBD_CHECK_OP(conn,open);
+ struct obd_export *export;
+ OBD_CHECK_SETUP(conn, export);
+ OBD_CHECK_OP(export->export_obd,open);
- rc = OBP(conn->oc_dev, open) (conn, obdo);
+ rc = OBP(export->export_obd, open) (conn, obdo);
RETURN(rc);
}
static inline int obd_setattr(struct obd_conn *conn, struct obdo *obdo)
{
int rc;
- OBD_CHECK_SETUP(conn);
- OBD_CHECK_OP(conn,setattr);
+ struct obd_export *export;
+ OBD_CHECK_SETUP(conn, export);
+ OBD_CHECK_OP(export->export_obd,setattr);
- rc = OBP(conn->oc_dev, setattr)(conn, obdo);
+ rc = OBP(export->export_obd, setattr)(conn, obdo);
RETURN(rc);
}
-static inline int obd_connect(struct obd_conn *conn)
+static inline int obd_connect(struct obd_conn *conn, struct obd_device *obd)
{
int rc;
- OBD_CHECK_SETUP(conn);
- OBD_CHECK_OP(conn,connect);
+ OBD_CHECK_DEVSETUP(obd);
+ OBD_CHECK_OP(obd,connect);
- rc = OBP(conn->oc_dev, connect)(conn);
+ rc = OBP(obd, connect)(conn, obd);
RETURN(rc);
}
static inline int obd_disconnect(struct obd_conn *conn)
{
int rc;
- OBD_CHECK_SETUP(conn);
- OBD_CHECK_OP(conn,disconnect);
+ struct obd_export *export;
+ OBD_CHECK_SETUP(conn, export);
+ OBD_CHECK_OP(export->export_obd,disconnect);
- rc = OBP(conn->oc_dev, disconnect)(conn);
+ rc = OBP(export->export_obd, disconnect)(conn);
RETURN(rc);
}
static inline int obd_statfs(struct obd_conn *conn, struct statfs *buf)
{
int rc;
- OBD_CHECK_SETUP(conn);
- OBD_CHECK_OP(conn,statfs);
+ struct obd_export *export;
+ OBD_CHECK_SETUP(conn, export);
+ OBD_CHECK_OP(export->export_obd,statfs);
- rc = OBP(conn->oc_dev, statfs)(conn, buf);
+ rc = OBP(export->export_obd, statfs)(conn, buf);
RETURN(rc);
}
obd_size count, obd_off offset)
{
int rc;
- OBD_CHECK_SETUP(conn);
- OBD_CHECK_OP(conn,punch);
+ struct obd_export *export;
+ OBD_CHECK_SETUP(conn, export);
+ OBD_CHECK_OP(export->export_obd,punch);
- rc = OBP(conn->oc_dev, punch)(conn, tgt, count, offset);
+ rc = OBP(export->export_obd, punch)(conn, tgt, count, offset);
RETURN(rc);
}
obd_flag *flags, void *callback)
{
int rc;
- OBD_CHECK_SETUP(conn);
- OBD_CHECK_OP(conn,brw);
+ struct obd_export *export;
+ OBD_CHECK_SETUP(conn, export);
+ OBD_CHECK_OP(export->export_obd,brw);
if (!(cmd & OBD_BRW_RWMASK)) {
CERROR("obd_brw: cmd must be OBD_BRW_READ or OBD_BRW_WRITE\n");
LBUG();
}
- rc = OBP(conn->oc_dev, brw)(cmd, conn, num_oa, oa, oa_bufs, buf,
+ rc = OBP(export->export_obd, brw)(cmd, conn, num_oa, oa, oa_bufs, buf,
count, offset, flags, callback);
RETURN(rc);
}
struct niobuf_local *local, void **desc_private)
{
int rc;
- OBD_CHECK_SETUP(conn);
- OBD_CHECK_OP(conn, preprw);
+ struct obd_export *export;
+ OBD_CHECK_SETUP(conn, export);
+ OBD_CHECK_OP(export->export_obd,preprw);
- rc = OBP(conn->oc_dev, preprw)(cmd, conn, objcount, obj, niocount,
+ rc = OBP(export->export_obd, preprw)(cmd, conn, objcount, obj, niocount,
remote, local, desc_private);
RETURN(rc);
}
void *desc_private)
{
int rc;
- OBD_CHECK_SETUP(conn);
- OBD_CHECK_OP(conn, commitrw);
+ struct obd_export *export;
+ OBD_CHECK_SETUP(conn, export);
+ OBD_CHECK_OP(export->export_obd,commitrw);
- rc = OBP(conn->oc_dev, commitrw)(cmd, conn, objcount, obj, niocount,
+ rc = OBP(export->export_obd, commitrw)(cmd, conn, objcount, obj, niocount,
local, desc_private);
RETURN(rc);
}
int len, void *karg, void *uarg)
{
int rc;
- OBD_CHECK_SETUP(conn);
- OBD_CHECK_OP(conn, iocontrol);
+ struct obd_export *export;
+ OBD_CHECK_SETUP(conn, export);
+ OBD_CHECK_OP(export->export_obd,iocontrol);
- rc = OBP(conn->oc_dev, iocontrol)(cmd, conn, len, karg, uarg);
+ rc = OBP(export->export_obd, iocontrol)(cmd, conn, len, karg, uarg);
RETURN(rc);
}
int datalen, struct lustre_handle *lockh)
{
int rc;
- OBD_CHECK_SETUP(conn);
- OBD_CHECK_OP(conn, enqueue);
+ struct obd_export *export;
+ OBD_CHECK_SETUP(conn, export);
+ OBD_CHECK_OP(export->export_obd,enqueue);
- rc = OBP(conn->oc_dev, enqueue)(conn, parent_lock, res_id, type,
+ rc = OBP(export->export_obd, enqueue)(conn, parent_lock, res_id, type,
cookie, cookielen, mode, flags, cb,
data, datalen, lockh);
RETURN(rc);
struct lustre_handle *lockh)
{
int rc;
- OBD_CHECK_SETUP(conn);
- OBD_CHECK_OP(conn, cancel);
+ struct obd_export *export;
+ OBD_CHECK_SETUP(conn, export);
+ OBD_CHECK_OP(export->export_obd,cancel);
- rc = OBP(conn->oc_dev, cancel)(conn, mode, lockh);
+ rc = OBP(export->export_obd, cancel)(conn, mode, lockh);
RETURN(rc);
}
* ======== OBD Metadata Support ===========
*/
-extern int obd_init_obdo_cache(void);
-extern void obd_cleanup_obdo_cache(void);
+extern int obd_init_caches(void);
+extern void obd_cleanup_caches(void);
static inline int obdo_has_inline(struct obdo *obdo)
oa->o_id = id;
oa->o_mode = mode;
oa->o_valid = valid;
- if ((err = OBP(conn->oc_dev, getattr)(conn, oa))) {
+ if ((err = obd_getattr(conn, oa))) {
obdo_free(oa);
RETURN(ERR_PTR(err));
}
int obd_register_type(struct obd_ops *ops, char *nm);
int obd_unregister_type(char *nm);
int obd_class_name2dev(char *name);
-
-struct obd_client {
- struct list_head cli_chain;
- struct obd_device *cli_obd;
- unsigned int cli_id;
- unsigned long cli_prealloc_quota;
- struct list_head cli_prealloc_inodes;
-};
+int obd_class_uuid2dev(char *name);
struct obd_prealloc_inode {
int gen_multi_cleanup(struct obd_device *obddev);
int gen_multi_attach(struct obd_device *obddev, uint32_t len, void *data);
int gen_multi_detach(struct obd_device *obddev);
-int gen_connect (struct obd_conn *conn);
+int gen_connect (struct obd_conn *conn, struct obd_device *obd);
int gen_disconnect(struct obd_conn *conn);
-struct obd_client *gen_client(const struct obd_conn *);
+struct obd_export *gen_client(struct obd_conn *);
int gen_cleanup(struct obd_device *obddev);
int gen_copy_data(struct obd_conn *dst_conn, struct obdo *dst,
struct obd_conn *src_conn, struct obdo *src,
#include <linux/types.h>
#include <linux/blkdev.h>
+static inline void fixme(void)
+{
+ CERROR("FIXME\n");
+}
+
static inline void OBD_FAIL_WRITE(int id, kdev_t dev)
{
if (OBD_FAIL_CHECK(id)) {
RETURN(0);
}
-static int lustre_handle(struct obd_device *dev, struct ptlrpc_service *svc,
- struct ptlrpc_request *req)
+static int lustre_handle(struct ptlrpc_request *req)
{
+ struct ptlrpc_service *svc = req->rq_svc;
struct obd_device *req_dev;
int id, rc;
ENTRY;
static int ldlm_iocontrol(long cmd, struct obd_conn *conn, int len, void *karg,
void *uarg)
{
- struct obd_device *obddev = conn->oc_dev;
+ struct obd_device *obddev = gen_conn2obd(conn);
struct ptlrpc_connection *connection;
int err;
ENTRY;
GOTO(out_free, sb = NULL);
}
- sbi->ll_osc_conn.oc_dev = &obd_dev[devno];
- err = obd_connect(&sbi->ll_osc_conn);
+ err = obd_connect(&sbi->ll_osc_conn, &obd_dev[devno]);
if (err) {
CERROR("cannot connect to %s: rc = %d\n", ost, err);
GOTO(out_free, sb = NULL);
GOTO(out_free, sb = NULL);
}
- sbi->ll_mdc_conn.oc_dev = &obd_dev[devno];
- err = obd_connect(&sbi->ll_mdc_conn);
+ err = obd_connect(&sbi->ll_mdc_conn, &obd_dev[devno]);
if (err) {
CERROR("cannot connect to %s: rc = %d\n", mds, err);
GOTO(out_free, sb = NULL);
void *data, int datalen)
{
struct ptlrpc_request *req;
- struct obd_device *obddev = conn->oc_dev;
+ struct obd_device *obddev = gen_conn2obd(conn);
struct mdc_obd *mdc = mdc_conn2mdc(conn);
__u64 res_id[RES_NAME_SIZE] = {dir->i_ino};
int size[5] = {sizeof(struct ldlm_request), sizeof(struct ldlm_intent)};
return 0;
}
-static int mdc_connect(struct obd_conn *conn)
+static int mdc_connect(struct obd_conn *conn, struct obd_device *obd)
{
- struct mdc_obd *mdc = mdc_conn2mdc(conn);
+ struct mdc_obd *mdc = &obd->u.mdc;
struct ptlrpc_request *request;
int rc, size = sizeof(mdc->mdc_target_uuid);
char *tmp = mdc->mdc_target_uuid;
ENTRY;
- conn->oc_dev->obd_namespace =
+ obd->obd_namespace =
ldlm_namespace_new("mdc", LDLM_NAMESPACE_CLIENT);
- if (conn->oc_dev->obd_namespace == NULL)
+ if (obd->obd_namespace == NULL)
RETURN(-ENOMEM);
request = ptlrpc_prep_req(mdc->mdc_client, mdc->mdc_conn,
static int mdc_disconnect(struct obd_conn *conn)
{
struct mdc_obd *mdc = mdc_conn2mdc(conn);
+ struct obd_device *obd = gen_conn2obd(conn);
struct ptlrpc_request *request;
struct mds_body *body;
int rc, size = sizeof(*body);
ENTRY;
- ldlm_namespace_free(conn->oc_dev->obd_namespace);
+ ldlm_namespace_free(obd->obd_namespace);
request = ptlrpc_prep_req(mdc->mdc_client, mdc->mdc_conn,
MDS_DISCONNECT, 1, &size,
NULL);
return rc;
}
-int mds_handle(struct obd_device *dev, struct ptlrpc_service *svc,
- struct ptlrpc_request *req)
+int mds_handle(struct ptlrpc_request *req)
{
+ struct obd_device *dev = req->rq_obd;
+ struct ptlrpc_service *svc = req->rq_svc;
struct mds_obd *mds = NULL;
int rc;
ENTRY;
ENTRY;
- if ( !list_empty(&obddev->obd_gen_clients) ) {
- CERROR("still has clients!\n");
+ if ( !list_empty(&obddev->obd_exports) ) {
+ CERROR("still has exports!\n");
RETURN(-EBUSY);
}
struct obd_device obd_dev[MAX_OBD_DEVICES];
struct list_head obd_types;
+
/* opening /dev/obd */
static int obd_class_open(struct inode * inode, struct file * file)
{
for (i=0; i < MAX_OBD_DEVICES; i++) {
struct obd_device *obd = &obd_dev[i];
- if (obd->obd_name && strncmp(name, obd->obd_name, 37) == 0) {
+ if (obd->obd_name && strcmp(name, obd->obd_name) == 0) {
+ res = i;
+ return res;
+ }
+ }
+
+ return res;
+}
+
+int obd_class_uuid2dev(char *name)
+{
+ int res = -1;
+ int i;
+
+ for (i=0; i < MAX_OBD_DEVICES; i++) {
+ struct obd_device *obd = &obd_dev[i];
+ if (obd->obd_name && strncmp(name, obd->obd_uuid, 37) == 0) {
res = i;
return res;
}
return type;
}
+inline void obd_data2conn(struct obd_conn *conn, struct obd_ioctl_data *data)
+{
+ conn->addr = data->ioc_addr;
+ conn->cookie = data->ioc_cookie;
+}
+
+
+inline void obd_conn2data(struct obd_ioctl_data *data, struct obd_conn *conn)
+{
+ data->ioc_addr = conn->addr;
+ data->ioc_cookie = conn->cookie;
+}
+
+
/* to control /dev/obd */
static int obd_class_ioctl (struct inode * inode, struct file * filp,
unsigned int cmd, unsigned long arg)
{
/* NOTE this must be larger than any of the ioctl data structs */
char buf[1024];
+ int len = 1024;
struct obd_ioctl_data *data;
struct obd_device *obd = filp->private_data;
struct obd_conn conn;
memset(buf, 0, sizeof(buf));
if (!obd && cmd != OBD_IOC_DEVICE && cmd != TCGETS &&
+ cmd != OBD_IOC_LIST &&
cmd != OBD_IOC_NAME2DEV && cmd != OBD_IOC_NEWDEV) {
CERROR("OBD ioctl: No device\n");
RETURN(-EINVAL);
}
- if (obd_ioctl_getdata(buf, buf + 800, (void *)arg)) {
+ if (obd_ioctl_getdata(buf, &len, (void *)arg)) {
CERROR("OBD ioctl: data error\n");
RETURN(-EINVAL);
}
RETURN(0);
}
+ case OBD_IOC_LIST: {
+ int i;
+ char *buf = data->ioc_bulk;
+ int remains = data->ioc_inllen1;
+
+ if (!data->ioc_inlbuf1) {
+ CERROR("No buffer passed!\n");
+ RETURN(-EINVAL);
+ }
+
+
+ for (i = 0 ; i < MAX_OBD_DEVICES ; i++) {
+ int l;
+ struct obd_device *obd = &obd_dev[i];
+ if (!obd->obd_type)
+ continue;
+ l = snprintf(buf, remains, "%2d %s %s %s\n",
+ i, obd->obd_type->typ_name,
+ obd->obd_name, obd->obd_uuid);
+ buf +=l;
+ remains -=l;
+ if (remains <= 0) {
+ CERROR("not enough space for device listing\n");
+ break;
+ }
+ }
+
+ err = copy_to_user((int *)arg, data, len);
+ RETURN(err);
+ }
+
+
case OBD_IOC_NAME2DEV: {
/* Resolve a device name. This does not change the
* currently selected device.
RETURN(err);
}
+ case OBD_IOC_UUID2DEV: {
+ /* Resolve a device uuid. This does not change the
+ * currently selected device.
+ */
+ int dev;
+
+ if (!data->ioc_inlbuf1) {
+ CERROR("No UUID passed!\n");
+ RETURN(-EINVAL);
+ }
+ CDEBUG(D_IOCTL, "device name %s\n", data->ioc_inlbuf1);
+ dev = obd_class_uuid2dev(data->ioc_inlbuf1);
+ data->ioc_dev = dev;
+ if (dev == -1) {
+ CDEBUG(D_IOCTL, "No device for name %s!\n",
+ data->ioc_inlbuf1);
+ RETURN(-EINVAL);
+ }
+
+ CDEBUG(D_IOCTL, "device name %s, dev %d\n", data->ioc_inlbuf1,
+ dev);
+ err = copy_to_user((int *)arg, data, sizeof(*data));
+ RETURN(err);
+ }
+
case OBD_IOC_NEWDEV: {
int dev = -1;
int i;
RETURN(-EBUSY);
}
- CDEBUG(D_IOCTL, "attach %s %s\n", MKSTR(data->ioc_inlbuf1),
- MKSTR(data->ioc_inlbuf2));
+ CDEBUG(D_IOCTL, "attach type %s name: %s uuid: %s\n",
+ MKSTR(data->ioc_inlbuf1),
+ MKSTR(data->ioc_inlbuf2), MKSTR(data->ioc_inlbuf3));
/* find the type */
type = obd_nm_to_type(data->ioc_inlbuf1);
obd->obd_type = type;
obd->obd_multi_count = 0;
- INIT_LIST_HEAD(&obd->obd_gen_clients);
- INIT_LIST_HEAD(&obd->obd_req_list);
+ INIT_LIST_HEAD(&obd->obd_exports);
/* do the attach */
if (OBT(obd) && OBP(obd, attach))
obd->obd_proc_entry =
proc_lustre_register_obd_device(obd);
if (data->ioc_inlbuf2) {
- int len = strlen(data->ioc_inlbuf2);
+ int len = strlen(data->ioc_inlbuf2) + 1;
OBD_ALLOC(obd->obd_name, len + 1);
if (!obd->obd_name) {
CERROR("no memory\n");
LBUG();
}
- memcpy(obd->obd_name, data->ioc_inlbuf2, len+1);
+ memcpy(obd->obd_name, data->ioc_inlbuf2, len + 1);
+ }
+ if (data->ioc_inlbuf3) {
+ int len = strlen(data->ioc_inlbuf3);
+ if (len > 37) {
+ CERROR("uuid should be shorter than 37 bytes\n");
+ if (obd->obd_name)
+ OBD_FREE(obd->obd_name,
+ strlen(obd->obd_name) + 1);
+ RETURN(-EINVAL);
+ }
+ memcpy(obd->obd_uuid, data->ioc_inlbuf3,
+ sizeof(obd->obd_uuid));
}
MOD_INC_USE_COUNT;
CERROR("OBD device %d not attached\n", obd->obd_minor);
RETURN(-ENODEV);
}
- if ( !list_empty(&obd->obd_gen_clients) ) {
- CERROR("OBD device %d has connected clients\n",
- obd->obd_minor);
- RETURN(-EBUSY);
- }
- if ( !list_empty(&obd->obd_req_list) ) {
- CERROR("OBD device %d has hanging requests\n",
+ if ( !list_empty(&obd->obd_exports) ) {
+ CERROR("OBD device %d has exports\n",
obd->obd_minor);
RETURN(-EBUSY);
}
}
case OBD_IOC_CONNECT: {
- conn.oc_id = data->ioc_conn1;
- conn.oc_dev = obd;
+ obd_data2conn(&conn, data);
- err = obd_connect(&conn);
+ err = obd_connect(&conn, obd);
CDEBUG(D_IOCTL, "assigned connection %d\n", conn.oc_id);
- data->ioc_conn1 = conn.oc_id;
+ obd_conn2data(data, &conn);
if (err)
RETURN(err);
}
case OBD_IOC_DISCONNECT: {
- conn.oc_id = data->ioc_conn1;
- conn.oc_dev = obd;
-
+ obd_data2conn(&conn, data);
err = obd_disconnect(&conn);
RETURN(err);
}
}
case OBD_IOC_CREATE: {
- conn.oc_id = data->ioc_conn1;
- conn.oc_dev = obd;
+ obd_data2conn(&conn, data);
err = obd_create(&conn, &data->ioc_obdo1);
if (err)
}
case OBD_IOC_GETATTR: {
- conn.oc_id = data->ioc_conn1;
- conn.oc_dev = obd;
+ obd_data2conn(&conn, data);
err = obd_getattr(&conn, &data->ioc_obdo1);
if (err)
RETURN(err);
}
case OBD_IOC_SETATTR: {
- conn.oc_id = data->ioc_conn1;
- conn.oc_dev = obd;
-
+ obd_data2conn(&conn, data);
err = obd_setattr(&conn, &data->ioc_obdo1);
if (err)
RETURN(err);
}
case OBD_IOC_DESTROY: {
- conn.oc_id = data->ioc_conn1;
- conn.oc_dev = obd;
+ obd_data2conn(&conn, data);
err = obd_destroy(&conn, &data->ioc_obdo1);
if (err)
* We don't really support multiple-obdo I/Os here,
* for example offset and count are not per-obdo.
*/
- struct obd_conn conns[2];
struct obdo *obdos[2] = { NULL, NULL };
obd_count oa_bufs[2] = { 0, 0 };
struct page **bufs = NULL;
int pages;
int i, j;
+ obd_data2conn(&conn, data);
+
pages = oa_bufs[0] = data->ioc_plen1 / PAGE_SIZE;
if (data->ioc_obdo2.o_id) {
num = 2;
unsigned long off;
void *from;
- conns[i].oc_id = (&data->ioc_conn1)[i];
- conns[i].oc_dev = obd;
-
from = (&data->ioc_pbuf1)[i];
off = data->ioc_offset;
}
}
- err = obd_brw(rw, conns, num, obdos, oa_bufs, bufs,
+ err = obd_brw(rw, &conn, num, obdos, oa_bufs, bufs,
counts, offsets, flags, NULL);
EXIT;
return err;
}
default: {
- conn.oc_id = data->ioc_conn1;
- conn.oc_dev = obd;
+ obd_data2conn(&conn, data);
err = obd_iocontrol(cmd, &conn, sizeof(*data), data, NULL);
if (err)
EXPORT_SYMBOL(obd_dev);
EXPORT_SYMBOL(obd_class_name2dev);
+EXPORT_SYMBOL(obd_class_uuid2dev);
EXPORT_SYMBOL(gen_connect);
EXPORT_SYMBOL(gen_client);
+EXPORT_SYMBOL(gen_conn2obd);
EXPORT_SYMBOL(gen_cleanup);
EXPORT_SYMBOL(gen_disconnect);
EXPORT_SYMBOL(gen_copy_data);
for (i = 0; i < MAX_OBD_DEVICES; i++) {
memset(&(obd_dev[i]), 0, sizeof(obd_dev[i]));
obd_dev[i].obd_minor = i;
- INIT_LIST_HEAD(&obd_dev[i].obd_gen_clients);
- INIT_LIST_HEAD(&obd_dev[i].obd_req_list);
- init_waitqueue_head(&obd_dev[i].obd_req_waitq);
+ INIT_LIST_HEAD(&obd_dev[i].obd_exports);
}
- err = obd_init_obdo_cache();
+ err = obd_init_caches();
if (err)
return err;
obd_sysctl_init();
}
}
- obd_cleanup_obdo_cache();
+ obd_cleanup_caches();
obd_sysctl_clean();
CERROR("obd memory leaked: %ld bytes\n", obd_memory);
obd_init_magic = 0;
#define DEBUG_SUBSYSTEM S_CLASS
#include <linux/obd_class.h>
+#include <linux/random.h>
+#include <linux/slab.h>
extern struct obd_device obd_dev[MAX_OBD_DEVICES];
kmem_cache_t *obdo_cachep = NULL;
+kmem_cache_t *export_cachep = NULL;
+kmem_cache_t *import_cachep = NULL;
-int obd_init_obdo_cache(void)
+void obd_cleanup_caches(void)
+{
+ int rc;
+ ENTRY;
+ if (obdo_cachep) {
+ rc = kmem_cache_destroy(obdo_cachep);
+ if (rc)
+ CERROR("Cannot destory obdo_cachep\n");
+ obdo_cachep = NULL;
+ }
+ if (import_cachep) {
+ rc = kmem_cache_destroy(import_cachep);
+ if (rc)
+ CERROR("Cannot destory import_cachep\n");
+ import_cachep = NULL;
+ }
+ if (export_cachep) {
+ rc = kmem_cache_destroy(export_cachep);
+ if (rc)
+ CERROR("Cannot destory import_cachep\n");
+ export_cachep = NULL;
+ }
+ EXIT;
+}
+
+int obd_init_caches(void)
{
ENTRY;
if (obdo_cachep == NULL) {
- CDEBUG(D_CACHE, "allocating obdo_cache\n");
obdo_cachep = kmem_cache_create("obdo_cache",
sizeof(struct obdo),
0, SLAB_HWCACHE_ALIGN,
NULL, NULL);
if (obdo_cachep == NULL)
- RETURN(-ENOMEM);
- else
- CDEBUG(D_CACHE, "allocated cache at %p\n", obdo_cachep);
- } else {
- CDEBUG(D_CACHE, "using existing cache at %p\n", obdo_cachep);
+ GOTO(out, -ENOMEM);
+ }
+
+ if (export_cachep == NULL) {
+ export_cachep = kmem_cache_create("export_cache",
+ sizeof(struct obd_export),
+ 0, SLAB_HWCACHE_ALIGN,
+ NULL, NULL);
+ if (export_cachep == NULL)
+ GOTO(out, -ENOMEM);
+ }
+
+ if (import_cachep == NULL) {
+ import_cachep = kmem_cache_create("import_cache",
+ sizeof(struct obd_import),
+ 0, SLAB_HWCACHE_ALIGN,
+ NULL, NULL);
+ if (import_cachep == NULL)
+ GOTO(out, -ENOMEM);
}
RETURN(0);
-}
+ out:
+ obd_cleanup_caches();
+ RETURN(-ENOMEM);
-void obd_cleanup_obdo_cache(void)
-{
- ENTRY;
- if (obdo_cachep != NULL) {
- CDEBUG(D_CACHE, "destroying obdo_cache at %p\n", obdo_cachep);
- if (kmem_cache_destroy(obdo_cachep))
- CERROR("unable to free cache\n");
- } else
- CERROR("called with NULL cache pointer\n");
-
- obdo_cachep = NULL;
- EXIT;
}
/* map connection to client */
-struct obd_client *gen_client(const struct obd_conn *conn)
+struct obd_export *gen_client(struct obd_conn *conn)
{
- struct obd_device * obddev;
- struct list_head * lh, * next;
- struct obd_client * cli;
+ struct obd_export * export;
if (!conn)
- return NULL;
+ RETURN(NULL);
- obddev = conn->oc_dev;
- lh = next = &obddev->obd_gen_clients;
- while ((lh = lh->next) != &obddev->obd_gen_clients) {
- cli = list_entry(lh, struct obd_client, cli_chain);
-
- if (cli->cli_id == conn->oc_id)
- return cli;
+ if (!conn->addr || conn->addr == -1 ) {
+ fixme();
+ RETURN(NULL);
}
+
+ export = (struct obd_export *) (unsigned long)conn->addr;
+ if (!kmem_cache_validate(export_cachep, (void *)export))
+ RETURN(NULL);
- return NULL;
+ if (export->export_cookie != conn->cookie)
+ return NULL;
+ return export;
} /* gen_client */
+struct obd_device *gen_conn2obd(struct obd_conn *conn)
+{
+ struct obd_export *export;
+ export = gen_client(conn);
+ if (export)
+ return export->export_obd;
+ fixme();
+ return NULL;
+}
/* a connection defines a context in which preallocation can be managed. */
-int gen_connect (struct obd_conn *conn)
+int gen_connect (struct obd_conn *conn, struct obd_device *obd)
{
- struct obd_client * cli;
+ struct obd_export * export;
- OBD_ALLOC(cli, sizeof(*cli));
- if ( !cli ) {
- CERROR("no memory! (minor %d)\n", conn->oc_dev->obd_minor);
+ export = kmem_cache_alloc(export_cachep, GFP_KERNEL);
+ if ( !export ) {
+ CERROR("no memory! (minor %d)\n", obd->obd_minor);
return -ENOMEM;
}
- INIT_LIST_HEAD(&cli->cli_prealloc_inodes);
+ memset(export, 0, sizeof(*export));
+ get_random_bytes(&export->export_cookie, sizeof(__u64));
/* XXX this should probably spinlocked? */
- cli->cli_id = ++conn->oc_dev->obd_gen_last_id;
- cli->cli_prealloc_quota = 0;
- cli->cli_obd = conn->oc_dev;
- list_add(&(cli->cli_chain), conn->oc_dev->obd_gen_clients.prev);
-
- CDEBUG(D_INFO, "connect: new ID %u\n", cli->cli_id);
- conn->oc_id = cli->cli_id;
+ export->export_id = ++obd->obd_gen_last_id;
+ export->export_obd = obd;
+ export->export_import.addr = conn->addr;
+ export->export_import.cookie = conn->cookie;
+
+ list_add(&(export->export_chain), export->export_obd->obd_exports.prev);
+
+ CDEBUG(D_INFO, "connect: new ID %u\n", export->export_id);
+ conn->oc_id = export->export_id;
+ conn->addr = (__u64) (unsigned long)export;
+ conn->cookie = export->export_cookie;
return 0;
} /* gen_connect */
int gen_disconnect(struct obd_conn *conn)
{
- struct obd_client * cli;
+ struct obd_export * export;
ENTRY;
- if (!(cli = gen_client(conn))) {
+ if (!(export = gen_client(conn))) {
+ fixme();
CDEBUG(D_IOCTL, "disconnect: attempting to free "
"nonexistent client %u\n", conn->oc_id);
RETURN(-EINVAL);
}
-
-
- list_del(&(cli->cli_chain));
- OBD_FREE(cli, sizeof(*cli));
+ list_del(&export->export_chain);
+ kmem_cache_free(export_cachep, export);
CDEBUG(D_INFO, "disconnect: ID %u\n", conn->oc_id);
CERROR("invalid device ID starting at: %s\n", p);
GOTO(err_disconnect, rc = -EINVAL);
}
+
+ if (tmp < 0 || tmp >= MAX_OBD_DEVICES) {
+ CERROR("Trying to sub dev %d - dev no too large\n",
+ tmp);
+ GOTO(err_disconnect, rc);
+ }
- obddev->obd_multi_conn[count].oc_dev = &obd_dev[tmp];
- rc = obd_connect(&obddev->obd_multi_conn[count]);
+ rc = obd_connect(&obddev->obd_multi_conn[count], &obd_dev[tmp]);
if (rc) {
CERROR("cannot connect to device %d: rc = %d\n", tmp,
rc);
int i;
for (i = 0; i < obddev->obd_multi_count; i++) {
- int rc = obd_disconnect(&obddev->obd_multi_conn[i]);
+ int rc;
+ struct obd_device *obd = gen_conn2obd(&obddev->obd_multi_conn[i]);
+
+ if (!obd) {
+ CERROR("no such device [i %d]\n", i);
+ RETURN(-EINVAL);
+ }
+
+ rc = obd_disconnect(&obddev->obd_multi_conn[i]);
if (rc)
- CERROR("disconnect failure %d\n",
- obddev->obd_multi_conn[i].oc_dev->obd_minor);
+ CERROR("disconnect failure %d\n", obd->obd_minor);
}
return 0;
}
int gen_cleanup(struct obd_device * obddev)
{
struct list_head * lh, * tmp;
- struct obd_client * cli;
+ struct obd_export * export;
ENTRY;
- lh = tmp = &obddev->obd_gen_clients;
+ lh = tmp = &obddev->obd_exports;
while ((tmp = tmp->next) != lh) {
- cli = list_entry(tmp, struct obd_client, cli_chain);
+ export = list_entry(tmp, struct obd_export, export_chain);
CDEBUG(D_INFO, "Disconnecting obd_connection %d, at %p\n",
- cli->cli_id, cli);
+ export->export_id, export);
}
return 0;
} /* sim_cleanup_device */
p = sprintf(&page[0], "/dev/obd%d: ", obddev->obd_minor);
- if (obddev->obd_refcnt==0) {
- /* obd is unused */
- p += sprintf(&page[p], "open but unused\n");
- }
- else { /* obd in use */
- p += sprintf(&page[p], "refcnt(%d)", obddev->obd_refcnt);
-
- if (obddev->obd_flags & OBD_ATTACHED) {
- p += sprintf(&page[p], ", attached(%s)",
- obddev->obd_type->typ_name);
- }
-
- if (obddev->obd_flags & OBD_SET_UP) {
- struct dentry *my_dentry;
- struct vfsmount *root_mnt;
- char *path;
- char *pathpage;
-
- if (!(pathpage = (char*) __get_free_page(GFP_KERNEL)))
- return -ENOMEM;
-
- my_dentry = obddev->obd_fsname.dentry;
- root_mnt = mntget(current->fs->rootmnt);
- path = d_path(my_dentry,root_mnt,pathpage,PAGE_SIZE);
-
- p += sprintf(&page[p], ", setup(%s)", path);
-
- free_page((unsigned long) pathpage);
- }
+ if (obddev->obd_flags & OBD_ATTACHED) {
+ p += sprintf(&page[p], ", attached(%s)",
+ obddev->obd_type->typ_name);
+ }
+
+ if (obddev->obd_flags & OBD_SET_UP) {
+ struct dentry *my_dentry;
+ struct vfsmount *root_mnt;
+ char *path;
+ char *pathpage;
+
+ if (!(pathpage = (char*) __get_free_page(GFP_KERNEL)))
+ return -ENOMEM;
- /* print connections */
- {
- struct list_head * lh;
- struct obd_client * cli=0;
-
- lh = &obddev->obd_gen_clients;
- while ((lh = lh->next) != &obddev->obd_gen_clients) {
- p += sprintf(&page[p],
- ((cli==0) ? ", connections(" : ",") );
- cli = list_entry(lh, struct obd_client, cli_chain);
- p += sprintf(&page[p], "%d", cli->cli_id);
- } /* while */
- if (cli!=0) { /* there was at least one client */
- p += sprintf(&page[p], ")");
- }
- }
-
- p += sprintf(&page[p], "\n");
- }
+ my_dentry = NULL;
+ root_mnt = mntget(current->fs->rootmnt);
+ path = d_path(my_dentry,root_mnt,pathpage,PAGE_SIZE);
+
+ p += sprintf(&page[p], ", setup(%s)", path);
+
+ free_page((unsigned long) pathpage);
+ }
+
+ /* print connections */
+ {
+ struct list_head * lh;
+ struct obd_export * export=0;
+
+ lh = &obddev->obd_exports;
+ while ((lh = lh->next) != &obddev->obd_exports) {
+ p += sprintf(&page[p],
+ ((export==0) ? ", connections(" : ",") );
+ export = list_entry(lh, struct obd_export, export_chain);
+ p += sprintf(&page[p], "%d", export->export_id);
+ } /* while */
+ if (export!=0) { /* there was at least one export */
+ p += sprintf(&page[p], ")");
+ }
+ }
+
+ p += sprintf(&page[p], "\n");
/* Compute eof and return value */
static obd_count GEN;
static long echo_pages = 0;
-static int echo_connect(struct obd_conn *conn)
+static int echo_connect(struct obd_conn *conn, struct obd_device *obd)
{
int rc;
MOD_INC_USE_COUNT;
- rc = gen_connect(conn);
+ rc = gen_connect(conn, obd);
if (rc)
MOD_DEC_USE_COUNT;
}
/* obd methods */
-static int filter_connect(struct obd_conn *conn)
+static int filter_connect(struct obd_conn *conn, struct obd_device *obd)
{
int rc;
MOD_INC_USE_COUNT;
- rc = gen_connect(conn);
+ rc = gen_connect(conn, obd);
if (rc)
MOD_DEC_USE_COUNT;
if (!(obddev->obd_flags & OBD_SET_UP))
RETURN(0);
- if (!list_empty(&obddev->obd_gen_clients)) {
+ if (!list_empty(&obddev->obd_exports)) {
CERROR("still has clients!\n");
RETURN(-EBUSY);
}
static int filter_getattr(struct obd_conn *conn, struct obdo *oa)
{
- struct obd_device *obddev;
+ struct obd_device *obddev = gen_conn2obd(conn);
struct dentry *dentry;
ENTRY;
RETURN(-EINVAL);
}
- obddev = conn->oc_dev;
+ obddev = gen_conn2obd(conn);
dentry = filter_fid2dentry(obddev, filter_parent(obddev, oa->o_mode),
oa->o_id, oa->o_mode);
if (IS_ERR(dentry))
static int filter_setattr(struct obd_conn *conn, struct obdo *oa)
{
struct obd_run_ctxt saved;
- struct obd_device *obddev;
+ struct obd_device *obd = gen_conn2obd(conn);
struct dentry *dentry;
struct iattr iattr;
struct inode *inode;
int rc;
ENTRY;
- if (!gen_client(conn)) {
- CDEBUG(D_IOCTL, "invalid client %u\n", conn->oc_id);
- RETURN(-EINVAL);
- }
-
- obddev = conn->oc_dev;
- dentry = filter_fid2dentry(obddev, filter_parent(obddev, oa->o_mode),
+ dentry = filter_fid2dentry(obd, filter_parent(obd, oa->o_mode),
oa->o_id, oa->o_mode);
if (IS_ERR(dentry))
RETURN(PTR_ERR(dentry));
lock_kernel();
if (iattr.ia_mode & ATTR_SIZE)
down(&inode->i_sem);
- push_ctxt(&saved, &conn->oc_dev->u.filter.fo_ctxt);
+ push_ctxt(&saved, &obd->u.filter.fo_ctxt);
if (inode->i_op->setattr)
rc = inode->i_op->setattr(dentry, &iattr);
else
static int filter_open(struct obd_conn *conn, struct obdo *oa)
{
- struct obd_device *obddev;
+ struct obd_device *obd;
struct dentry *dentry;
/* ENTRY; */
RETURN(-EINVAL);
}
- obddev = conn->oc_dev;
- dentry = filter_fid2dentry(obddev, filter_parent(obddev, oa->o_mode),
+ obd = gen_conn2obd(conn);
+ dentry = filter_fid2dentry(obd, filter_parent(obd, oa->o_mode),
oa->o_id, oa->o_mode);
if (IS_ERR(dentry))
RETURN(PTR_ERR(dentry));
static int filter_close(struct obd_conn *conn, struct obdo *oa)
{
- struct obd_device *obddev;
+ struct obd_device *obd;
struct dentry *dentry;
/* ENTRY; */
RETURN(-EINVAL);
}
- obddev = conn->oc_dev;
- dentry = filter_fid2dentry(obddev, filter_parent(obddev, oa->o_mode),
+ obd = gen_conn2obd(conn);
+ dentry = filter_fid2dentry(obd, filter_parent(obd, oa->o_mode),
oa->o_id, oa->o_mode);
if (IS_ERR(dentry))
RETURN(PTR_ERR(dentry));
struct obd_run_ctxt saved;
struct file *file;
int mode;
- struct obd_device *obddev = conn->oc_dev;
+ struct obd_device *obd = gen_conn2obd(conn);
struct iattr;
ENTRY;
return -EINVAL;
}
- oa->o_id = filter_next_id(conn->oc_dev);
+ oa->o_id = filter_next_id(obd);
if (!(oa->o_mode && S_IFMT)) {
CERROR("filter obd: no type!\n");
return -ENOENT;
filter_id(name, oa->o_id, oa->o_mode);
mode = (oa->o_mode & ~S_IFMT) | S_IFREG;
- push_ctxt(&saved, &obddev->u.filter.fo_ctxt);
+ push_ctxt(&saved, &obd->u.filter.fo_ctxt);
file = filp_open(name, O_RDONLY | O_CREAT, mode);
pop_ctxt(&saved);
if (IS_ERR(file)) {
static int filter_destroy(struct obd_conn *conn, struct obdo *oa)
{
struct obd_run_ctxt saved;
- struct obd_device *obddev;
- struct obd_client *cli;
+ struct obd_device *obd;
+ struct obd_export *export;
struct inode *inode;
struct dentry *dir_dentry, *object_dentry;
int rc;
ENTRY;
- if (!(cli = gen_client(conn))) {
+ if (!(export = gen_client(conn))) {
CERROR("invalid client %u\n", conn->oc_id);
RETURN(-EINVAL);
}
CDEBUG(D_INODE, "destroying object %Ld\n",oa->o_id);
- obddev = conn->oc_dev;
+ obd = gen_conn2obd(conn);
- dir_dentry = filter_parent(obddev, oa->o_mode);
+ dir_dentry = filter_parent(obd, oa->o_mode);
down(&dir_dentry->d_inode->i_sem);
- object_dentry = filter_fid2dentry(obddev, dir_dentry, oa->o_id,
+ object_dentry = filter_fid2dentry(obd, dir_dentry, oa->o_id,
oa->o_mode);
if (IS_ERR(object_dentry))
GOTO(out, rc = -ENOENT);
}
inode->i_mode = S_IFREG;
- push_ctxt(&saved, &obddev->u.filter.fo_ctxt);
+ push_ctxt(&saved, &obd->u.filter.fo_ctxt);
rc = vfs_unlink(dir_dentry->d_inode, object_dentry);
pop_ctxt(&saved);
RETURN(error);
}
-/* buffer must lie in user memory here */
-static int filter_read(struct obd_conn *conn, struct obdo *oa, char *buf,
- obd_size *count, obd_off offset)
-{
- struct file * file;
- unsigned long retval;
- int err;
- ENTRY;
-
- if (!gen_client(conn)) {
- CDEBUG(D_IOCTL, "invalid client %u\n", conn->oc_id);
- RETURN(-EINVAL);
- }
-
- file = filter_obj_open(conn->oc_dev, oa->o_id, oa->o_mode);
- if (IS_ERR(file))
- RETURN(PTR_ERR(file));
-
- /* count doubles as retval */
- retval = file->f_op->read(file, buf, *count, (loff_t *)&offset);
- filp_close(file, 0);
-
- if ( retval >= 0 ) {
- err = 0;
- *count = retval;
- } else {
- err = retval;
- *count = 0;
- }
-
- return err;
-}
-
-
-/* buffer must lie in user memory here */
-static int filter_write(struct obd_conn *conn, struct obdo *oa, char *buf,
- obd_size *count, obd_off offset)
-{
- struct obd_run_ctxt saved;
- int err;
- struct file * file;
- unsigned long retval;
- ENTRY;
-
- if (!gen_client(conn)) {
- CDEBUG(D_IOCTL, "invalid client %u\n", conn->oc_id);
- RETURN(-EINVAL);
- }
-
- file = filter_obj_open(conn->oc_dev, oa->o_id, oa->o_mode);
- if (IS_ERR(file))
- RETURN(PTR_ERR(file));
-
- /* count doubles as retval */
- push_ctxt(&saved, &conn->oc_dev->u.filter.fo_ctxt);
- retval = file->f_op->write(file, buf, *count, (loff_t *)&offset);
- pop_ctxt(&saved);
- filp_close(file, 0);
-
- if ( retval >= 0 ) {
- err = 0;
- *count = retval;
- EXIT;
- } else {
- err = retval;
- *count = 0;
- EXIT;
- }
-
- return err;
-} /* filter_write */
-
static int filter_pgcache_brw(int cmd, struct obd_conn *conn, obd_count num_oa,
struct obdo **oa, obd_count *oa_bufs,
struct page **pages, obd_size *count,
unsigned long retval;
int error;
struct file *file;
+ struct obd_device *obd = gen_conn2obd(conn);
ENTRY;
if (!gen_client(conn)) {
RETURN(-EINVAL);
}
- sb = conn->oc_dev->u.filter.fo_sb;
- push_ctxt(&saved, &conn->oc_dev->u.filter.fo_ctxt);
+ sb = obd->u.filter.fo_sb;
+ push_ctxt(&saved, &obd->u.filter.fo_ctxt);
pnum = 0; /* pnum indexes buf 0..num_pages */
for (onum = 0; onum < num_oa; onum++) {
int pg;
- file = filter_obj_open(conn->oc_dev, oa[onum]->o_id,
- oa[onum]->o_mode);
+ file = filter_obj_open(obd, oa[onum]->o_id, oa[onum]->o_mode);
if (IS_ERR(file))
GOTO(out, retval = PTR_ERR(file));
struct inode *ioobj_to_inode(struct obd_conn *conn, struct obd_ioobj *o)
{
- struct super_block *sb = conn->oc_dev->u.filter.fo_sb;
+ struct obd_device *obd = gen_conn2obd(conn);
+ struct super_block *sb = obd->u.filter.fo_sb;
struct inode *inode = NULL;
ENTRY;
RETURN(NULL);
}
- inode = filter_inode_from_obj(conn->oc_dev, o->ioo_id, S_IFREG);
+ inode = filter_inode_from_obj(obd, o->ioo_id, S_IFREG);
if (!inode || inode->i_nlink == 0 || is_bad_inode(inode)) {
CERROR("from obdo - fatal: invalid inode %ld (%s).\n",
(long)o->ioo_id, inode ? inode->i_nlink ? "bad inode" :
struct niobuf_local *res, void **desc_private)
{
struct obd_run_ctxt saved;
- struct obd_device *obddev;
+ struct obd_device *obd;
struct obd_ioobj *o = obj;
struct niobuf_remote *b = nb;
struct niobuf_local *r = res;
ENTRY;
memset(res, 0, sizeof(*res) * niocount);
- obddev = conn->oc_dev;
+ obd = gen_conn2obd(conn);
- push_ctxt(&saved, &obddev->u.filter.fo_ctxt);
+ push_ctxt(&saved, &obd->u.filter.fo_ctxt);
if (cmd & OBD_BRW_WRITE) {
*desc_private = filter_journal_start(&journal_save,
- &obddev->u.filter,
+ &obd->u.filter,
objcount, obj, niocount,
nb);
if (IS_ERR(*desc_private))
struct inode *inode;
int j;
- dentry = filter_fid2dentry(obddev,
- filter_parent(obddev, S_IFREG),
+ dentry = filter_fid2dentry(obd,
+ filter_parent(obd, S_IFREG),
o->ioo_id, S_IFREG);
if (IS_ERR(dentry))
GOTO(out_clean, rc = PTR_ERR(dentry));
out_stop:
if (cmd & OBD_BRW_WRITE) {
- int err = filter_journal_stop(journal_save, &obddev->u.filter,
+ int err = filter_journal_stop(journal_save, &obd->u.filter,
*desc_private);
if (!rc)
rc = err;
struct obd_run_ctxt saved;
struct obd_ioobj *o = obj;
struct niobuf_local *r = res;
+ struct obd_device *obd = gen_conn2obd(conn);
void *journal_save;
int found_locked = 0;
int rc = 0;
int i;
ENTRY;
- push_ctxt(&saved, &conn->oc_dev->u.filter.fo_ctxt);
+ push_ctxt(&saved, &obd->u.filter.fo_ctxt);
journal_save = current->journal_info;
if (journal_save)
CERROR("Existing handle %p???\n", journal_save);
RETURN(-EINVAL);
}
- sb = conn->oc_dev->u.filter.fo_sb;
+ sb = gen_conn2obd(conn)->u.filter.fo_sb;
err = sb->s_op->statfs(sb, statfs);
RETURN(err);
static int filter_get_info(struct obd_conn *conn, obd_count keylen,
void *key, obd_count *vallen, void **val)
{
- struct obd_device *obddev;
- struct obd_client * cli;
+ struct obd_device *obd;
+ struct obd_export * export;
ENTRY;
- if (!(cli = gen_client(conn))) {
+ if (!(export = gen_client(conn))) {
CDEBUG(D_IOCTL, "invalid client %u\n", conn->oc_id);
RETURN(-EINVAL);
}
- obddev = conn->oc_dev;
+ obd = gen_conn2obd(conn);
if ( keylen == strlen("blocksize") &&
memcmp(key, "blocksize", keylen) == 0 ) {
*vallen = sizeof(long);
- *val = (void *)(long)obddev->u.filter.fo_sb->s_blocksize;
+ *val = (void *)(long)obd->u.filter.fo_sb->s_blocksize;
RETURN(0);
}
if ( keylen == strlen("blocksize_bits") &&
memcmp(key, "blocksize_bits", keylen) == 0 ){
*vallen = sizeof(long);
- *val = (void *)(long)obddev->u.filter.fo_sb->s_blocksize_bits;
+ *val = (void *)(long)obd->u.filter.fo_sb->s_blocksize_bits;
RETURN(0);
}
o_destroy: filter_destroy,
o_open: filter_open,
o_close: filter_close,
- o_read: filter_read,
- o_write: filter_write,
o_brw: filter_pgcache_brw,
o_punch: filter_truncate,
o_preprw: filter_preprw,
obddev = &obd_dev[devno];
sbi->osi_obd = obddev;
- sbi->osi_conn.oc_dev = obddev;
- err = obd_connect(&sbi->osi_conn);
+ err = obd_connect(&sbi->osi_conn, obddev);
if ( err ) {
CERROR("OBDFS: cannot connect to %s\n", device);
EXIT;
#include <linux/obd_ost.h>
#include <linux/obd_lov.h>
+static void osc_obd2cl(struct obd_device *obd, struct ptlrpc_client **cl,
+ struct ptlrpc_connection **connection)
+{
+ struct osc_obd *osc = &obd->u.osc;
+ *cl = osc->osc_client;
+ *connection = osc->osc_conn;
+}
+
static void osc_con2cl(struct obd_conn *conn, struct ptlrpc_client **cl,
struct ptlrpc_connection **connection)
{
- struct osc_obd *osc = &conn->oc_dev->u.osc;
+ struct osc_obd *osc = &gen_conn2obd(conn)->u.osc;
*cl = osc->osc_client;
*connection = osc->osc_conn;
}
static void osc_con2dlmcl(struct obd_conn *conn, struct ptlrpc_client **cl,
struct ptlrpc_connection **connection)
{
- struct osc_obd *osc = &conn->oc_dev->u.osc;
+ struct osc_obd *osc = &gen_conn2obd(conn)->u.osc;
*cl = osc->osc_ldlm_client;
*connection = osc->osc_conn;
}
-static int osc_connect(struct obd_conn *conn)
+static int osc_connect(struct obd_conn *conn, struct obd_device *obd)
{
- struct osc_obd *osc = &conn->oc_dev->u.osc;
+ struct osc_obd *osc = &obd->u.osc;
struct ptlrpc_request *request;
struct ptlrpc_client *cl;
struct ptlrpc_connection *connection;
int rc, size = sizeof(osc->osc_target_uuid);
ENTRY;
- osc_con2cl(conn, &cl, &connection);
+ osc_obd2cl(obd, &cl, &connection);
request = ptlrpc_prep_req(cl, connection, OST_CONNECT, 1, &size, &tmp);
if (!request)
RETURN(-ENOMEM);
int *flags, void *callback, void *data, int datalen,
struct lustre_handle *lockh)
{
- struct obd_device *obddev = oconn->oc_dev;
+ struct obd_device *obddev = gen_conn2obd(oconn);
struct ptlrpc_connection *conn;
struct ptlrpc_client *cl;
struct ldlm_extent *extent = extentp;
#include <linux/lustre_net.h>
#include <linux/lustre_dlm.h>
-static int ost_destroy(struct ost_obd *ost, struct ptlrpc_request *req)
+static int ost_destroy(struct ptlrpc_request *req)
{
- struct obd_conn conn;
+ struct obd_conn *conn = (struct obd_conn *)req->rq_reqmsg;
struct ost_body *body;
int rc, size = sizeof(*body);
ENTRY;
body = lustre_msg_buf(req->rq_reqmsg, 0);
- conn.oc_id = body->connid;
- conn.oc_dev = ost->ost_tgt;
rc = lustre_pack_msg(1, &size, NULL, &req->rq_replen, &req->rq_repmsg);
if (rc)
RETURN(rc);
- req->rq_status = obd_destroy(&conn, &body->oa);
+ req->rq_status = obd_destroy(conn, &body->oa);
RETURN(0);
}
-static int ost_getattr(struct ost_obd *ost, struct ptlrpc_request *req)
+static int ost_getattr(struct ptlrpc_request *req)
{
- struct obd_conn conn;
+ struct obd_conn *conn = (struct obd_conn *)req->rq_reqmsg;
struct ost_body *body, *repbody;
int rc, size = sizeof(*body);
ENTRY;
body = lustre_msg_buf(req->rq_reqmsg, 0);
- conn.oc_id = body->connid;
- conn.oc_dev = ost->ost_tgt;
rc = lustre_pack_msg(1, &size, NULL, &req->rq_replen, &req->rq_repmsg);
if (rc)
repbody = lustre_msg_buf(req->rq_repmsg, 0);
memcpy(&repbody->oa, &body->oa, sizeof(body->oa));
- req->rq_status = obd_getattr(&conn, &repbody->oa);
+ req->rq_status = obd_getattr(conn, &repbody->oa);
RETURN(0);
}
-static int ost_open(struct ost_obd *ost, struct ptlrpc_request *req)
+static int ost_open(struct ptlrpc_request *req)
{
- struct obd_conn conn;
+ struct obd_conn *conn = (struct obd_conn *)req->rq_reqmsg;
struct ost_body *body, *repbody;
int rc, size = sizeof(*body);
ENTRY;
body = lustre_msg_buf(req->rq_reqmsg, 0);
- conn.oc_id = body->connid;
- conn.oc_dev = ost->ost_tgt;
rc = lustre_pack_msg(1, &size, NULL, &req->rq_replen, &req->rq_repmsg);
if (rc)
repbody = lustre_msg_buf(req->rq_repmsg, 0);
memcpy(&repbody->oa, &body->oa, sizeof(body->oa));
- req->rq_status = obd_open(&conn, &repbody->oa);
+ req->rq_status = obd_open(conn, &repbody->oa);
RETURN(0);
}
-static int ost_close(struct ost_obd *ost, struct ptlrpc_request *req)
+static int ost_close(struct ptlrpc_request *req)
{
- struct obd_conn conn;
+ struct obd_conn *conn = (struct obd_conn *)req->rq_reqmsg;
struct ost_body *body, *repbody;
int rc, size = sizeof(*body);
ENTRY;
body = lustre_msg_buf(req->rq_reqmsg, 0);
- conn.oc_id = body->connid;
- conn.oc_dev = ost->ost_tgt;
rc = lustre_pack_msg(1, &size, NULL, &req->rq_replen, &req->rq_repmsg);
if (rc)
repbody = lustre_msg_buf(req->rq_repmsg, 0);
memcpy(&repbody->oa, &body->oa, sizeof(body->oa));
- req->rq_status = obd_close(&conn, &repbody->oa);
+ req->rq_status = obd_close(conn, &repbody->oa);
RETURN(0);
}
-static int ost_create(struct ost_obd *ost, struct ptlrpc_request *req)
+static int ost_create(struct ptlrpc_request *req)
{
- struct obd_conn conn;
+ struct obd_conn *conn = (struct obd_conn *)req->rq_reqmsg;
struct ost_body *body, *repbody;
int rc, size = sizeof(*body);
ENTRY;
body = lustre_msg_buf(req->rq_reqmsg, 0);
- conn.oc_id = body->connid;
- conn.oc_dev = ost->ost_tgt;
rc = lustre_pack_msg(1, &size, NULL, &req->rq_replen, &req->rq_repmsg);
if (rc)
repbody = lustre_msg_buf(req->rq_repmsg, 0);
memcpy(&repbody->oa, &body->oa, sizeof(body->oa));
- req->rq_status = obd_create(&conn, &repbody->oa);
+ req->rq_status = obd_create(conn, &repbody->oa);
RETURN(0);
}
-static int ost_punch(struct ost_obd *ost, struct ptlrpc_request *req)
+static int ost_punch(struct ptlrpc_request *req)
{
- struct obd_conn conn;
+ struct obd_conn *conn = (struct obd_conn *)req->rq_reqmsg;
struct ost_body *body, *repbody;
int rc, size = sizeof(*body);
ENTRY;
body = lustre_msg_buf(req->rq_reqmsg, 0);
- conn.oc_id = body->connid;
- conn.oc_dev = ost->ost_tgt;
rc = lustre_pack_msg(1, &size, NULL, &req->rq_replen, &req->rq_repmsg);
if (rc)
repbody = lustre_msg_buf(req->rq_repmsg, 0);
memcpy(&repbody->oa, &body->oa, sizeof(body->oa));
- req->rq_status = obd_punch(&conn, &repbody->oa,
+ req->rq_status = obd_punch(conn, &repbody->oa,
repbody->oa.o_blocks, repbody->oa.o_size);
RETURN(0);
}
-static int ost_setattr(struct ost_obd *ost, struct ptlrpc_request *req)
+static int ost_setattr(struct ptlrpc_request *req)
{
- struct obd_conn conn;
+ struct obd_conn *conn = (struct obd_conn *)req->rq_reqmsg;
struct ost_body *body, *repbody;
int rc, size = sizeof(*body);
ENTRY;
body = lustre_msg_buf(req->rq_reqmsg, 0);
- conn.oc_id = body->connid;
- conn.oc_dev = ost->ost_tgt;
rc = lustre_pack_msg(1, &size, NULL, &req->rq_replen, &req->rq_repmsg);
if (rc)
repbody = lustre_msg_buf(req->rq_repmsg, 0);
memcpy(&repbody->oa, &body->oa, sizeof(body->oa));
- req->rq_status = obd_setattr(&conn, &repbody->oa);
+ req->rq_status = obd_setattr(conn, &repbody->oa);
RETURN(0);
}
static int ost_connect(struct ptlrpc_request *req)
{
- struct obd_conn conn;
struct ost_body *body;
- struct ost_obd *ost;
+ struct obd_device *target;
+ struct obd_conn conn;
char *uuid;
int rc, size = sizeof(*body), i;
ENTRY;
RETURN(0);
}
- i = obd_class_name2dev(uuid);
+ i = obd_class_uuid2dev(uuid);
if (i == -1) {
req->rq_status = -ENODEV;
RETURN(0);
}
- ost = &(obd_dev[i].u.ost);
- conn.oc_dev = ost->ost_tgt;
+ target = &obd_dev[i];
+ if (!target) {
+ req->rq_status = -ENODEV;
+ RETURN(0);
+ }
+
+ conn.addr = req->rq_reqmsg->conn;
+ conn.cookie = req->rq_reqmsg->token;
rc = lustre_pack_msg(1, &size, NULL, &req->rq_replen, &req->rq_repmsg);
if (rc)
RETURN(rc);
- req->rq_repmsg->target_id = i;
- req->rq_status = obd_connect(&conn);
+ req->rq_status = obd_connect(&conn, target);
+ req->rq_repmsg->conn = conn.addr;
+ req->rq_repmsg->token = conn.cookie;
CDEBUG(D_IOCTL, "rep buffer %p, id %d\n", req->rq_repmsg, conn.oc_id);
body = lustre_msg_buf(req->rq_repmsg, 0);
RETURN(0);
}
-static int ost_disconnect(struct ost_obd *ost, struct ptlrpc_request *req)
+static int ost_disconnect(struct ptlrpc_request *req)
{
- struct obd_conn conn;
+ struct obd_conn *conn = (struct obd_conn *)req->rq_reqmsg;
struct ost_body *body;
int rc;
ENTRY;
body = lustre_msg_buf(req->rq_reqmsg, 0);
- conn.oc_id = body->connid;
- conn.oc_dev = ost->ost_tgt;
rc = lustre_pack_msg(0, NULL, NULL, &req->rq_replen, &req->rq_repmsg);
if (rc)
RETURN(rc);
- CDEBUG(D_IOCTL, "Disconnecting %d\n", conn.oc_id);
- req->rq_status = obd_disconnect(&conn);
+ req->rq_status = obd_disconnect(conn);
RETURN(0);
}
-static int ost_get_info(struct ost_obd *ost, struct ptlrpc_request *req)
+static int ost_get_info(struct ptlrpc_request *req)
{
- struct obd_conn conn;
+ struct obd_conn *conn = (struct obd_conn *)req->rq_reqmsg;
struct ost_body *body;
int rc, size[2] = {sizeof(*body)};
char *bufs[2] = {NULL, NULL}, *ptr;
ENTRY;
body = lustre_msg_buf(req->rq_reqmsg, 0);
- conn.oc_id = body->connid;
- conn.oc_dev = ost->ost_tgt;
ptr = lustre_msg_buf(req->rq_reqmsg, 1);
if (!ptr)
RETURN(-EINVAL);
- req->rq_status = obd_get_info(&conn, req->rq_reqmsg->buflens[1], ptr,
+ req->rq_status = obd_get_info(conn, req->rq_reqmsg->buflens[1], ptr,
&(size[1]), (void **)&(bufs[1]));
rc = lustre_pack_msg(2, size, bufs, &req->rq_replen, &req->rq_repmsg);
RETURN(rc);
}
-static int ost_brw_read(struct ost_obd *obddev, struct ptlrpc_request *req)
+static int ost_brw_read(struct ptlrpc_request *req)
{
+ struct obd_conn *conn = (struct obd_conn *)req->rq_reqmsg;
struct ptlrpc_bulk_desc *desc;
- struct obd_conn conn;
void *tmp1, *tmp2, *end2;
struct niobuf_remote *remote_nb;
struct niobuf_local *local_nb = NULL;
niocount = req->rq_reqmsg->buflens[2] / sizeof(*remote_nb);
cmd = body->data;
- conn.oc_id = body->connid;
- conn.oc_dev = req->rq_obd->u.ost.ost_tgt;
-
for (i = 0; i < objcount; i++) {
ost_unpack_ioo(&tmp1, &ioo);
if (tmp2 + ioo->ioo_bufcnt > end2) {
/* The unpackers move tmp1 and tmp2, so reset them before using */
tmp1 = lustre_msg_buf(req->rq_reqmsg, 1);
tmp2 = lustre_msg_buf(req->rq_reqmsg, 2);
- req->rq_status = obd_preprw(cmd, &conn, objcount,
+ req->rq_status = obd_preprw(cmd, conn, objcount,
tmp1, niocount, tmp2, local_nb, NULL);
if (req->rq_status)
/* The unpackers move tmp1 and tmp2, so reset them before using */
tmp1 = lustre_msg_buf(req->rq_reqmsg, 1);
tmp2 = lustre_msg_buf(req->rq_reqmsg, 2);
- req->rq_status = obd_commitrw(cmd, &conn, objcount,
+ req->rq_status = obd_commitrw(cmd, conn, objcount,
tmp1, niocount, local_nb, NULL);
out_bulk:
OBD_FREE(local_nb, sizeof(*local_nb) * niocount);
out:
if (rc)
- ptlrpc_error(obddev->ost_service, req);
+ ptlrpc_error(req->rq_svc, req);
else
- ptlrpc_reply(obddev->ost_service, req);
+ ptlrpc_reply(req->rq_svc, req);
RETURN(rc);
}
-static int ost_brw_write(struct ost_obd *obddev, struct ptlrpc_request *req)
+static int ost_brw_write(struct ptlrpc_request *req)
{
+ struct obd_conn *conn = (struct obd_conn *)req->rq_reqmsg;
struct ptlrpc_bulk_desc *desc;
- struct obd_conn conn;
struct niobuf_remote *remote_nb;
struct niobuf_local *local_nb, *lnb;
struct obd_ioobj *ioo;
niocount = req->rq_reqmsg->buflens[2] / sizeof(*remote_nb);
cmd = body->data;
- conn.oc_id = body->connid;
- conn.oc_dev = req->rq_obd->u.ost.ost_tgt;
-
for (i = 0; i < objcount; i++) {
ost_unpack_ioo((void *)&tmp1, &ioo);
if (tmp2 + ioo->ioo_bufcnt > end2) {
/* The unpackers move tmp1 and tmp2, so reset them before using */
tmp1 = lustre_msg_buf(req->rq_reqmsg, 1);
tmp2 = lustre_msg_buf(req->rq_reqmsg, 2);
- req->rq_status = obd_preprw(cmd, &conn, objcount,
+ req->rq_status = obd_preprw(cmd, conn, objcount,
tmp1, niocount, tmp2, local_nb, &desc_priv);
if (req->rq_status)
GOTO(out_free, rc = 0); /* XXX is this correct? */
GOTO(fail_bulk, rc);
reply_sent = 1;
- ptlrpc_reply(obddev->ost_service, req);
+ ptlrpc_reply(req->rq_svc, req);
wait_event_interruptible(desc->b_waitq,
desc->b_flags & PTL_BULK_FL_RCVD);
- rc = obd_commitrw(cmd, &conn, objcount, tmp1, niocount, local_nb,
+ rc = obd_commitrw(cmd, conn, objcount, tmp1, niocount, local_nb,
desc->b_desc_private);
ptlrpc_free_bulk(desc);
EXIT;
out:
if (!reply_sent) {
if (rc)
- ptlrpc_error(obddev->ost_service, req);
+ ptlrpc_error(req->rq_svc, req);
else
- ptlrpc_reply(obddev->ost_service, req);
+ ptlrpc_reply(req->rq_svc, req);
}
return rc;
goto out_free;
}
-static int ost_brw(struct ost_obd *obddev, struct ptlrpc_request *req)
+static int ost_brw(struct ptlrpc_request *req)
{
struct ost_body *body = lustre_msg_buf(req->rq_reqmsg, 0);
if (body->data & OBD_BRW_WRITE)
- return ost_brw_write(obddev, req);
+ return ost_brw_write(req);
else
- return ost_brw_read(obddev, req);
+ return ost_brw_read(req);
}
-static int ost_handle(struct obd_device *obddev, struct ptlrpc_service *svc,
- struct ptlrpc_request *req)
+
+static int ost_handle(struct ptlrpc_request *req)
{
int rc;
- struct ost_obd *ost = NULL;
ENTRY;
rc = lustre_unpack_msg(req->rq_reqmsg, req->rq_reqlen);
}
if (req->rq_reqmsg->opc != OST_CONNECT) {
- int id = req->rq_reqmsg->target_id;
- struct obd_device *obddev;
- if (id < 0 || id > MAX_OBD_DEVICES)
- GOTO(out, rc = -ENODEV);
- obddev = &obd_dev[id];
- if (strcmp(obddev->obd_type->typ_name, "ost") != 0)
+ struct obd_export *export;
+ export = gen_client((struct obd_conn *) req->rq_reqmsg);
+ if (!export)
+ GOTO(out, rc = -ENOTCONN);
+ if (strcmp(req->rq_obd->obd_type->typ_name, "ost") != 0)
GOTO(out, rc = -EINVAL);
- ost = &obddev->u.ost;
- req->rq_obd = obddev;
}
switch (req->rq_reqmsg->opc) {
case OST_DISCONNECT:
CDEBUG(D_INODE, "disconnect\n");
OBD_FAIL_RETURN(OBD_FAIL_OST_DISCONNECT_NET, 0);
- rc = ost_disconnect(ost, req);
+ rc = ost_disconnect(req);
break;
case OST_GET_INFO:
CDEBUG(D_INODE, "get_info\n");
OBD_FAIL_RETURN(OBD_FAIL_OST_GET_INFO_NET, 0);
- rc = ost_get_info(ost, req);
+ rc = ost_get_info(req);
break;
case OST_CREATE:
CDEBUG(D_INODE, "create\n");
OBD_FAIL_RETURN(OBD_FAIL_OST_CREATE_NET, 0);
- rc = ost_create(ost, req);
+ rc = ost_create(req);
break;
case OST_DESTROY:
CDEBUG(D_INODE, "destroy\n");
OBD_FAIL_RETURN(OBD_FAIL_OST_DESTROY_NET, 0);
- rc = ost_destroy(ost, req);
+ rc = ost_destroy(req);
break;
case OST_GETATTR:
CDEBUG(D_INODE, "getattr\n");
OBD_FAIL_RETURN(OBD_FAIL_OST_GETATTR_NET, 0);
- rc = ost_getattr(ost, req);
+ rc = ost_getattr(req);
break;
case OST_SETATTR:
CDEBUG(D_INODE, "setattr\n");
OBD_FAIL_RETURN(OBD_FAIL_OST_SETATTR_NET, 0);
- rc = ost_setattr(ost, req);
+ rc = ost_setattr(req);
break;
case OST_OPEN:
CDEBUG(D_INODE, "setattr\n");
OBD_FAIL_RETURN(OBD_FAIL_OST_OPEN_NET, 0);
- rc = ost_open(ost, req);
+ rc = ost_open(req);
break;
case OST_CLOSE:
CDEBUG(D_INODE, "setattr\n");
OBD_FAIL_RETURN(OBD_FAIL_OST_CLOSE_NET, 0);
- rc = ost_close(ost, req);
+ rc = ost_close(req);
break;
case OST_BRW:
CDEBUG(D_INODE, "brw\n");
OBD_FAIL_RETURN(OBD_FAIL_OST_BRW_NET, 0);
- rc = ost_brw(ost, req);
+ rc = ost_brw(req);
/* ost_brw sends its own replies */
RETURN(rc);
case OST_PUNCH:
CDEBUG(D_INODE, "punch\n");
OBD_FAIL_RETURN(OBD_FAIL_OST_PUNCH_NET, 0);
- rc = ost_punch(ost, req);
+ rc = ost_punch(req);
break;
#if 0
case OST_STATFS:
CDEBUG(D_INODE, "statfs\n");
OBD_FAIL_RETURN(OBD_FAIL_OST_STATFS_NET, 0);
- rc = ost_statfs(ost, req);
+ rc = ost_statfs(req);
break;
#endif
default:
req->rq_status = -ENOTSUPP;
- rc = ptlrpc_error(svc, req);
+ rc = ptlrpc_error(req->rq_svc, req);
RETURN(rc);
}
//req->rq_status = rc;
if (rc) {
CERROR("ost: processing error %d\n", rc);
- ptlrpc_error(svc, req);
+ ptlrpc_error(req->rq_svc, req);
} else {
CDEBUG(D_INODE, "sending reply\n");
- ptlrpc_reply(svc, req);
+ ptlrpc_reply(req->rq_svc, req);
}
return 0;
MOD_INC_USE_COUNT;
tgt = &obd_dev[data->ioc_dev];
- ost->ost_tgt = tgt;
if (!(tgt->obd_flags & OBD_ATTACHED) ||
!(tgt->obd_flags & OBD_SET_UP)) {
CERROR("device not attached or not set up (%d)\n",
GOTO(error_dec, err = -EINVAL);
}
- ost->ost_conn.oc_dev = tgt;
- err = obd_connect(&ost->ost_conn);
+ err = obd_connect(&ost->ost_conn, tgt);
if (err) {
CERROR("fail to connect to device %d\n", data->ioc_dev);
GOTO(error_dec, err = -EINVAL);
ENTRY;
- if ( !list_empty(&obddev->obd_gen_clients) ) {
+ if ( !list_empty(&obddev->obd_exports) ) {
CERROR("still has clients!\n");
RETURN(-EBUSY);
}
RETURN(0);
}
-int connmgr_handle(struct obd_device *dev, struct ptlrpc_service *svc,
- struct ptlrpc_request *req)
+int connmgr_handle(struct ptlrpc_request *req)
{
int rc;
ENTRY;
break;
default:
- rc = ptlrpc_error(svc, req);
+ rc = ptlrpc_error(req->rq_svc, req);
RETURN(rc);
}
EXIT;
out:
if (rc) {
- ptlrpc_error(svc, req);
+ ptlrpc_error(req->rq_svc, req);
} else {
CDEBUG(D_NET, "sending reply\n");
- ptlrpc_reply(svc, req);
+ ptlrpc_reply(req->rq_svc, req);
}
return 0;
int connmgr_iocontrol(long cmd, struct obd_conn *conn, int len, void *karg,
void *uarg)
{
- struct recovd_obd *recovd = &conn->oc_dev->u.recovd;
+ struct obd_device *obd = gen_conn2obd(conn);
+ struct recovd_obd *recovd = &obd->u.recovd;
ENTRY;
if (cmd == OBD_IOC_RECOVD_NEWCONN) {
* on the stack of mds_handle instead. */
start = event->mem_desc.start;
memset(&request, 0, sizeof(request));
+ request.rq_svc = svc;
request.rq_obd = obddev;
request.rq_xid = event->match_bits;
request.rq_reqmsg = event->mem_desc.start + event->offset;
}
spin_unlock(&svc->srv_lock);
- rc = svc->srv_handler(obddev, svc, &request);
+ rc = svc->srv_handler(&request);
ptlrpc_put_connection(request.rq_connection);
ptl_handled_rpc(svc, start);
return rc;
$OBDCTL <<- EOF || return $?
newdev
- attach mds MDSDEV
+ attach mds MDSDEV MDSUUID
setup ${MDS} ${MDSFS}
quit
EOF
$OBDCTL <<- EOF || return $?
newdev
- attach ${OSTTYPE} OBDDEV
+ attach ${OSTTYPE} OBDDEV OBDUUID
setup ${OBD} ${OBDARG}
quit
EOF
$OBDCTL <<- EOF || return $?
newdev
- attach ost OSTDEV
+ attach ost OSTDEV OSTUUID
setup \$OBDDEV
quit
EOF
$OBDCTL <<- EOF || return $rc
newdev
attach osc $THEOSC
- setup OSTDEV $OSTNODE
+ setup OBDUUID $OSTNODE
quit
EOF
done
int fd = -1;
-int connid = -1;
+uint64_t conn_addr = -1;
+uint64_t conn_cookie;
char rawbuf[8192];
char *buf = rawbuf;
int max = 8192;
do { \
memset(&data, 0, sizeof(data)); \
data.ioc_version = OBD_IOCTL_VERSION; \
- data.ioc_conn1 = connid; \
+ data.ioc_addr = conn_addr; \
+ data.ioc_cookie = conn_cookie; \
data.ioc_len = sizeof(data); \
if (fd < 0) { \
fprintf(stderr, "No device open, use device\n"); \
return 0;
}
-#if 1
#define difftime(a, b) \
((double)(a)->tv_sec - (b)->tv_sec + \
((double)((a)->tv_usec - (b)->tv_usec) / 1000000))
-#else
-
-#define difftime(a, b) (((a)->tv_sec - (b)->tv_sec) + \
- (((a)->tv_usec - (b)->tv_usec) / 1000000))
-#endif
static int be_verbose(int verbose, struct timeval *next_time,
int num, int *next_num, int num_total)
{
struct obd_ioctl_data data;
- if (connid == -1)
- return 0;
+ if (conn_addr == -1)
+ return 0;
IOCINIT(data);
OBD_IOC_DISCONNECT, strerror(errno));
} else {
if (verbose)
- printf("%s: disconnected connid %d\n", cmdname(func),
- connid);
- connid = -1;
+ printf("%s: disconnected conn %Lx\n", cmdname(func),
+ conn_addr);
+ conn_addr = -1;
}
return rc;
fprintf(stderr, "error: %s: %x %s\n", cmdname(argv[0]),
OBD_IOC_CONNECT, strerror(rc = errno));
else
- connid = data.ioc_conn1;
-
+ conn_addr = data.ioc_addr;
+ conn_cookie = data.ioc_cookie;
return rc;
}
return -1;
}
+ if (conn_addr == -1)
+ return 0;
+
return do_disconnect(argv[0], 0);
}
return rc;
}
+static int jt_list(int argc, char **argv)
+{
+ char buf[1024];
+ struct obd_ioctl_data *data = (struct obd_ioctl_data *)buf;
+
+ if (getfd(argv[0]))
+ return -1;
+
+ memset(buf, 0, sizeof(buf));
+ data->ioc_version = OBD_IOCTL_VERSION;
+ data->ioc_addr = conn_addr;
+ data->ioc_cookie = conn_addr;
+ data->ioc_len = sizeof(buf);
+ data->ioc_inllen1 = sizeof(buf) - size_round(sizeof(*data));
+
+ if (argc != 1) {
+ fprintf(stderr, "usage: %s\n", cmdname(argv[0]));
+ return -1;
+ }
+
+ rc = ioctl(fd, OBD_IOC_LIST , data);
+ if (rc < 0)
+ fprintf(stderr, "error: %s: %s\n", cmdname(argv[0]),
+ strerror(rc=errno));
+ else {
+ printf("%s", data->ioc_bulk);
+ }
+
+ return rc;
+}
+
static int jt_attach(int argc, char **argv)
{
struct obd_ioctl_data data;
IOCINIT(data);
- if (argc != 2 && argc != 3) {
+ if (argc != 2 && argc != 3 && argc != 4) {
fprintf(stderr, "usage: %s type [name [uuid]]\n",
cmdname(argv[0]));
return -1;
data.ioc_inllen1 = strlen(argv[1]) + 1;
data.ioc_inlbuf1 = argv[1];
- if (argc == 3) {
+ if (argc >= 3) {
data.ioc_inllen2 = strlen(argv[2]) + 1;
data.ioc_inlbuf2 = argv[2];
}
+ if (argc == 4) {
+ data.ioc_inllen3 = strlen(argv[3]) + 1;
+ data.ioc_inlbuf3 = argv[3];
+ }
+
if (obd_ioctl_pack(&data, &buf, max)) {
fprintf(stderr, "error: %s: invalid ioctl\n", cmdname(argv[0]));
return -2;
return -2;
}
IOCINIT(data);
- data.ioc_conn2 = connid;
data.ioc_obdo1.o_id = 2;
data.ioc_count = len;
data.ioc_offset = 0;
"--threads <threads> <devno> <command [args ...]>"},
/* Device configuration commands */
+ {"list", jt_list, 0, "list the devices (no args)"},
{"newdev", jt_newdev, 0, "set device to a new unused obd (no args)"},
{"device", jt_device, 0, "set current device (args device_no name)"},
{"name2dev", jt_name2dev, 0, "set device by name (args name)"},