Whamcloud - gitweb
Lproc-snmp code drop
[fs/lustre-release.git] / lustre / mdc / mdc_request.c
index 4478db2..4b5f6b2 100644 (file)
 #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;
@@ -61,13 +63,11 @@ int mdc_getstatus(struct lustre_handle *conn, struct ll_fid *rootfid,
                 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;
@@ -155,21 +155,44 @@ int mdc_getattr(struct lustre_handle *conn,
         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);
@@ -179,16 +202,24 @@ static int mdc_blocking_ast(struct ldlm_lock *lock, struct ldlm_lock_desc *desc,
                         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();
         }
@@ -253,7 +284,8 @@ static void fixup_req_for_recreate(struct ptlrpc_request *fixreq,
         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;
                 }
@@ -316,11 +348,13 @@ static void mdc_replay_create(struct ptlrpc_request *req)
         /* 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 */
@@ -373,9 +407,9 @@ int mdc_enqueue(struct lustre_handle *conn, int lock_type,
 {
         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};
@@ -542,6 +576,15 @@ int mdc_enqueue(struct lustre_handle *conn, int lock_type,
         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;
 };
@@ -708,8 +751,7 @@ int mdc_readpage(struct lustre_handle *conn, obd_id ino, int type, __u64 offset,
         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);
@@ -718,7 +760,8 @@ int mdc_statfs(struct lustre_handle *conn, struct obd_statfs *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);
@@ -731,26 +774,52 @@ int mdc_statfs(struct lustre_handle *conn, struct obd_statfs *osfs,
 
         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>");
@@ -760,8 +829,8 @@ MODULE_LICENSE("GPL");
 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);