]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
kclient: maintain list of flushing snaps; reflush after reconnect
authorSage Weil <sage@newdream.net>
Wed, 29 Jul 2009 22:52:41 +0000 (15:52 -0700)
committerSage Weil <sage@newdream.net>
Thu, 30 Jul 2009 22:25:02 +0000 (15:25 -0700)
src/kernel/caps.c
src/kernel/mds_client.c
src/kernel/mds_client.h
src/kernel/snap.c
src/kernel/super.h

index de6be4df62b55c3c2c3ef515b8213c062c19d8b9..933e34c2c3c2152debdff2862423feabe8bc8b91 100644 (file)
@@ -1161,6 +1161,10 @@ retry:
 
                capsnap->flush_tid = ++session->s_cap_flush_tid;
                atomic_inc(&capsnap->nref);
+               if (!list_empty(&capsnap->flushing_item))
+                       list_del_init(&capsnap->flushing_item);
+               list_add_tail(&capsnap->flushing_item,
+                             &session->s_cap_snaps_flushing);
                spin_unlock(&inode->i_lock);
 
                dout("flush_snaps %p cap_snap %p follows %lld size %llu\n",
@@ -1609,8 +1613,28 @@ void ceph_kick_flushing_caps(struct ceph_mds_client *mdsc,
                             struct ceph_mds_session *session)
 {
        struct ceph_inode_info *ci;
+       struct ceph_cap_snap *capsnap;
 
        dout("kick_flushing_caps mds%d\n", session->s_mds);
+       list_for_each_entry(capsnap, &session->s_cap_snaps_flushing,
+                           flushing_item) {
+               struct ceph_inode_info *ci = capsnap->ci;
+               struct inode *inode = &ci->vfs_inode;
+               struct ceph_cap *cap;
+
+               spin_lock(&inode->i_lock);
+               cap = ci->i_auth_cap;
+               if (cap && cap->session == session) {
+                       dout("kick_flushing_caps %p cap %p capsnap %p\n", inode,
+                            cap, capsnap);
+                       __ceph_flush_snaps(ci, &session);
+               } else {
+                       pr_err("ceph %p auth cap %p not mds%d ???\n", inode,
+                              cap, session->s_mds);
+                       spin_unlock(&inode->i_lock);
+               }
+       }
+
        list_for_each_entry(ci, &session->s_cap_flushing, i_flushing_item) {
                struct inode *inode = &ci->vfs_inode;
                struct ceph_cap *cap;
@@ -2229,6 +2253,7 @@ static void handle_cap_flushsnap_ack(struct inode *inode,
                             capsnap, follows);
                        ceph_put_snap_context(capsnap->context);
                        list_del(&capsnap->ci_item);
+                       list_del(&capsnap->flushing_item);
                        ceph_put_cap_snap(capsnap);
                        drop = 1;
                        break;
index 6c2c290757a0100c0a45c9f75491d7c3be18e34f..337a9bdc40948c03992f0b38bef8137606e257f7 100644 (file)
@@ -335,6 +335,7 @@ static struct ceph_mds_session *register_session(struct ceph_mds_client *mdsc,
        INIT_LIST_HEAD(&s->s_cap_releases);
        INIT_LIST_HEAD(&s->s_cap_releases_done);
        INIT_LIST_HEAD(&s->s_cap_flushing);
+       INIT_LIST_HEAD(&s->s_cap_snaps_flushing);
        s->s_cap_flush_tid = 0;
 
        dout("register_session mds%d\n", mds);
index fa294df93917664aebe80cfca5ff344dce5bae8e..a8f8deee92084fc3f151149fc0dd0c59ff00d811 100644 (file)
@@ -107,6 +107,7 @@ struct ceph_mds_session {
 
        /* protected by mutex */
        struct list_head  s_cap_flushing;     /* inodes w/ flushing caps */
+       struct list_head  s_cap_snaps_flushing;
        u64               s_cap_flush_tid;
        unsigned long     s_renew_requested; /* last time we sent a renew req */
 
index b349612ea94df24ee30491f67aa6cd2d7d251c7b..ffc7b493392ec75f80a3c7c89802b333fb128832 100644 (file)
@@ -414,7 +414,6 @@ void ceph_queue_cap_snap(struct ceph_inode_info *ci,
                pr_err("ceph ENOMEM allocating ceph_cap_snap on %p\n", inode);
                return;
        }
-       atomic_set(&capsnap->nref, 1);
 
        spin_lock(&inode->i_lock);
        used = __ceph_caps_used(ci);
@@ -428,6 +427,12 @@ void ceph_queue_cap_snap(struct ceph_inode_info *ci,
                kfree(capsnap);
        } else if (ci->i_wrbuffer_ref_head || (used & CEPH_CAP_FILE_WR)) {
                igrab(inode);
+
+               atomic_set(&capsnap->nref, 1);
+               capsnap->ci = ci;
+               INIT_LIST_HEAD(&capsnap->ci_item);
+               INIT_LIST_HEAD(&capsnap->flushing_item);
+
                capsnap->follows = snapc->seq - 1;
                capsnap->context = ceph_get_snap_context(snapc);
                capsnap->issued = __ceph_caps_issued(ci, NULL);
index 07d6aa41d4fe285870b1eae645a063118ef2aed3..6de97adc8a66dd47730f15d5f897975af359086d 100644 (file)
@@ -183,8 +183,9 @@ struct ceph_cap {
  */
 struct ceph_cap_snap {
        atomic_t nref;
+       struct ceph_inode_info *ci;
+       struct list_head ci_item, flushing_item;
 
-       struct list_head ci_item;
        u64 follows, flush_tid;
        int issued, dirty;
        struct ceph_snap_context *context;