# See the file COPYING in this distribution
AUTOMAKE_OPTIONS = foreign
-SUBDIRS = ptlrpc llite lib ldlm obdecho mdc osc extN mds ost utils tests obdfilter
-SUBDIRS+= obdclass obdext2 obdfs demos doc scripts
+
+# NOTE: keep extN before mds
+SUBDIRS = ptlrpc llite lib ldlm obdecho mdc osc extN mds ost
+SUBDIRS+= utils tests obdfilter obdclass obdfs demos doc scripts
EXTRA_DIST = BUGS FDL Rules include patches
# We get the version from the spec file.
SUFFIXES = .lyx .pdf .sgml .html .txt .fig .eps
DOCS = master.pdf lustre-HOWTO.txt
-IMAGES = bigpicture.eps intermezzo.eps mds.eps portals-lib.eps client.eps layering.eps metadata.eps sb.eps cow.eps lockacq.eps obdfs.eps snapsetup.eps dirbodyapi.eps loraid.eps ost.eps updates.eps hotmigrate.eps lustreclusters.eps osthw.eps portals-lib.eps
+IMAGES = networklayer.fig bigpicture.eps intermezzo.eps mds.eps portals.eps client.eps layering.eps metadata.eps sb.eps cow.eps lockacq.eps obdfs.eps snapsetup.eps dirbodyapi.eps loraid.eps ost.eps updates.eps hotmigrate.eps lustreclusters.eps osthw.eps portals-lib.eps lockqueues.eps lockexample1.eps lockexample2.eps lockexample3.eps lockexample4.eps lockseverity.eps
CLEANFILES = $(IMAGES) $(DOCS)
EXTRA_DIST = $(DOCS)
master.pdf: master.lyx $(IMAGES)
+syncweb: master.pdf
+ cp master.pdf /usr/src/www/content/lustre/docs/master.pdf
+ ( cd /usr/src/www ; make lustre ; make synclustre )
+
dist-hook:
rm -rf $(distdir)/figs/CVS
0.0.1 2/19/2002 <braam@clusterfs.com>
0.0.2 3/14/2002 <braam@clusterfs.com> describe branches / stable tag
+0.0.3 6/10/2002 <braam@clusterfs.com> describe release mechanisms
This document describes versioning of source and binaries for Lustre.
+Packages
+========
+
+RPM's that you build should get 3 figure versions, CVS versions will
+be 4 digits, and can correspond to test RPM's, and lead up to the
+package version. So let's plan on releasing
+
+So you'd build 2 sets of test rpms this week:
+
+0.0.9.1
+0.0.9.2
+
+we decide it's fine then and we release
+
+0.1.0
+
+We go on developing with
+
+0.1.0.{1,2,3,4,...}
+
+as test releases and then we release:
+
+0.1.1
+
+The 0.1 sequence is an unstable sequence, like 2.5 for the kernel is.
+So we expect lots of 0.1.X releases leading up to a stable 0.2 (or
+1.0) at the time of deployment.
+
CVS
===
What will run, what won't ?
---------------------------
-1. If the test level is non-zero no guarantees of any kind are made.
+1. If the test level is non-zero, i.e. there are 4 digits in the
+ version, no guarantees of any kind are made.
2. For three digit releases/tags the code should perform
according to the announcement.
Moving tags
-----------
-The last stable release will be tagged: CVS tag "stable"
+The last stable release will be tagged: CVS tag "t_last_stable"
The last operational development snapshot will be CVS tag "dstable"
Branches
cvs update -A
-fixing any conflicts and then committing.
\ No newline at end of file
+fixing any conflicts and then committing.
#define OBD_LDLM_DEVICENAME "ldlm"
-typedef int cluster_host;
-typedef int cluster_pid;
-
typedef enum {
ELDLM_OK = 0,
ELDLM_LOCK_CHANGED = 300,
+ ELDLM_LOCK_ABORTED = 301,
+ ELDLM_RESOURCE_FREED = 302,
ELDLM_NAMESPACE_EXISTS = 400,
ELDLM_BAD_NAMESPACE = 401
} ldlm_error_t;
+#define LDLM_NAMESPACE_SERVER 0
+#define LDLM_NAMESPACE_CLIENT 1
+
#define LDLM_FL_LOCK_CHANGED (1 << 0)
#define LDLM_FL_BLOCK_GRANTED (1 << 1)
#define LDLM_FL_BLOCK_CONV (1 << 2)
#define LDLM_FL_BLOCK_WAIT (1 << 3)
#define LDLM_FL_DYING (1 << 4)
+#define LDLM_FL_AST_SENT (1 << 5)
#define L2B(c) (1 << c)
*/
struct ldlm_namespace {
- struct obd_device *ns_obddev;
- __u32 ns_local; /* is this a local lock tree? */
- struct list_head *ns_hash; /* hash table for ns */
- __u32 ns_refcount; /* count of resources in the hash */
- struct list_head ns_root_list; /* all root resources in ns */
- spinlock_t ns_lock; /* protects hash, refcount, list */
+ struct ptlrpc_client ns_client; /* used for revocation callbacks */
+ __u32 ns_local; /* is this a local lock tree? */
+ struct list_head *ns_hash; /* hash table for ns */
+ __u32 ns_refcount; /* count of resources in the hash */
+ struct list_head ns_root_list; /* all root resources in ns */
+ spinlock_t ns_lock; /* protects hash, refcount, list */
};
/*
struct ptlrpc_connection *l_connection;
struct ptlrpc_client *l_client;
__u32 l_flags;
- struct ldlm_handle l_remote_handle;
+ struct lustre_handle l_remote_handle;
void *l_data;
__u32 l_data_len;
+ void *l_cookie;
+ int l_cookie_len;
struct ldlm_extent l_extent;
- //void *l_event;
- //XXX cluster_host l_holder;
__u32 l_version[RES_VERSION_SIZE];
__u32 l_readers;
};
typedef int (*ldlm_res_compat)(struct ldlm_lock *child, struct ldlm_lock *new);
-typedef int (*ldlm_res_policy)(struct ldlm_resource *parent,
- struct ldlm_extent *req_ex,
- struct ldlm_extent *new_ex,
+typedef int (*ldlm_res_policy)(struct ldlm_lock *lock, void *req_cookie,
ldlm_mode_t mode, void *data);
#define LDLM_PLAIN 0
ldlm_mode_t lr_most_restr;
__u32 lr_type; /* PLAIN, EXTENT, or MDSINTENT */
struct ldlm_resource *lr_root;
- //XXX cluster_host lr_master;
__u64 lr_name[RES_NAME_SIZE];
__u32 lr_version[RES_VERSION_SIZE];
__u32 lr_refcount;
return (struct ldlm_extent *)(res->lr_name);
}
-static inline void *ldlm_handle2object(struct ldlm_handle *handle)
-{
- if (handle)
- return (void *)(unsigned long)(handle->addr);
- return NULL;
-}
-
-static inline void ldlm_object2handle(void *object, struct ldlm_handle *handle)
-{
- handle->addr = (__u64)(unsigned long)object;
-}
-
extern struct obd_ops ldlm_obd_ops;
/* ldlm_extent.c */
int ldlm_extent_compat(struct ldlm_lock *, struct ldlm_lock *);
-int ldlm_extent_policy(struct ldlm_resource *, struct ldlm_extent *,
- struct ldlm_extent *, ldlm_mode_t, void *);
+int ldlm_extent_policy(struct ldlm_lock *, void *, ldlm_mode_t, void *);
/* ldlm_lock.c */
void ldlm_lock_free(struct ldlm_lock *lock);
void ldlm_lock_decref(struct ldlm_lock *lock, __u32 mode);
void ldlm_grant_lock(struct ldlm_resource *res, struct ldlm_lock *lock);
int ldlm_local_lock_match(struct ldlm_namespace *ns, __u64 *res_id, __u32 type,
- struct ldlm_extent *extent, ldlm_mode_t mode,
- struct ldlm_handle *lockh);
+ void *cookie, int cookielen, ldlm_mode_t mode,
+ struct lustre_handle *lockh);
ldlm_error_t ldlm_local_lock_create(struct ldlm_namespace *ns,
- struct ldlm_handle *parent_lock_handle,
+ struct lustre_handle *parent_lock_handle,
__u64 *res_id, __u32 type,
ldlm_mode_t mode,
void *data,
__u32 data_len,
- struct ldlm_handle *lockh);
-ldlm_error_t ldlm_local_lock_enqueue(struct ldlm_handle *lockh,
- struct ldlm_extent *req_ex,
+ struct lustre_handle *lockh);
+ldlm_error_t ldlm_local_lock_enqueue(struct lustre_handle *lockh,
+ void *cookie, int cookie_len,
int *flags,
ldlm_lock_callback completion,
ldlm_lock_callback blocking);
-struct ldlm_resource *ldlm_local_lock_convert(struct ldlm_handle *lockh,
+struct ldlm_resource *ldlm_local_lock_convert(struct lustre_handle *lockh,
int new_mode, int *flags);
struct ldlm_resource *ldlm_local_lock_cancel(struct ldlm_lock *lock);
void ldlm_reprocess_all(struct ldlm_resource *res);
int ldlm_test(struct obd_device *device, struct ptlrpc_connection *conn);
/* resource.c */
-struct ldlm_namespace *ldlm_namespace_new(struct obd_device *, __u32 local);
+struct ldlm_namespace *ldlm_namespace_new(__u32 local);
int ldlm_namespace_free(struct ldlm_namespace *ns);
+
+/* resourc.c - internal */
struct ldlm_resource *ldlm_resource_get(struct ldlm_namespace *ns,
struct ldlm_resource *parent,
__u64 *name, __u32 type, int create);
void ldlm_resource_dump(struct ldlm_resource *res);
/* ldlm_request.c */
-int ldlm_cli_enqueue(struct ptlrpc_client *cl, struct ptlrpc_connection *peer,
+int ldlm_cli_enqueue(struct ptlrpc_client *cl,
+ struct ptlrpc_connection *peer,
+ struct ptlrpc_request *req,
struct ldlm_namespace *ns,
- struct ldlm_handle *parent_lock_handle,
+ struct lustre_handle *parent_lock_handle,
__u64 *res_id,
__u32 type,
- struct ldlm_extent *req_ex,
+ void *cookie, int cookielen,
ldlm_mode_t mode,
int *flags,
+ ldlm_lock_callback callback,
void *data,
__u32 data_len,
- struct ldlm_handle *lockh);
+ struct lustre_handle *lockh);
int ldlm_cli_callback(struct ldlm_lock *lock, struct ldlm_lock *new,
void *data, __u32 data_len);
-int ldlm_cli_convert(struct ptlrpc_client *, struct ldlm_handle *,
+int ldlm_cli_convert(struct ptlrpc_client *, struct lustre_handle *,
int new_mode, int *flags);
int ldlm_cli_cancel(struct ptlrpc_client *, struct ldlm_lock *);
#define PTL_RPC_MSG_REQUEST 4711
#define PTL_RPC_MSG_ERR 4712
+struct lustre_handle {
+ __u64 addr;
+ __u64 cookie;
+};
+
struct lustre_msg {
- __u64 conn;
- __u64 token;
+ __u64 conn; /* pointer to ptlrpc_connection */
+ __u64 token; /* security token */
- __u32 opc;
- __u32 xid;
__u64 last_rcvd;
__u64 last_committed;
__u64 transno;
+ __u32 opc;
__u32 status;
__u32 type;
- __u32 connid;
+ __u32 target_id;
__u32 bufcount;
__u32 buflens[0];
};
#define OBD_FL_INLINEDATA (0x00000001)
#define OBD_FL_OBDMDEXISTS (0x00000002)
+#define OBD_FL_CREATEONOPEN (0x00000004)
#define OBD_INLINESZ 60
#define OBD_OBDMDSZ 60
#define MDS_REINT 4
#define MDS_READPAGE 6
#define MDS_CONNECT 7
-#define MDS_STATFS 8
+#define MDS_DISCONNECT 8
+#define MDS_GETSTATUS 9
+#define MDS_STATFS 10
#define REINT_SETATTR 1
#define REINT_CREATE 2
LCK_NL
} ldlm_mode_t;
-struct ldlm_handle {
- __u64 addr;
- __u64 cookie;
-};
-
struct ldlm_extent {
__u64 start;
__u64 end;
};
+struct ldlm_intent {
+ __u64 opc;
+};
+
struct ldlm_resource_desc {
__u32 lr_type;
__u64 lr_name[RES_NAME_SIZE];
};
struct ldlm_request {
- __u32 flags;
+ __u32 lock_flags;
struct ldlm_lock_desc lock_desc;
- struct ldlm_handle lock_handle1;
- struct ldlm_handle lock_handle2;
+ struct lustre_handle lock_handle1;
+ struct lustre_handle lock_handle2;
};
struct ldlm_reply {
- __u32 flags;
- struct ldlm_handle lock_handle;
- struct ldlm_extent lock_extent;
+ __u32 lock_flags;
+ __u64 lock_resource_name[3];
+ struct lustre_handle lock_handle;
+ struct ldlm_extent lock_extent; /* XXX make this policy 1 &2 */
+ __u64 lock_policy_res1;
+ __u64 lock_policy_res2;
};
/*
* OBD IOCTLS
*/
-
-
#define OBD_IOCTL_VERSION 0x00010001
struct obd_ioctl_data {
# include <string.h>
#endif
+#include <linux/portals_lib.h>
+#include <linux/lustre_idl.h>
+
#ifdef __KERNEL__
/* page.c */
inline void lustre_put_page(struct page *page);
}
#endif
+/* FIXME: This needs to validate pointers and cookies */
+static inline void *lustre_handle2object(struct lustre_handle *handle)
+{
+ if (handle)
+ return (void *)(unsigned long)(handle->addr);
+ return NULL;
+}
+
+static inline void ldlm_object2handle(void *object, struct lustre_handle *handle)
+{
+ handle->addr = (__u64)(unsigned long)object;
+}
+
+
#include <linux/portals_lib.h>
#endif /* _LUSTRE_LIB_H */
struct obdo *lli_obdo;
char *lli_symlink_name;
char lli_inline[LL_INLINESZ];
+ struct lustre_handle lli_intent_lock_handle;
};
#define LL_SUPER_MAGIC 0x0BD00BD0
#define LL_COMMITCBD_RUNNING 0x4
struct ll_sb_info {
- struct obd_conn ll_conn;
+ struct obd_conn ll_mdc_conn;
+ struct obd_conn ll_osc_conn;
ino_t ll_rootino; /* number of root inode */
- struct ptlrpc_client ll_mds_client;
- struct ptlrpc_connection *ll_mds_conn;
- struct ldlm_namespace *ll_namespace;
wait_queue_head_t ll_commitcbd_waitq;
wait_queue_head_t ll_commitcbd_ctl_waitq;
int ll_commitcbd_flags;
- struct task_struct *ll_commitcbd_thread;
+ struct task_struct *ll_commitcbd_thread;
time_t ll_commitcbd_waketime;
time_t ll_commitcbd_timeout;
spinlock_t ll_commitcbd_lock;
static inline struct obd_conn *ll_s2obdconn(struct super_block *sb)
{
- return &(ll_s2sbi(sb))->ll_conn;
+ return &(ll_s2sbi(sb))->ll_osc_conn;
+}
+
+static inline struct mdc_obd *sbi2mdc(struct ll_sb_info *sbi)
+{
+ struct obd_device *obd = sbi->ll_mdc_conn.oc_dev;
+ return &obd->u.mdc;
}
static inline struct ll_sb_info *ll_i2sbi(struct inode *inode)
inode->i_mode & S_IFMT);
}
+/* namei.c */
+int ll_lock(struct inode *dir, struct dentry *dentry,
+ struct lookup_intent *it, struct lustre_handle *lockh);
+int ll_unlock(__u32 mode, struct lustre_handle *lockh);
+
+
+
/* dir.c */
extern struct file_operations ll_dir_operations;
extern struct inode_operations ll_dir_inode_operations;
#include <linux/obd_class.h>
#include <linux/lustre_idl.h>
#include <linux/lustre_net.h>
+#include <linux/lustre_dlm.h>
#include <linux/obd_lov.h> /* for lov_md */
#define LUSTRE_MDS_NAME "mds"
+#define LUSTRE_MDC_NAME "mdc"
struct mds_update_record {
__u32 ur_opcode;
};
/* mds/mds_reint.c */
-int mds_reint_rec(struct mds_update_record *r, struct ptlrpc_request *req);
+int mds_reint_rec(struct mds_update_record *r, int offset,
+ struct ptlrpc_request *req);
struct mds_client_info *mds_uuid_to_mci(struct mds_obd *mds, __u8 *uuid);
/* lib/mds_updates.c */
+void mds_unpack_body(struct mds_body *b);
void mds_pack_req_body(struct ptlrpc_request *);
void mds_pack_rep_body(struct ptlrpc_request *);
-void mds_unpack_req_body(struct ptlrpc_request *);
-void mds_unpack_rep_body(struct ptlrpc_request *);
-int mds_update_unpack(struct ptlrpc_request *, struct mds_update_record *);
-
-void mds_setattr_pack(struct mds_rec_setattr *, struct inode *, struct iattr *);
-void mds_create_pack(struct mds_rec_create *, struct inode *, __u32 mode,
- __u64 id, __u32 uid, __u32 gid, __u64 time);
-void mds_unlink_pack(struct mds_rec_unlink *, struct inode *inode,
- struct inode *child);
-void mds_link_pack(struct mds_rec_link *, struct inode *ino, struct inode *dir);
-void mds_rename_pack(struct mds_rec_rename *, struct inode *srcdir,
- struct inode *tgtdir);
+int mds_update_unpack(struct ptlrpc_request *, int offset,
+ struct mds_update_record *);
+
+void mds_getattr_pack(struct ptlrpc_request *req, int offset,
+ struct inode *inode,
+ const char *name, int namelen);
+void mds_setattr_pack(struct ptlrpc_request *, int offset, struct inode *,
+ struct iattr *, const char *name, int namelen);
+void mds_create_pack(struct ptlrpc_request *, int offset, struct inode *,
+ __u32 mode, __u64 id, __u32 uid, __u32 gid, __u64 time,
+ const char *name, int namelen, const char *tgt,
+ int tgtlen);
+void mds_unlink_pack(struct ptlrpc_request *, int offset, struct inode *inode,
+ struct inode *child, const char *name, int namelen);
+void mds_link_pack(struct ptlrpc_request *, int offset, struct inode *ino,
+ struct inode *dir, const char *name, int namelen);
+void mds_rename_pack(struct ptlrpc_request *, int offset, struct inode *srcdir,
+ struct inode *tgtdir, const char *name, int namelen,
+ const char *tgt, int tgtlen);
+void mds_pack_inode2fid(struct ll_fid *fid, struct inode *inode);
+void mds_pack_inode2body(struct mds_body *body, struct inode *inode);
/* mds/handler.c */
struct dentry *mds_fid2dentry(struct mds_obd *mds, struct ll_fid *fid, struct vfsmount **mnt);
+int mds_lock_callback(struct ldlm_lock *lock, struct ldlm_lock *new,
+ void *data, int data_len);
+int mds_reint(int offset, struct ptlrpc_request *req);
/* mdc/mdc_request.c */
-int mdc_connect(struct ptlrpc_client *, struct ptlrpc_connection *,
+static inline struct mdc_obd *mdc_conn2mdc(struct obd_conn *conn)
+{
+ return &conn->oc_dev->u.mdc;
+}
+
+int mdc_enqueue(struct obd_conn *conn, int lock_type, struct lookup_intent *it,
+ int lock_mode, struct inode *dir, struct dentry *de,
+ struct lustre_handle *h, __u64 id, char *tgt, int tgtlen,
+ void *data, int datalen);
+int mdc_getstatus(struct obd_conn *conn,
struct ll_fid *rootfid, __u64 *last_committed, __u64 *last_rcvd,
__u32 *last_xid, struct ptlrpc_request **);
-int mdc_getattr(struct ptlrpc_client *, struct ptlrpc_connection *, ino_t ino,
- int type, unsigned long valid, size_t ea_size,
- struct ptlrpc_request **);
-int mdc_setattr(struct ptlrpc_client *, struct ptlrpc_connection *,
+int mdc_getattr(struct obd_conn *conn,
+ ino_t ino, int type, unsigned long valid, size_t ea_size,
+ struct ptlrpc_request **request);
+int mdc_setattr(struct obd_conn *conn,
struct inode *, struct iattr *iattr, struct ptlrpc_request **);
-int mdc_open(struct ptlrpc_client *, struct ptlrpc_connection *, ino_t ino,
- int type, int flags, __u64 cookie, __u64 *fh, struct ptlrpc_request **req);
-int mdc_close(struct ptlrpc_client *cl, struct ptlrpc_connection *peer,
+int mdc_open(struct obd_conn *conn,
+ ino_t ino, int type, int flags, __u64 objid, __u64 cookie,
+ __u64 *fh, struct ptlrpc_request **request);
+int mdc_close(struct obd_conn *conn,
ino_t ino, int type, __u64 fh, struct ptlrpc_request **req);
-int mdc_readpage(struct ptlrpc_client *, struct ptlrpc_connection *, ino_t ino,
+int mdc_readpage(struct obd_conn *conn, ino_t ino,
int type, __u64 offset, char *addr, struct ptlrpc_request **);
-int mdc_create(struct ptlrpc_client *, struct ptlrpc_connection *,
+int mdc_create(struct obd_conn *conn,
struct inode *dir, const char *name, int namelen,
const char *tgt, int tgtlen, int mode, __u32 uid, __u32 gid,
__u64 time, __u64 rdev, struct obdo *obdo,
struct ptlrpc_request **);
-int mdc_unlink(struct ptlrpc_client *, struct ptlrpc_connection *,
+int mdc_unlink(struct obd_conn *conn,
struct inode *dir, struct inode *child, const char *name,
int namelen, struct ptlrpc_request **);
-int mdc_link(struct ptlrpc_client *, struct ptlrpc_connection *,
+int mdc_link(struct obd_conn *conn,
struct dentry *src, struct inode *dir, const char *name,
int namelen, struct ptlrpc_request **);
-int mdc_rename(struct ptlrpc_client *, struct ptlrpc_connection *,
+int mdc_rename(struct obd_conn *conn,
struct inode *src, struct inode *tgt, const char *old,
int oldlen, const char *new, int newlen,
struct ptlrpc_request **);
#define CONNMGR_REQUEST_PORTAL 1
#define CONNMGR_REPLY_PORTAL 2
-#define OSC_REQUEST_PORTAL 3
+//#define OSC_REQUEST_PORTAL 3
#define OSC_REPLY_PORTAL 4
#define OSC_BULK_PORTAL 5
#define OST_REQUEST_PORTAL 6
-#define OST_REPLY_PORTAL 7
+//#define OST_REPLY_PORTAL 7
#define OST_BULK_PORTAL 8
#define MDC_REQUEST_PORTAL 9
#define MDC_REPLY_PORTAL 10
__u32 cli_reply_portal;
__u64 cli_last_rcvd;
__u64 cli_last_committed;
+ __u32 cli_target_devno;
void *cli_data;
struct semaphore cli_rpc_sem; /* limits outstanding requests */
wait_queue_head_t b_waitq;
struct list_head b_page_list;
__u32 b_page_count;
- atomic_t b_finished_count;
+ atomic_t b_pages_remaining;
void *b_desc_private;
};
struct mds_client_info;
struct mds_server_data;
+struct mdc_obd {
+ struct ptlrpc_client *mdc_client;
+ struct ptlrpc_client *mdc_ldlm_client;
+ struct ptlrpc_connection *mdc_conn;
+ __u8 mdc_target_uuid[37];
+};
+
struct mds_obd {
+ struct ldlm_namespace *mds_local_namespace;
struct ptlrpc_service *mds_service;
+ struct ptlrpc_client *mds_ldlm_client; /* to be an LDLM client */
+ struct ptlrpc_connection *mds_ldlm_conn; /* to be an LDLM client */
char *mds_fstype;
struct super_block *mds_sb;
struct ost_obd {
struct ptlrpc_service *ost_service;
-
- struct obd_device *ost_tgt;
- struct obd_conn ost_conn;
+ struct obd_device *ost_tgt; /* the exported OBD */
+ struct obd_conn ost_conn; /* the local connection to the OBD */
};
struct osc_obd {
struct ptlrpc_client *osc_client;
struct ptlrpc_client *osc_ldlm_client;
struct ptlrpc_connection *osc_conn;
+ __u8 osc_target_uuid[37];
};
typedef __u8 uuid_t[37];
struct ext2_obd ext2;
struct filter_obd filter;
struct mds_obd mds;
+ struct mdc_obd mdc;
struct ost_obd ost;
struct osc_obd osc;
struct ldlm_obd ldlm;
int objcount, struct obd_ioobj *obj,
int niocount, struct niobuf_local *local,
void *desc_private);
-
- int (*o_enqueue)(struct obd_conn *conn, struct ldlm_namespace *ns,
- struct ldlm_handle *parent_lock, __u64 *res_id,
- __u32 type, struct ldlm_extent *, __u32 mode,
- int *flags, void *data, int datalen,
- struct ldlm_handle *lockh);
- int (*o_cancel)(struct obd_conn *, __u32 mode, struct ldlm_handle *);
+ int (*o_enqueue)(struct obd_conn *conn,
+ struct lustre_handle *parent_lock, __u64 *res_id,
+ __u32 type, void *cookie, int cookielen, __u32 mode,
+ int *flags, void *cb, void *data, int datalen,
+ struct lustre_handle *lockh);
+ int (*o_cancel)(struct obd_conn *, __u32 mode, struct lustre_handle *);
};
#endif
/*
* ======== OBD Device Declarations ===========
*/
-#define MAX_OBD_DEVICES 8
+#define MAX_OBD_DEVICES 32
extern struct obd_device obd_dev[MAX_OBD_DEVICES];
#define OBD_ATTACHED 0x1
RETURN(rc);
}
-static inline int obd_enqueue(struct obd_conn *conn, struct ldlm_namespace *ns,
- struct ldlm_handle *parent_lock, __u64 *res_id,
- __u32 type, struct ldlm_extent *extent,
- __u32 mode, int *flags, void *data, int datalen,
- struct ldlm_handle *lockh)
+static inline int obd_enqueue(struct obd_conn *conn,
+ struct lustre_handle *parent_lock, __u64 *res_id,
+ __u32 type, void *cookie, int cookielen,
+ __u32 mode, int *flags, void *cb, void *data,
+ int datalen, struct lustre_handle *lockh)
{
int rc;
OBD_CHECK_SETUP(conn);
OBD_CHECK_OP(conn, enqueue);
-
- rc = OBP(conn->oc_dev, enqueue)(conn, ns, parent_lock, res_id, type,
- extent, mode, flags, data, datalen,
- lockh);
+
+ rc = OBP(conn->oc_dev, enqueue)(conn, parent_lock, res_id, type,
+ cookie, cookielen, mode, flags, cb,
+ data, datalen, lockh);
RETURN(rc);
}
static inline int obd_cancel(struct obd_conn *conn, __u32 mode,
- struct ldlm_handle *lockh)
+ struct lustre_handle *lockh)
{
int rc;
OBD_CHECK_SETUP(conn);
#ifdef __KERNEL__
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;
#define OBD_FAIL_MDS_CONNECT_NET 0x117
#define OBD_FAIL_MDS_CONNECT_PACK 0x118
#define OBD_FAIL_MDS_REINT_NET_REP 0x119
+#define OBD_FAIL_MDS_DISCONNECT_NET 0x11a
+#define OBD_FAIL_MDS_GETSTATUS_NET 0x11b
+#define OBD_FAIL_MDS_GETSTATUS_PACK 0x11c
#define OBD_FAIL_OST 0x200
#define OBD_FAIL_OST_CONNECT_NET 0x201
*
* by Cluster File Systems, Inc.
* authors, Peter Braam <braam@clusterfs.com> &
- * Phil Schwan <phil@clusterfs.com>
+ * Phil Schwan <phil@clusterfs.com>
*/
#define DEBUG_SUBSYSTEM S_LDLM
RETURN(1);
}
+/* The purpose of this function is to return:
+ * - the maximum extent
+ * - containing the requested extent
+ * - and not overlapping existing extents outside the requested one
+ *
+ * An alternative policy is to not shrink the new extent when conflicts exist.
+ *
+ * To reconstruct our formulas, take a deep breath. */
static void policy_internal(struct list_head *queue, struct ldlm_extent *req_ex,
struct ldlm_extent *new_ex, ldlm_mode_t mode)
{
}
}
-/* The purpose of this function is to return:
- * - the maximum extent
- * - containing the requested extent
- * - and not overlapping existing extents outside the requested one
- *
- * An alternative policy is to not shrink the new extent when conflicts exist.
- *
- * To reconstruct our formulas, take a deep breath. */
-int ldlm_extent_policy(struct ldlm_resource *res, struct ldlm_extent *req_ex,
- struct ldlm_extent *new_ex, ldlm_mode_t mode, void *data)
+/* apply the internal policy by walking all the lists */
+int ldlm_extent_policy(struct ldlm_lock *lock, void *req_cookie,
+ ldlm_mode_t mode, void *data)
{
- new_ex->start = 0;
- new_ex->end = ~0;
+ struct ldlm_resource *res = lock->l_resource;
+ struct ldlm_extent *req_ex = req_cookie;
+ struct ldlm_extent new_ex;
+ new_ex.start = 0;
+ new_ex.end = ~0;
if (!res)
LBUG();
- policy_internal(&res->lr_granted, req_ex, new_ex, mode);
- policy_internal(&res->lr_converting, req_ex, new_ex, mode);
- policy_internal(&res->lr_waiting, req_ex, new_ex, mode);
+ policy_internal(&res->lr_granted, req_ex, &new_ex, mode);
+ policy_internal(&res->lr_converting, req_ex, &new_ex, mode);
+ policy_internal(&res->lr_waiting, req_ex, &new_ex, mode);
+
+ memcpy(&lock->l_extent, &new_ex, sizeof(new_ex));
- if (new_ex->end != req_ex->end || new_ex->start != req_ex->start)
+ if (new_ex.end != req_ex->end || new_ex.start != req_ex->start)
return ELDLM_LOCK_CHANGED;
- return 0;
+ else
+ return 0;
}
* See the file COPYING in this distribution
*
* by Cluster File Systems, Inc.
- * authors, Peter Braam <braam@clusterfs.com> &
+ * authors, Peter Braam <braam@clusterfs.com> &
* Phil Schwan <phil@clusterfs.com>
*/
#define DEBUG_SUBSYSTEM S_LDLM
#include <linux/slab.h>
+#include <linux/module.h>
#include <linux/lustre_dlm.h>
+#include <linux/lustre_mds.h>
extern kmem_cache_t *ldlm_lock_slab;
+int (*mds_reint_p)(int offset, struct ptlrpc_request *req) = NULL;
+int (*mds_getattr_name_p)(int offset, struct ptlrpc_request *req) = NULL;
static int ldlm_plain_compat(struct ldlm_lock *a, struct ldlm_lock *b);
-static int ldlm_intent_compat(struct ldlm_lock *a, struct ldlm_lock *b);
+static int ldlm_intent_policy(struct ldlm_lock *lock, void *req_cookie,
+ ldlm_mode_t mode, void *data);
ldlm_res_compat ldlm_res_compat_table [] = {
[LDLM_PLAIN] ldlm_plain_compat,
[LDLM_EXTENT] ldlm_extent_compat,
- [LDLM_MDSINTENT] ldlm_intent_compat
+ [LDLM_MDSINTENT] ldlm_plain_compat
};
ldlm_res_policy ldlm_res_policy_table [] = {
[LDLM_PLAIN] NULL,
[LDLM_EXTENT] ldlm_extent_policy,
- [LDLM_MDSINTENT] NULL
+ [LDLM_MDSINTENT] ldlm_intent_policy
};
-static int ldlm_plain_compat(struct ldlm_lock *a, struct ldlm_lock *b)
+static int ldlm_intent_policy(struct ldlm_lock *lock, void *req_cookie,
+ ldlm_mode_t mode, void *data)
{
- return lockmode_compat(a->l_req_mode, b->l_req_mode);
+ struct ptlrpc_request *req = req_cookie;
+ int rc = 0;
+ ENTRY;
+
+ if (!req_cookie)
+ RETURN(0);
+
+ if (req->rq_reqmsg->bufcount > 1) {
+ /* an intent needs to be considered */
+ struct ldlm_intent *it = lustre_msg_buf(req->rq_reqmsg, 1);
+ struct mds_body *mds_rep;
+ struct ldlm_reply *rep;
+ struct ldlm_namespace *ns = lock->l_resource->lr_namespace;
+ __u32 type = lock->l_resource->lr_type;
+ __u64 new_resid[3] = {0, 0, 0};
+ int bufcount, rc, size[3] = {sizeof(struct ldlm_reply),
+ sizeof(struct mds_body),
+ sizeof(struct obdo)};
+
+ it->opc = NTOH__u64(it->opc);
+
+ switch(it->opc) {
+ case IT_GETATTR:
+ /* Note that in the negative case you may be returning
+ * a file and its obdo */
+ case IT_CREAT:
+ case IT_CREAT|IT_OPEN:
+ case IT_MKDIR:
+ case IT_SYMLINK:
+ case IT_MKNOD:
+ case IT_LINK:
+ case IT_OPEN:
+ case IT_RENAME:
+ bufcount = 3;
+ break;
+ default:
+ bufcount = 2;
+ }
+
+ rc = lustre_pack_msg(bufcount, size, NULL, &req->rq_replen,
+ &req->rq_repmsg);
+ if (rc) {
+ rc = req->rq_status = -ENOMEM;
+ RETURN(rc);
+ }
+
+ rep = lustre_msg_buf(req->rq_repmsg, 0);
+ rep->lock_policy_res1 = 1;
+ switch ( it->opc ) {
+ case IT_CREAT:
+ case IT_CREAT|IT_OPEN:
+ case IT_MKDIR:
+ case IT_SETATTR:
+ case IT_SYMLINK:
+ case IT_MKNOD:
+ case IT_LINK:
+ case IT_RENAME2:
+ if (mds_reint_p == NULL)
+ mds_reint_p =
+ inter_module_get_request
+ ("mds_reint", "mds");
+ if (IS_ERR(mds_reint_p)) {
+ CERROR("MDSINTENT locks require the MDS "
+ "module.\n");
+ LBUG();
+ RETURN(-EINVAL);
+ }
+ rc = mds_reint_p(2, req);
+ if (rc)
+ LBUG();
+ break;
+ case IT_GETATTR:
+ case IT_READDIR:
+ case IT_RENAME:
+ case IT_OPEN:
+ if (mds_getattr_name_p == NULL)
+ mds_getattr_name_p =
+ inter_module_get_request
+ ("mds_getattr_name", "mds");
+ if (IS_ERR(mds_getattr_name_p)) {
+ CERROR("MDSINTENT locks require the MDS "
+ "module.\n");
+ LBUG();
+ RETURN(-EINVAL);
+ }
+ rc = mds_getattr_name_p(2, req);
+ if (rc)
+ LBUG();
+ break;
+ case IT_READDIR|IT_OPEN:
+ LBUG();
+ break;
+ default:
+ CERROR("Unhandled intent\n");
+ LBUG();
+ }
+
+ mds_rep = lustre_msg_buf(req->rq_repmsg, 1);
+ rep->lock_policy_res2 = req->rq_status;
+ new_resid[0] = mds_rep->ino;
+
+ CDEBUG(D_INFO, "remote intent: locking %d instead of"
+ "%ld\n", mds_rep->ino,
+ (long)lock->l_resource->lr_name[0]);
+ ldlm_resource_put(lock->l_resource);
+
+ lock->l_resource =
+ ldlm_resource_get(ns, NULL, new_resid, type, 1);
+ if (lock->l_resource == NULL) {
+ LBUG();
+ RETURN(-ENOMEM);
+ }
+ RETURN(ELDLM_LOCK_CHANGED);
+ } else {
+ int size = sizeof(struct ldlm_reply);
+ rc = lustre_pack_msg(1, &size, NULL, &req->rq_replen,
+ &req->rq_repmsg);
+ if (rc) {
+ CERROR("out of memory\n");
+ LBUG();
+ RETURN(-ENOMEM);
+ }
+ }
+ RETURN(rc);
}
-static int ldlm_intent_compat(struct ldlm_lock *a, struct ldlm_lock *b)
+static int ldlm_plain_compat(struct ldlm_lock *a, struct ldlm_lock *b)
{
- LBUG();
- return 0;
+ return lockmode_compat(a->l_req_mode, b->l_req_mode);
}
/* Args: referenced, unlocked parent (or NULL)
spin_unlock(&lock->l_lock);
}
+void ldlm_send_blocking_ast(struct ldlm_lock *lock, struct ldlm_lock *new)
+{
+ ENTRY;
+
+ spin_lock(&lock->l_lock);
+ if (lock->l_flags & LDLM_FL_AST_SENT) {
+ EXIT;
+ return;
+ }
+
+ lock->l_flags |= LDLM_FL_AST_SENT;
+ spin_unlock(&lock->l_lock);
+
+ lock->l_blocking_ast(lock, new, lock->l_data, lock->l_data_len);
+ EXIT;
+}
+
/* Args: unlocked lock */
void ldlm_lock_decref(struct ldlm_lock *lock, __u32 mode)
{
- int rc;
+ ENTRY;
+
+ if (lock == NULL)
+ LBUG();
spin_lock(&lock->l_lock);
if (mode == LCK_NL || mode == LCK_CR || mode == LCK_PR)
}
CDEBUG(D_INFO, "final decref done on dying lock, "
- "cancelling.\n");
+ "calling callback.\n");
spin_unlock(&lock->l_lock);
- rc = ldlm_cli_cancel(lock->l_client, lock);
- if (rc) {
- /* FIXME: do something more dramatic */
- CERROR("ldlm_cli_cancel: %d\n", rc);
- }
+ lock->l_blocking_ast(lock, NULL, lock->l_data,
+ lock->l_data_len);
} else
spin_unlock(&lock->l_lock);
+ EXIT;
}
/* Args: locked lock */
rc = 1;
- CDEBUG(D_OTHER, "compat function failed and lock modes are "
- "incompatible; sending blocking AST.\n");
- if (send_cbs && child->l_blocking_ast != NULL)
- child->l_blocking_ast(child, lock, child->l_data,
- child->l_data_len);
+ CDEBUG(D_OTHER, "compat function failed and lock modes incompat\n");
+ if (send_cbs && child->l_blocking_ast != NULL) {
+ CDEBUG(D_OTHER, "incompatible; sending blocking AST.\n");
+ ldlm_send_blocking_ast(child, lock);
+ }
}
return rc;
ENTRY;
rc = _ldlm_lock_compat(lock, send_cbs, &lock->l_resource->lr_granted);
+ /* FIXME: should we be sending ASTs to converting? */
rc |= _ldlm_lock_compat(lock, send_cbs,
&lock->l_resource->lr_converting);
}
static int search_queue(struct list_head *queue, ldlm_mode_t mode,
- struct ldlm_extent *extent, struct ldlm_handle *lockh)
+ struct ldlm_extent *extent, struct lustre_handle *lockh)
{
struct list_head *tmp;
- list_for_each(tmp, queue) {
+ list_for_each(tmp, queue) {
struct ldlm_lock *lock;
lock = list_entry(tmp, struct ldlm_lock, l_res_link);
continue;
/* lock_convert() takes the resource lock, so we're sure that
- * req_mode, lr_type, and l_extent won't change beneath us */
+ * req_mode, lr_type, and l_cookie won't change beneath us */
if (lock->l_req_mode != mode)
continue;
* Returns 1 if it finds an already-existing lock that is compatible; in this
* case, lockh is filled in with a addref()ed lock */
int ldlm_local_lock_match(struct ldlm_namespace *ns, __u64 *res_id, __u32 type,
- struct ldlm_extent *extent, ldlm_mode_t mode,
- struct ldlm_handle *lockh)
+ void *cookie, int cookielen, ldlm_mode_t mode,
+ struct lustre_handle *lockh)
{
struct ldlm_resource *res;
int rc = 0;
RETURN(0);
spin_lock(&res->lr_lock);
- if (search_queue(&res->lr_granted, mode, extent, lockh))
+ if (search_queue(&res->lr_granted, mode, cookie, lockh))
GOTO(out, rc = 1);
- if (search_queue(&res->lr_converting, mode, extent, lockh))
+ if (search_queue(&res->lr_converting, mode, cookie, lockh))
GOTO(out, rc = 1);
- if (search_queue(&res->lr_waiting, mode, extent, lockh))
+ if (search_queue(&res->lr_waiting, mode, cookie, lockh))
GOTO(out, rc = 1);
EXIT;
/* Must be called without the resource lock held. Returns a referenced,
* unlocked ldlm_lock. */
ldlm_error_t ldlm_local_lock_create(struct ldlm_namespace *ns,
- struct ldlm_handle *parent_lock_handle,
+ struct lustre_handle *parent_lock_handle,
__u64 *res_id, __u32 type,
ldlm_mode_t mode,
void *data,
__u32 data_len,
- struct ldlm_handle *lockh)
+ struct lustre_handle *lockh)
{
struct ldlm_resource *res, *parent_res = NULL;
struct ldlm_lock *lock, *parent_lock;
- parent_lock = ldlm_handle2object(parent_lock_handle);
+ parent_lock = lustre_handle2object(parent_lock_handle);
if (parent_lock)
parent_res = parent_lock->l_resource;
}
/* Must be called with lock->l_lock and lock->l_resource->lr_lock not held */
-ldlm_error_t ldlm_local_lock_enqueue(struct ldlm_handle *lockh,
- struct ldlm_extent *req_ex,
+ldlm_error_t ldlm_local_lock_enqueue(struct lustre_handle *lockh,
+ void *cookie, int cookie_len,
int *flags,
ldlm_lock_callback completion,
ldlm_lock_callback blocking)
ldlm_res_policy policy;
ENTRY;
- lock = ldlm_handle2object(lockh);
+ lock = lustre_handle2object(lockh);
res = lock->l_resource;
local = res->lr_namespace->ns_local;
spin_lock(&res->lr_lock);
lock->l_blocking_ast = blocking;
- if ((res->lr_type == LDLM_EXTENT && !req_ex) ||
- (res->lr_type != LDLM_EXTENT && req_ex))
- LBUG();
+ if (res->lr_type == LDLM_EXTENT)
+ memcpy(&lock->l_extent, cookie, sizeof(lock->l_extent));
- if ((policy = ldlm_res_policy_table[res->lr_type])) {
- struct ldlm_extent new_ex;
- int rc = policy(res, req_ex, &new_ex, lock->l_req_mode, NULL);
+ /* policies are not executed on the client */
+ if (!local && (policy = ldlm_res_policy_table[res->lr_type])) {
+ int rc = policy(lock, cookie, lock->l_req_mode, NULL);
if (rc == ELDLM_LOCK_CHANGED) {
+ res = lock->l_resource;
*flags |= LDLM_FL_LOCK_CHANGED;
- memcpy(req_ex, &new_ex, sizeof(new_ex));
}
}
- if (req_ex)
- memcpy(&lock->l_extent, req_ex, sizeof(*req_ex));
+ lock->l_cookie = cookie;
+ lock->l_cookie_len = cookie_len;
if (local && lock->l_req_mode == lock->l_granted_mode) {
/* The server returned a blocked lock, but it was granted before
}
/* If this is a local resource, put it on the appropriate list. */
+ list_del_init(&lock->l_res_link);
if (local) {
if (*flags & LDLM_FL_BLOCK_CONV)
ldlm_resource_add_lock(res, res->lr_converting.prev,
struct list_head *tmp, *pos;
ENTRY;
- list_for_each_safe(tmp, pos, converting) {
+ list_for_each_safe(tmp, pos, converting) {
struct ldlm_lock *pending;
pending = list_entry(tmp, struct ldlm_lock, l_res_link);
if (ldlm_lock_compat(pending, 1))
RETURN(1);
- list_del_init(&pending->l_res_link);
+ list_del_init(&pending->l_res_link);
ldlm_grant_lock(res, pending);
ldlm_lock_addref(pending, pending->l_req_mode);
}
/* Must be called with lock and lock->l_resource unlocked */
-struct ldlm_resource *ldlm_local_lock_convert(struct ldlm_handle *lockh,
+struct ldlm_resource *ldlm_local_lock_convert(struct lustre_handle *lockh,
int new_mode, int *flags)
{
struct ldlm_lock *lock;
struct ldlm_resource *res;
ENTRY;
- lock = ldlm_handle2object(lockh);
+ lock = lustre_handle2object(lockh);
res = lock->l_resource;
spin_lock(&res->lr_lock);
extern kmem_cache_t *ldlm_resource_slab;
extern kmem_cache_t *ldlm_lock_slab;
+extern int (*mds_reint_p)(int offset, struct ptlrpc_request *req);
+extern int (*mds_getattr_name_p)(int offset, struct ptlrpc_request *req);
#define LOOPBACK(x) (((x) & cpu_to_be32(0xff000000)) == cpu_to_be32(0x7f000000))
ldlm_mode_t mode, void *data, __u32 data_len)
{
ENTRY;
- ldlm_lock_dump(lock);
if (!lock)
LBUG();
if (!lock->l_resource)
LBUG();
+ ldlm_lock_dump(lock);
+
spin_lock(&lock->l_resource->lr_lock);
spin_lock(&lock->l_lock);
if (!new) {
spin_unlock(&lock->l_lock);
spin_unlock(&lock->l_resource->lr_lock);
if (!lock->l_readers && !lock->l_writers) {
- CDEBUG(D_INFO, "Lock already unused, canceling.\n");
- if (ldlm_cli_cancel(lock->l_client, lock))
- LBUG();
+ CDEBUG(D_INFO, "Lock already unused, calling "
+ "callback (%p).\n", lock->l_blocking_ast);
+ if (lock->l_blocking_ast != NULL)
+ lock->l_blocking_ast(lock, new, lock->l_data,
+ lock->l_data_len);
} else {
CDEBUG(D_INFO, "Lock still has references; lock will be"
" cancelled later.\n");
RETURN(0);
}
+/* FIXME: I think that this is no longer necessary. */
static int local_callback(struct ldlm_lock *l, struct ldlm_lock *new,
void *data, __u32 data_len)
{
struct ldlm_lock *lock;
/* the 'remote handle' is the lock in the FS's namespace */
- lock = ldlm_handle2object(&l->l_remote_handle);
+ lock = lustre_handle2object(&l->l_remote_handle);
return common_callback(lock, new, l->l_granted_mode, data, data_len);
}
{
struct ldlm_reply *dlm_rep;
struct ldlm_request *dlm_req;
- int rc, size = sizeof(*dlm_rep);
+ int rc, size = sizeof(*dlm_rep), cookielen;
+ __u32 flags;
ldlm_error_t err;
struct ldlm_lock *lock = NULL;
ldlm_lock_callback callback;
+ struct lustre_handle lockh;
+ void *cookie;
ENTRY;
/* Is this lock managed locally? */
else
callback = ldlm_cli_callback;
- rc = lustre_pack_msg(1, &size, NULL, &req->rq_replen, &req->rq_repmsg);
- if (rc) {
- CERROR("out of memory\n");
- RETURN(-ENOMEM);
- }
- dlm_rep = lustre_msg_buf(req->rq_repmsg, 0);
dlm_req = lustre_msg_buf(req->rq_reqmsg, 0);
-
- memcpy(&dlm_rep->lock_extent, &dlm_req->lock_desc.l_extent,
- sizeof(dlm_rep->lock_extent));
- dlm_rep->flags = dlm_req->flags;
+ if (dlm_req->lock_desc.l_resource.lr_type == LDLM_MDSINTENT) {
+ /* In this case, the reply buffer is allocated deep in
+ * local_lock_enqueue by the policy function. */
+ cookie = req;
+ cookielen = sizeof(*req);
+ } else {
+ rc = lustre_pack_msg(1, &size, NULL, &req->rq_replen,
+ &req->rq_repmsg);
+ if (rc) {
+ CERROR("out of memory\n");
+ RETURN(-ENOMEM);
+ }
+ if (dlm_req->lock_desc.l_resource.lr_type == LDLM_EXTENT) {
+ cookie = &dlm_req->lock_desc.l_extent;
+ cookielen = sizeof(struct ldlm_extent);
+ }
+ }
err = ldlm_local_lock_create(obddev->obd_namespace,
&dlm_req->lock_handle2,
dlm_req->lock_desc.l_resource.lr_name,
dlm_req->lock_desc.l_resource.lr_type,
dlm_req->lock_desc.l_req_mode,
- lustre_msg_buf(req->rq_reqmsg, 1),
- req->rq_reqmsg->buflens[1],
- &dlm_rep->lock_handle);
+ NULL, 0, &lockh);
if (err != ELDLM_OK)
GOTO(out, err);
- err = ldlm_local_lock_enqueue(&dlm_rep->lock_handle,
- &dlm_rep->lock_extent,
- &dlm_rep->flags,
+ flags = dlm_req->lock_flags;
+ err = ldlm_local_lock_enqueue(&lockh,
+ cookie, cookielen,
+ &flags,
callback, callback);
if (err != ELDLM_OK)
GOTO(out, err);
- lock = ldlm_handle2object(&dlm_rep->lock_handle);
+ dlm_rep = lustre_msg_buf(req->rq_repmsg, 0);
+ dlm_rep->lock_flags = flags;
+
+ memcpy(&dlm_rep->lock_handle, &lockh, sizeof(lockh));
+ lock = lustre_handle2object(&lockh);
+ if (dlm_req->lock_desc.l_resource.lr_type == LDLM_EXTENT)
+ memcpy(&dlm_rep->lock_extent, &lock->l_extent,
+ sizeof(lock->l_extent));
+ if (dlm_rep->lock_flags & LDLM_FL_LOCK_CHANGED)
+ memcpy(dlm_rep->lock_resource_name, lock->l_resource->lr_name,
+ sizeof(dlm_rep->lock_resource_name));
+
memcpy(&lock->l_remote_handle, &dlm_req->lock_handle1,
sizeof(lock->l_remote_handle));
lock->l_connection = ptlrpc_connection_addref(req->rq_connection);
}
dlm_req = lustre_msg_buf(req->rq_reqmsg, 0);
dlm_rep = lustre_msg_buf(req->rq_repmsg, 0);
- dlm_rep->flags = dlm_req->flags;
+ dlm_rep->lock_flags = dlm_req->lock_flags;
res = ldlm_local_lock_convert(&dlm_req->lock_handle1,
dlm_req->lock_desc.l_req_mode,
- &dlm_rep->flags);
+ &dlm_rep->lock_flags);
req->rq_status = 0;
if (ptlrpc_reply(svc, req) != 0)
LBUG();
}
dlm_req = lustre_msg_buf(req->rq_reqmsg, 0);
- lock = ldlm_handle2object(&dlm_req->lock_handle1);
+ lock = lustre_handle2object(&dlm_req->lock_handle1);
res = ldlm_local_lock_cancel(lock);
req->rq_status = 0;
if (ptlrpc_reply(svc, req) != 0)
if (rc != 0)
RETURN(rc);
- lock1 = ldlm_handle2object(&dlm_req->lock_handle1);
- lock2 = ldlm_handle2object(&dlm_req->lock_handle2);
+ lock1 = lustre_handle2object(&dlm_req->lock_handle1);
+ lock2 = lustre_handle2object(&dlm_req->lock_handle2);
common_callback(lock1, lock2, dlm_req->lock_desc.l_granted_mode, NULL,
0);
RETURN(0);
}
-static int ldlm_handle(struct obd_device *dev, struct ptlrpc_service *svc,
+static int lustre_handle(struct obd_device *dev, struct ptlrpc_service *svc,
struct ptlrpc_request *req)
{
- int rc;
+ struct obd_device *req_dev;
+ int id, rc;
ENTRY;
rc = lustre_unpack_msg(req->rq_reqmsg, req->rq_reqlen);
GOTO(out, rc = -EINVAL);
}
+ id = req->rq_reqmsg->target_id;
+ if (id < 0 || id > MAX_OBD_DEVICES)
+ GOTO(out, rc = -ENODEV);
+ req_dev = req->rq_obd = &obd_dev[id];
+
switch (req->rq_reqmsg->opc) {
case LDLM_ENQUEUE:
CDEBUG(D_INODE, "enqueue\n");
OBD_FAIL_RETURN(OBD_FAIL_LDLM_ENQUEUE, 0);
- rc = _ldlm_enqueue(dev, svc, req);
+ rc = _ldlm_enqueue(req_dev, svc, req);
break;
case LDLM_CONVERT:
int err;
ENTRY;
- obddev->obd_namespace = ldlm_namespace_new(obddev, 0);
- if (obddev->obd_namespace == NULL)
- LBUG();
-
ldlm->ldlm_service =
ptlrpc_init_svc(64 * 1024, LDLM_REQUEST_PORTAL,
- LDLM_REPLY_PORTAL, "self", ldlm_handle);
+ LDLM_REPLY_PORTAL, "self", lustre_handle);
if (!ldlm->ldlm_service)
LBUG();
CERROR("cannot start thread\n");
LBUG();
}
-
- OBD_ALLOC(ldlm->ldlm_client, sizeof(*ldlm->ldlm_client));
- if (ldlm->ldlm_client == NULL)
+ err = ptlrpc_start_thread(obddev, ldlm->ldlm_service, "lustre_dlm");
+ if (err) {
+ CERROR("cannot start thread\n");
LBUG();
- ptlrpc_init_client(NULL, NULL,
- LDLM_REQUEST_PORTAL, LDLM_REPLY_PORTAL,
- ldlm->ldlm_client);
+ }
+ err = ptlrpc_start_thread(obddev, ldlm->ldlm_service, "lustre_dlm");
+ if (err) {
+ CERROR("cannot start thread\n");
+ LBUG();
+ }
MOD_INC_USE_COUNT;
RETURN(0);
struct ldlm_obd *ldlm = &obddev->u.ldlm;
ENTRY;
- ldlm_namespace_free(obddev->obd_namespace);
-
ptlrpc_stop_all_threads(ldlm->ldlm_service);
rpc_unregister_service(ldlm->ldlm_service);
OBD_FREE(ldlm->ldlm_client, sizeof(*ldlm->ldlm_client));
OBD_FREE(ldlm->ldlm_service, sizeof(*ldlm->ldlm_service));
+ if (mds_reint_p != NULL)
+ inter_module_put("mds_reint");
+ if (mds_getattr_name_p != NULL)
+ inter_module_put("mds_getattr_name");
+
MOD_DEC_USE_COUNT;
RETURN(0);
}
EXPORT_SYMBOL(ldlm_lock_decref);
EXPORT_SYMBOL(ldlm_cli_convert);
EXPORT_SYMBOL(ldlm_cli_enqueue);
-EXPORT_SYMBOL(ldlm_handle2object);
+EXPORT_SYMBOL(ldlm_cli_cancel);
+EXPORT_SYMBOL(lustre_handle2object);
EXPORT_SYMBOL(ldlm_test);
EXPORT_SYMBOL(ldlm_lock_dump);
EXPORT_SYMBOL(ldlm_namespace_new);
#include <linux/lustre_dlm.h>
int ldlm_cli_enqueue(struct ptlrpc_client *cl, struct ptlrpc_connection *conn,
+ struct ptlrpc_request *req,
struct ldlm_namespace *ns,
- struct ldlm_handle *parent_lock_handle,
+ struct lustre_handle *parent_lock_handle,
__u64 *res_id,
__u32 type,
- struct ldlm_extent *req_ex,
+ void *cookie, int cookielen,
ldlm_mode_t mode,
int *flags,
+ ldlm_lock_callback callback,
void *data,
__u32 data_len,
- struct ldlm_handle *lockh)
+ struct lustre_handle *lockh)
{
struct ldlm_lock *lock;
struct ldlm_request *body;
struct ldlm_reply *reply;
- struct ptlrpc_request *req;
- char *bufs[2] = {NULL, data};
- int rc, size[2] = {sizeof(*body), data_len};
+ int rc, size = sizeof(*body), req_passed_in = 1;
ENTRY;
*flags = 0;
rc = ldlm_local_lock_create(ns, parent_lock_handle, res_id, type, mode,
- NULL, 0, lockh);
+ data, data_len, lockh);
if (rc != ELDLM_OK)
GOTO(out, rc);
- lock = ldlm_handle2object(lockh);
+ lock = lustre_handle2object(lockh);
- req = ptlrpc_prep_req(cl, conn, LDLM_ENQUEUE, 2, size, bufs);
- if (!req)
- GOTO(out, rc = -ENOMEM);
+ if (req == NULL) {
+ req = ptlrpc_prep_req(cl, conn, LDLM_ENQUEUE, 1, &size, NULL);
+ if (!req)
+ GOTO(out, rc = -ENOMEM);
+ req_passed_in = 0;
+ } else if (req->rq_reqmsg->buflens[0] != sizeof(*body))
+ LBUG();
/* Dump all of this data into the request buffer */
body = lustre_msg_buf(req->rq_reqmsg, 0);
sizeof(body->lock_desc.l_resource.lr_name));
body->lock_desc.l_req_mode = mode;
- if (req_ex)
- memcpy(&body->lock_desc.l_extent, req_ex,
+ if (type == LDLM_EXTENT)
+ memcpy(&body->lock_desc.l_extent, cookie,
sizeof(body->lock_desc.l_extent));
- body->flags = *flags;
+ body->lock_flags = *flags;
memcpy(&body->lock_handle1, lockh, sizeof(body->lock_handle1));
sizeof(body->lock_handle2));
/* Continue as normal. */
- size[0] = sizeof(*reply);
- req->rq_replen = lustre_msg_size(1, size);
+ if (!req_passed_in) {
+ size = sizeof(*reply);
+ req->rq_replen = lustre_msg_size(1, &size);
+ }
rc = ptlrpc_queue_wait(req);
rc = ptlrpc_check_status(req, rc);
reply = lustre_msg_buf(req->rq_repmsg, 0);
memcpy(&lock->l_remote_handle, &reply->lock_handle,
sizeof(lock->l_remote_handle));
- memcpy(req_ex, &reply->lock_extent, sizeof(*req_ex));
- *flags = reply->flags;
+ if (type == LDLM_EXTENT)
+ memcpy(cookie, &reply->lock_extent, sizeof(reply->lock_extent));
+ *flags = reply->lock_flags;
CDEBUG(D_INFO, "remote handle: %p, flags: %d\n",
(void *)(unsigned long)reply->lock_handle.addr, *flags);
(unsigned long long)reply->lock_extent.start,
(unsigned long long)reply->lock_extent.end);
- ptlrpc_free_req(req);
+ if (*flags & LDLM_FL_LOCK_CHANGED) {
+ CDEBUG(D_INFO, "remote intent success, locking %ld instead of"
+ "%ld\n", (long)reply->lock_resource_name[0],
+ (long)lock->l_resource->lr_name[0]);
+ ldlm_resource_put(lock->l_resource);
- rc = ldlm_local_lock_enqueue(lockh, req_ex, flags, NULL, NULL);
+ lock->l_resource =
+ ldlm_resource_get(ns, NULL, reply->lock_resource_name,
+ type, 1);
+ if (lock->l_resource == NULL) {
+ LBUG();
+ RETURN(-ENOMEM);
+ }
+ }
+
+ if (!req_passed_in)
+ ptlrpc_free_req(req);
+
+ rc = ldlm_local_lock_enqueue(lockh, cookie, cookielen, flags, callback,
+ callback);
if (*flags & (LDLM_FL_BLOCK_WAIT | LDLM_FL_BLOCK_GRANTED |
LDLM_FL_BLOCK_CONV)) {
{
struct ldlm_request *body;
struct ptlrpc_request *req;
- struct obd_device *obddev = lock->l_resource->lr_namespace->ns_obddev;
- struct ptlrpc_client *cl = obddev->u.ldlm.ldlm_client;
- int rc, size[2] = {sizeof(*body), data_len};
- char *bufs[2] = {NULL, data};
+ struct ptlrpc_client *cl = &lock->l_resource->lr_namespace->ns_client;
+ int rc, size = sizeof(*body);
ENTRY;
- req = ptlrpc_prep_req(cl, lock->l_connection, LDLM_CALLBACK, 2, size,
- bufs);
+ req = ptlrpc_prep_req(cl, lock->l_connection, LDLM_CALLBACK, 1, &size,
+ NULL);
if (!req)
GOTO(out, rc = -ENOMEM);
return rc;
}
-int ldlm_cli_convert(struct ptlrpc_client *cl, struct ldlm_handle *lockh,
+int ldlm_cli_convert(struct ptlrpc_client *cl, struct lustre_handle *lockh,
int new_mode, int *flags)
{
struct ldlm_request *body;
+ struct ldlm_reply *reply;
struct ldlm_lock *lock;
struct ldlm_resource *res;
struct ptlrpc_request *req;
- int rc, size[2] = {sizeof(*body), 0};
- char *bufs[2] = {NULL, NULL};
+ int rc, size = sizeof(*body);
ENTRY;
- lock = ldlm_handle2object(lockh);
+ lock = lustre_handle2object(lockh);
*flags = 0;
- size[1] = lock->l_data_len;
- bufs[1] = lock->l_data;
- req = ptlrpc_prep_req(cl, lock->l_connection, LDLM_CONVERT, 2, size,
- bufs);
+ req = ptlrpc_prep_req(cl, lock->l_connection, LDLM_CONVERT, 1, &size,
+ NULL);
if (!req)
GOTO(out, rc = -ENOMEM);
sizeof(body->lock_handle1));
body->lock_desc.l_req_mode = new_mode;
- body->flags = *flags;
+ body->lock_flags = *flags;
- req->rq_replen = lustre_msg_size(1, size);
+ size = sizeof(*reply);
+ req->rq_replen = lustre_msg_size(1, &size);
rc = ptlrpc_queue_wait(req);
rc = ptlrpc_check_status(req, rc);
if (rc != ELDLM_OK)
GOTO(out, rc);
- body = lustre_msg_buf(req->rq_repmsg, 0);
- res = ldlm_local_lock_convert(lockh, new_mode, &body->flags);
+ reply = lustre_msg_buf(req->rq_repmsg, 0);
+ res = ldlm_local_lock_convert(lockh, new_mode, &reply->lock_flags);
if (res != NULL)
ldlm_reprocess_all(res);
if (lock->l_req_mode != lock->l_granted_mode) {
struct ldlm_request *body;
struct ptlrpc_request *req;
struct ldlm_resource *res;
- int rc, size[2] = {sizeof(*body), 0};
- char *bufs[2] = {NULL, NULL};
+ int rc, size = sizeof(*body);
ENTRY;
- if (lock->l_data_len == sizeof(struct inode)) {
- /* FIXME: do something better than throwing away everything */
- struct inode *inode = lock->l_data;
- if (inode == NULL)
- LBUG();
- down(&inode->i_sem);
- invalidate_inode_pages(inode);
- up(&inode->i_sem);
- }
-
- size[1] = lock->l_data_len;
- bufs[1] = lock->l_data;
- req = ptlrpc_prep_req(cl, lock->l_connection, LDLM_CANCEL, 2, size,
- bufs);
+ req = ptlrpc_prep_req(cl, lock->l_connection, LDLM_CANCEL, 1, &size,
+ NULL);
if (!req)
GOTO(out, rc = -ENOMEM);
res = ldlm_local_lock_cancel(lock);
if (res != NULL)
ldlm_reprocess_all(res);
+ else
+ rc = ELDLM_RESOURCE_FREED;
EXIT;
out:
return rc;
kmem_cache_t *ldlm_resource_slab, *ldlm_lock_slab;
-struct ldlm_namespace *ldlm_namespace_new(struct obd_device *obddev,
- __u32 local)
+struct ldlm_namespace *ldlm_namespace_new(__u32 local)
{
- struct ldlm_namespace *ns;
+ struct ldlm_namespace *ns = NULL;
struct list_head *bucket;
OBD_ALLOC(ns, sizeof(*ns));
if (!ns) {
LBUG();
- RETURN(NULL);
+ GOTO(out, NULL);
}
+
ns->ns_hash = vmalloc(sizeof(*ns->ns_hash) * RES_HASH_SIZE);
if (!ns->ns_hash) {
- OBD_FREE(ns, sizeof(*ns));
LBUG();
- RETURN(NULL);
+ GOTO(out, ns);
}
- ns->ns_obddev = obddev;
+ ptlrpc_init_client(NULL, NULL,
+ LDLM_REQUEST_PORTAL, LDLM_REPLY_PORTAL,
+ &ns->ns_client);
+
INIT_LIST_HEAD(&ns->ns_root_list);
ns->ns_lock = SPIN_LOCK_UNLOCKED;
ns->ns_refcount = 0;
for (bucket = ns->ns_hash + RES_HASH_SIZE - 1; bucket >= ns->ns_hash;
bucket--)
INIT_LIST_HEAD(bucket);
+ RETURN(ns);
- return ns;
+ out:
+ if (ns && ns->ns_hash)
+ vfree(ns->ns_hash);
+ if (ns)
+ OBD_FREE(ns, sizeof(*ns));
+ return NULL;
}
static int cleanup_resource(struct ldlm_resource *res, struct list_head *q)
{
struct list_head *tmp, *pos;
- int rc = 0;
+ int rc = 0, client = res->lr_namespace->ns_local;
+ ENTRY;
list_for_each_safe(tmp, pos, q) {
struct ldlm_lock *lock;
+ lock = list_entry(tmp, struct ldlm_lock, l_res_link);
- if (rc) {
- /* Res was already cleaned up. */
- LBUG();
- }
+ if (client) {
+ rc = ldlm_cli_cancel(lock->l_client, lock);
+ if (rc < 0) {
+ CERROR("ldlm_cli_cancel: %d\n", rc);
+ LBUG();
+ }
+ if (rc == ELDLM_RESOURCE_FREED)
+ rc = 1;
+ } else {
+ CERROR("Freeing a lock still held by a client node.\n");
- lock = list_entry(tmp, struct ldlm_lock, l_res_link);
- spin_lock(&lock->l_lock);
- ldlm_resource_del_lock(lock);
- ldlm_lock_free(lock);
+ spin_lock(&lock->l_lock);
+ ldlm_resource_del_lock(lock);
+ ldlm_lock_free(lock);
- rc = ldlm_resource_put(res);
+ rc = ldlm_resource_put(res);
+ }
}
- return rc;
+ RETURN(rc);
}
int ldlm_namespace_free(struct ldlm_namespace *ns)
struct list_head *tmp, *pos;
int i, rc;
+ if (!ns)
+ RETURN(ELDLM_OK);
/* We should probably take the ns_lock, but then ldlm_resource_put
* couldn't take it. Hmm. */
for (i = 0; i < RES_HASH_SIZE; i++) {
}
vfree(ns->ns_hash /* , sizeof(struct list_head) * RES_HASH_SIZE */);
+ ptlrpc_cleanup_client(&ns->ns_client);
OBD_FREE(ns, sizeof(*ns));
return ELDLM_OK;
struct list_head *bucket;
struct list_head *tmp = bucket;
struct ldlm_resource *res = NULL;
-
ENTRY;
- if (ns->ns_hash == NULL)
+ if (ns == NULL || ns->ns_hash == NULL) {
+ LBUG();
RETURN(NULL);
+ }
spin_lock(&ns->ns_lock);
bucket = ns->ns_hash + ldlm_hash_fn(parent, name);
void ldlm_resource_add_lock(struct ldlm_resource *res, struct list_head *head,
struct ldlm_lock *lock)
{
+ ldlm_resource_dump(res);
+ ldlm_lock_dump(lock);
+ if (!list_empty(&lock->l_res_link))
+ LBUG();
+
list_add(&lock->l_res_link, head);
res->lr_refcount++;
}
lock->l_resource->lr_refcount--;
}
-int ldlm_get_resource_handle(struct ldlm_resource *res, struct ldlm_handle *h)
+int ldlm_get_resource_handle(struct ldlm_resource *res, struct lustre_handle *h)
{
LBUG();
return 0;
struct ldlm_resource *res;
__u64 res_id[RES_NAME_SIZE] = {1, 2, 3};
ldlm_error_t err;
- struct ldlm_handle lockh_1, lockh_2;
+ struct lustre_handle lockh_1, lockh_2;
int flags;
- ns = ldlm_namespace_new(obddev, 0);
+ ns = ldlm_namespace_new(LDLM_NAMESPACE_SERVER);
if (ns == NULL)
LBUG();
err = ldlm_local_lock_create(ns, NULL, res_id, LDLM_PLAIN, LCK_CR,
NULL, 0, &lockh_1);
- err = ldlm_local_lock_enqueue(&lockh_1, NULL, &flags,
+ err = ldlm_local_lock_enqueue(&lockh_1, NULL, 0, &flags,
ldlm_test_callback, ldlm_test_callback);
if (err != ELDLM_OK)
LBUG();
err = ldlm_local_lock_create(ns, NULL, res_id, LDLM_PLAIN, LCK_EX,
NULL, 0, &lockh_2);
- err = ldlm_local_lock_enqueue(&lockh_2, NULL, &flags,
+ err = ldlm_local_lock_enqueue(&lockh_2, NULL, 0, &flags,
ldlm_test_callback, ldlm_test_callback);
if (err != ELDLM_OK)
LBUG();
struct ldlm_lock *lock;
__u64 res_id[RES_NAME_SIZE] = {0, 0, 0};
struct ldlm_extent ext1 = {4, 6}, ext2 = {6, 9}, ext3 = {10, 11};
- struct ldlm_handle ext1_h, ext2_h, ext3_h;
+ struct lustre_handle ext1_h, ext2_h, ext3_h;
ldlm_error_t err;
int flags;
- ns = ldlm_namespace_new(obddev, 0);
+ ns = ldlm_namespace_new(LDLM_NAMESPACE_SERVER);
if (ns == NULL)
LBUG();
flags = 0;
err = ldlm_local_lock_create(ns, NULL, res_id, LDLM_EXTENT, LCK_PR,
NULL, 0, &ext1_h);
- err = ldlm_local_lock_enqueue(&ext1_h, &ext1, &flags, NULL, NULL);
+ err = ldlm_local_lock_enqueue(&ext1_h, &ext1, sizeof(ext1), &flags,
+ NULL, NULL);
if (err != ELDLM_OK)
LBUG();
if (!(flags & LDLM_FL_LOCK_CHANGED))
flags = 0;
err = ldlm_local_lock_create(ns, NULL, res_id, LDLM_EXTENT, LCK_PR,
NULL, 0, &ext2_h);
- err = ldlm_local_lock_enqueue(&ext2_h, &ext2, &flags, NULL, NULL);
+ err = ldlm_local_lock_enqueue(&ext2_h, &ext2, sizeof(ext2), &flags,
+ NULL, NULL);
if (err != ELDLM_OK)
LBUG();
if (!(flags & LDLM_FL_LOCK_CHANGED))
flags = 0;
err = ldlm_local_lock_create(ns, NULL, res_id, LDLM_EXTENT, LCK_EX,
NULL, 0, &ext3_h);
- err = ldlm_local_lock_enqueue(&ext3_h, &ext3, &flags, NULL, NULL);
+ err = ldlm_local_lock_enqueue(&ext3_h, &ext3, sizeof(ext3), &flags,
+ NULL, NULL);
if (err != ELDLM_OK)
LBUG();
if (!(flags & LDLM_FL_BLOCK_GRANTED))
ldlm_reprocess_all(res);
flags = 0;
- lock = ldlm_handle2object(&ext2_h);
+ lock = lustre_handle2object(&ext2_h);
res = ldlm_local_lock_cancel(lock);
if (res != NULL)
ldlm_reprocess_all(res);
__u64 res_id[RES_NAME_SIZE] = {1, 2, 3};
struct ldlm_extent ext = {4, 6};
- struct ldlm_handle lockh1;
+ struct lustre_handle lockh1;
int flags = 0;
ldlm_error_t err;
- err = ldlm_cli_enqueue(ldlm->ldlm_client, conn, obddev->obd_namespace,
- NULL, res_id, LDLM_EXTENT, &ext, LCK_PR, &flags,
- NULL, 0, &lockh1);
+ err = ldlm_cli_enqueue(ldlm->ldlm_client, conn, NULL,
+ obddev->obd_namespace, NULL, res_id, LDLM_EXTENT,
+ &ext, sizeof(ext), LCK_PR, &flags, NULL, NULL, 0,
+ &lockh1);
CERROR("ldlm_cli_enqueue: %d\n", err);
RETURN(err);
#include <linux/lustre_mds.h>
#include <linux/lustre_lite.h>
+void mds_pack_inode2fid(struct ll_fid *fid, struct inode *inode)
+{
+ fid->id = HTON__u64(inode->i_ino);
+ fid->generation = HTON__u32(inode->i_generation);
+ fid->f_type = HTON__u32(S_IFMT & inode->i_mode);
+}
+
+
+void mds_pack_inode2body(struct mds_body *b, struct inode *inode)
+{
+ b->valid = OBD_MD_FLID | OBD_MD_FLATIME | OBD_MD_FLMTIME | OBD_MD_FLCTIME | OBD_MD_FLMODE | OBD_MD_FLUID | OBD_MD_FLGID | OBD_MD_FLNLINK | OBD_MD_FLGENER | OBD_MD_FLSIZE | OBD_MD_FLOBJID;
+ b->size = HTON__u64(inode->i_size);
+ b->mode = HTON__u32(inode->i_mode);
+ b->uid = HTON__u32(inode->i_uid);
+ b->gid = HTON__u32(inode->i_gid);
+ b->mtime = HTON__u32(inode->i_mtime);
+ b->ctime = HTON__u32(inode->i_ctime);
+ b->atime = HTON__u32(inode->i_atime);
+ b->flags = HTON__u32(inode->i_flags);
+ //b->major = HTON__u32(inode->i_major);
+ //b->minor = HTON__u32(inode->i_minor);
+ b->ino = HTON__u32(inode->i_ino);
+ b->nlink = HTON__u32(inode->i_nlink);
+ b->generation = HTON__u32(inode->i_generation);
+}
+
+
void mds_pack_fid(struct ll_fid *fid)
{
fid->id = HTON__u64(fid->id);
b->last_xid = HTON__u32(b->last_xid);
}
+void mds_getattr_pack(struct ptlrpc_request *req, int offset,
+ struct inode *inode,
+ const char *name, int namelen)
+{
+ struct mds_body *rec;
+ rec = lustre_msg_buf(req->rq_reqmsg, offset);
+
+ ll_inode2fid(&rec->fid1, inode);
+ if (name) {
+ char *tmp;
+ tmp = lustre_msg_buf(req->rq_reqmsg, offset + 1);
+ LOGL0(name, namelen, tmp);
+ }
+}
+
+
void mds_pack_req_body(struct ptlrpc_request *req)
{
struct mds_body *b = lustre_msg_buf(req->rq_reqmsg, 0);
/* packing of MDS records */
-void mds_create_pack(struct mds_rec_create *rec, struct inode *inode,
- __u32 mode, __u64 rdev, __u32 uid, __u32 gid, __u64 time)
+void mds_create_pack(struct ptlrpc_request *req, int offset,
+ struct inode *inode, __u32 mode, __u64 rdev, __u32 uid,
+ __u32 gid, __u64 time, const char *name, int namelen,
+ const char *tgt, int tgtlen)
{
+ struct mds_rec_create *rec;
+ char *tmp;
+ rec = lustre_msg_buf(req->rq_reqmsg, offset);
+
/* XXX do something about time, uid, gid */
rec->cr_opcode = HTON__u32(REINT_CREATE);
ll_inode2fid(&rec->cr_fid, inode);
rec->cr_uid = HTON__u32(uid);
rec->cr_gid = HTON__u32(gid);
rec->cr_time = HTON__u64(time);
+
+ tmp = lustre_msg_buf(req->rq_reqmsg, offset + 1);
+ LOGL0(name, namelen, tmp);
+
+ if (tgt) {
+ tmp = lustre_msg_buf(req->rq_reqmsg, offset + 2);
+ LOGL0(tgt, tgtlen, tmp);
+ }
}
-void mds_setattr_pack(struct mds_rec_setattr *rec, struct inode *inode,
- struct iattr *iattr)
+void mds_setattr_pack(struct ptlrpc_request *req, int offset,
+ struct inode *inode, struct iattr *iattr,
+ const char *name, int namelen)
{
+ struct mds_rec_setattr *rec;
+ rec = lustre_msg_buf(req->rq_reqmsg, offset);
+
rec->sa_opcode = HTON__u32(REINT_SETATTR);
ll_inode2fid(&rec->sa_fid, inode);
rec->sa_valid = HTON__u32(iattr->ia_valid);
rec->sa_mtime = HTON__u64(iattr->ia_mtime);
rec->sa_ctime = HTON__u64(iattr->ia_ctime);
rec->sa_attr_flags = HTON__u32(iattr->ia_attr_flags);
+
+ if (namelen) {
+ char *tmp;
+ tmp = lustre_msg_buf(req->rq_reqmsg, offset + 1);
+ LOGL0(name, namelen, tmp);
+ }
}
-void mds_unlink_pack(struct mds_rec_unlink *rec, struct inode *inode,
- struct inode *child)
+void mds_unlink_pack(struct ptlrpc_request *req, int offset,
+ struct inode *inode, struct inode *child,
+ const char *name, int namelen)
{
+ struct mds_rec_unlink *rec;
+ char *tmp;
+
+ rec = lustre_msg_buf(req->rq_reqmsg, offset);
+
rec->ul_opcode = HTON__u32(REINT_UNLINK);
ll_inode2fid(&rec->ul_fid1, inode);
ll_inode2fid(&rec->ul_fid2, child);
+
+ tmp = lustre_msg_buf(req->rq_reqmsg, offset + 1);
+ LOGL0(name, namelen, tmp);
}
-void mds_link_pack(struct mds_rec_link *rec,
- struct inode *inode, struct inode *dir)
+void mds_link_pack(struct ptlrpc_request *req, int offset,
+ struct inode *inode, struct inode *dir,
+ const char *name, int namelen)
{
+ struct mds_rec_link *rec;
+ char *tmp;
+
+ rec = lustre_msg_buf(req->rq_reqmsg, offset);
+
rec->lk_opcode = HTON__u32(REINT_LINK);
ll_inode2fid(&rec->lk_fid1, inode);
ll_inode2fid(&rec->lk_fid2, dir);
+
+ tmp = lustre_msg_buf(req->rq_reqmsg, offset + 1);
+ LOGL0(name, namelen, tmp);
}
-void mds_rename_pack(struct mds_rec_rename *rec, struct inode *srcdir,
- struct inode *tgtdir)
+void mds_rename_pack(struct ptlrpc_request *req, int offset,
+ struct inode *srcdir, struct inode *tgtdir,
+ const char *old, int oldlen, const char *new, int newlen)
{
+ struct mds_rec_rename *rec;
+ char *tmp;
+
+ rec = lustre_msg_buf(req->rq_reqmsg, offset);
+
/* XXX do something about time, uid, gid */
rec->rn_opcode = HTON__u32(REINT_RENAME);
ll_inode2fid(&rec->rn_fid1, srcdir);
ll_inode2fid(&rec->rn_fid2, tgtdir);
+
+ tmp = lustre_msg_buf(req->rq_reqmsg, offset + 1);
+ LOGL0(old, oldlen, tmp);
+
+ if (new) {
+ tmp = lustre_msg_buf(req->rq_reqmsg, offset + 2);
+ LOGL0(new, newlen, tmp);
+ }
}
/* unpacking */
fid->f_type = NTOH__u32(fid->f_type);
}
-static void mds_unpack_body(struct mds_body *b)
+void mds_unpack_body(struct mds_body *b)
{
if (b == NULL)
LBUG();
b->last_xid = NTOH__u32(b->last_xid);
}
-
-void mds_unpack_req_body(struct ptlrpc_request *req)
-{
- struct mds_body *b = lustre_msg_buf(req->rq_reqmsg, 0);
- mds_unpack_body(b);
-}
-
-void mds_unpack_rep_body(struct ptlrpc_request *req)
-{
- struct mds_body *b = lustre_msg_buf(req->rq_repmsg, 0);
- mds_unpack_body(b);
-}
-
-static int mds_setattr_unpack(struct ptlrpc_request *req,
+static int mds_setattr_unpack(struct ptlrpc_request *req, int offset,
struct mds_update_record *r)
{
struct iattr *attr = &r->ur_iattr;
- struct mds_rec_setattr *rec = lustre_msg_buf(req->rq_reqmsg, 0);
+ struct mds_rec_setattr *rec = lustre_msg_buf(req->rq_reqmsg, offset);
ENTRY;
- if (req->rq_reqmsg->bufcount != 1 ||
- req->rq_reqmsg->buflens[0] != sizeof(*rec))
+ if (req->rq_reqmsg->bufcount < offset + 1 ||
+ req->rq_reqmsg->buflens[offset] != sizeof(*rec))
RETURN(-EFAULT);
r->ur_fid1 = &rec->sa_fid;
attr->ia_mtime = NTOH__u64(rec->sa_mtime);
attr->ia_ctime = NTOH__u64(rec->sa_ctime);
attr->ia_attr_flags = NTOH__u32(rec->sa_attr_flags);
+
+ if (req->rq_reqmsg->bufcount == offset + 2) {
+ r->ur_namelen = req->rq_reqmsg->buflens[offset + 1];
+ r->ur_name = lustre_msg_buf(req->rq_reqmsg, offset + 1);
+ } else
+ r->ur_namelen = 0;
+
RETURN(0);
}
-static int mds_create_unpack(struct ptlrpc_request *req,
+static int mds_create_unpack(struct ptlrpc_request *req, int offset,
struct mds_update_record *r)
{
- struct mds_rec_create *rec = lustre_msg_buf(req->rq_reqmsg, 0);
+ struct mds_rec_create *rec = lustre_msg_buf(req->rq_reqmsg, offset);
ENTRY;
- if (req->rq_reqmsg->bufcount < 2 ||
- req->rq_reqmsg->buflens[0] != sizeof(*rec))
+ if (req->rq_reqmsg->bufcount != offset + 3 ||
+ req->rq_reqmsg->buflens[offset] != sizeof(*rec))
RETURN(-EFAULT);
r->ur_fid1 = &rec->cr_fid;
r->ur_gid = NTOH__u32(rec->cr_gid);
r->ur_time = NTOH__u64(rec->cr_time);
- r->ur_name = lustre_msg_buf(req->rq_reqmsg, 1);
- r->ur_namelen = req->rq_reqmsg->buflens[1];
+ r->ur_name = lustre_msg_buf(req->rq_reqmsg, offset + 1);
+ r->ur_namelen = req->rq_reqmsg->buflens[offset + 1];
- if (S_ISLNK(r->ur_mode)) {
- r->ur_tgt = lustre_msg_buf(req->rq_reqmsg, 2);
- r->ur_tgtlen = req->rq_reqmsg->buflens[2];
- }
+ r->ur_tgt = lustre_msg_buf(req->rq_reqmsg, offset + 2);
+ r->ur_tgtlen = req->rq_reqmsg->buflens[offset + 2];
RETURN(0);
}
-static int mds_link_unpack(struct ptlrpc_request *req,
+static int mds_link_unpack(struct ptlrpc_request *req, int offset,
struct mds_update_record *r)
{
- struct mds_rec_link *rec = lustre_msg_buf(req->rq_reqmsg, 0);
+ struct mds_rec_link *rec = lustre_msg_buf(req->rq_reqmsg, offset);
ENTRY;
- if (req->rq_reqmsg->bufcount != 2 ||
- req->rq_reqmsg->buflens[0] != sizeof(*rec))
+ if (req->rq_reqmsg->bufcount != offset + 2 ||
+ req->rq_reqmsg->buflens[offset] != sizeof(*rec))
RETURN(-EFAULT);
r->ur_fid1 = &rec->lk_fid1;
r->ur_fid2 = &rec->lk_fid2;
- r->ur_name = lustre_msg_buf(req->rq_reqmsg, 1);
- r->ur_namelen = req->rq_reqmsg->buflens[1];
+ r->ur_name = lustre_msg_buf(req->rq_reqmsg, offset + 1);
+ r->ur_namelen = req->rq_reqmsg->buflens[offset + 1];
RETURN(0);
}
-static int mds_unlink_unpack(struct ptlrpc_request *req,
+static int mds_unlink_unpack(struct ptlrpc_request *req, int offset,
struct mds_update_record *r)
{
- struct mds_rec_unlink *rec = lustre_msg_buf(req->rq_reqmsg, 0);
+ struct mds_rec_unlink *rec = lustre_msg_buf(req->rq_reqmsg, offset);
ENTRY;
- if (req->rq_reqmsg->bufcount != 2 ||
- req->rq_reqmsg->buflens[0] != sizeof(*rec))
+ if (req->rq_reqmsg->bufcount != offset + 2 ||
+ req->rq_reqmsg->buflens[offset] != sizeof(*rec))
RETURN(-EFAULT);
r->ur_fid1 = &rec->ul_fid1;
r->ur_fid2 = &rec->ul_fid2;
- r->ur_name = lustre_msg_buf(req->rq_reqmsg, 1);
- r->ur_namelen = req->rq_reqmsg->buflens[1];
+ r->ur_name = lustre_msg_buf(req->rq_reqmsg, offset + 1);
+ r->ur_namelen = req->rq_reqmsg->buflens[offset + 1];
RETURN(0);
}
-static int mds_rename_unpack(struct ptlrpc_request *req,
+static int mds_rename_unpack(struct ptlrpc_request *req, int offset,
struct mds_update_record *r)
{
- struct mds_rec_rename *rec = lustre_msg_buf(req->rq_reqmsg, 0);
+ struct mds_rec_rename *rec = lustre_msg_buf(req->rq_reqmsg, offset);
ENTRY;
- if (req->rq_reqmsg->bufcount != 3 ||
- req->rq_reqmsg->buflens[0] != sizeof(*rec))
+ if (req->rq_reqmsg->bufcount != offset + 3 ||
+ req->rq_reqmsg->buflens[offset] != sizeof(*rec))
RETURN(-EFAULT);
r->ur_fid1 = &rec->rn_fid1;
r->ur_fid2 = &rec->rn_fid2;
- r->ur_name = lustre_msg_buf(req->rq_reqmsg, 1);
- r->ur_namelen = req->rq_reqmsg->buflens[1];
+ r->ur_name = lustre_msg_buf(req->rq_reqmsg, offset + 1);
+ r->ur_namelen = req->rq_reqmsg->buflens[offset + 1];
- r->ur_tgt = lustre_msg_buf(req->rq_reqmsg, 2);
- r->ur_tgtlen = req->rq_reqmsg->buflens[2];
+ r->ur_tgt = lustre_msg_buf(req->rq_reqmsg, offset + 2);
+ r->ur_tgtlen = req->rq_reqmsg->buflens[offset + 2];
RETURN(0);
}
-typedef int (*update_unpacker)(struct ptlrpc_request *req,
+typedef int (*update_unpacker)(struct ptlrpc_request *req, int offset,
struct mds_update_record *r);
static update_unpacker mds_unpackers[REINT_MAX + 1] = {
[REINT_RECREATE] mds_create_unpack,
};
-int mds_update_unpack(struct ptlrpc_request *req, struct mds_update_record *rec)
+int mds_update_unpack(struct ptlrpc_request *req, int offset,
+ struct mds_update_record *rec)
{
- struct mds_update_record_hdr *hdr = lustre_msg_buf(req->rq_reqmsg, 0);
+ struct mds_update_record_hdr *hdr =
+ lustre_msg_buf(req->rq_reqmsg, offset);
int rc;
ENTRY;
- if (!hdr || req->rq_reqmsg->buflens[0] < sizeof(__u32))
+ if (!hdr || req->rq_reqmsg->buflens[offset] < sizeof(*hdr))
RETURN(-EFAULT);
rec->ur_opcode = NTOH__u32(hdr->ur_opcode);
if (rec->ur_opcode < 0 || rec->ur_opcode > REINT_MAX)
RETURN(-EFAULT);
- rc = mds_unpackers[rec->ur_opcode](req, rec);
+ rc = mds_unpackers[rec->ur_opcode](req, offset, rec);
RETURN(rc);
}
LINX=page.c
-llite_SOURCES = recover.c commit_callback.c page.c super.c rw.c file.c dir.c sysctl.c namei.c symlink.c
+llite_SOURCES = dcache.c recover.c commit_callback.c page.c super.c rw.c file.c dir.c sysctl.c namei.c symlink.c
dist-hook:
list='$(LINX)'; for f in $$list; do rm -f $(distdir)/$$f; done
-/*
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
*
* This code is issued under the GNU General Public License.
* See the file COPYING in this distribution
extern struct address_space_operations ll_aops;
+void ll_intent_release(struct dentry *de)
+{
+ struct ldlm_lock *lock;
+ struct lustre_handle *handle;
+ ENTRY;
+
+ if (de->d_it == NULL) {
+ EXIT;
+ return;
+ }
+
+ handle = (struct lustre_handle *)de->d_it->it_lock_handle;
+ lock = lustre_handle2object(handle);
+ CDEBUG(D_INFO, "calling ldlm_lock_decref(%p, %d)\n", lock,
+ de->d_it->it_lock_mode);
+ ldlm_lock_decref(lock, de->d_it->it_lock_mode);
+ EXIT;
+}
+
int ll_revalidate2(struct dentry *de, int flags, struct lookup_intent *it)
{
ENTRY;
-
- RETURN(1);
+ RETURN(0);
}
struct dentry_operations ll_d_ops = {
- d_revalidate2: ll_revalidate2
+ d_revalidate2: ll_revalidate2,
+ d_intent_release: ll_intent_release
};
#include <linux/lustre_idl.h>
#include <linux/lustre_mds.h>
#include <linux/lustre_lite.h>
+#include <linux/lustre_dlm.h>
typedef struct ext2_dir_entry_2 ext2_dirent;
__u64 offset;
int rc = 0;
struct ptlrpc_request *request = NULL;
+ struct lustre_handle lockh;
+ struct lookup_intent it = {IT_READDIR };
ENTRY;
goto readpage_out;
}
+ rc = ll_lock(inode, NULL, &it, &lockh);
+ if (rc != ELDLM_OK)
+ CERROR("lock enqueue: err: %d\n", rc);
+ ldlm_lock_dump((void *)(unsigned long)lockh.addr);
+
if (Page_Uptodate(page)) {
CERROR("Explain this please?\n");
EXIT;
offset = page->index << PAGE_SHIFT;
buf = kmap(page);
- rc = mdc_readpage(&sbi->ll_mds_client, sbi->ll_mds_conn, inode->i_ino,
+ rc = mdc_readpage(&sbi->ll_mdc_conn, inode->i_ino,
S_IFDIR, offset, buf, &request);
kunmap(page);
ptlrpc_free_req(request);
SetPageUptodate(page);
UnlockPage(page);
+ rc = ll_unlock(LCK_PR, &lockh);
+ if (rc != ELDLM_OK)
+ CERROR("ll_unlock: err: %d\n", rc);
return rc;
} /* ll_dir_readpage */
struct ll_file_data *fd;
struct obdo *oa;
struct ll_sb_info *sbi = ll_i2sbi(inode);
+ struct ll_inode_info *lli = ll_i2info(inode);
+ __u64 id = 0;
ENTRY;
if (file->private_data)
LBUG();
+ /* delayed create of object (intent created inode) */
+ /* XXX object needs to be cleaned up if mdc_open fails */
+ /* XXX error handling appropriate here? */
+ if (lli->lli_obdo == NULL) {
+ struct inode * inode = file->f_dentry->d_inode;
+
+ oa = lli->lli_obdo = obdo_alloc();
+ oa->o_valid = OBD_MD_FLMODE;
+ oa->o_mode = S_IFREG | 0600;
+ rc = obd_create(ll_i2obdconn(inode), oa);
+ if (rc)
+ RETURN(rc);
+ lli->lli_flags &= ~OBD_FL_CREATEONOPEN;
+ }
+
+ oa = lli->lli_obdo;
+ if (oa == NULL) {
+ LBUG();
+ GOTO(out_mdc, rc = -EINVAL);
+ }
+
fd = kmem_cache_alloc(ll_file_data_slab, SLAB_KERNEL);
if (!fd)
GOTO(out, rc = -ENOMEM);
memset(fd, 0, sizeof(*fd));
- rc = mdc_open(&sbi->ll_mds_client, sbi->ll_mds_conn, inode->i_ino,
- S_IFREG, file->f_flags, (__u64)(unsigned long)file,
- &fd->fd_mdshandle, &req);
+ rc = mdc_open(&sbi->ll_mdc_conn, inode->i_ino, S_IFREG, file->f_flags,
+ id, (__u64)(unsigned long)file, &fd->fd_mdshandle, &req);
fd->fd_req = req;
ptlrpc_req_finished(req);
if (rc)
if (!fd->fd_mdshandle)
CERROR("mdc_open didn't assign fd_mdshandle\n");
- oa = ll_i2info(inode)->lli_obdo;
- if (oa == NULL) {
- LBUG();
- GOTO(out_mdc, rc = -ENOMEM);
- }
rc = obd_open(ll_i2obdconn(inode), oa);
- if (rc) {
+ if (rc)
GOTO(out_mdc, rc = -abs(rc));
- }
file->private_data = fd;
return 0;
out_mdc:
- mdc_close(&sbi->ll_mds_client, sbi->ll_mds_conn, inode->i_ino,
+ mdc_close(&sbi->ll_mdc_conn, inode->i_ino,
S_IFREG, fd->fd_mdshandle, &req);
out_req:
ptlrpc_free_req(req);
}
}
- rc = mdc_close(&sbi->ll_mds_client, sbi->ll_mds_conn, inode->i_ino,
+ rc = mdc_close(&sbi->ll_mdc_conn, inode->i_ino,
S_IFREG, fd->fd_mdshandle, &req);
ptlrpc_req_finished(req);
- if (rc) {
- if (rc > 0)
+ if (rc) {
+ if (rc > 0)
rc = -rc;
GOTO(out, rc);
}
ll_inode_setattr(inode, &attr, 0);
}
+static int ll_lock_callback(struct ldlm_lock *lock, struct ldlm_lock *new,
+ void *data, __u32 data_len)
+{
+ struct inode *inode = lock->l_data;
+ ENTRY;
+
+ if (new == NULL) {
+ /* Completion AST. Do nothing. */
+ RETURN(0);
+ }
+
+ if (data_len != sizeof(struct inode))
+ LBUG();
+
+ /* FIXME: do something better than throwing away everything */
+ if (inode == NULL)
+ LBUG();
+ down(&inode->i_sem);
+ invalidate_inode_pages(inode);
+ up(&inode->i_sem);
+
+ if (ldlm_cli_cancel(lock->l_client, lock) < 0)
+ LBUG();
+ RETURN(0);
+}
+
static ssize_t ll_file_read(struct file *filp, char *buf, size_t count,
loff_t *ppos)
{
struct inode *inode = filp->f_dentry->d_inode;
struct ll_sb_info *sbi = ll_i2sbi(inode);
struct ldlm_extent extent;
- struct ldlm_handle lockh;
+ struct lustre_handle lockh;
__u64 res_id[RES_NAME_SIZE] = {inode->i_ino};
int flags = 0;
ldlm_error_t err;
CDEBUG(D_INFO, "Locking inode %ld, start %Lu end %Lu\n",
inode->i_ino, extent.start, extent.end);
- err = obd_enqueue(&sbi->ll_conn, sbi->ll_namespace, NULL,
- res_id, LDLM_EXTENT, &extent, LCK_PR, &flags,
- inode, sizeof(*inode), &lockh);
+ err = obd_enqueue(&sbi->ll_osc_conn, NULL, res_id, LDLM_EXTENT,
+ &extent, sizeof(extent), LCK_PR, &flags,
+ ll_lock_callback, inode, sizeof(*inode),
+ &lockh);
if (err != ELDLM_OK)
CERROR("lock enqueue: err: %d\n", err);
ldlm_lock_dump((void *)(unsigned long)lockh.addr);
CDEBUG(D_INFO, "Reading inode %ld, %d bytes, offset %Ld\n",
inode->i_ino, count, *ppos);
retval = generic_file_read(filp, buf, count, ppos);
+
if (retval > 0)
ll_update_atime(inode);
if (!(fd->fd_flags & LL_FILE_IGNORE_LOCK)) {
- err = obd_cancel(&sbi->ll_conn, LCK_PR, &lockh);
+ err = obd_cancel(&sbi->ll_osc_conn, LCK_PR, &lockh);
if (err != ELDLM_OK)
CERROR("lock cancel: err: %d\n", err);
}
struct inode *inode = file->f_dentry->d_inode;
struct ll_sb_info *sbi = ll_i2sbi(inode);
struct ldlm_extent extent;
- struct ldlm_handle lockh;
+ struct lustre_handle lockh;
__u64 res_id[RES_NAME_SIZE] = {inode->i_ino};
int flags = 0;
ldlm_error_t err;
CDEBUG(D_INFO, "Locking inode %ld, start %Lu end %Lu\n",
inode->i_ino, extent.start, extent.end);
- err = obd_enqueue(&sbi->ll_conn, sbi->ll_namespace, NULL,
- res_id, LDLM_EXTENT, &extent, LCK_PW, &flags,
- inode, sizeof(*inode), &lockh);
+ err = obd_enqueue(&sbi->ll_osc_conn, NULL, res_id, LDLM_EXTENT,
+ &extent, sizeof(extent), LCK_PW, &flags,
+ ll_lock_callback, inode, sizeof(*inode),
+ &lockh);
if (err != ELDLM_OK)
CERROR("lock enqueue: err: %d\n", err);
ldlm_lock_dump((void *)(unsigned long)lockh.addr);
retval = generic_file_write(file, buf, count, ppos);
if (!(fd->fd_flags & LL_FILE_IGNORE_LOCK)) {
- err = obd_cancel(&sbi->ll_conn, LCK_PW, &lockh);
+ err = obd_cancel(&sbi->ll_osc_conn, LCK_PW, &lockh);
if (err != ELDLM_OK)
CERROR("lock cancel: err: %d\n", err);
}
-/*
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
*
* This code is issued under the GNU General Public License.
* See the file COPYING in this distribution
* David S. Miller (davem@caip.rutgers.edu), 1995
* Directory entry file type support and forward compatibility hooks
* for B-tree directories by Theodore Ts'o (tytso@mit.edu), 1998
- *
+ *
* Changes for use in OBDFS
* Copyright (c) 1999, Seagate Technology Inc.
* Copyright (C) 2001, Cluster File Systems, Inc.
* Rewritten based on recent ext2 page cache use.
- *
+ *
*/
#include <linux/fs.h>
#include <linux/obd_support.h>
#include <linux/lustre_lite.h>
+#include <linux/lustre_dlm.h>
extern struct address_space_operations ll_aops;
/* from super.c */
inode->i_nlink++;
}
-/* postpone the disk update until the inode really goes away */
+/* postpone the disk update until the inode really goes away */
static inline void ext2_dec_count(struct inode *inode)
{
inode->i_nlink--;
return 1;
}
-static struct dentry *ll_lookup(struct inode * dir, struct dentry *dentry)
+extern struct dentry_operations ll_d_ops;
+
+int ll_lock(struct inode *dir, struct dentry *dentry,
+ struct lookup_intent *it, struct lustre_handle *lockh)
+{
+ struct ll_sb_info *sbi = ll_i2sbi(dir);
+ int err;
+
+ if ((it->it_op & (IT_CREAT | IT_MKDIR | IT_SYMLINK | IT_SETATTR |
+ IT_MKNOD)) )
+ err = mdc_enqueue(&sbi->ll_mdc_conn, LDLM_MDSINTENT,
+ it, LCK_PW, dir, dentry, lockh, 0, NULL, 0,
+ dir, sizeof(*dir));
+ else if (it->it_op & (IT_READDIR | IT_GETATTR | IT_OPEN))
+ err = mdc_enqueue(&sbi->ll_mdc_conn, LDLM_MDSINTENT,
+ it, LCK_PR, dir, dentry, lockh, 0, NULL, 0,
+ dir, sizeof(*dir));
+ else
+ LBUG();
+
+ RETURN(err);
+}
+
+int ll_unlock(__u32 mode, struct lustre_handle *lockh)
+{
+ struct ldlm_lock *lock;
+ ENTRY;
+
+ lock = lustre_handle2object(lockh);
+ ldlm_lock_decref(lock, mode);
+
+ RETURN(0);
+}
+
+static struct dentry *ll_lookup2(struct inode * dir, struct dentry *dentry,
+ struct lookup_intent *it)
{
struct ptlrpc_request *request = NULL;
struct inode * inode = NULL;
struct ll_sb_info *sbi = ll_i2sbi(dir);
struct ll_inode_md md;
- int err, type;
+ struct lustre_handle lockh;
+ int err, type, offset;
ino_t ino;
ENTRY;
+
+ CDEBUG(D_INFO, "name: %*s, intent op: %d\n", dentry->d_name.len,
+ dentry->d_name.name, it->it_op);
+
if (dentry->d_name.len > EXT2_NAME_LEN)
RETURN(ERR_PTR(-ENAMETOOLONG));
- ino = ll_inode_by_name(dir, dentry, &type);
- if (!ino)
+ err = ll_lock(dir, dentry, it, &lockh);
+ memcpy(it->it_lock_handle, &lockh, sizeof(lockh));
+
+ if ( (it->it_op & (IT_CREAT | IT_MKDIR | IT_SYMLINK)) &&
+ it->it_disposition && !it->it_status)
GOTO(negative, NULL);
- err = mdc_getattr(&sbi->ll_mds_client, sbi->ll_mds_conn, ino, type,
- OBD_MD_FLNOTOBD|OBD_MD_FLBLOCKS, 0, &request);
- if (err) {
- CERROR("failure %d inode %ld\n", err, (long)ino);
- ptlrpc_free_req(request);
- RETURN(ERR_PTR(-abs(err)));
+ if ( (it->it_op & (IT_GETATTR)) &&
+ it->it_disposition && it->it_status)
+ GOTO(negative, NULL);
+
+ if (!it->it_disposition) {
+ struct ll_inode_info *lli = ll_i2info(dir);
+ memcpy(&lli->lli_intent_lock_handle, &lockh, sizeof(lockh));
+
+ ino = ll_inode_by_name(dir, dentry, &type);
+
+ err = mdc_getattr(&sbi->ll_mdc_conn, ino, type,
+ OBD_MD_FLNOTOBD|OBD_MD_FLBLOCKS, 0, &request);
+ if (err) {
+ CERROR("failure %d inode %ld\n", err, (long)ino);
+ ptlrpc_free_req(request);
+ RETURN(ERR_PTR(-abs(err)));
+ }
+ offset = 0;
+ } else {
+ offset = 1;
+ request = (struct ptlrpc_request *)it->it_data;
}
if (S_ISREG(type)) {
- if (request->rq_repmsg->bufcount < 2 ||
- request->rq_repmsg->buflens[1] != sizeof(struct obdo))
+ if (request->rq_repmsg->bufcount < offset + 2 ||
+ request->rq_repmsg->buflens[offset + 1] !=
+ sizeof(struct obdo))
LBUG();
- md.obdo = lustre_msg_buf(request->rq_repmsg, 1);
+ md.obdo = lustre_msg_buf(request->rq_repmsg, offset + 1);
} else
md.obdo = NULL;
- md.body = lustre_msg_buf(request->rq_repmsg, 0);
+ md.body = lustre_msg_buf(request->rq_repmsg, offset);
inode = iget4(dir->i_sb, ino, ll_find_inode, &md);
+ if (it->it_op & IT_RENAME)
+ it->it_data = dentry;
+
ptlrpc_free_req(request);
- if (!inode)
+ if (!inode)
RETURN(ERR_PTR(-ENOMEM));
EXIT;
negative:
+ dentry->d_op = &ll_d_ops;
d_add(dentry, inode);
return NULL;
}
-static struct inode *ll_create_node(struct inode *dir, const char *name,
- int namelen, const char *tgt, int tgtlen,
- int mode, __u64 extra, struct obdo *obdo)
+static struct inode *ll_create_node(struct inode *dir, const char *name,
+ int namelen, const char *tgt, int tgtlen,
+ int mode, __u64 extra,
+ struct lookup_intent *it, struct obdo *obdo)
{
struct inode *inode;
struct ptlrpc_request *request = NULL;
struct mds_body *body;
- int err;
+ int rc;
time_t time = CURRENT_TIME;
struct ll_sb_info *sbi = ll_i2sbi(dir);
struct ll_inode_md md;
ENTRY;
- err = mdc_create(&sbi->ll_mds_client, sbi->ll_mds_conn, dir, name,
- namelen, tgt, tgtlen, mode, current->fsuid,
- current->fsgid, time, extra, obdo, &request);
- if (err) {
- inode = ERR_PTR(err);
- GOTO(out, err);
+ if (!it->it_disposition) {
+ rc = mdc_create(&sbi->ll_mdc_conn, dir, name, namelen, tgt,
+ tgtlen, mode, current->fsuid,
+ current->fsgid, time, extra, obdo, &request);
+ if (rc) {
+ inode = ERR_PTR(rc);
+ GOTO(out, rc);
+ }
+ body = lustre_msg_buf(request->rq_repmsg, 0);
+ } else {
+ request = it->it_data;
+ body = lustre_msg_buf(request->rq_repmsg, 1);
}
- body = lustre_msg_buf(request->rq_repmsg, 0);
+
body->valid = (__u32)OBD_MD_FLNOTOBD;
body->nlink = 1;
}
if (!list_empty(&inode->i_dentry)) {
- CERROR("new_inode -fatal: inode %d, ct %d lnk %d\n",
- body->ino, atomic_read(&inode->i_count),
+ CERROR("new_inode -fatal: inode %d, ct %d lnk %d\n",
+ body->ino, atomic_read(&inode->i_count),
inode->i_nlink);
iput(inode);
LBUG();
ENTRY;
- err = mdc_unlink(&sbi->ll_mds_client, sbi->ll_mds_conn, dir, child,
+ err = mdc_unlink(&sbi->ll_mdc_conn, dir, child,
name, len, &request);
ptlrpc_free_req(request);
- EXIT;
- return err;
+ RETURN(err);
}
-int ll_mdc_link(struct dentry *src, struct inode *dir,
+int ll_mdc_link(struct dentry *src, struct inode *dir,
const char *name, int len)
{
struct ptlrpc_request *request = NULL;
ENTRY;
- err = mdc_link(&sbi->ll_mds_client, sbi->ll_mds_conn, src, dir, name,
+ err = mdc_link(&sbi->ll_mdc_conn, src, dir, name,
len, &request);
ptlrpc_free_req(request);
- EXIT;
- return err;
+ RETURN(err);
}
-int ll_mdc_rename(struct inode *src, struct inode *tgt,
+int ll_mdc_rename(struct inode *src, struct inode *tgt,
struct dentry *old, struct dentry *new)
{
struct ptlrpc_request *request = NULL;
- int err;
struct ll_sb_info *sbi = ll_i2sbi(src);
+ int err;
ENTRY;
- err = mdc_rename(&sbi->ll_mds_client, sbi->ll_mds_conn, src, tgt,
- old->d_name.name, old->d_name.len,
+ err = mdc_rename(&sbi->ll_mdc_conn, src, tgt,
+ old->d_name.name, old->d_name.len,
new->d_name.name, new->d_name.len, &request);
ptlrpc_free_req(request);
- EXIT;
- return err;
+ RETURN(err);
}
/*
* is so far negative - it has no inode.
*
* If the create succeeds, we fill in the inode information
- * with d_instantiate().
+ * with d_instantiate().
*/
-static int ll_create (struct inode * dir, struct dentry * dentry, int mode)
+static int ll_create(struct inode * dir, struct dentry * dentry, int mode)
{
- int err, rc;
+ int rc = 0;
struct obdo oa;
struct inode *inode;
- memset(&oa, 0, sizeof(oa));
- oa.o_valid = OBD_MD_FLMODE;
- oa.o_mode = S_IFREG | 0600;
- rc = obd_create(ll_i2obdconn(dir), &oa);
- if (rc) {
- CERROR("error creating OST object: rc = %d\n", rc);
- RETURN(rc);
- }
+ if (dentry->d_it->it_disposition == 0) {
+ memset(&oa, 0, sizeof(oa));
+ oa.o_valid = OBD_MD_FLMODE;
+ oa.o_mode = S_IFREG | 0600;
+ rc = obd_create(ll_i2obdconn(dir), &oa);
+ if (rc)
+ RETURN(rc);
+ }
mode = mode | S_IFREG;
CDEBUG(D_DENTRY, "name %s mode %o o_id %lld\n",
dentry->d_name.name, mode, (unsigned long long)oa.o_id);
- inode = ll_create_node(dir, dentry->d_name.name, dentry->d_name.len,
- NULL, 0, mode, 0, &oa);
-
- if (IS_ERR(inode)) {
- rc = PTR_ERR(inode);
- CERROR("error creating MDS object for id %Ld: rc = %d\n",
- (unsigned long long)oa.o_id, rc);
- GOTO(out_destroy, rc);
- }
-
- inode->i_op = &ll_file_inode_operations;
- inode->i_fop = &ll_file_operations;
- inode->i_mapping->a_ops = &ll_aops;
- rc = ext2_add_nondir(dentry, inode);
- /* XXX Handle err, but this will probably get more complex anyways */
+ inode = ll_create_node(dir, dentry->d_name.name, dentry->d_name.len,
+ NULL, 0, mode, 0, dentry->d_it, &oa);
+ if (IS_ERR(inode)) {
+ rc = PTR_ERR(inode);
+ CERROR("error creating MDS object for id %Ld: rc = %d\n",
+ (unsigned long long)oa.o_id, rc);
+ GOTO(out_destroy, rc);
+ }
+
+ // XXX clean up the object
+ inode->i_op = &ll_file_inode_operations;
+ inode->i_fop = &ll_file_operations;
+ inode->i_mapping->a_ops = &ll_aops;
+
+ if (dentry->d_it->it_disposition) {
+ struct ll_inode_info *ii = ll_i2info(inode);
+ ii->lli_flags |= OBD_FL_CREATEONOPEN;
+ memcpy(&ii->lli_intent_lock_handle,
+ dentry->d_it->it_lock_handle,
+ sizeof(struct lustre_handle));
+ }
+
+ /* no directory data updates when intents rule */
+ if (dentry->d_it->it_disposition == 0)
+ rc = ext2_add_nondir(dentry, inode);
+ else
+ d_instantiate(dentry, inode);
RETURN(rc);
out_destroy:
- err = obd_destroy(ll_i2obdconn(dir), &oa);
- if (err)
- CERROR("error destroying object %Ld in error path: err = %d\n",
- (unsigned long long)oa.o_id, err);
- return err;
-} /* ll_create */
-
+ rc = obd_destroy(ll_i2obdconn(dir), &oa);
+ if (rc)
+ CERROR("error destroying object %Ld in error path: err = %d\n",
+ (unsigned long long)oa.o_id, rc);
+ return rc;
+}
-static int ll_mknod (struct inode * dir, struct dentry *dentry, int mode,
- int rdev)
+static int ll_mknod(struct inode *dir, struct dentry *dentry, int mode,
+ int rdev)
{
- struct inode * inode = ll_create_node(dir, dentry->d_name.name,
+ struct inode * inode = ll_create_node(dir, dentry->d_name.name,
dentry->d_name.len, NULL, 0,
- mode, rdev, NULL);
+ mode, rdev, NULL, NULL);
int err = PTR_ERR(inode);
if (!IS_ERR(inode)) {
init_special_inode(inode, mode, rdev);
return err;
}
-static int ll_symlink (struct inode * dir, struct dentry * dentry,
- const char * symname)
+static int ll_symlink(struct inode *dir, struct dentry *dentry,
+ const char *symname)
{
int err = -ENAMETOOLONG;
unsigned l = strlen(symname);
if (l > LL_INLINESZ)
return err;
- inode = ll_create_node(dir, dentry->d_name.name,
+ inode = ll_create_node(dir, dentry->d_name.name,
dentry->d_name.len, symname, l,
- S_IFLNK | S_IRWXUGO, 0, NULL);
+ S_IFLNK | S_IRWXUGO, 0, dentry->d_it, NULL);
err = PTR_ERR(inode);
if (IS_ERR(inode))
return err;
oinfo = ll_i2info(inode);
-
+
inode->i_op = &ll_fast_symlink_inode_operations;
memcpy(oinfo->lli_inline, symname, l);
inode->i_size = l-1;
err = ext2_add_nondir(dentry, inode);
- if (err) {
+ if (err) {
ext2_dec_count(inode);
iput (inode);
}
return err;
}
-static int ll_link (struct dentry * old_dentry, struct inode * dir,
- struct dentry *dentry)
+static int ll_link(struct dentry * old_dentry, struct inode * dir,
+ struct dentry *dentry)
{
int err;
struct inode *inode = old_dentry->d_inode;
if (inode->i_nlink >= EXT2_LINK_MAX)
return -EMLINK;
- err = ll_mdc_link(old_dentry, dir,
+ err = ll_mdc_link(old_dentry, dir,
dentry->d_name.name, dentry->d_name.len);
- if (err) {
+ if (err) {
EXIT;
return err;
}
return ext2_add_nondir(dentry, inode);
}
-
static int ll_mkdir(struct inode * dir, struct dentry * dentry, int mode)
{
struct inode * inode;
ext2_inc_count(dir);
- inode = ll_create_node (dir, dentry->d_name.name,
- dentry->d_name.len, NULL, 0,
- S_IFDIR | mode, 0, NULL);
+ inode = ll_create_node (dir, dentry->d_name.name,
+ dentry->d_name.len, NULL, 0,
+ S_IFDIR | mode, 0, dentry->d_it, NULL);
err = PTR_ERR(inode);
if (IS_ERR(inode))
goto out_dir;
if (err)
goto out_fail;
- err = ll_add_link(dentry, inode);
- if (err)
- goto out_fail;
+ /* no directory data updates when intents rule */
+ if (dentry->d_it->it_disposition == 0) {
+ err = ll_add_link(dentry, inode);
+ if (err)
+ goto out_fail;
+ }
d_instantiate(dentry, inode);
out:
de = ext2_find_entry (dir, dentry, &page);
if (!de)
goto out;
-
+
err = ll_mdc_unlink(dir, dentry->d_inode,
dentry->d_name.name, dentry->d_name.len);
- if (err)
+ if (err)
goto out;
err = ext2_delete_entry (de, page);
}
static int ll_rename (struct inode * old_dir, struct dentry * old_dentry,
- struct inode * new_dir, struct dentry * new_dentry )
+ struct inode * new_dir, struct dentry * new_dentry )
{
struct inode * old_inode = old_dentry->d_inode;
struct inode * new_inode = new_dentry->d_inode;
struct ext2_dir_entry_2 * old_de;
int err = -ENOENT;
- err = ll_mdc_rename(old_dir, new_dir, old_dentry, new_dentry);
- if (err)
+ if (new_dentry->d_it) {
+ struct ptlrpc_request *req = new_dentry->d_it->it_data;
+ err = req->rq_status;
+ goto out;
+ }
+
+ err = ll_mdc_rename(old_dir, new_dir, old_dentry, new_dentry);
+ if (err)
goto out;
old_de = ext2_find_entry (old_dir, old_dentry, &old_page);
}
return 0;
-
out_dir:
if (dir_de) {
kunmap(dir_page);
struct inode_operations ll_dir_inode_operations = {
create: ll_create,
- lookup: ll_lookup,
+ lookup2: ll_lookup2,
link: ll_link,
unlink: ll_unlink,
symlink: ll_symlink,
#include <linux/lustre_lite.h>
#include <linux/lustre_ha.h>
+
static int ll_reconnect(struct ll_sb_info *sbi)
{
struct ll_fid rootfid;
int err;
struct ptlrpc_request *request;
- ptlrpc_readdress_connection(sbi->ll_mds_conn, "mds");
+ ptlrpc_readdress_connection(sbi2mdc(sbi)->mdc_conn, "mds");
- err = connmgr_connect(ptlrpc_connmgr, sbi->ll_mds_conn);
+ err = connmgr_connect(ptlrpc_connmgr, sbi2mdc(sbi)->mdc_conn);
if (err) {
CERROR("cannot connect to MDS: rc = %d\n", err);
- ptlrpc_put_connection(sbi->ll_mds_conn);
+ ptlrpc_put_connection(sbi2mdc(sbi)->mdc_conn);
GOTO(out_disc, err = -ENOTCONN);
}
- sbi->ll_mds_conn->c_level = LUSTRE_CONN_CON;
+ sbi2mdc(sbi)->mdc_conn->c_level = LUSTRE_CONN_CON;
/* XXX: need to store the last_* values somewhere */
- err = mdc_connect(&sbi->ll_mds_client, sbi->ll_mds_conn,
+ err = mdc_getstatus(&sbi->ll_mdc_conn,
&rootfid, &last_committed,
&last_rcvd,
&last_xid,
CERROR("cannot mds_connect: rc = %d\n", err);
GOTO(out_disc, err = -ENOTCONN);
}
- sbi->ll_mds_client.cli_last_rcvd = last_xid;
- sbi->ll_mds_conn->c_level = LUSTRE_CONN_RECOVD;
+ sbi2mdc(sbi)->mdc_client->cli_last_rcvd = last_xid;
+ sbi2mdc(sbi)->mdc_conn->c_level = LUSTRE_CONN_RECOVD;
out_disc:
return err;
}
- sbi->ll_mds_conn->c_level = LUSTRE_CONN_FULL;
+ sbi2mdc(sbi)->mdc_conn->c_level = LUSTRE_CONN_FULL;
recovd_cli_fixed(cli);
/* Finally, continue what we delayed since recovery started */
&bufs_per_obdo, &page, &count, &offset, &flags, NULL);
kunmap(page);
- if ((iattr.ia_size = offset + to) > inode->i_size) {
+ iattr.ia_size = offset + to;
+ if (iattr.ia_size > inode->i_size) {
/* do NOT truncate when writing in the middle of a file */
inode->i_size = iattr.ia_size;
iattr.ia_valid = ATTR_SIZE;
}
+int ll_flush_inode_pages(struct inode * inode)
+{
+ //int i;
+ // obd_count num_obdo = 1;
+ obd_count bufs_per_obdo = 0;
+ struct obdo *oa = NULL;
+ obd_size *count = NULL;
+ obd_off *offset = NULL;
+ obd_flag *flags = NULL;
+ int err = 0;
+
+ ENTRY;
+
+ spin_lock(&pagecache_lock);
+
+ spin_unlock(&pagecache_lock);
+
+
+ OBD_ALLOC(count, sizeof(obd_size) * bufs_per_obdo);
+ if (!count)
+ GOTO(out, err=-ENOMEM);
+
+ OBD_ALLOC(offset, sizeof(obd_off) * bufs_per_obdo);
+ if (!offset)
+ GOTO(out, err=-ENOMEM);
+
+ OBD_ALLOC(flags, sizeof(obd_flag) * bufs_per_obdo);
+ if (!flags)
+ GOTO(out, err=-ENOMEM);
+
+#if 0
+ for (i = 0 ; i < bufs_per_obdo ; i++) {
+ count[i] = PAGE_SIZE;
+ offset[i] = ((obd_off)(iobuf->maplist[i])->index) << PAGE_SHIFT;
+ flags[i] = OBD_BRW_CREATE;
+ }
+
+ oa = ll_oa_from_inode(inode, OBD_MD_FLNOTOBD);
+ if (!oa)
+ RETURN(-ENOMEM);
+
+ err = obd_brw(rw, ll_i2obdconn(inode), num_obdo, &oa, &bufs_per_obdo,
+ iobuf->maplist, count, offset, flags);
+ if (err == 0)
+ err = bufs_per_obdo * 4096;
+#endif
+ out:
+ if (oa)
+ obdo_free(oa);
+ if (flags)
+ OBD_FREE(flags, sizeof(obd_flag) * bufs_per_obdo);
+ if (count)
+ OBD_FREE(count, sizeof(obd_count) * bufs_per_obdo);
+ if (offset)
+ OBD_FREE(offset, sizeof(obd_off) * bufs_per_obdo);
+ RETURN(err);
+}
+
+
struct address_space_operations ll_aops = {
readpage: ll_readpage,
RETURN(retval);
}
-static void ll_options(char *options, char **dev, char **vers)
+static void ll_options(char *options, char **ost, char **mds)
{
char *this_char;
ENTRY;
this_char != NULL;
this_char = strtok (NULL, ",")) {
CDEBUG(D_INFO, "this_char %s\n", this_char);
- if ( (!*dev && (*dev = ll_read_opt("device", this_char)))||
- (!*vers && (*vers = ll_read_opt("version", this_char))) )
+ if ( (!*ost && (*ost = ll_read_opt("ost", this_char)))||
+ (!*mds && (*mds = ll_read_opt("mds", this_char))) )
continue;
}
EXIT;
{
struct inode *root = 0;
struct ll_sb_info *sbi;
- char *device = NULL;
- char *version = NULL;
+ char *ost = NULL;
+ char *mds = NULL;
int devno;
int err;
struct ll_fid rootfid;
sb->u.generic_sbp = sbi;
- ll_options(data, &device, &version);
+ ll_options(data, &ost, &mds);
- if (!device) {
- CERROR("no device\n");
+ if (!ost) {
+ CERROR("no ost\n");
GOTO(out_free, sb = NULL);
}
- devno = simple_strtoul(device, NULL, 0);
+ if (!mds) {
+ CERROR("no mds\n");
+ GOTO(out_free, sb = NULL);
+ }
+
+ devno = simple_strtoul(ost, NULL, 0);
if (devno >= MAX_OBD_DEVICES) {
- CERROR("device of %s too high\n", device);
+ CERROR("devno of %s too high\n", ost);
GOTO(out_free, sb = NULL);
}
- sbi->ll_conn.oc_dev = &obd_dev[devno];
- err = obd_connect(&sbi->ll_conn);
+ sbi->ll_osc_conn.oc_dev = &obd_dev[devno];
+ err = obd_connect(&sbi->ll_osc_conn);
if (err) {
- CERROR("cannot connect to %s: rc = %d\n", device, err);
+ CERROR("cannot connect to %s: rc = %d\n", ost, err);
GOTO(out_free, sb = NULL);
}
- sbi->ll_namespace = ldlm_namespace_new(NULL, 1);
- if (sbi->ll_namespace == NULL) {
- CERROR("failed to create local lock namespace\n");
- GOTO(out_obd, sb = NULL);
+ devno = simple_strtoul(mds, NULL, 0);
+ if (devno >= MAX_OBD_DEVICES) {
+ CERROR("devno of %s too high\n", mds);
+ GOTO(out_free, sb = NULL);
}
- ptlrpc_init_client(ptlrpc_connmgr, ll_recover,
- MDS_REQUEST_PORTAL, MDC_REPLY_PORTAL,
- &sbi->ll_mds_client);
-
- sbi->ll_mds_client.cli_data = sbi;
- sbi->ll_mds_client.cli_name = "mdc";
- sbi->ll_mds_conn = ptlrpc_uuid_to_connection("mds");
- if (!sbi->ll_mds_conn) {
- CERROR("cannot find MDS\n");
- GOTO(out_ldlm, sb = NULL);
+ sbi->ll_mdc_conn.oc_dev = &obd_dev[devno];
+ err = obd_connect(&sbi->ll_mdc_conn);
+ if (err) {
+ CERROR("cannot connect to %s: rc = %d\n", mds, err);
+ GOTO(out_free, sb = NULL);
}
+#if 0
err = connmgr_connect(ptlrpc_connmgr, sbi->ll_mds_conn);
if (err) {
CERROR("cannot connect to MDS: rc = %d\n", err);
GOTO(out_rpc, sb = NULL);
}
+#endif
- sbi->ll_mds_conn->c_level = LUSTRE_CONN_FULL;
+ sbi2mdc(sbi)->mdc_conn->c_level = LUSTRE_CONN_FULL;
/* XXX: need to store the last_* values somewhere */
- err = mdc_connect(&sbi->ll_mds_client, sbi->ll_mds_conn,
- &rootfid, &last_committed, &last_rcvd, &last_xid,
- &request);
+ err = mdc_getstatus(&sbi->ll_mdc_conn,
+ &rootfid, &last_committed,
+ &last_rcvd, &last_xid,
+ &request);
if (err) {
CERROR("cannot mds_connect: rc = %d\n", err);
GOTO(out_disc, sb = NULL);
sb->s_op = &ll_super_operations;
/* make root inode */
- err = mdc_getattr(&sbi->ll_mds_client, sbi->ll_mds_conn,
+ err = mdc_getattr(&sbi->ll_mdc_conn,
sbi->ll_rootino, S_IFDIR,
OBD_MD_FLNOTOBD|OBD_MD_FLBLOCKS, 0, &request);
if (err) {
ptlrpc_free_req(request);
out_dev:
- if (device)
- OBD_FREE(device, strlen(device) + 1);
- if (version)
- OBD_FREE(version, strlen(version) + 1);
+ if (mds)
+ OBD_FREE(mds, strlen(mds) + 1);
+ if (ost)
+ OBD_FREE(ost, strlen(ost) + 1);
RETURN(sb);
out_cdb:
ll_commitcbd_cleanup(sbi);
out_mdc:
- ptlrpc_cleanup_client(&sbi->ll_mds_client);
+ obd_disconnect(&sbi->ll_mdc_conn);
+ obd_disconnect(&sbi->ll_osc_conn);
out_disc:
ptlrpc_free_req(request);
-out_rpc:
- ptlrpc_put_connection(sbi->ll_mds_conn);
-out_ldlm:
- ldlm_namespace_free(sbi->ll_namespace);
-out_obd:
- obd_disconnect(&sbi->ll_conn);
+ obd_disconnect(&sbi->ll_osc_conn);
out_free:
OBD_FREE(sbi, sizeof(*sbi));
struct ll_sb_info *sbi = ll_s2sbi(sb);
ENTRY;
ll_commitcbd_cleanup(sbi);
- ptlrpc_cleanup_client(&sbi->ll_mds_client);
- ptlrpc_put_connection(sbi->ll_mds_conn);
- ldlm_namespace_free(sbi->ll_namespace);
- obd_disconnect(&sbi->ll_conn);
- OBD_FREE(sbi, sizeof(*sbi));
+ obd_disconnect(&sbi->ll_osc_conn);
+ obd_disconnect(&sbi->ll_mdc_conn);
+
MOD_DEC_USE_COUNT;
EXIT;
} /* ll_put_super */
/* change incore inode */
ll_attr2inode(inode, attr, do_trunc);
- err = mdc_setattr(&sbi->ll_mds_client, sbi->ll_mds_conn, inode, attr,
+ err = mdc_setattr(&sbi->ll_mdc_conn, inode, attr,
&request);
if (err)
CERROR("mdc_setattr fails (%d)\n", err);
int err;
ENTRY;
- err = obd_statfs(&ll_s2sbi(sb)->ll_conn, &tmp);
+ err = obd_statfs(&ll_s2sbi(sb)->ll_osc_conn, &tmp);
if (err) {
CERROR("obd_statfs fails (%d)\n", err);
RETURN(err);
int rc, size;
ENTRY;
- rc = mdc_getattr(&sbi->ll_mds_client, sbi->ll_mds_conn,
+ rc = mdc_getattr(&sbi->ll_mdc_conn,
dentry->d_inode->i_ino, S_IFLNK,
OBD_MD_LINKNAME, dentry->d_inode->i_size, &request);
if (rc) {
-/*
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
+ *
* Copyright (C) 2001 Cluster File Systems, Inc.
*
* This code is issued under the GNU General Public License.
#include <linux/obd_class.h>
#include <linux/lustre_mds.h>
-static int mdc_reint(struct ptlrpc_client *cl, struct ptlrpc_request *request, int level)
+static int mdc_reint(struct ptlrpc_request *request, int level)
{
int rc;
request->rq_level = level;
return rc;
}
-int mdc_setattr(struct ptlrpc_client *cl, struct ptlrpc_connection *conn,
+int mdc_setattr(struct obd_conn *conn,
struct inode *inode, struct iattr *iattr,
struct ptlrpc_request **request)
{
+ struct mdc_obd *mdc = mdc_conn2mdc(conn);
struct mds_rec_setattr *rec;
struct ptlrpc_request *req;
int rc, size = sizeof(*rec);
ENTRY;
- req = ptlrpc_prep_req(cl, conn, MDS_REINT, 1, &size, NULL);
+ req = ptlrpc_prep_req(mdc->mdc_client, mdc->mdc_conn,
+ MDS_REINT, 1, &size, NULL);
if (!req)
RETURN(-ENOMEM);
- rec = lustre_msg_buf(req->rq_reqmsg, 0);
- mds_setattr_pack(rec, inode, iattr);
+ mds_setattr_pack(req, 0, inode, iattr, NULL, 0);
size = sizeof(struct mds_body);
req->rq_replen = lustre_msg_size(1, &size);
- rc = mdc_reint(cl, req, LUSTRE_CONN_FULL);
+ rc = mdc_reint(req, LUSTRE_CONN_FULL);
*request = req;
if (rc == -ERESTARTSYS )
rc = 0;
RETURN(rc);
}
-int mdc_create(struct ptlrpc_client *cl, struct ptlrpc_connection *conn,
+int mdc_create(struct obd_conn *conn,
struct inode *dir, const char *name, int namelen,
const char *tgt, int tgtlen, int mode, __u32 uid,
__u32 gid, __u64 time, __u64 rdev, struct obdo *obdo,
struct ptlrpc_request **request)
{
struct mds_rec_create *rec;
+ struct mdc_obd *mdc = mdc_conn2mdc(conn);
struct ptlrpc_request *req;
- int rc, size[3] = {sizeof(*rec), namelen + 1, 0};
+ int rc, size[3] = {sizeof(struct mds_rec_create), namelen + 1, 0};
char *tmp, *bufs[3] = {NULL, NULL, NULL};
int level, bufcount = 2;
ENTRY;
bufcount = 3;
}
- req = ptlrpc_prep_req(cl, conn, MDS_REINT, bufcount, size, bufs);
+ req = ptlrpc_prep_req(mdc->mdc_client, mdc->mdc_conn, MDS_REINT,
+ bufcount, size, bufs);
if (!req)
RETURN(-ENOMEM);
rec = lustre_msg_buf(req->rq_reqmsg, 0);
- mds_create_pack(rec, dir, mode, rdev, uid, gid, time);
-
- tmp = lustre_msg_buf(req->rq_reqmsg, 1);
- LOGL0(name, namelen, tmp);
+ mds_create_pack(req, 0, dir, mode, rdev, uid, gid, time,
+ name, namelen, NULL, 0);
if (S_ISREG(mode)) {
tmp = lustre_msg_buf(req->rq_reqmsg, 2);
level = LUSTRE_CONN_FULL;
resend:
- rc = mdc_reint(cl, req, level);
+ rc = mdc_reint(req, level);
if (rc == -ERESTARTSYS) {
struct mds_update_record_hdr *hdr =
lustre_msg_buf(req->rq_reqmsg, 0);
RETURN(rc);
}
-int mdc_unlink(struct ptlrpc_client *cl, struct ptlrpc_connection *conn,
+int mdc_unlink(struct obd_conn *conn,
struct inode *dir, struct inode *child, const char *name,
int namelen, struct ptlrpc_request **request)
{
- struct mds_rec_unlink *rec;
+ struct mdc_obd *mdc = mdc_conn2mdc(conn);
struct ptlrpc_request *req;
- int rc, size[2] = {sizeof(*rec), namelen + 1};
- char *tmp;
+ int rc, size[2] = {sizeof(struct mds_rec_unlink), namelen + 1};
ENTRY;
- req = ptlrpc_prep_req(cl, conn, MDS_REINT, 2, size, NULL);
+ req = ptlrpc_prep_req(mdc->mdc_client, mdc->mdc_conn, MDS_REINT, 2,
+ size, NULL);
if (!req)
RETURN(-ENOMEM);
- rec = lustre_msg_buf(req->rq_reqmsg, 0);
- mds_unlink_pack(rec, dir, child);
-
- tmp = lustre_msg_buf(req->rq_reqmsg, 1);
- LOGL0(name, namelen, tmp);
+ mds_unlink_pack(req, 0, dir, child, name, namelen);
size[0] = sizeof(struct mds_body);
req->rq_replen = lustre_msg_size(1, size);
- rc = mdc_reint(cl, req, LUSTRE_CONN_FULL);
+ rc = mdc_reint(req, LUSTRE_CONN_FULL);
*request = req;
if (rc == -ERESTARTSYS )
rc = 0;
RETURN(rc);
}
-int mdc_link(struct ptlrpc_client *cl, struct ptlrpc_connection *conn,
+int mdc_link(struct obd_conn *conn,
struct dentry *src, struct inode *dir, const char *name,
int namelen, struct ptlrpc_request **request)
{
- struct mds_rec_link *rec;
+ struct mdc_obd *mdc = mdc_conn2mdc(conn);
struct ptlrpc_request *req;
- int rc, size[2] = {sizeof(*rec), namelen + 1};
- char *tmp;
+ int rc, size[2] = {sizeof(struct mds_rec_link), namelen + 1};
ENTRY;
- req = ptlrpc_prep_req(cl, conn, MDS_REINT, 2, size, NULL);
+ req = ptlrpc_prep_req(mdc->mdc_client, mdc->mdc_conn, MDS_REINT, 2,
+ size, NULL);
if (!req)
RETURN(-ENOMEM);
- rec = lustre_msg_buf(req->rq_reqmsg, 0);
- mds_link_pack(rec, src->d_inode, dir);
-
- tmp = lustre_msg_buf(req->rq_reqmsg, 1);
- LOGL0(name, namelen, tmp);
+ mds_link_pack(req, 0, src->d_inode, dir, name, namelen);
size[0] = sizeof(struct mds_body);
req->rq_replen = lustre_msg_size(1, size);
- rc = mdc_reint(cl, req, LUSTRE_CONN_FULL);
+ rc = mdc_reint(req, LUSTRE_CONN_FULL);
*request = req;
if (rc == -ERESTARTSYS )
rc = 0;
RETURN(rc);
}
-int mdc_rename(struct ptlrpc_client *cl, struct ptlrpc_connection *conn,
+int mdc_rename(struct obd_conn *conn,
struct inode *src, struct inode *tgt, const char *old,
int oldlen, const char *new, int newlen,
struct ptlrpc_request **request)
{
- struct mds_rec_rename *rec;
+ struct mdc_obd *mdc = mdc_conn2mdc(conn);
struct ptlrpc_request *req;
- int rc, size[3] = {sizeof(*rec), oldlen + 1, newlen + 1};
- char *tmp;
+ int rc, size[3] = {sizeof(struct mds_rec_rename), oldlen + 1,
+ newlen + 1};
ENTRY;
- req = ptlrpc_prep_req(cl, conn, MDS_REINT, 3, size, NULL);
+ req = ptlrpc_prep_req(mdc->mdc_client, mdc->mdc_conn,
+ MDS_REINT, 3, size, NULL);
if (!req)
RETURN(-ENOMEM);
- rec = lustre_msg_buf(req->rq_reqmsg, 0);
- mds_rename_pack(rec, src, tgt);
-
- tmp = lustre_msg_buf(req->rq_reqmsg, 1);
- LOGL0(old, oldlen, tmp);
-
- if (tgt) {
- tmp = lustre_msg_buf(req->rq_reqmsg, 2);
- LOGL0(new, newlen, tmp);
- }
+ mds_rename_pack(req, 0, src, tgt, old, oldlen, new, newlen);
size[0] = sizeof(struct mds_body);
req->rq_replen = lustre_msg_size(1, size);
- rc = mdc_reint(cl, req, LUSTRE_CONN_FULL);
+ rc = mdc_reint(req, LUSTRE_CONN_FULL);
*request = req;
if (rc == -ERESTARTSYS )
rc = 0;
*/
#define EXPORT_SYMTAB
+#define DEBUG_SUBSYSTEM S_MDC
#include <linux/module.h>
#include <linux/miscdevice.h>
-
-#define DEBUG_SUBSYSTEM S_MDC
-
#include <linux/lustre_mds.h>
#include <linux/lustre_lite.h>
+#include <linux/lustre_dlm.h>
#define REQUEST_MINOR 244
extern int mds_queue_req(struct ptlrpc_request *);
-int mdc_connect(struct ptlrpc_client *cl, struct ptlrpc_connection *conn,
- struct ll_fid *rootfid, __u64 *last_committed, __u64 *last_rcvd,
- __u32 *last_xid, struct ptlrpc_request **request)
+
+int mdc_getstatus(struct obd_conn *conn, struct ll_fid *rootfid,
+ __u64 *last_committed, __u64 *last_rcvd,
+ __u32 *last_xid, struct ptlrpc_request **request)
{
struct ptlrpc_request *req;
struct mds_body *body;
+ struct mdc_obd *mdc = mdc_conn2mdc(conn);
int rc, size = sizeof(*body);
ENTRY;
- req = ptlrpc_prep_req(cl, conn, MDS_CONNECT, 1, &size, NULL);
+ req = ptlrpc_prep_req(mdc->mdc_client, mdc->mdc_conn,
+ MDS_GETSTATUS, 1, &size, NULL);
if (!req)
GOTO(out, rc = -ENOMEM);
rc = ptlrpc_check_status(req, rc);
if (!rc) {
- mds_unpack_rep_body(req);
body = lustre_msg_buf(req->rq_repmsg, 0);
+ mds_unpack_body(body);
memcpy(rootfid, &body->fid1, sizeof(*rootfid));
*last_committed = req->rq_repmsg->last_committed;
*last_rcvd = req->rq_repmsg->last_rcvd;
}
-int mdc_getattr(struct ptlrpc_client *cl, struct ptlrpc_connection *conn,
+int mdc_getattr(struct obd_conn *conn,
ino_t ino, int type, unsigned long valid, size_t ea_size,
struct ptlrpc_request **request)
{
+ struct mdc_obd *mdc = mdc_conn2mdc(conn);
struct ptlrpc_request *req;
struct mds_body *body;
int rc, size[2] = {sizeof(*body), 0}, bufcount = 1;
ENTRY;
- req = ptlrpc_prep_req(cl, conn, MDS_GETATTR, 1, size, NULL);
+ req = ptlrpc_prep_req(mdc->mdc_client, mdc->mdc_conn,
+ MDS_GETATTR, 1, size, NULL);
if (!req)
GOTO(out, rc = -ENOMEM);
rc = ptlrpc_check_status(req, rc);
if (!rc) {
- mds_unpack_rep_body(req);
body = lustre_msg_buf(req->rq_repmsg, 0);
+ mds_unpack_body(body);
CDEBUG(D_NET, "mode: %o\n", body->mode);
}
return rc;
}
-int mdc_open(struct ptlrpc_client *cl, struct ptlrpc_connection *conn,
- ino_t ino, int type, int flags, __u64 cookie, __u64 *fh,
- struct ptlrpc_request **request)
+static int mdc_lock_callback(struct ldlm_lock *lock, struct ldlm_lock *new,
+ void *data, int data_len)
+{
+ int rc;
+ struct inode *inode = data;
+ ENTRY;
+
+ if (new == NULL) {
+ /* Completion AST. Do nothing. */
+ RETURN(0);
+ }
+
+ if (data_len != sizeof(*inode)) {
+ CERROR("data_len should be %d, but is %d\n", sizeof(*inode),
+ data_len);
+ LBUG();
+ }
+
+ /* FIXME: do something better than throwing away everything */
+ if (inode == NULL)
+ LBUG();
+ invalidate_inode_pages(inode);
+
+ rc = ldlm_cli_cancel(lock->l_client, lock);
+ if (rc < 0) {
+ CERROR("ldlm_cli_cancel: %d\n", rc);
+ LBUG();
+ }
+ RETURN(0);
+}
+
+int mdc_enqueue(struct obd_conn *conn, int lock_type, struct lookup_intent *it,
+ int lock_mode, struct inode *dir, struct dentry *de,
+ struct lustre_handle *lockh, __u64 id, char *tgt, int tgtlen,
+ void *data, int datalen)
{
+ struct ptlrpc_request *req;
+ struct obd_device *obddev = conn->oc_dev;
+ 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)};
+ int rc, flags;
+ struct ldlm_reply *dlm_rep;
+ struct ldlm_intent *lit;
+ ENTRY;
+
+ switch (it->it_op) {
+ case IT_MKDIR:
+ it->it_mode = (it->it_mode | S_IFDIR) & ~current->fs->umask;
+ break;
+ case IT_SETATTR:
+ it->it_op = IT_GETATTR;
+ break;
+ case (IT_CREAT|IT_OPEN):
+ case IT_CREAT:
+ it->it_mode = (it->it_mode | S_IFREG) & ~current->fs->umask;
+ break;
+ case IT_SYMLINK:
+ it->it_mode = (it->it_mode | S_IFLNK) & ~current->fs->umask;
+ break;
+ }
+
+ if (it->it_op & (IT_MKDIR | IT_CREAT | IT_SYMLINK | IT_MKNOD)) {
+ size[2] = sizeof(struct mds_rec_create);
+ size[3] = de->d_name.len + 1;
+ size[4] = tgtlen + 1;
+ req = ptlrpc_prep_req(mdc->mdc_ldlm_client, mdc->mdc_conn,
+ LDLM_ENQUEUE, 5, size, NULL);
+ if (!req)
+ RETURN(-ENOMEM);
+
+ /* pack the intent */
+ lit = lustre_msg_buf(req->rq_reqmsg, 1);
+ lit->opc = NTOH__u64((__u64)it->it_op);
+
+ /* pack the intended request */
+ mds_create_pack(req, 2, dir, it->it_mode, id, current->fsuid,
+ current->fsgid, CURRENT_TIME, de->d_name.name,
+ de->d_name.len, tgt, tgtlen);
+
+ size[0] = sizeof(struct ldlm_reply);
+ size[1] = sizeof(struct mds_body);
+ size[2] = sizeof(struct obdo);
+ req->rq_replen = lustre_msg_size(3, size);
+ } else if ( it->it_op == IT_RENAME2 ) {
+ struct dentry *old_de = it->it_data;
+
+ size[2] = sizeof(struct mds_rec_rename);
+ size[3] = old_de->d_name.len + 1;
+ size[4] = de->d_name.len + 1;
+ req = ptlrpc_prep_req(mdc->mdc_ldlm_client, mdc->mdc_conn,
+ LDLM_ENQUEUE, 5, size, NULL);
+ if (!req)
+ RETURN(-ENOMEM);
+
+ /* pack the intent */
+ lit = lustre_msg_buf(req->rq_reqmsg, 1);
+ lit->opc = NTOH__u64((__u64)it->it_op);
+
+ /* pack the intended request */
+ mds_rename_pack(req, 2, old_de->d_inode, dir,
+ old_de->d_parent->d_name.name,
+ old_de->d_parent->d_name.len,
+ de->d_name.name, de->d_name.len);
+
+ size[0] = sizeof(struct ldlm_reply);
+ size[1] = sizeof(struct mds_body);
+ req->rq_replen = lustre_msg_size(2, size);
+ } else if ( it->it_op == IT_GETATTR || it->it_op == IT_RENAME ||
+ it->it_op == IT_OPEN ) {
+ size[2] = sizeof(struct mds_body);
+ size[3] = de->d_name.len + 1;
+
+ req = ptlrpc_prep_req(mdc->mdc_ldlm_client, mdc->mdc_conn,
+ LDLM_ENQUEUE, 4, size, NULL);
+ if (!req)
+ RETURN(-ENOMEM);
+
+ /* pack the intent */
+ lit = lustre_msg_buf(req->rq_reqmsg, 1);
+ lit->opc = NTOH__u64((__u64)it->it_op);
+
+ /* pack the intended request */
+ mds_getattr_pack(req, 2, dir, de->d_name.name, de->d_name.len);
+
+ /* get ready for the reply */
+ size[0] = sizeof(struct ldlm_reply);
+ size[1] = sizeof(struct mds_body);
+ size[2] = sizeof(struct obdo);
+ req->rq_replen = lustre_msg_size(3, size);
+ } else if ( it->it_op == IT_SETATTR) {
+ size[2] = sizeof(struct mds_rec_setattr);
+ size[3] = de->d_name.len + 1;
+ req = ptlrpc_prep_req(mdc->mdc_ldlm_client, mdc->mdc_conn,
+ LDLM_ENQUEUE, 5, size, NULL);
+ if (!req)
+ RETURN(-ENOMEM);
+
+ lit = lustre_msg_buf(req->rq_reqmsg, 1);
+ lit->opc = NTOH__u64((__u64)it->it_op);
+
+ if (!it->it_iattr)
+ LBUG();
+
+ mds_setattr_pack(req, 2, dir, it->it_iattr,
+ de->d_name.name, de->d_name.len);
+ size[0] = sizeof(struct ldlm_reply);
+ size[1] = sizeof(struct mds_body);
+ req->rq_replen = lustre_msg_size(2, size);
+ } else if ( it->it_op == IT_READDIR ) {
+ req = ptlrpc_prep_req(mdc->mdc_ldlm_client, mdc->mdc_conn,
+ LDLM_ENQUEUE, 1, size, NULL);
+ if (!req)
+ RETURN(-ENOMEM);
+
+ /* get ready for the reply */
+ size[0] = sizeof(struct ldlm_reply);
+ req->rq_replen = lustre_msg_size(1, size);
+ } else {
+ LBUG();
+ }
+
+ rc = ldlm_cli_enqueue(mdc->mdc_ldlm_client, mdc->mdc_conn, req,
+ obddev->obd_namespace, NULL, res_id, lock_type,
+ NULL, 0, lock_mode, &flags,
+ (void *)mdc_lock_callback, data, datalen, lockh);
+
+ if (rc != 0) {
+ CERROR("ldlm_cli_enqueue: %d\n", rc);
+ RETURN(rc);
+ }
+
+ dlm_rep = lustre_msg_buf(req->rq_repmsg, 0);
+ it->it_disposition = (int) dlm_rep->lock_policy_res1;
+ it->it_status = (int) dlm_rep->lock_policy_res2;
+ it->it_lock_mode = lock_mode;
+ it->it_data = req;
+
+ RETURN(0);
+}
+
+int mdc_open(struct obd_conn *conn, ino_t ino, int type, int flags, __u64 objid,
+ __u64 cookie, __u64 *fh, struct ptlrpc_request **request)
+{
+ struct mdc_obd *mdc = mdc_conn2mdc(conn);
struct mds_body *body;
int rc, size = sizeof(*body);
struct ptlrpc_request *req;
- req = ptlrpc_prep_req(cl, conn, MDS_OPEN, 1, &size, NULL);
+ req = ptlrpc_prep_req(mdc->mdc_client, mdc->mdc_conn,
+ MDS_OPEN, 1, &size, NULL);
if (!req)
GOTO(out, rc = -ENOMEM);
req->rq_flags |= PTL_RPC_FL_REPLAY;
req->rq_level = LUSTRE_CONN_FULL;
body = lustre_msg_buf(req->rq_reqmsg, 0);
+
ll_ino2fid(&body->fid1, ino, 0, type);
body->flags = HTON__u32(flags);
body->extra = cookie;
rc = ptlrpc_check_status(req, rc);
if (!rc) {
- mds_unpack_rep_body(req);
body = lustre_msg_buf(req->rq_repmsg, 0);
+ mds_unpack_body(body);
*fh = body->extra;
}
return rc;
}
-int mdc_close(struct ptlrpc_client *cl, struct ptlrpc_connection *conn,
+int mdc_close(struct obd_conn *conn,
ino_t ino, int type, __u64 fh, struct ptlrpc_request **request)
{
+ struct mdc_obd *mdc = mdc_conn2mdc(conn);
struct mds_body *body;
int rc, size = sizeof(*body);
struct ptlrpc_request *req;
- req = ptlrpc_prep_req(cl, conn, MDS_CLOSE, 1, &size, NULL);
+ req = ptlrpc_prep_req(mdc->mdc_client, mdc->mdc_conn,
+ MDS_CLOSE, 1, &size, NULL);
if (!req)
GOTO(out, rc = -ENOMEM);
return rc;
}
-int mdc_readpage(struct ptlrpc_client *cl, struct ptlrpc_connection *conn,
- ino_t ino, int type, __u64 offset, char *addr,
- struct ptlrpc_request **request)
+int mdc_readpage(struct obd_conn *conn, ino_t ino, int type, __u64 offset,
+ char *addr, struct ptlrpc_request **request)
{
+ struct mdc_obd *mdc = mdc_conn2mdc(conn);
struct ptlrpc_request *req = NULL;
struct ptlrpc_bulk_desc *desc = NULL;
struct ptlrpc_bulk_page *bulk = NULL;
CDEBUG(D_INODE, "inode: %ld\n", (long)ino);
- desc = ptlrpc_prep_bulk(conn);
+ desc = ptlrpc_prep_bulk(mdc->mdc_conn);
if (desc == NULL)
GOTO(out, rc = -ENOMEM);
- req = ptlrpc_prep_req(cl, conn, MDS_READPAGE, 1, &size, NULL);
+ req = ptlrpc_prep_req(mdc->mdc_client, mdc->mdc_conn,
+ MDS_READPAGE, 1, &size, NULL);
if (!req)
GOTO(out2, rc = -ENOMEM);
bulk = ptlrpc_prep_bulk_page(desc);
bulk->b_buflen = PAGE_SIZE;
bulk->b_buf = addr;
- bulk->b_xid = req->rq_reqmsg->xid;
+ bulk->b_xid = req->rq_xid;
desc->b_portal = MDS_BULK_PORTAL;
rc = ptlrpc_register_bulk(desc);
if (rc) {
ptlrpc_abort_bulk(desc);
GOTO(out2, rc);
- } else
- mds_unpack_rep_body(req);
+ } else {
+ body = lustre_msg_buf(req->rq_repmsg, 0);
+ mds_unpack_body(body);
+ }
EXIT;
out2:
}
#endif
-static int request_ioctl(struct inode *inode, struct file *file,
- unsigned int cmd, unsigned long arg)
+static int mdc_ioctl(long cmd, struct obd_conn *conn, int len, void *karg,
+ void *uarg)
{
+#if 0
+ /* FIXME XXX : This should use the new ioc_data to pass args in */
int err = 0;
struct ptlrpc_client cl;
struct ptlrpc_connection *conn;
ENTRY;
- if (MINOR(inode->i_rdev) != REQUEST_MINOR)
- RETURN(-EINVAL);
-
if (_IOC_TYPE(cmd) != IOC_REQUEST_TYPE ||
_IOC_NR(cmd) < IOC_REQUEST_MIN_NR ||
_IOC_NR(cmd) > IOC_REQUEST_MAX_NR ) {
ptlrpc_init_client(NULL, NULL,
MDS_REQUEST_PORTAL, MDC_REPLY_PORTAL, &cl);
- conn = ptlrpc_uuid_to_connection("mds");
- if (!conn) {
+ connection = ptlrpc_uuid_to_connection("mds");
+ if (!connection) {
CERROR("cannot create client\n");
RETURN(-EINVAL);
}
switch (cmd) {
case IOC_REQUEST_GETATTR: {
CERROR("-- getting attr for ino %lu\n", arg);
- err = mdc_getattr(&cl, conn, arg, S_IFDIR, ~0, 0, &request);
+ err = mdc_getattr(&cl, connection, arg, S_IFDIR, ~0, 0,
+ &request);
CERROR("-- done err %d\n", err);
GOTO(out, err);
GOTO(out, err);
}
CERROR("-- readpage 0 for ino %lu\n", arg);
- err = mdc_readpage(&cl, conn, arg, S_IFDIR, 0, buf, &request);
+ err = mdc_readpage(&cl, connection, arg, S_IFDIR, 0, buf,
+ &request);
CERROR("-- done err %d\n", err);
OBD_FREE(buf, PAGE_SIZE);
iattr.ia_atime = 0;
iattr.ia_valid = ATTR_MODE | ATTR_ATIME;
- err = mdc_setattr(&cl, conn, &inode, &iattr, &request);
+ err = mdc_setattr(&cl, connection, &inode, &iattr, &request);
CERROR("-- done err %d\n", err);
GOTO(out, err);
iattr.ia_atime = 0;
iattr.ia_valid = ATTR_MODE | ATTR_ATIME;
- err = mdc_create(&cl, conn, &inode,
+ err = mdc_create(&cl, connection, &inode,
"foofile", strlen("foofile"),
NULL, 0, 0100707, 47114711,
11, 47, 0, NULL, &request);
__u64 fh, ino;
copy_from_user(&ino, (__u64 *)arg, sizeof(ino));
CERROR("-- opening ino %llu\n", (unsigned long long)ino);
- err = mdc_open(&cl, conn, ino, S_IFDIR, O_RDONLY, 4711, &fh,
- &request);
+ err = mdc_open(&cl, connection, ino, S_IFDIR, O_RDONLY, 4711,
+ &fh, &request);
copy_to_user((__u64 *)arg, &fh, sizeof(fh));
CERROR("-- done err %d (fh=%Lu)\n", err,
(unsigned long long)fh);
case IOC_REQUEST_CLOSE: {
CERROR("-- closing ino 2, filehandle %lu\n", arg);
- err = mdc_close(&cl, conn, 2, S_IFDIR, arg, &request);
+ err = mdc_close(&cl, connection, 2, S_IFDIR, arg, &request);
CERROR("-- done err %d\n", err);
GOTO(out, err);
out:
ptlrpc_free_req(request);
- ptlrpc_put_connection(conn);
+ ptlrpc_put_connection(connection);
ptlrpc_cleanup_client(&cl);
RETURN(err);
+#endif
+ return 0;
}
+static int mdc_setup(struct obd_device *obddev, obd_count len, void *buf)
+{
+ struct obd_ioctl_data* data = buf;
+ struct mdc_obd *mdc = &obddev->u.mdc;
+ char server_uuid[37];
+ int rc;
+ ENTRY;
-static struct file_operations requestdev_fops = {
- ioctl: request_ioctl,
-};
+ if (data->ioc_inllen1 < 1) {
+ CERROR("osc setup requires a TARGET UUID\n");
+ RETURN(-EINVAL);
+ }
-static struct miscdevice request_dev = {
- REQUEST_MINOR,
- "request",
- &requestdev_fops
+ if (data->ioc_inllen1 > 37) {
+ CERROR("mdc UUID must be less than 38 characters\n");
+ RETURN(-EINVAL);
+ }
+
+ if (data->ioc_inllen2 < 1) {
+ CERROR("mdc setup requires a SERVER UUID\n");
+ RETURN(-EINVAL);
+ }
+
+ if (data->ioc_inllen2 > 37) {
+ CERROR("mdc UUID must be less than 38 characters\n");
+ RETURN(-EINVAL);
+ }
+
+ memcpy(mdc->mdc_target_uuid, data->ioc_inlbuf1, data->ioc_inllen1);
+ memcpy(server_uuid, data->ioc_inlbuf2, MIN(data->ioc_inllen2,
+ sizeof(server_uuid)));
+
+ mdc->mdc_conn = ptlrpc_uuid_to_connection(server_uuid);
+ if (!mdc->mdc_conn)
+ RETURN(-ENOENT);
+
+ OBD_ALLOC(mdc->mdc_client, sizeof(*mdc->mdc_client));
+ if (mdc->mdc_client == NULL)
+ GOTO(out_conn, rc = -ENOMEM);
+
+ OBD_ALLOC(mdc->mdc_ldlm_client, sizeof(*mdc->mdc_ldlm_client));
+ if (mdc->mdc_ldlm_client == NULL)
+ GOTO(out_client, rc = -ENOMEM);
+
+ ptlrpc_init_client(NULL, NULL, MDS_REQUEST_PORTAL, MDC_REPLY_PORTAL,
+ mdc->mdc_client);
+ ptlrpc_init_client(NULL, NULL, LDLM_REQUEST_PORTAL, LDLM_REPLY_PORTAL,
+ mdc->mdc_ldlm_client);
+ mdc->mdc_client->cli_name = "mdc";
+ mdc->mdc_ldlm_client->cli_name = "ldlm";
+ /* XXX get recovery hooked in here again */
+ //ptlrpc_init_client(ptlrpc_connmgr, ll_recover,...
+
+ ptlrpc_init_client(ptlrpc_connmgr, NULL,
+ MDS_REQUEST_PORTAL, MDC_REPLY_PORTAL,
+ mdc->mdc_client);
+
+ MOD_INC_USE_COUNT;
+ RETURN(0);
+
+ out_client:
+ OBD_FREE(mdc->mdc_client, sizeof(*mdc->mdc_client));
+ out_conn:
+ ptlrpc_put_connection(mdc->mdc_conn);
+ return rc;
+}
+
+static int mdc_cleanup(struct obd_device * obddev)
+{
+ struct mdc_obd *mdc = &obddev->u.mdc;
+
+ ptlrpc_cleanup_client(mdc->mdc_client);
+ OBD_FREE(mdc->mdc_client, sizeof(*mdc->mdc_client));
+ ptlrpc_cleanup_client(mdc->mdc_ldlm_client);
+ OBD_FREE(mdc->mdc_ldlm_client, sizeof(*mdc->mdc_ldlm_client));
+ ptlrpc_put_connection(mdc->mdc_conn);
+
+ MOD_DEC_USE_COUNT;
+ return 0;
+}
+
+static int mdc_connect(struct obd_conn *conn)
+{
+ struct mdc_obd *mdc = mdc_conn2mdc(conn);
+ struct ptlrpc_request *request;
+ int rc, size = sizeof(mdc->mdc_target_uuid);
+ char *tmp = mdc->mdc_target_uuid;
+
+ ENTRY;
+
+ conn->oc_dev->obd_namespace = ldlm_namespace_new(LDLM_NAMESPACE_CLIENT);
+ if (conn->oc_dev->obd_namespace == NULL)
+ RETURN(-ENOMEM);
+
+ request = ptlrpc_prep_req(mdc->mdc_client, mdc->mdc_conn,
+ MDS_CONNECT, 1, &size, &tmp);
+ if (!request)
+ RETURN(-ENOMEM);
+
+ request->rq_replen = lustre_msg_size(0, NULL);
+
+ rc = ptlrpc_queue_wait(request);
+ if (rc)
+ GOTO(out, rc);
+
+ mdc->mdc_client->cli_target_devno = request->rq_repmsg->target_id;
+ mdc->mdc_ldlm_client->cli_target_devno =
+ mdc->mdc_client->cli_target_devno;
+ EXIT;
+ out:
+ ptlrpc_free_req(request);
+ return rc;
+}
+
+static int mdc_disconnect(struct obd_conn *conn)
+{
+ struct mdc_obd *mdc = mdc_conn2mdc(conn);
+ struct ptlrpc_request *request;
+ struct mds_body *body;
+ int rc, size = sizeof(*body);
+ ENTRY;
+
+ ldlm_namespace_free(conn->oc_dev->obd_namespace);
+ request = ptlrpc_prep_req(mdc->mdc_client, mdc->mdc_conn,
+ MDS_DISCONNECT, 1, &size,
+ NULL);
+ if (!request)
+ RETURN(-ENOMEM);
+
+ body = lustre_msg_buf(request->rq_reqmsg, 0);
+ body->valid = conn->oc_id;
+
+ request->rq_replen = lustre_msg_size(0, NULL);
+
+ rc = ptlrpc_queue_wait(request);
+ GOTO(out, rc);
+ out:
+ ptlrpc_free_req(request);
+ return rc;
+}
+
+struct obd_ops mdc_obd_ops = {
+ o_setup: mdc_setup,
+ o_cleanup: mdc_cleanup,
+ o_connect: mdc_connect,
+ o_disconnect: mdc_disconnect,
+ o_iocontrol: mdc_ioctl
};
static int __init ptlrpc_request_init(void)
{
- misc_register(&request_dev);
- return 0;
+ return obd_register_type(&mdc_obd_ops, LUSTRE_MDC_NAME);
}
static void __exit ptlrpc_request_exit(void)
{
- misc_deregister(&request_dev);
+ obd_unregister_type(LUSTRE_MDC_NAME);
}
-MODULE_AUTHOR("Peter J. Braam <braam@clusterfs.com>");
-MODULE_DESCRIPTION("Lustre MDS Request Tester v1.0");
+MODULE_AUTHOR("Cluster File Systems <info@clusterfs.com>");
+MODULE_DESCRIPTION("Lustre Metadata Client v1.0");
MODULE_LICENSE("GPL");
-EXPORT_SYMBOL(mdc_connect);
+EXPORT_SYMBOL(mdc_getstatus);
+EXPORT_SYMBOL(mdc_enqueue);
EXPORT_SYMBOL(mdc_getattr);
EXPORT_SYMBOL(mdc_create);
EXPORT_SYMBOL(mdc_unlink);
* This code is issued under the GNU General Public License.
* See the file COPYING in this distribution
*
- * by Peter Braam <braam@clusterfs.com>
+ * by Peter Braam <braam@clusterfs.com> &
+ * Andreas Dilger <braam@clusterfs.com>
*
* This server is single threaded at present (but can easily be multi threaded)
*
#include <linux/module.h>
#include <linux/lustre_mds.h>
+#include <linux/lustre_dlm.h>
+extern int mds_update_last_rcvd(struct mds_obd *mds, void *handle,
+ struct ptlrpc_request *req);
+static int mds_cleanup(struct obd_device * obddev);
static int mds_sendpage(struct ptlrpc_request *req, struct file *file,
__u64 offset)
if (rc != PAGE_SIZE)
GOTO(cleanup_buf, rc = -EIO);
- bulk->b_xid = req->rq_reqmsg->xid;
+ bulk->b_xid = req->rq_xid;
bulk->b_buf = buf;
bulk->b_buflen = PAGE_SIZE;
desc->b_portal = MDS_BULK_PORTAL;
return result;
}
-static
-int mds_connect(struct ptlrpc_request *req)
+static int mds_connect(struct ptlrpc_request *req)
+{
+ struct mds_obd *mds;
+ char *uuid;
+ int rc, i;
+ ENTRY;
+
+ uuid = lustre_msg_buf(req->rq_reqmsg, 0);
+ if (req->rq_reqmsg->buflens[0] > 37) {
+ /* Invalid UUID */
+ req->rq_status = -EINVAL;
+ RETURN(-EINVAL);
+ }
+
+ i = obd_class_name2dev(uuid);
+ if (i == -1) {
+ req->rq_status = -ENODEV;
+ RETURN(-ENODEV);
+ }
+
+ mds = &(obd_dev[i].u.mds);
+ if (mds != &(req->rq_obd->u.mds)) {
+ CERROR("device %d (%s) is not an mds\n", i, uuid);
+ req->rq_status = -ENODEV;
+ RETURN(-ENODEV);
+ }
+
+ CDEBUG(D_INFO, "MDS connect from UUID '%s'\n",
+ ptlrpc_req_to_uuid(req));
+ rc = lustre_pack_msg(0, NULL, NULL, &req->rq_replen, &req->rq_repmsg);
+ if (rc || OBD_FAIL_CHECK(OBD_FAIL_MDS_CONNECT_PACK)) {
+ req->rq_status = -ENOMEM;
+ RETURN(-ENOMEM);
+ }
+ req->rq_repmsg->target_id = i;
+
+ RETURN(0);
+}
+
+/* FIXME: the error cases need fixing to avoid leaks */
+static int mds_getstatus(struct mds_obd *mds, struct ptlrpc_request *req)
{
struct mds_body *body;
- struct mds_obd *mds = &req->rq_obd->u.mds;
struct mds_client_info *mci;
struct mds_client_data *mcd;
int rc, size = sizeof(*body);
ENTRY;
- CDEBUG(D_INFO, "MDS connect from UUID '%s'\n", ptlrpc_req_to_uuid(req));
rc = lustre_pack_msg(1, &size, NULL, &req->rq_replen, &req->rq_repmsg);
- if (rc || OBD_FAIL_CHECK(OBD_FAIL_MDS_CONNECT_PACK)) {
+ if (rc || OBD_FAIL_CHECK(OBD_FAIL_MDS_GETSTATUS_PACK)) {
CERROR("mds: out of memory for message: size=%d\n", size);
req->rq_status = -ENOMEM;
RETURN(0);
}
body = lustre_msg_buf(req->rq_reqmsg, 0);
- mds_unpack_req_body(req);
+ mds_unpack_body(body);
/* Anything we need to do here with the client's trans no or so? */
body = lustre_msg_buf(req->rq_repmsg, 0);
req->rq_status = -ENOMEM;
RETURN(0);
}
+ memcpy(mcd->mcd_uuid, ptlrpc_req_to_uuid(req),
+ sizeof(mcd->mcd_uuid));
rc = mds_client_add(mds, mcd, -1);
if (rc) {
req->rq_status = rc;
CDEBUG(D_INFO, "found existing data for UUID '%s' at #%d\n",
mcd->mcd_uuid, mci->mci_off);
}
- /* mcd_last_xid is is stored in little endian on the disk and
+ /* mcd_last_xid is is stored in little endian on the disk and
mds_pack_rep_body converts it to network order */
body->last_xid = le32_to_cpu(mcd->mcd_last_xid);
mds_pack_rep_body(req);
RETURN(0);
}
-static int mds_getattr(struct ptlrpc_request *req)
+static int mds_disconnect(struct mds_obd *mds, struct ptlrpc_request *req)
+{
+ struct mds_body *body;
+ int rc;
+ ENTRY;
+
+ body = lustre_msg_buf(req->rq_reqmsg, 0);
+
+ rc = lustre_pack_msg(0, NULL, NULL, &req->rq_replen, &req->rq_repmsg);
+ if (rc)
+ RETURN(rc);
+
+ RETURN(0);
+}
+
+int mds_lock_callback(struct ldlm_lock *lock, struct ldlm_lock *new,
+ void *data, int data_len)
{
+ ENTRY;
+
+ if (new == NULL) {
+ /* Completion AST. Do nothing */
+ RETURN(0);
+ }
+
+ if (ldlm_cli_cancel(lock->l_client, lock) < 0)
+ LBUG();
+ RETURN(0);
+}
+
+static int mds_getattr_name(int offset, struct ptlrpc_request *req)
+{
+ struct mds_obd *mds = &req->rq_obd->u.mds;
+ struct mds_body *body;
+ struct dentry *de = NULL, *dchild = NULL;
+ struct inode *dir;
+ struct ldlm_lock *lock;
+ struct lustre_handle lockh;
+ char *name;
+ int namelen, flags, lock_mode, rc = 0;
+ __u64 res_id[3] = {0, 0, 0};
+ ENTRY;
+
+ if (strcmp(req->rq_obd->obd_type->typ_name, "mds") != 0)
+ LBUG();
+
+ if (req->rq_reqmsg->bufcount <= offset + 1) {
+ LBUG();
+ GOTO(out_pre_de, rc = -EINVAL);
+ }
+
+ body = lustre_msg_buf(req->rq_reqmsg, offset);
+ name = lustre_msg_buf(req->rq_reqmsg, offset + 1);
+ namelen = req->rq_reqmsg->buflens[offset + 1];
+ /* requests were at offset 2, replies go back at 1 */
+ if (offset)
+ offset = 1;
+
+ de = mds_fid2dentry(mds, &body->fid1, NULL);
+ if (IS_ERR(de)) {
+ LBUG();
+ GOTO(out_pre_de, rc = -ESTALE);
+ }
+
+ dir = de->d_inode;
+ CDEBUG(D_INODE, "parent ino %ld\n", dir->i_ino);
+
+ lock_mode = (req->rq_reqmsg->opc == MDS_REINT) ? LCK_CW : LCK_PW;
+ res_id[0] = dir->i_ino;
+
+ rc = ldlm_local_lock_match(mds->mds_local_namespace, res_id, LDLM_PLAIN,
+ NULL, 0, lock_mode, &lockh);
+ if (rc == 0) {
+ rc = ldlm_cli_enqueue(mds->mds_ldlm_client, mds->mds_ldlm_conn,
+ NULL, mds->mds_local_namespace, NULL,
+ res_id, LDLM_PLAIN, NULL, 0, lock_mode,
+ &flags, (void *)mds_lock_callback,
+ NULL, 0, &lockh);
+ if (rc != ELDLM_OK) {
+ CERROR("lock enqueue: err: %d\n", rc);
+ GOTO(out_create_de, rc = -EIO);
+ }
+ }
+ ldlm_lock_dump((void *)(unsigned long)lockh.addr);
+
+ down(&dir->i_sem);
+ dchild = lookup_one_len(name, de, namelen - 1);
+ if (IS_ERR(dchild)) {
+ CERROR("child lookup error %ld\n", PTR_ERR(dchild));
+ up(&dir->i_sem);
+ LBUG();
+ GOTO(out_create_dchild, rc = -ESTALE);
+ }
+
+ if (dchild->d_inode) {
+ struct mds_body *body;
+ struct obdo *obdo;
+ struct inode *inode = dchild->d_inode;
+ CERROR("child exists (dir %ld, name %s, ino %ld)\n",
+ dir->i_ino, name, dchild->d_inode->i_ino);
+
+ body = lustre_msg_buf(req->rq_repmsg, offset);
+ mds_pack_inode2fid(&body->fid1, inode);
+ mds_pack_inode2body(body, inode);
+ if (S_ISREG(inode->i_mode)) {
+ obdo = lustre_msg_buf(req->rq_repmsg, offset + 1);
+ mds_fs_get_obdo(mds, inode, obdo);
+ }
+ /* now a normal case for intent locking */
+ rc = 0;
+ } else {
+ rc = -EEXIST;
+ }
+
+ EXIT;
+out_create_dchild:
+ l_dput(dchild);
+ up(&dir->i_sem);
+ lock = lustre_handle2object(&lockh);
+ ldlm_lock_decref(lock, lock_mode);
+out_create_de:
+ l_dput(de);
+ out_pre_de:
+ req->rq_status = rc;
+ return 0;
+}
+
+
+static int mds_getattr(int offset, struct ptlrpc_request *req)
+{
+ struct mds_obd *mds = &req->rq_obd->u.mds;
struct dentry *de;
struct inode *inode;
struct mds_body *body;
- struct mds_obd *mds = &req->rq_obd->u.mds;
int rc, size[2] = {sizeof(*body)}, bufcount = 1;
ENTRY;
- body = lustre_msg_buf(req->rq_reqmsg, 0);
+ body = lustre_msg_buf(req->rq_reqmsg, offset);
de = mds_fid2dentry(mds, &body->fid1, NULL);
if (IS_ERR(de)) {
req->rq_status = -ENOENT;
- RETURN(0);
+ RETURN(-ENOENT);
}
inode = de->d_inode;
if (rc || OBD_FAIL_CHECK(OBD_FAIL_MDS_GETATTR_PACK)) {
CERROR("mds: out of memory\n");
req->rq_status = -ENOMEM;
- GOTO(out, 0);
+ GOTO(out, rc = -ENOMEM);
}
if (body->valid & OBD_MD_LINKNAME) {
if (rc < 0) {
req->rq_status = rc;
CERROR("readlink failed: %d\n", rc);
- GOTO(out, 0);
+ GOTO(out, rc);
}
}
lustre_msg_buf(req->rq_repmsg, 1));
if (rc < 0) {
req->rq_status = rc;
- CERROR("mds_fs_get_objid failed: %d\n", rc);
- GOTO(out, 0);
+ CERROR("mds_fs_get_obdo failed: %d\n", rc);
+ GOTO(out, rc);
}
}
out:
l_dput(de);
- RETURN(0);
+ RETURN(rc);
}
-static
-int mds_open(struct ptlrpc_request *req)
+static int mds_open(struct ptlrpc_request *req)
{
- struct mds_obd *mds = &req->rq_obd->u.mds;
struct dentry *de;
struct mds_body *body;
struct file *file;
struct vfsmount *mnt;
+ struct mds_obd *mds = &req->rq_obd->u.mds;
struct mds_client_info *mci;
__u32 flags;
struct list_head *tmp;
mci = mds_uuid_to_mci(mds, ptlrpc_req_to_uuid(req));
- if (!mci) {
+ if (!mci) {
CERROR("mds: no mci!\n");
req->rq_status = -ENOTCONN;
RETURN(0);
body = lustre_msg_buf(req->rq_reqmsg, 0);
/* was this animal open already? */
- list_for_each(tmp, &mci->mci_open_head) {
+ list_for_each(tmp, &mci->mci_open_head) {
struct mds_file_data *fd;
fd = list_entry(tmp, struct mds_file_data, mfd_list);
- if (body->extra == fd->mfd_clientfd &&
- body->fid1.id == fd->mfd_file->f_dentry->d_inode->i_ino) {
+ if (body->extra == fd->mfd_clientfd &&
+ body->fid1.id == fd->mfd_file->f_dentry->d_inode->i_ino) {
CERROR("Re opening %Ld\n", body->fid1.id);
RETURN(0);
}
}
OBD_ALLOC(mfd, sizeof(*mfd));
- if (!mfd) {
+ if (!mfd) {
CERROR("mds: out of memory\n");
req->rq_status = -ENOMEM;
RETURN(0);
RETURN(0);
}
+ /* check if this inode has seen a delayed object creation */
+ if (req->rq_reqmsg->bufcount > 1) {
+ void *handle;
+ struct inode *inode = de->d_inode;
+ struct iattr iattr;
+ struct obdo *obdo;
+ int rc;
+
+ obdo = lustre_msg_buf(req->rq_reqmsg, 1);
+ iattr.ia_valid = ATTR_MODE;
+ iattr.ia_mode = inode->i_mode;
+
+ handle = mds_fs_start(mds, de->d_inode, MDS_FSOP_SETATTR);
+ if (!handle) {
+ req->rq_status = -ENOMEM;
+ RETURN(0);
+ }
+
+ /* XXX error handling */
+ rc = mds_fs_set_obdo(mds, inode, handle, obdo);
+ rc = mds_fs_setattr(mds, de, handle, &iattr);
+ if (!rc)
+ rc = mds_update_last_rcvd(mds, handle, req);
+ else {
+ req->rq_status = rc;
+ RETURN(0);
+ }
+ /* FIXME: need to return last_rcvd, last_committed */
+
+ /* FIXME: keep rc intact */
+ rc = mds_fs_commit(mds, de->d_inode, handle);
+ if (rc) {
+ req->rq_status = rc;
+ RETURN(0);
+ }
+ }
+
flags = body->flags;
file = dentry_open(de, mnt, flags & ~O_DIRECT);
if (!file || IS_ERR(file)) {
file->private_data = mfd;
mfd->mfd_file = file;
mfd->mfd_clientfd = body->extra;
- list_add(&mfd->mfd_list, &mci->mci_open_head);
+ list_add(&mfd->mfd_list, &mci->mci_open_head);
body = lustre_msg_buf(req->rq_repmsg, 0);
body->extra = (__u64) (unsigned long)file;
struct dentry *de;
struct mds_body *body;
struct file *file;
+ struct mds_obd *mds = &req->rq_obd->u.mds;
struct vfsmount *mnt;
struct mds_file_data *mfd;
int rc;
}
body = lustre_msg_buf(req->rq_reqmsg, 0);
- de = mds_fid2dentry(&req->rq_obd->u.mds, &body->fid1, &mnt);
+ de = mds_fid2dentry(mds, &body->fid1, &mnt);
if (IS_ERR(de)) {
req->rq_status = -ENOENT;
RETURN(0);
}
file = (struct file *)(unsigned long)body->extra;
- if (!file->f_dentry)
+ if (!file->f_dentry)
LBUG();
mfd = (struct mds_file_data *)file->private_data;
list_del(&mfd->mfd_list);
RETURN(0);
}
-int mds_readpage(struct ptlrpc_request *req)
+static int mds_readpage(struct mds_obd *mds, struct ptlrpc_request *req)
{
struct vfsmount *mnt;
struct dentry *de;
}
body = lustre_msg_buf(req->rq_reqmsg, 0);
- de = mds_fid2dentry(&req->rq_obd->u.mds, &body->fid1, &mnt);
+ de = mds_fid2dentry(mds, &body->fid1, &mnt);
if (IS_ERR(de)) {
req->rq_status = PTR_ERR(de);
RETURN(0);
RETURN(0);
}
-int mds_reint(struct ptlrpc_request *req)
+int mds_reint(int offset, struct ptlrpc_request *req)
{
int rc;
struct mds_update_record rec;
- rc = mds_update_unpack(req, &rec);
+ rc = mds_update_unpack(req, offset, &rec);
if (rc || OBD_FAIL_CHECK(OBD_FAIL_MDS_REINT_UNPACK)) {
CERROR("invalid record\n");
req->rq_status = -EINVAL;
RETURN(0);
}
/* rc will be used to interrupt a for loop over multiple records */
- rc = mds_reint_rec(&rec, req);
- return 0;
+ rc = mds_reint_rec(&rec, offset, req);
+ return rc;
}
int mds_handle(struct obd_device *dev, struct ptlrpc_service *svc,
struct ptlrpc_request *req)
{
- struct mds_obd *mds = &req->rq_obd->u.mds;
+ struct mds_obd *mds;
int rc;
ENTRY;
GOTO(out, rc = -EINVAL);
}
+ if (req->rq_reqmsg->opc != MDS_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, "mds") != 0)
+ GOTO(out, rc = -EINVAL);
+ mds = &obddev->u.mds;
+ req->rq_obd = obddev;
+ }
+
switch (req->rq_reqmsg->opc) {
case MDS_CONNECT:
- CDEBUG(D_INODE, "getattr\n");
+ CDEBUG(D_INODE, "connect\n");
OBD_FAIL_RETURN(OBD_FAIL_MDS_CONNECT_NET, 0);
rc = mds_connect(req);
break;
+ case MDS_DISCONNECT:
+ CDEBUG(D_INODE, "disconnect\n");
+ OBD_FAIL_RETURN(OBD_FAIL_MDS_DISCONNECT_NET, 0);
+ rc = mds_disconnect(mds, req);
+ break;
+
+ case MDS_GETSTATUS:
+ CDEBUG(D_INODE, "getstatus\n");
+ OBD_FAIL_RETURN(OBD_FAIL_MDS_GETSTATUS_NET, 0);
+ rc = mds_getstatus(mds, req);
+ break;
+
case MDS_GETATTR:
CDEBUG(D_INODE, "getattr\n");
OBD_FAIL_RETURN(OBD_FAIL_MDS_GETATTR_NET, 0);
- rc = mds_getattr(req);
+ rc = mds_getattr(0, req);
break;
case MDS_READPAGE:
CDEBUG(D_INODE, "readpage\n");
OBD_FAIL_RETURN(OBD_FAIL_MDS_READPAGE_NET, 0);
- rc = mds_readpage(req);
+ rc = mds_readpage(mds, req);
if (OBD_FAIL_CHECK(OBD_FAIL_MDS_SENDPAGE))
return 0;
break;
- case MDS_REINT:
+ case MDS_REINT: {
+ int size = sizeof(struct mds_body);
CDEBUG(D_INODE, "reint\n");
OBD_FAIL_RETURN(OBD_FAIL_MDS_REINT_NET, 0);
- rc = mds_reint(req);
+
+ rc = lustre_pack_msg(1, &size, NULL, &req->rq_replen,
+ &req->rq_repmsg);
+ if (rc) {
+ rc = req->rq_status = -ENOMEM;
+ break;
+ }
+ rc = mds_reint(0, req);
OBD_FAIL_RETURN(OBD_FAIL_MDS_REINT_NET_REP, 0);
break;
+ }
case MDS_OPEN:
CDEBUG(D_INODE, "open\n");
* a difference on a per-client basis, because last_rcvd is global
* and we are not supposed to allow transactions while in recovery.
*/
- req->rq_repmsg->last_rcvd = HTON__u64(mds->mds_last_rcvd);
- req->rq_repmsg->last_committed = HTON__u64(mds->mds_last_committed);
- CDEBUG(D_INFO, "last_rcvd %Lu, last_committed %Lu, xid %d\n",
- (unsigned long long)mds->mds_last_rcvd,
- (unsigned long long)mds->mds_last_committed,
- cpu_to_le32(req->rq_reqmsg->xid));
if (rc) {
ptlrpc_error(svc, req);
} else {
+ req->rq_repmsg->last_rcvd = HTON__u64(mds->mds_last_rcvd);
+ req->rq_repmsg->last_committed =
+ HTON__u64(mds->mds_last_committed);
+ CDEBUG(D_INFO, "last_rcvd %Lu, last_committed %Lu, xid %d\n",
+ (unsigned long long)mds->mds_last_rcvd,
+ (unsigned long long)mds->mds_last_committed,
+ cpu_to_le32(req->rq_xid));
CDEBUG(D_NET, "sending reply\n");
ptlrpc_reply(svc, req);
}
return rc;
}
+
/* mount the file system (secretly) */
static int mds_setup(struct obd_device *obddev, obd_count len, void *buf)
{
GOTO(err_svc, rc);
}
+ rc = -ENOENT;
+ mds->mds_ldlm_conn = ptlrpc_uuid_to_connection("self");
+ if (!mds->mds_ldlm_conn) {
+ mds_cleanup(obddev);
+ GOTO(err_thread, rc);
+ }
+
+ obddev->obd_namespace = ldlm_namespace_new(LDLM_NAMESPACE_SERVER);
+ if (obddev->obd_namespace == NULL) {
+ LBUG();
+ mds_cleanup(obddev);
+ GOTO(err_thread, rc);
+ }
+
+ mds->mds_local_namespace = ldlm_namespace_new(LDLM_NAMESPACE_CLIENT);
+ if (mds->mds_local_namespace == NULL) {
+ LBUG();
+ mds_cleanup(obddev);
+ GOTO(err_thread, rc);
+ }
+
+ OBD_ALLOC(mds->mds_ldlm_client, sizeof(*mds->mds_ldlm_client));
+ if (mds->mds_ldlm_client == NULL) {
+ LBUG();
+ mds_cleanup(obddev);
+ GOTO(err_thread, rc);
+ }
+ ptlrpc_init_client(NULL, NULL, LDLM_REQUEST_PORTAL, LDLM_REPLY_PORTAL,
+ mds->mds_ldlm_client);
+ mds->mds_ldlm_client->cli_target_devno = obddev->obd_minor;
+ mds->mds_ldlm_client->cli_name = "mds ldlm";
+
rc = mds_recover(obddev);
if (rc)
GOTO(err_thread, rc);
mntput(mds->mds_vfsmnt);
mds->mds_sb = 0;
kfree(mds->mds_fstype);
+
+ ldlm_namespace_free(mds->mds_local_namespace);
+ ldlm_namespace_free(obddev->obd_namespace);
+
+ OBD_FREE(mds->mds_ldlm_client, sizeof(*mds->mds_ldlm_client));
+
lock_kernel();
#ifdef CONFIG_DEV_RDONLY
dev_clear_rdonly(2);
static int __init mds_init(void)
{
+ inter_module_register("mds_reint", THIS_MODULE, &mds_reint);
+ inter_module_register("mds_getattr_name", THIS_MODULE,
+ &mds_getattr_name);
obd_register_type(&mds_obd_ops, LUSTRE_MDS_NAME);
return 0;
}
static void __exit mds_exit(void)
{
+ inter_module_unregister("mds_reint");
+ inter_module_unregister("mds_getattr_name");
obd_unregister_type(LUSTRE_MDS_NAME);
}
-MODULE_AUTHOR("Peter J. Braam <braam@clusterfs.com>");
+MODULE_AUTHOR("Cluster File Systems <info@clusterfs.com>");
MODULE_DESCRIPTION("Lustre Metadata Server (MDS) v0.01");
MODULE_LICENSE("GPL");
mds_ext3_fs_ops.cl_delete_inode(inode);
}
+
static void mds_ext3_callback_status(void *jcb, int error)
{
struct mds_cb_data *mcb = (struct mds_cb_data *)jcb;
#include <linux/lustre_lib.h>
#include <linux/lustre_idl.h>
#include <linux/lustre_mds.h>
+#include <linux/lustre_dlm.h>
#include <linux/obd_class.h>
struct mds_client_info *mds_uuid_to_mci(struct mds_obd *mds, __u8 *uuid)
req->rq_repmsg->transno = HTON__u64(mds->mds_last_rcvd);
mci->mci_mcd->mcd_last_rcvd = cpu_to_le64(mds->mds_last_rcvd);
mci->mci_mcd->mcd_mount_count = cpu_to_le64(mds->mds_mount_count);
- mci->mci_mcd->mcd_last_xid = cpu_to_le32(req->rq_reqmsg->xid);
+ mci->mci_mcd->mcd_last_xid = cpu_to_le64(req->rq_xid);
mds_fs_set_last_rcvd(mds, handle);
push_ctxt(&saved, &mds->mds_ctxt);
return rc;
}
-static int mds_reint_setattr(struct mds_update_record *rec,
+static int mds_reint_setattr(struct mds_update_record *rec, int offset,
struct ptlrpc_request *req)
{
struct mds_obd *mds = &req->rq_obd->u.mds;
return(0);
}
-static int mds_reint_recreate(struct mds_update_record *rec,
+static int mds_reint_recreate(struct mds_update_record *rec, int offset,
struct ptlrpc_request *req)
{
struct dentry *de = NULL;
body = lustre_msg_buf(req->rq_repmsg, 0);
body->ino = dchild->d_inode->i_ino;
body->generation = dchild->d_inode->i_generation;
- } else {
+ } else {
CERROR("child doesn't exist (dir %ld, name %s)\n",
dir->i_ino, rec->ur_name);
rc = -ENOENT;
return 0;
}
-static int mds_reint_create(struct mds_update_record *rec,
+static int mds_reint_create(struct mds_update_record *rec, int offset,
struct ptlrpc_request *req)
{
struct dentry *de = NULL;
struct dentry *dchild = NULL;
struct inode *dir;
void *handle;
- int rc = 0, type = rec->ur_mode & S_IFMT;
- int err;
+ struct ldlm_lock *lock;
+ struct lustre_handle lockh;
+ int rc = 0, err, flags, lock_mode, type = rec->ur_mode & S_IFMT;
+ __u64 res_id[3] = {0,0,0};
ENTRY;
+ /* requests were at offset 2, replies go back at 1 */
+ if (offset)
+ offset = 1;
+
+ if (strcmp(req->rq_obd->obd_type->typ_name, "mds") != 0)
+ LBUG();
+
de = mds_fid2dentry(mds, rec->ur_fid1, NULL);
if (IS_ERR(de) || OBD_FAIL_CHECK(OBD_FAIL_MDS_REINT_CREATE)) {
LBUG();
GOTO(out_create_de, rc = -ESTALE);
}
dir = de->d_inode;
- CDEBUG(D_INODE, "parent ino %ld name %s mode %o\n",
+ CDEBUG(D_INODE, "parent ino %ld name %s mode %o\n",
dir->i_ino, rec->ur_name, rec->ur_mode);
+ lock_mode = (req->rq_reqmsg->opc == MDS_REINT) ? LCK_CW : LCK_PW;
+ res_id[0] = dir->i_ino;
+
+ rc = ldlm_local_lock_match(mds->mds_local_namespace, res_id, LDLM_PLAIN,
+ NULL, 0, lock_mode, &lockh);
+ if (rc == 0) {
+ rc = ldlm_cli_enqueue(mds->mds_ldlm_client, mds->mds_ldlm_conn,
+ NULL, mds->mds_local_namespace, NULL,
+ res_id, LDLM_PLAIN, NULL, 0, lock_mode,
+ &flags, (void *)mds_lock_callback, NULL,
+ 0, &lockh);
+ if (rc != ELDLM_OK) {
+ CERROR("lock enqueue: err: %d\n", rc);
+ GOTO(out_create_de, rc = -EIO);
+ }
+ }
+ ldlm_lock_dump((void *)(unsigned long)lockh.addr);
+
down(&dir->i_sem);
dchild = lookup_one_len(rec->ur_name, de, rec->ur_namelen - 1);
if (IS_ERR(dchild)) {
}
if (dchild->d_inode) {
+ struct mds_body *body;
+ struct obdo *obdo;
+ struct inode *inode = dchild->d_inode;
CERROR("child exists (dir %ld, name %s, ino %ld)\n",
dir->i_ino, rec->ur_name, dchild->d_inode->i_ino);
- LBUG();
+
+ body = lustre_msg_buf(req->rq_repmsg, offset);
+ mds_pack_inode2fid(&body->fid1, inode);
+ mds_pack_inode2body(body, inode);
+ if (S_ISREG(inode->i_mode)) {
+ obdo = lustre_msg_buf(req->rq_repmsg, offset + 1);
+ mds_fs_get_obdo(mds, inode, obdo);
+ }
+ /* now a normal case for intent locking */
GOTO(out_create_dchild, rc = -EEXIST);
}
/* XXX should we abort here in case of error? */
}
- body = lustre_msg_buf(req->rq_repmsg, 0);
+ body = lustre_msg_buf(req->rq_repmsg, offset);
body->ino = inode->i_ino;
body->generation = inode->i_generation;
}
-
+ EXIT;
out_create_commit:
err = mds_fs_commit(mds, dir, handle);
if (err) {
out_create_dchild:
l_dput(dchild);
up(&dir->i_sem);
+ lock = lustre_handle2object(&lockh);
+ ldlm_lock_decref(lock, lock_mode);
out_create_de:
l_dput(de);
req->rq_status = rc;
return 0;
}
-static int mds_reint_unlink(struct mds_update_record *rec,
+static int mds_reint_unlink(struct mds_update_record *rec, int offset,
struct ptlrpc_request *req)
{
struct dentry *de = NULL;
return 0;
}
-static int mds_reint_link(struct mds_update_record *rec,
+static int mds_reint_link(struct mds_update_record *rec, int offset,
struct ptlrpc_request *req)
{
struct dentry *de_src = NULL;
return 0;
}
-static int mds_reint_rename(struct mds_update_record *rec,
+static int mds_reint_rename(struct mds_update_record *rec, int offset,
struct ptlrpc_request *req)
{
struct dentry *de_srcdir = NULL;
GOTO(out_rename_srcdir, rc = -ESTALE);
}
+#warning FIXME: This needs locking attention
+
de_old = lookup_one_len(rec->ur_name, de_srcdir, rec->ur_namelen - 1);
if (IS_ERR(de_old)) {
CERROR("old child lookup error %ld\n", PTR_ERR(de_old));
return 0;
}
-typedef int (*mds_reinter)(struct mds_update_record *, struct ptlrpc_request*);
+typedef int (*mds_reinter)(struct mds_update_record *, int offset,
+ struct ptlrpc_request *);
static mds_reinter reinters[REINT_MAX+1] = {
[REINT_SETATTR] mds_reint_setattr,
[REINT_RECREATE] mds_reint_recreate,
};
-int mds_reint_rec(struct mds_update_record *rec, struct ptlrpc_request *req)
+int mds_reint_rec(struct mds_update_record *rec, int offset,
+ struct ptlrpc_request *req)
{
- int rc, size = sizeof(struct mds_body);
+ int rc;
if (rec->ur_opcode < 1 || rec->ur_opcode > REINT_MAX) {
CERROR("opcode %d not valid\n", rec->ur_opcode);
RETURN(rc);
}
- rc = lustre_pack_msg(1, &size, NULL, &req->rq_replen, &req->rq_repmsg);
- if (rc) {
- CERROR("mds: out of memory\n");
- rc = req->rq_status = -ENOMEM;
- RETURN(rc);
- }
-
- rc = reinters[rec->ur_opcode](rec, req);
+ rc = reinters[rec->ur_opcode](rec, offset, req);
return rc;
}
RETURN(0);
}
-static int obd_class_name2dev(char *name)
+int obd_class_name2dev(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 && strcmp(name, obd->obd_name) == 0) {
+ if (obd->obd_name && strncmp(name, obd->obd_name, 37) == 0) {
res = i;
return res;
}
EXPORT_SYMBOL(obd_unregister_type);
EXPORT_SYMBOL(obd_dev);
-
+EXPORT_SYMBOL(obd_class_name2dev);
EXPORT_SYMBOL(gen_connect);
EXPORT_SYMBOL(gen_client);
EXPORT_SYMBOL(gen_cleanup);
int err;
int i;
- printk(KERN_INFO "OBD class driver v0.01, braam@stelias.com\n");
+ printk(KERN_INFO "OBD class driver v0.9, info@clusterfs.com\n");
INIT_LIST_HEAD(&obd_types);
static int osc_connect(struct obd_conn *conn)
{
+ struct osc_obd *osc = &conn->oc_dev->u.osc;
struct ptlrpc_request *request;
struct ptlrpc_client *cl;
struct ptlrpc_connection *connection;
struct ost_body *body;
- int rc, size = sizeof(*body);
+ char *tmp = osc->osc_target_uuid;
+ int rc, size = sizeof(osc->osc_target_uuid);
ENTRY;
osc_con2cl(conn, &cl, &connection);
- request = ptlrpc_prep_req(cl, connection, OST_CONNECT, 0, NULL, NULL);
+ request = ptlrpc_prep_req(cl, connection, OST_CONNECT, 1, &size, &tmp);
if (!request)
RETURN(-ENOMEM);
+ size = sizeof(*body);
request->rq_replen = lustre_msg_size(1, &size);
rc = ptlrpc_queue_wait(request);
body = lustre_msg_buf(request->rq_repmsg, 0);
CDEBUG(D_INODE, "received connid %d\n", body->connid);
+ /* This might be redundant. */
+ cl->cli_target_devno = request->rq_repmsg->target_id;
+ osc->osc_ldlm_client->cli_target_devno = cl->cli_target_devno;
+ /* XXX: Make this a handle */
conn->oc_id = body->connid;
EXIT;
out:
body = lustre_msg_buf(request->rq_reqmsg, 0);
body->connid = conn->oc_id;
- request->rq_replen = lustre_msg_size(1, &size);
+ request->rq_replen = lustre_msg_size(0, NULL);
rc = ptlrpc_queue_wait(request);
GOTO(out, rc);
body = lustre_msg_buf(request->rq_reqmsg, 0);
memcpy(&body->oa, oa, sizeof(*oa));
- body->oa.o_valid = ~0;
body->connid = conn->oc_id;
request->rq_replen = lustre_msg_size(1, &size);
offset, flags, (bulk_callback_t)callback);
}
-static int osc_enqueue(struct obd_conn *oconn, struct ldlm_namespace *ns,
- struct ldlm_handle *parent_lock, __u64 *res_id,
- __u32 type, struct ldlm_extent *extent, __u32 mode,
- int *flags, void *data, int datalen,
- struct ldlm_handle *lockh)
+static int osc_enqueue(struct obd_conn *oconn,
+ struct lustre_handle *parent_lock, __u64 *res_id,
+ __u32 type, void *extentp, int extent_len, __u32 mode,
+ int *flags, void *callback, void *data, int datalen,
+ struct lustre_handle *lockh)
{
+ struct obd_device *obddev = oconn->oc_dev;
struct ptlrpc_connection *conn;
struct ptlrpc_client *cl;
+ struct ldlm_extent *extent = extentp;
int rc;
__u32 mode2;
/* Next, search for already existing extent locks that will cover us */
osc_con2dlmcl(oconn, &cl, &conn);
- rc = ldlm_local_lock_match(ns, res_id, type, extent, mode, lockh);
+ rc = ldlm_local_lock_match(obddev->obd_namespace, res_id, type, extent,
+ sizeof(extent), mode, lockh);
if (rc == 1) {
/* We already have a lock, and it's referenced */
return 0;
else
mode2 = LCK_PW;
- rc = ldlm_local_lock_match(ns, res_id, type, extent, mode2, lockh);
+ rc = ldlm_local_lock_match(obddev->obd_namespace, res_id, type, extent,
+ sizeof(extent), mode2, lockh);
if (rc == 1) {
int flags;
- struct ldlm_lock *lock = ldlm_handle2object(lockh);
+ struct ldlm_lock *lock = lustre_handle2object(lockh);
/* FIXME: This is not incredibly elegant, but it might
* be more elegant than adding another parameter to
* lock_match. I want a second opinion. */
return rc;
}
- rc = ldlm_cli_enqueue(cl, conn, ns, parent_lock, res_id, type,
- extent, mode, flags, data, datalen, lockh);
+ rc = ldlm_cli_enqueue(cl, conn, NULL, obddev->obd_namespace,
+ parent_lock, res_id, type, extent, sizeof(extent),
+ mode, flags, callback, data, datalen, lockh);
return rc;
}
static int osc_cancel(struct obd_conn *oconn, __u32 mode,
- struct ldlm_handle *lockh)
+ struct lustre_handle *lockh)
{
struct ldlm_lock *lock;
ENTRY;
- lock = ldlm_handle2object(lockh);
+ lock = lustre_handle2object(lockh);
ldlm_lock_decref(lock, mode);
RETURN(0);
static int osc_setup(struct obd_device *obddev, obd_count len, void *buf)
{
+ struct obd_ioctl_data* data = buf;
struct osc_obd *osc = &obddev->u.osc;
+ char server_uuid[37];
int rc;
ENTRY;
- osc->osc_conn = ptlrpc_uuid_to_connection("ost");
- if (!osc->osc_conn)
+ if (data->ioc_inllen1 < 1) {
+ CERROR("osc setup requires a TARGET UUID\n");
+ RETURN(-EINVAL);
+ }
+
+ if (data->ioc_inllen1 > 37) {
+ CERROR("osc TARGET UUID must be less than 38 characters\n");
+ RETURN(-EINVAL);
+ }
+
+ if (data->ioc_inllen2 < 1) {
+ CERROR("osc setup requires a SERVER UUID\n");
RETURN(-EINVAL);
+ }
+
+ if (data->ioc_inllen2 > 37) {
+ CERROR("osc SERVER UUID must be less than 38 characters\n");
+ RETURN(-EINVAL);
+ }
+
+ memcpy(osc->osc_target_uuid, data->ioc_inlbuf1, data->ioc_inllen1);
+ memcpy(server_uuid, data->ioc_inlbuf2, MIN(data->ioc_inllen2,
+ sizeof(server_uuid)));
+
+ osc->osc_conn = ptlrpc_uuid_to_connection(server_uuid);
+ if (!osc->osc_conn)
+ RETURN(-ENOENT);
+
+ obddev->obd_namespace = ldlm_namespace_new(LDLM_NAMESPACE_CLIENT);
+ if (obddev->obd_namespace == NULL)
+ GOTO(out_conn, rc = -ENOMEM);
OBD_ALLOC(osc->osc_client, sizeof(*osc->osc_client));
if (osc->osc_client == NULL)
- GOTO(out_conn, rc = -ENOMEM);
+ GOTO(out_ns, rc = -ENOMEM);
OBD_ALLOC(osc->osc_ldlm_client, sizeof(*osc->osc_ldlm_client));
if (osc->osc_ldlm_client == NULL)
out_client:
OBD_FREE(osc->osc_client, sizeof(*osc->osc_client));
+ out_ns:
+ ldlm_namespace_free(obddev->obd_namespace);
out_conn:
ptlrpc_put_connection(osc->osc_conn);
return rc;
{
struct osc_obd *osc = &obddev->u.osc;
+ ldlm_namespace_free(obddev->obd_namespace);
+
ptlrpc_cleanup_client(osc->osc_client);
OBD_FREE(osc->osc_client, sizeof(*osc->osc_client));
ptlrpc_cleanup_client(osc->osc_ldlm_client);
static int __init osc_init(void)
{
- obd_register_type(&osc_obd_ops, LUSTRE_OSC_NAME);
- return 0;
+ return obd_register_type(&osc_obd_ops, LUSTRE_OSC_NAME);
}
static void __exit osc_exit(void)
#include <linux/module.h>
#include <linux/obd_ost.h>
#include <linux/lustre_net.h>
+#include <linux/lustre_dlm.h>
static int ost_destroy(struct ost_obd *ost, struct ptlrpc_request *req)
{
RETURN(0);
}
-static int ost_connect(struct ost_obd *ost, struct ptlrpc_request *req)
+static int ost_connect(struct ptlrpc_request *req)
{
struct obd_conn conn;
struct ost_body *body;
- int rc, size = sizeof(*body);
+ struct ost_obd *ost;
+ char *uuid;
+ int rc, size = sizeof(*body), i;
ENTRY;
+ uuid = lustre_msg_buf(req->rq_reqmsg, 0);
+ if (req->rq_reqmsg->buflens[0] > 37) {
+ /* Invalid UUID */
+ req->rq_status = -EINVAL;
+ RETURN(0);
+ }
+
+ i = obd_class_name2dev(uuid);
+ if (i == -1) {
+ req->rq_status = -ENODEV;
+ RETURN(0);
+ }
+
+ ost = &(obd_dev[i].u.ost);
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_repmsg->target_id = i;
req->rq_status = obd_connect(&conn);
CDEBUG(D_IOCTL, "rep buffer %p, id %d\n", req->rq_repmsg, conn.oc_id);
{
struct obd_conn conn;
struct ost_body *body;
- int rc, size = sizeof(*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(1, &size, NULL, &req->rq_replen, &req->rq_repmsg);
+ rc = lustre_pack_msg(0, NULL, NULL, &req->rq_replen, &req->rq_repmsg);
if (rc)
RETURN(rc);
struct ptlrpc_request *req)
{
int rc;
- struct ost_obd *ost = &obddev->u.ost;
+ struct ost_obd *ost;
ENTRY;
rc = lustre_unpack_msg(req->rq_reqmsg, req->rq_reqlen);
GOTO(out, rc = -EINVAL);
}
+ 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)
+ GOTO(out, rc = -EINVAL);
+ ost = &obddev->u.ost;
+ req->rq_obd = obddev;
+ }
+
switch (req->rq_reqmsg->opc) {
case OST_CONNECT:
CDEBUG(D_INODE, "connect\n");
OBD_FAIL_RETURN(OBD_FAIL_OST_CONNECT_NET, 0);
- rc = ost_connect(ost, req);
+ rc = ost_connect(req);
break;
case OST_DISCONNECT:
CDEBUG(D_INODE, "disconnect\n");
GOTO(error_dec, err = -EINVAL);
}
+ obddev->obd_namespace = ldlm_namespace_new(LDLM_NAMESPACE_SERVER);
+ if (obddev->obd_namespace == NULL)
+ LBUG();
+
ost->ost_service = ptlrpc_init_svc(128 * 1024,
OST_REQUEST_PORTAL, OSC_REPLY_PORTAL,
"self", ost_handle);
}
c = ptlrpc_get_connection(&peer);
- if (c)
+ if (c) {
+ memcpy(c->c_remote_uuid, uuid, sizeof(c->c_remote_uuid));
c->c_epoch++;
+ }
return c;
}
ptl_set_inv_handle(&bulk->b_me_h);
list_add_tail(&bulk->b_link, &desc->b_page_list);
desc->b_page_count++;
+ atomic_inc(&desc->b_pages_remaining);
}
return bulk;
}
void ptlrpc_free_bulk_page(struct ptlrpc_bulk_page *bulk)
{
- if (!bulk) {
+ ENTRY;
+ if (bulk == NULL) {
EXIT;
return;
}
list_del(&bulk->b_link);
bulk->b_desc->b_page_count--;
OBD_FREE(bulk, sizeof(*bulk));
+ EXIT;
}
struct ptlrpc_request *ptlrpc_prep_req(struct ptlrpc_client *cl,
rc = lustre_pack_msg(count, lengths, bufs,
&request->rq_reqlen, &request->rq_reqmsg);
if (rc) {
- OBD_FREE(request, sizeof(*request));
CERROR("cannot pack request %d\n", rc);
+ OBD_FREE(request, sizeof(*request));
RETURN(NULL);
}
request->rq_reqmsg->token = conn->c_remote_token;
request->rq_reqmsg->opc = HTON__u32(opcode);
request->rq_reqmsg->type = HTON__u32(PTL_RPC_MSG_REQUEST);
+ request->rq_reqmsg->target_id = HTON__u32(cl->cli_target_devno);
+
INIT_LIST_HEAD(&request->rq_list);
/* this will be dec()d once in req_finished, once in free_committed */
atomic_set(&request->rq_refcount, 2);
spin_lock(&conn->c_lock);
- request->rq_reqmsg->xid = HTON__u32(++conn->c_xid_out);
+ request->rq_xid = HTON__u32(++conn->c_xid_out);
request->rq_xid = conn->c_xid_out;
spin_unlock(&conn->c_lock);
}
resend:
req->rq_time = CURRENT_TIME;
- req->rq_timeout = 30;
+ req->rq_timeout = 3;
rc = ptl_send_rpc(req);
if (rc) {
CERROR("error %d, opcode %d\n", rc, req->rq_reqmsg->opc);
CERROR("unpack_rep failed: %d\n", rc);
GOTO(out, rc);
}
- CDEBUG(D_NET, "got rep %d\n", req->rq_repmsg->xid);
+ CDEBUG(D_NET, "got rep %Ld\n", req->rq_xid);
if (req->rq_repmsg->status == 0)
CDEBUG(D_NET, "--> buf %p len %d status %d\n", req->rq_repmsg,
req->rq_replen, req->rq_repmsg->status);
GOTO(out, rc);
}
- CDEBUG(D_NET, "got rep %d\n", req->rq_repmsg->xid);
+ CDEBUG(D_NET, "got rep %Ld\n", req->rq_xid);
if (req->rq_repmsg->status == 0)
CDEBUG(D_NET, "--> buf %p len %d status %d\n", req->rq_repmsg,
req->rq_replen, req->rq_repmsg->status);
spin_unlock(&conn_lock);
rc = 1;
}
+ if (atomic_read(&c->c_refcount) < 0)
+ CERROR("refcount < 0!\n");
RETURN(rc);
}
*/
static int reply_in_callback(ptl_event_t *ev)
{
- struct ptlrpc_request *rpc = ev->mem_desc.user_ptr;
+ struct ptlrpc_request *req = ev->mem_desc.user_ptr;
ENTRY;
+ if (req->rq_xid != ev->match_bits) {
+ CERROR("Reply packet for wrong request\n");
+ LBUG();
+ }
+
if (ev->type == PTL_EVENT_PUT) {
- rpc->rq_repmsg = ev->mem_desc.start + ev->offset;
+ req->rq_repmsg = ev->mem_desc.start + ev->offset;
barrier();
- wake_up_interruptible(&rpc->rq_wait_for_rep);
+ wake_up_interruptible(&req->rq_wait_for_rep);
} else {
// XXX make sure we understand all events, including ACK's
CERROR("Unknown event %d\n", ev->type);
int request_in_callback(ptl_event_t *ev)
{
struct ptlrpc_service *service = ev->mem_desc.user_ptr;
- int index;
if (ev->rlength != ev->mlength)
CERROR("Warning: Possibly truncated rpc (%d/%d)\n",
ev->mlength, ev->rlength);
- spin_lock(&service->srv_lock);
- for (index = 0; index < service->srv_ring_length; index++)
- if ( service->srv_buf[index] == ev->mem_desc.start)
- break;
-
- if (index == service->srv_ring_length)
- LBUG();
-
- service->srv_ref_count[index]++;
-
- if (ptl_is_valid_handle(&ev->unlinked_me)) {
- int idx;
-
- for (idx = 0; idx < service->srv_ring_length; idx++)
- if (service->srv_me_h[idx].handle_idx ==
- ev->unlinked_me.handle_idx)
- break;
- if (idx == service->srv_ring_length)
- LBUG();
-
- CDEBUG(D_NET, "unlinked %d\n", idx);
- ptl_set_inv_handle(&(service->srv_me_h[idx]));
-
- if (service->srv_ref_count[idx] == 0)
- ptlrpc_link_svc_me(service, idx);
- }
-
- spin_unlock(&service->srv_lock);
if (ev->type == PTL_EVENT_PUT)
wake_up(&service->srv_waitq);
else
CDEBUG(D_NET, "got ACK event\n");
if (bulk->b_cb != NULL)
bulk->b_cb(bulk);
- if (atomic_dec_and_test(&desc->b_finished_count)) {
+ if (atomic_dec_and_test(&desc->b_pages_remaining)) {
desc->b_flags |= PTL_BULK_FL_SENT;
wake_up_interruptible(&desc->b_waitq);
if (desc->b_cb != NULL)
CERROR("bulkbuf != mem_desc -- why?\n");
if (bulk->b_cb != NULL)
bulk->b_cb(bulk);
- if (atomic_dec_and_test(&desc->b_finished_count)) {
+ if (atomic_dec_and_test(&desc->b_pages_remaining)) {
desc->b_flags |= PTL_BULK_FL_RCVD;
wake_up_interruptible(&desc->b_waitq);
if (desc->b_cb != NULL)
CDEBUG(D_NET, "Sending %d bytes to portal %d, xid %Ld\n",
request->rq_req_md.length, portal, request->rq_xid);
- rc = PtlPut(md_h, ack, remote_id, portal, 0, request->rq_reqmsg->xid,
+ rc = PtlPut(md_h, ack, remote_id, portal, 0, request->rq_xid,
0, 0);
if (rc != PTL_OK) {
CERROR("PtlPut(%Lu, %d, %Ld) failed: %d\n", remote_id.nid,
ptl_process_id_t remote_id;
ENTRY;
- atomic_set(&desc->b_finished_count, desc->b_page_count);
-
list_for_each_safe(tmp, next, &desc->b_page_list) {
- /* only request an ACK for the last page */
- int ack = (next == &desc->b_page_list);
struct ptlrpc_bulk_page *bulk;
bulk = list_entry(tmp, struct ptlrpc_bulk_page, b_link);
bulk->b_md.start = bulk->b_buf;
bulk->b_md.length = bulk->b_buflen;
bulk->b_md.eventq = bulk_source_eq;
- bulk->b_md.threshold = 1 + ack; /* SENT and (if last) ACK */
+ bulk->b_md.threshold = 2; /* SENT and ACK */
bulk->b_md.options = PTL_MD_OP_PUT;
bulk->b_md.user_ptr = bulk;
CDEBUG(D_NET, "Sending %d bytes to portal %d, xid %d\n",
bulk->b_md.length, desc->b_portal, bulk->b_xid);
- rc = PtlPut(bulk->b_md_h, (ack ? PTL_ACK_REQ : PTL_NOACK_REQ),
- remote_id, desc->b_portal, 0, bulk->b_xid, 0, 0);
+ rc = PtlPut(bulk->b_md_h, PTL_ACK_REQ, remote_id,
+ desc->b_portal, 0, bulk->b_xid, 0, 0);
if (rc != PTL_OK) {
CERROR("PtlPut(%Lu, %d, %d) failed: %d\n",
remote_id.nid, desc->b_portal, bulk->b_xid, rc);
int rc;
ENTRY;
- atomic_set(&desc->b_finished_count, desc->b_page_count);
-
list_for_each_safe(tmp, next, &desc->b_page_list) {
struct ptlrpc_bulk_page *bulk;
bulk = list_entry(tmp, struct ptlrpc_bulk_page, b_link);
req->rq_type = PTL_RPC_TYPE_REPLY;
req->rq_repmsg->conn = req->rq_connection->c_remote_conn;
req->rq_repmsg->token = req->rq_connection->c_remote_token;
- req->rq_repmsg->xid = HTON__u32(req->rq_reqmsg->xid);
req->rq_repmsg->status = HTON__u32(req->rq_status);
req->rq_reqmsg->type = HTON__u32(req->rq_type);
return ptl_send_buf(req, req->rq_connection, svc->srv_rep_portal);
rc = PtlMEAttach(request->rq_connection->c_peer.peer_ni,
request->rq_client->cli_reply_portal,
- local_id, request->rq_reqmsg->xid, 0, PTL_UNLINK,
+ local_id, request->rq_xid, 0, PTL_UNLINK,
PTL_INS_AFTER, &request->rq_reply_me_h);
if (rc != PTL_OK) {
CERROR("PtlMEAttach failed: %d\n", rc);
int index;
spin_lock(&service->srv_lock);
-
for (index = 0; index < service->srv_ring_length; index++)
if (service->srv_buf[index] == start)
break;
RETURN(-EINVAL);
m->opc = NTOH__u32(m->opc);
- m->xid = NTOH__u32(m->xid);
m->status = NTOH__u32(m->status);
m->type = NTOH__u32(m->type);
- m->connid = NTOH__u32(m->connid);
m->bufcount = NTOH__u32(m->bufcount);
m->last_rcvd = NTOH__u64(m->last_rcvd);
m->last_committed = NTOH__u64(m->last_committed);
+ m->target_id = NTOH__u32(m->target_id);
required_len = size_round(sizeof(*m) + m->bufcount * sizeof(__u32));
if (len < required_len)
start = event->mem_desc.start;
memset(&request, 0, sizeof(request));
request.rq_obd = obddev;
+ request.rq_xid = event->match_bits;
request.rq_reqmsg = event->mem_desc.start + event->offset;
request.rq_reqlen = event->mem_desc.length;
- if (request.rq_reqmsg->xid != event->match_bits)
- LBUG();
-
- CDEBUG(D_NET, "got req %d\n", request.rq_reqmsg->xid);
+ CDEBUG(D_NET, "got req %Ld\n", request.rq_xid);
peer.peer_nid = event->initiator.nid;
/* FIXME: this NI should be the incoming NI.
return rc;
}
+void ptlrpc_rotate_reqbufs(struct ptlrpc_service *service,
+ ptl_event_t *ev)
+{
+ int index;
+
+ for (index = 0; index < service->srv_ring_length; index++)
+ if (service->srv_buf[index] == ev->mem_desc.start)
+ break;
+
+ if (index == service->srv_ring_length)
+ LBUG();
+
+ service->srv_ref_count[index]++;
+
+ if (ptl_is_valid_handle(&ev->unlinked_me)) {
+ int idx;
+
+ for (idx = 0; idx < service->srv_ring_length; idx++)
+ if (service->srv_me_h[idx].handle_idx ==
+ ev->unlinked_me.handle_idx)
+ break;
+ if (idx == service->srv_ring_length)
+ LBUG();
+
+ CDEBUG(D_NET, "unlinked %d\n", idx);
+ ptl_set_inv_handle(&(service->srv_me_h[idx]));
+
+ if (service->srv_ref_count[idx] == 0)
+ ptlrpc_link_svc_me(service, idx);
+ }
+}
+
static int ptlrpc_main(void *arg)
{
int rc;
if (thread->t_flags & SVC_EVENT) {
thread->t_flags &= ~SVC_EVENT;
+ ptlrpc_rotate_reqbufs(svc, &event);
+
rc = handle_incoming_request(obddev, svc, &event);
thread->t_flags &= ~SVC_EVENT;
continue;
directio
openme
writeme
+mcreate
+tchmod
fsx
CFLAGS := -g -Wall
# LDADD = -lldap
# LDADD := -lreadline -ltermcap # -lefence
-bin_PROGRAMS = openunlink testreq truncate directio openme writeme fsx #ldaptest
+bin_PROGRAMS = openunlink testreq truncate directio openme writeme mcreate tchmod toexcl fsx #ldaptest
# ldaptest_SOURCES = ldaptest.c
+tchmod_SOURCES = tchmod.c
+toexcl_SOURCES = toexcl.c
testreq_SOURCES = testreq.c
+mcreate_SOURCES = mcreate.c
truncate_SOURCES = truncate.c
directio_SOURCES = directio.c
openunlink_SOURCES = openunlink.c
#!/bin/sh
# Config file for mounting a client Lustre filesystem
+SETUP_MDC=y
SETUP_OSC=y
OSCMT=/mnt/lustre
SETUP_MOUNT=y
--- /dev/null
+#!/bin/sh
+# Config file for mounting a client Lustre filesystem
+MDC_NAMES="MDCDEV1 MDCDEV2"
+OSC_NAMES="OSCDEV1 OSCDEV2"
+SETUP_MDC=y
+SETUP_OSC=y
+MT1="/mnt/lustre1 OSCDEV1 MDCDEV1"
+MT2="/mnt/lustre2 OSCDEV2 MDCDEV2"
+MOUNT_LIST="MT1 MT2"
+SETUP_MOUNT=y
fi
[ -z "$OSTNODE" ] && OSTNODE=$SERVER
+ [ -z "$MDSNODE" ] && MDSNODE=$SERVER
if [ -z "$DLM" ]; then
if [ "$LOCALHOST" == "$SERVER" ]; then
$PTLCTL <<- EOF
setup $NETWORK
mynid $LOCALHOST
- connect $SERVER $PORT
- add_uuid self
- add_uuid mds
+ connect $MDSNODE $PORT
+ add_uuid $MDSNODE
connect $OSTNODE $PORT
- add_uuid ost
+ add_uuid $OSTNODE
connect $DLM $PORT
- add_uuid ldlm
+ add_uuid $DLM
+ add_uuid self
quit
EOF
}
do_insmod $LUSTRE/mdc/mdc.o || exit -1
do_insmod $LUSTRE/llite/llite.o || exit -1
+ echo "$R/tmp/lustre-log" > /proc/sys/portals/debug_path
list_mods
if $OBDCTL name2dev RPCDEV > /dev/null 2>&1; then
}
setup_osc() {
+ set -vx
[ "$SETUP_OSC" != "y" ] && return 0
+ [ "$OSC_NAMES" ] || OSC_NAMES=OSCDEV
- if $OBDCTL name2dev OSCDEV > /dev/null 2>&1; then
+ for THEOSC in $OSC_NAMES ; do
+ OSCDEVNO=`find_devno $THEOSC`
+ if $OBDCTL name2dev $THEOSC > /dev/null 2>&1; then
echo "$0: OSCDEV is already configured"
return 0
+ fi
+
+ $OBDCTL <<- EOF || return $rc
+ newdev
+ attach osc $THEOSC
+ setup OSTDEV $OSTNODE
+ quit
+ EOF
+ done
+}
+
+setup_mdc() {
+ set -vx
+ [ "$SETUP_MDC" != "y" ] && return 0
+ [ "$MDC_NAMES" ] || MDC_NAMES=MDCDEV
+
+ for THEMDC in $MDC_NAMES ; do
+ MDCDEVNO=`find_devno $THEMDC`
+ if $OBDCTL name2dev $THEMDC > /dev/null 2>&1; then
+ echo "$0: MDCDEV is already configured"
+ return 0
fi
$OBDCTL <<- EOF || return $?
newdev
- attach osc OSCDEV
- setup -1
+ attach mdc $THEMDC
+ setup MDSDEV $MDSNODE
quit
EOF
+ done
}
+
setup_mount() {
+ set -vx
[ "$SETUP_MOUNT" != "y" ] && return 0
+ [ "$MDC_NAMES" ] || MDC_NAMES=MDCDEV
+ [ "$OSC_NAMES" ] || OSC_NAMES=OSCDEV
+ [ -z "$MOUNT_LIST" -a "$OSCMT" ] && MOUNT_LIST="MT" && MT="$OSCMT OSCDEV MDCDEV"
- [ "$OSCMT" ] || fail "error: $0: OSCMT unset"
+ [ "$MOUNT_LIST" ] || fail "error: $0: MOUNT_LIST unset"
- if mount | grep -q $OSCMT; then
- echo "$0: $OSCMT is already mounted"
- return 0
- fi
+ for THEMOUNT in $MOUNT_LIST; do
+ eval "echo \$$THEMOUNT" | while read MTPT THEOSC THEMDC; do
+ if mount | grep -q $MTPT; then
+ echo "$0: $MTPT is already mounted"
+ return 0
+ fi
- [ ! -d $OSCMT ] && mkdir $OSCMT
- echo "$0: mounting \$OSCDEV on $OSCMT"
- mount -t lustre_lite -o device=`find_devno OSCDEV` none $OSCMT
+ [ ! -d $MTPT ] && mkdir $MTPT
+ echo mount -t lustre_lite -o ost=`find_devno $THEOSC`,mds=`find_devno $THEMDC` none $MTPT
+ mount -t lustre_lite -o ost=`find_devno $THEOSC`,mds=`find_devno $THEMDC` none $MTPT
+ done
+ done
}
setup_client() {
- setup_osc && setup_mount
+ setup_osc && setup_mdc && setup_mount
}
DEBUG_ON="echo 0xffffffff > /proc/sys/portals/debug"
setup $NETWORK
disconnect
del_uuid self
- del_uuid mds
- del_uuid ost
- del_uuid ldlm
+ del_uuid $MDSNODE
+ del_uuid $OSTNODE
+ del_uuid $DLM
quit
EOF
[ "$SETUP" -a -z "$SETUP_MOUNT" ] && return 0
[ "$OSCMT" ] || OSCMT=/mnt/lustre
- if [ "`mount | grep $OSCMT`" ]; then
- umount $OSCMT || fail "unable to unmount $OSCMT"
- fi
+ for THEMOUNT in $OSCMT; do
+ if [ "`mount | grep $THEMOUNT`" ]; then
+ umount $THEMOUNT || fail "unable to unmount $THEMOUNT"
+ fi
+ done
}
cleanup_osc() {
[ "$SETUP" -a -z "$SETUP_OSC" ] && return 0
+ [ "$OSC_NAMES" ] || OSC_NAMES=OSCDEV
- OSCDEVNO=`find_devno OSCDEV`
- if [ "$OSCDEVNO" ]; then
+ for THEOSC in $OSC_NAMES ; do
+ OSCDEVNO=`find_devno $THEOSC`
+ if [ "$OSCDEVNO" ]; then
$OBDCTL <<- EOF
device $OSCDEVNO
cleanup
detach
quit
EOF
- fi
+ fi
+ done
+}
+
+cleanup_mdc() {
+ [ "$SETUP" -a -z "$SETUP_MDC" ] && return 0
+ [ "$MDC_NAMES" ] || MDC_NAMES=MDCDEV
+
+ for THEMDC in $MDC_NAMES ; do
+ MDCDEVNO=`find_devno $THEMDC`
+ if [ "$MDCDEVNO" ]; then
+ $OBDCTL <<- EOF
+ device $MDCDEVNO
+ cleanup
+ detach
+ quit
+ EOF
+ fi
+ done
}
cleanup_rpc() {
}
cleanup_client() {
- cleanup_mount && cleanup_osc && cleanup_rpc
+ cleanup_mount && cleanup_osc && cleanup_mdc && cleanup_rpc
}
fail() {
setup_opts "$@"
-$DBGCTL debug_kernel /tmp/debug.1
+TIME=`date +'%s'`
+
+$DBGCTL debug_kernel /tmp/debug.1.$TIME
cleanup_client
-$DBGCTL debug_kernel /tmp/debug.2
+$DBGCTL debug_kernel /tmp/debug.2.$TIME
cleanup_server
-$DBGCTL debug_kernel /tmp/debug.3
-cleanup_ldlm
-$DBGCTL debug_kernel /tmp/debug.4
+$DBGCTL debug_kernel /tmp/debug.3.$TIME
cleanup_lustre
-$DBGCTL debug_kernel /tmp/debug.5
+$DBGCTL debug_kernel /tmp/debug.4.$TIME
+cleanup_ldlm
+$DBGCTL debug_kernel /tmp/debug.5.$TIME
cleanup_portals
. $SRCDIR/common.sh
export DEBUG_WAIT=yes
-. $SRCDIR/llsetup.sh $SRCDIR/net-local.cfg $SRCDIR/mds.cfg $SRCDIR/obdext2.cfg $SRCDIR/client-mount.cfg $SRCDIR/ldlm.cfg || exit 2
+. $SRCDIR/llsetup.sh $SRCDIR/net-local.cfg $SRCDIR/mds.cfg $SRCDIR/obdfilter.cfg $SRCDIR/client-mount.cfg $SRCDIR/ldlm.cfg || exit 2
debug_client_on
#debug_client_off
SRCDIR="`dirname $0`/"
. $SRCDIR/common.sh
-$DBGCTL debug_kernel /tmp/debug.1
+TIME=`date +'%s'`
+
+$DBGCTL debug_kernel /tmp/debug.1.$TIME
if mount | grep '/mnt/lustre'; then
umount /mnt/lustre || fail "cannot unmount"
killall acceptor
rmmod llite
-rmmod mdc
$OBDCTL <<EOF
-name2dev OSCDEV
-cleanup
-detach
-name2dev LDLMDEV
+name2dev MDCDEV
cleanup
detach
-name2dev RPCDEV
+name2dev OSCDEV
cleanup
detach
name2dev OSTDEV
name2dev MDSDEV
cleanup
detach
+name2dev LDLMDEV
+cleanup
+detach
+name2dev RPCDEV
+cleanup
+detach
quit
EOF
rmmod mds_ext3
rmmod mds_ext2
rmmod mds
+rmmod mdc
rmmod osc
rmmod ost
rmmod obdfilter
rmmod obdclass
rmmod extN
-$DBGCTL debug_kernel /tmp/debug.2
+$DBGCTL debug_kernel /tmp/debug.2.$TIME
$PTLCTL <<EOF
setup tcp
disconnect
del_uuid self
-del_uuid mds
-del_uuid ost
-del_uuid ldlm
+del_uuid localhost
+del_uuid localhost
+del_uuid localhost
quit
EOF
. $SRCDIR/common.sh
export DEBUG_WAIT=yes
-. $SRCDIR/llrsetup.sh $SRCDIR/net-local.cfg $SRCDIR/client-mount.cfg $SRCDIR/mds.cfg $SRCDIR/obdext2.cfg $SRCDIR/ldlm.cfg || exit 2
+. $SRCDIR/llrsetup.sh $SRCDIR/net-local.cfg $SRCDIR/client-mount.cfg $SRCDIR/mds.cfg $SRCDIR/obdfilter.cfg $SRCDIR/ldlm.cfg || exit 2
debug_client_on
#debug_client_off
--- /dev/null
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include <string.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+int main(int argc, char ** argv)
+{
+ int rc;
+
+ if (argc < 2) {
+ printf("Usage %s filename\n", argv[0]);
+ return 1;
+ }
+
+ rc = mknod(argv[1], S_IFREG| 0444, 0);
+ if (rc) {
+ printf("error: %s\n", strerror(errno));
+ }
+ return rc;
+}
# Config file for setting up an object storage target with obdfilter
OSTDEV=/tmp/ost
OSTSIZE=10000
-OSTFS=ext2
+OSTFS=extN
OSTTYPE=obdfilter
SETUP_OST=y
mynid localhost
setup tcp
connect $SERVER $PORT
+add_uuid $SERVER
add_uuid self
-add_uuid ost
quit
EOF
}
-echo
-echo "Test 5 reopen a file:" `date` "creating and writing/mnt/lustre/foo"
-echo
-rm -rf /mnt/lustre/*
-./openme /mnt/lustre/foo3 &
-./writeme /mnt/lustre/iogoeson &
-sleep 1
-ls -l /mnt/lustre
-echo 0x80000107 > /proc/sys/lustre/fail_loc
-mknod /mnt/lustre/dev c 10 240 &
-echo "MDS dropped create request -- sleep 4 secs - watch for timeout"
-sleep 4
-reconnect
-sleep 1
-echo "did things recover? check for file foo, bar, check log for reopen."
-ls -l /mnt/lustre
-echo "Test 5 done"
-exit
echo
echo "Test 1 drop request:" `date` "creating /mnt/lustre/foo"
touch /mnt/lustre/foo &
ps axww | grep touch
echo "MDS dropped create request -- sleep 4 secs - watch for timeout"
-sleep 4
-reconnect
+sleep 7
+# reconnect
sleep 1
echo "did things recover? check for file foo."
ls -l /mnt/lustre
+echo "Test 1 done"
echo
echo "MDS dropped create request -- sleep 4 secs - watch for timeout"
sleep 4
touch /mnt/lustre/a/f &
-reconnect
-sleep 1
+#reconnect
+sleep 5
echo "did things recover? check for file foo and a/f"
ls -l /mnt/lustre
ls -l /mnt/lustre/a
+echo "Test 2 done"
echo
-echo "Test 4 dropped reply:" `date` "creating /mnt/lustre/foo2"
+echo "Test 3 dropped reply:" `date` "creating /mnt/lustre/foo2"
echo
rm -rf /mnt/lustre/*
echo 0x80000119 > /proc/sys/lustre/fail_loc
ps axww | grep touch
echo "MDS dropped create request -- sleep 4 secs - watch for timeout"
sleep 4
-reconnect
+# reconnect
echo failure cleared
-sleep 1
+sleep 4
echo "did things recover? check for file foo2"
ls -l /mnt/lustre
+echo "Test 3 done"
-
-exit
-
echo
-echo "Test 3: Multiple failures"
+echo "Test 4: Multiple failures"
echo
echo 0x0000107 > /proc/sys/lustre/fail_loc
touch /mnt/lustre/bar &
echo "touch program will have repeated failures sleeping 10"
sleep 10
echo 0 > /proc/sys/lustre/fail_loc
-reconnect
-sleep 1
+# reconnect
+sleep 6
echo "failure cleared"
echo "did things recover? Check for file bar"
ls -l /mnt/lustre/bar
+echo "Test 4 done"
+
+echo
+echo "Test 5: Continue writing during recovery:" `date` "creating and writing/mnt/lustre/foo"
+echo
+rm -rf /mnt/lustre/*
+./openme /mnt/lustre/foo3 &
+./writeme /mnt/lustre/iogoeson &
+sleep 1
+ls -l /mnt/lustre
+echo 0x80000107 > /proc/sys/lustre/fail_loc
+mknod /mnt/lustre/dev c 10 240 &
+echo "MDS dropped create request -- sleep 4 secs - watch for timeout"
+sleep 6
+# reconnect
+sleep 1
+echo "did things recover? check for file foo, bar, check log for reopen."
+ls -l /mnt/lustre
+echo "Test 5 done"
--- /dev/null
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+int main(int argc, char **argv)
+{
+ mode_t mode;
+
+ if (argc != 3) {
+ printf("usage: %s mode name\n", argv[0]);
+ return 1;
+ }
+
+ mode = strtoul(argv[1], NULL, 8);
+ return chmod(argv[2], mode);
+}
--- /dev/null
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <string.h>
+
+int main(int argc, char **argv)
+{
+ int rc;
+
+ if (argc != 2) {
+ printf("usage: %s name\n", argv[0]);
+ return 1;
+ }
+
+ rc = open(argv[1], O_CREAT|O_EXCL, 0644);
+ if (rc == -1)
+ printf("open failed: %s\n", strerror(errno));
+ else
+ printf("open success.\n");
+ return 0;
+}
set -vx
date
echo "ha assist checking for problems"
-sleep 3
+sleep 1
if [ ! -e /tmp/halog ]; then
echo "no problems, exiting"
exit
setup tcp
close_uuid mds
del_uuid mds
-connect dev5 1234
+connect localhost 1234
add_uuid mds
quit
EOF3