]> bbs.cooldavid.org Git - net-next-2.6.git/blobdiff - fs/ceph/mds_client.c
ceph: release cap on import if we don't have the inode
[net-next-2.6.git] / fs / ceph / mds_client.c
index 885aa5710cfd541997fa9764dffba33b0e8ad644..d28b6a9c0f96800210e2051e54cbe37b0af81334 100644 (file)
@@ -1176,8 +1176,8 @@ static int check_cap_flush(struct ceph_mds_client *mdsc, u64 want_flush_seq)
 /*
  * called under s_mutex
  */
-static void send_cap_releases(struct ceph_mds_client *mdsc,
-                      struct ceph_mds_session *session)
+void ceph_send_cap_releases(struct ceph_mds_client *mdsc,
+                           struct ceph_mds_session *session)
 {
        struct ceph_msg *msg;
 
@@ -1768,12 +1768,12 @@ int ceph_mdsc_do_request(struct ceph_mds_client *mdsc,
        mutex_unlock(&mdsc->mutex);
        dout("do_request waiting\n");
        if (req->r_timeout) {
-               err = (long)wait_for_completion_interruptible_timeout(
+               err = (long)wait_for_completion_killable_timeout(
                        &req->r_completion, req->r_timeout);
                if (err == 0)
                        err = -EIO;
        } else {
-               err = wait_for_completion_interruptible(&req->r_completion);
+               err = wait_for_completion_killable(&req->r_completion);
        }
        dout("do_request waited, got %d\n", err);
        mutex_lock(&mdsc->mutex);
@@ -2014,16 +2014,21 @@ static void handle_forward(struct ceph_mds_client *mdsc,
        mutex_lock(&mdsc->mutex);
        req = __lookup_request(mdsc, tid);
        if (!req) {
-               dout("forward %llu to mds%d - req dne\n", tid, next_mds);
+               dout("forward tid %llu to mds%d - req dne\n", tid, next_mds);
                goto out;  /* dup reply? */
        }
 
-       if (fwd_seq <= req->r_num_fwd) {
-               dout("forward %llu to mds%d - old seq %d <= %d\n",
+       if (req->r_aborted) {
+               dout("forward tid %llu aborted, unregistering\n", tid);
+               __unregister_request(mdsc, req);
+       } else if (fwd_seq <= req->r_num_fwd) {
+               dout("forward tid %llu to mds%d - old seq %d <= %d\n",
                     tid, next_mds, req->r_num_fwd, fwd_seq);
        } else {
                /* resend. forward race not possible; mds would drop */
-               dout("forward %llu to mds%d (we resend)\n", tid, next_mds);
+               dout("forward tid %llu to mds%d (we resend)\n", tid, next_mds);
+               BUG_ON(req->r_err);
+               BUG_ON(req->r_got_result);
                req->r_num_fwd = fwd_seq;
                req->r_resend_mds = next_mds;
                put_request_session(req);
@@ -2428,6 +2433,7 @@ static void handle_lease(struct ceph_mds_client *mdsc,
        struct ceph_dentry_info *di;
        int mds = session->s_mds;
        struct ceph_mds_lease *h = msg->front.iov_base;
+       u32 seq;
        struct ceph_vino vino;
        int mask;
        struct qstr dname;
@@ -2441,6 +2447,7 @@ static void handle_lease(struct ceph_mds_client *mdsc,
        vino.ino = le64_to_cpu(h->ino);
        vino.snap = CEPH_NOSNAP;
        mask = le16_to_cpu(h->mask);
+       seq = le32_to_cpu(h->seq);
        dname.name = (void *)h + sizeof(*h) + sizeof(u32);
        dname.len = msg->front.iov_len - sizeof(*h) - sizeof(u32);
        if (dname.len != get_unaligned_le32(h+1))
@@ -2451,8 +2458,9 @@ static void handle_lease(struct ceph_mds_client *mdsc,
 
        /* lookup inode */
        inode = ceph_find_inode(sb, vino);
-       dout("handle_lease '%s', mask %d, ino %llx %p\n",
-            ceph_lease_op_name(h->action), mask, vino.ino, inode);
+       dout("handle_lease %s, mask %d, ino %llx %p %.*s\n",
+            ceph_lease_op_name(h->action), mask, vino.ino, inode,
+            dname.len, dname.name);
        if (inode == NULL) {
                dout("handle_lease no inode %llx\n", vino.ino);
                goto release;
@@ -2477,7 +2485,8 @@ static void handle_lease(struct ceph_mds_client *mdsc,
        switch (h->action) {
        case CEPH_MDS_LEASE_REVOKE:
                if (di && di->lease_session == session) {
-                       h->seq = cpu_to_le32(di->lease_seq);
+                       if (ceph_seq_cmp(di->lease_seq, seq) > 0)
+                               h->seq = cpu_to_le32(di->lease_seq);
                        __ceph_mdsc_drop_dentry_lease(dentry);
                }
                release = 1;
@@ -2491,7 +2500,7 @@ static void handle_lease(struct ceph_mds_client *mdsc,
                        unsigned long duration =
                                le32_to_cpu(h->duration_ms) * HZ / 1000;
 
-                       di->lease_seq = le32_to_cpu(h->seq);
+                       di->lease_seq = seq;
                        dentry->d_time = di->lease_renew_from + duration;
                        di->lease_renew_after = di->lease_renew_from +
                                (duration >> 1);
@@ -2541,7 +2550,7 @@ void ceph_mdsc_lease_send_msg(struct ceph_mds_session *session,
                return;
        lease = msg->front.iov_base;
        lease->action = action;
-       lease->mask = cpu_to_le16(CEPH_LOCK_DN);
+       lease->mask = cpu_to_le16(1);
        lease->ino = cpu_to_le64(ceph_vino(inode).ino);
        lease->first = lease->last = cpu_to_le64(ceph_vino(inode).snap);
        lease->seq = cpu_to_le32(seq);
@@ -2571,7 +2580,7 @@ void ceph_mdsc_lease_release(struct ceph_mds_client *mdsc, struct inode *inode,
 
        BUG_ON(inode == NULL);
        BUG_ON(dentry == NULL);
-       BUG_ON(mask != CEPH_LOCK_DN);
+       BUG_ON(mask == 0);
 
        /* is dentry lease valid? */
        spin_lock(&dentry->d_lock);
@@ -2684,7 +2693,7 @@ static void delayed_work(struct work_struct *work)
                add_cap_releases(mdsc, s, -1);
                if (s->s_state == CEPH_MDS_SESSION_OPEN ||
                    s->s_state == CEPH_MDS_SESSION_HUNG)
-                       send_cap_releases(mdsc, s);
+                       ceph_send_cap_releases(mdsc, s);
                mutex_unlock(&s->s_mutex);
                ceph_put_mds_session(s);