From: Sage Weil Date: Wed, 29 Jul 2009 22:52:41 +0000 (-0700) Subject: kclient: maintain list of flushing snaps; reflush after reconnect X-Git-Tag: v0.12~42 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=2c6606d315bcae465582e3e2841eeab40505f3c4;p=ceph.git kclient: maintain list of flushing snaps; reflush after reconnect --- diff --git a/src/kernel/caps.c b/src/kernel/caps.c index de6be4df62b5..933e34c2c3c2 100644 --- a/src/kernel/caps.c +++ b/src/kernel/caps.c @@ -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; diff --git a/src/kernel/mds_client.c b/src/kernel/mds_client.c index 6c2c290757a0..337a9bdc4094 100644 --- a/src/kernel/mds_client.c +++ b/src/kernel/mds_client.c @@ -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); diff --git a/src/kernel/mds_client.h b/src/kernel/mds_client.h index fa294df93917..a8f8deee9208 100644 --- a/src/kernel/mds_client.h +++ b/src/kernel/mds_client.h @@ -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 */ diff --git a/src/kernel/snap.c b/src/kernel/snap.c index b349612ea94d..ffc7b493392e 100644 --- a/src/kernel/snap.c +++ b/src/kernel/snap.c @@ -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); diff --git a/src/kernel/super.h b/src/kernel/super.h index 07d6aa41d4fe..6de97adc8a66 100644 --- a/src/kernel/super.h +++ b/src/kernel/super.h @@ -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;