#include <linux/lustre_dlm.h>
#include <linux/init.h>
#include <linux/obd_lov.h>
+#include <linux/lprocfs_status.h>
#define REQUEST_MINOR 244
extern int mds_queue_req(struct ptlrpc_request *);
+extern lprocfs_vars_t status_var_nm_1[];
+extern lprocfs_vars_t status_class_var[];
-int mdc_getstatus(struct lustre_handle *conn, struct ll_fid *rootfid,
- __u64 *last_committed, __u64 *last_xid,
- struct ptlrpc_request **request)
+/* should become mdc_getinfo() */
+int mdc_getstatus(struct lustre_handle *conn, struct ll_fid *rootfid)
{
struct ptlrpc_request *req;
struct mds_body *body;
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_xid = req->rq_repmsg->last_xid;
- CDEBUG(D_NET,"root ino=%ld, last_committed=%Lu, last_xid=%Ld\n",
- (unsigned long)rootfid->id,
- (unsigned long long)*last_committed,
- (unsigned long long)*last_xid);
+ CDEBUG(D_NET, "root ino="LPU64", last_committed="LPU64
+ ", last_xid="LPU64"\n",
+ rootfid->id, req->rq_repmsg->last_committed,
+ req->rq_repmsg->last_xid);
}
EXIT;
return rc;
}
+static void d_delete_aliases(struct inode *inode)
+{
+ struct dentry *dentry = NULL;
+ struct list_head *tmp;
+ int dentry_count = 0;
+ ENTRY;
+
+ spin_lock(&dcache_lock);
+ list_for_each(tmp, &inode->i_dentry) {
+ dentry = list_entry(tmp, struct dentry, d_alias);
+ dentry_count++;
+ }
+
+ /* XXX FIXME tell phil/peter that you see this -- unless you're playing
+ * with hard links, in which case, stop. */
+ LASSERT(dentry_count <= 1);
+
+ if (dentry_count == 0) {
+ spin_unlock(&dcache_lock);
+ EXIT;
+ return;
+ }
+
+ CDEBUG(D_INODE, "d_deleting dentry %p\n", dentry);
+ dget_locked(dentry);
+ spin_unlock(&dcache_lock);
+ d_delete(dentry);
+ dput(dentry);
+ EXIT;
+}
+
static int mdc_blocking_ast(struct ldlm_lock *lock, struct ldlm_lock_desc *desc,
void *data, __u32 data_len, int flag)
{
int rc;
- struct inode *inode = data;
struct lustre_handle lockh;
ENTRY;
- if (data_len != sizeof(*inode)) {
- CERROR("data_len should be %d, but is %d\n", sizeof(*inode),
- data_len);
- LBUG();
- RETURN(-EINVAL);
- }
-
switch (flag) {
case LDLM_CB_BLOCKING:
ldlm_lock2handle(lock, &lockh);
RETURN(rc);
}
break;
- case LDLM_CB_CANCELING:
- /* FIXME: do something better than throwing away everything */
- if (inode == NULL)
- LBUG();
+ case LDLM_CB_CANCELING: {
+ /* Invalidate all dentries associated with this inode */
+ struct inode *inode = data;
+
+ LASSERT(inode != NULL);
+ LASSERT(data_len == sizeof(*inode));
+
if (S_ISDIR(inode->i_mode)) {
CDEBUG(D_INODE, "invalidating inode %ld\n",
inode->i_ino);
ll_invalidate_inode_pages(inode);
}
+
+ LASSERT(igrab(inode) == inode);
+ d_delete_aliases(inode);
+ iput(inode);
break;
+ }
default:
LBUG();
}
if (fixreq->rq_reqmsg->opc == LDLM_ENQUEUE) {
lockreq = lustre_msg_buf(fixreq->rq_reqmsg, 0);
- if (lockreq->lock_desc.l_resource.lr_type != LDLM_MDSINTENT) {
+ if (lockreq->lock_desc.l_resource.lr_type != LDLM_PLAIN &&
+ !(lockreq->lock_flags & LDLM_FL_HAS_INTENT)) {
DEBUG_REQ(D_HA, fixreq, "non-intent lock, skipping");
return;
}
/* XXX cargo-culted right out of ll_iget */
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
inode = iget4(saved->sb, body->fid1.id, create_replay_find_inode, req);
-#else
+#endif
+#if 0
{
extern int ll_read_inode2(struct inode *inode, void *opaque);
inode = iget5_locked(saved->sb, body->fid1.id,
- create_replay_find_inode, req);
+ create_replay_find_inode,
+ ll_read_inode2, req);
if (!inode)
LBUG(); /* XXX ick */
{
struct ptlrpc_request *req;
struct obd_device *obddev = class_conn2obd(conn);
- __u64 res_id[RES_NAME_SIZE] = {dir->i_ino};
+ __u64 res_id[RES_NAME_SIZE] = {dir->i_ino, (__u64)dir->i_generation};
int size[6] = {sizeof(struct ldlm_request), sizeof(struct ldlm_intent)};
- int rc, flags = 0;
+ int rc, flags = LDLM_FL_HAS_INTENT;
int repsize[3] = {sizeof(struct ldlm_reply),
sizeof(struct mds_body),
obddev->u.cli.cl_max_mds_easize};
RETURN(0);
}
+int mdc_cancel_unused(struct lustre_handle *conn, struct inode *inode,
+ int flags)
+{
+ __u64 res_id[RES_NAME_SIZE] = {inode->i_ino, inode->i_generation};
+ struct obd_device *obddev = class_conn2obd(conn);
+ ENTRY;
+ RETURN(ldlm_cli_cancel_unused(obddev->obd_namespace, res_id, flags));
+}
+
struct replay_open_data {
struct lustre_handle *fh;
};
return rc;
}
-int mdc_statfs(struct lustre_handle *conn, struct obd_statfs *osfs,
- struct ptlrpc_request **request)
+static int mdc_statfs(struct lustre_handle *conn, struct obd_statfs *osfs)
{
struct ptlrpc_request *req;
int rc, size = sizeof(*osfs);
req = ptlrpc_prep_req(class_conn2cliimp(conn), MDS_STATFS, 0, NULL,
NULL);
if (!req)
- GOTO(out, rc = -ENOMEM);
+ RETURN(-ENOMEM);
+
req->rq_replen = lustre_msg_size(1, &size);
rc = ptlrpc_queue_wait(req);
EXIT;
out:
- *request = req;
+ ptlrpc_req_finished(req);
return rc;
}
+int mdc_attach(struct obd_device *dev,
+ obd_count len, void *data)
+{
+ int rc;
+ rc = lprocfs_reg_obd(dev, (lprocfs_vars_t*)status_var_nm_1, (void*)dev);
+ return rc;
+}
+
+int mdc_detach(struct obd_device *dev)
+{
+ int rc;
+ rc = lprocfs_dereg_obd(dev);
+ return rc;
+}
struct obd_ops mdc_obd_ops = {
+ o_attach: mdc_attach,
+ o_detach: mdc_detach,
o_setup: client_obd_setup,
o_cleanup: client_obd_cleanup,
o_connect: client_obd_connect,
o_disconnect: client_obd_disconnect,
+ o_statfs: mdc_statfs,
};
static int __init ptlrpc_request_init(void)
{
- return class_register_type(&mdc_obd_ops, LUSTRE_MDC_NAME);
+ int rc;
+ rc = class_register_type(&mdc_obd_ops,
+ (lprocfs_vars_t*)status_class_var,
+ LUSTRE_MDC_NAME);
+ if(rc)
+ RETURN(rc);
+ return 0;
+
}
static void __exit ptlrpc_request_exit(void)
{
+
class_unregister_type(LUSTRE_MDC_NAME);
+
}
MODULE_AUTHOR("Cluster File Systems <info@clusterfs.com>");
EXPORT_SYMBOL(mdc_getstatus);
EXPORT_SYMBOL(mdc_getlovinfo);
EXPORT_SYMBOL(mdc_enqueue);
+EXPORT_SYMBOL(mdc_cancel_unused);
EXPORT_SYMBOL(mdc_getattr);
-EXPORT_SYMBOL(mdc_statfs);
EXPORT_SYMBOL(mdc_create);
EXPORT_SYMBOL(mdc_unlink);
EXPORT_SYMBOL(mdc_rename);