From e35da0123e9077c650a1199333989b80885676a6 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Wed, 20 Aug 2008 21:29:22 -0700 Subject: [PATCH] kclient: i_cap_snap_pending --- src/kernel/caps.c | 58 +++++++++++++++++++++++++++++++--------------- src/kernel/snap.c | 12 +++++----- src/kernel/super.h | 1 + 3 files changed, 46 insertions(+), 25 deletions(-) diff --git a/src/kernel/caps.c b/src/kernel/caps.c index b610ab759e005..dc563aaf1fd2c 100644 --- a/src/kernel/caps.c +++ b/src/kernel/caps.c @@ -527,16 +527,23 @@ void ceph_take_cap_refs(struct ceph_inode_info *ci, int got) int ceph_get_cap_refs(struct ceph_inode_info *ci, int need, int want, int *got, loff_t endoff) { + struct inode *inode = &ci->vfs_inode; int ret = 0; int have, implemented; - dout(30, "get_cap_refs on %p need %d want %d\n", &ci->vfs_inode, - need, want); - spin_lock(&ci->vfs_inode.i_lock); - if (endoff >= 0 && endoff > (loff_t)ci->i_max_size) { - dout(20, "get_cap_refs endoff %llu > max_size %llu\n", - endoff, ci->i_max_size); - goto sorry; + dout(30, "get_cap_refs %p need %d want %d\n", inode, need, want); + spin_lock(&inode->i_lock); + if (need & CEPH_CAP_WR) { + if (endoff >= 0 && endoff > (loff_t)ci->i_max_size) { + dout(20, "get_cap_refs %p endoff %llu > maxsize %llu\n", + inode, endoff, ci->i_max_size); + goto sorry; + } + if (ci->i_cap_snap_pending) { + dout(20, "get_cap_refs %p cap_snap_pending %lld\n", + inode, ci->i_cap_snap_pending); + goto sorry; + } } have = __ceph_caps_issued(ci, &implemented); if ((have & need) == need) { @@ -548,27 +555,30 @@ int ceph_get_cap_refs(struct ceph_inode_info *ci, int need, int want, int *got, */ int not = want & ~(have & need); int revoking = implemented & ~have; - dout(30, "get_cap_refs have %d but not %d (revoking %d)\n", - have, not, revoking); + dout(30, "get_cap_refs %p have %d but not %d (revoking %d)\n", + inode, have, not, revoking); if ((revoking & not) == 0) { *got = need | (have & want); __take_cap_refs(ci, *got); ret = 1; } } else - dout(30, "get_cap_refs have %d needed %d\n", have, need); + dout(30, "get_cap_refs %p have %d needed %d\n", inode, + have, need); sorry: - spin_unlock(&ci->vfs_inode.i_lock); - dout(30, "get_cap_refs on %p ret %d got %d\n", &ci->vfs_inode, + spin_unlock(&inode->i_lock); + dout(30, "get_cap_refs %p ret %d got %d\n", inode, ret, *got); return ret; } void ceph_put_cap_refs(struct ceph_inode_info *ci, int had) { - int last = 0; + struct inode *inode = &ci->vfs_inode; + int last = 0, wake = 0; + u64 seq; - spin_lock(&ci->vfs_inode.i_lock); + spin_lock(&inode->i_lock); if (had & CEPH_CAP_RD) if (--ci->i_rd_ref == 0) last++; @@ -576,22 +586,32 @@ void ceph_put_cap_refs(struct ceph_inode_info *ci, int had) if (--ci->i_rdcache_ref == 0) last++; if (had & CEPH_CAP_WR) - if (--ci->i_wr_ref == 0) + if (--ci->i_wr_ref == 0) { last++; + if (ci->i_cap_snap_pending) { + dout(30, "put_cap_refs %p cap_snap_pending\n", + inode); + seq = ci->i_cap_snap_pending; + ci->i_cap_snap_pending = 0; + ceph_queue_cap_snap(ci, seq); + wake = 1; + } + } if (had & CEPH_CAP_WRBUFFER) { if (atomic_dec_and_test(&ci->i_wrbuffer_ref)) last++; dout(30, "put_cap_refs %p wrbuffer %d -> %d (?)\n", - &ci->vfs_inode, atomic_read(&ci->i_wrbuffer_ref)+1, + inode, atomic_read(&ci->i_wrbuffer_ref)+1, atomic_read(&ci->i_wrbuffer_ref)); } - spin_unlock(&ci->vfs_inode.i_lock); + spin_unlock(&inode->i_lock); - dout(30, "put_cap_refs on %p had %d %s\n", &ci->vfs_inode, had, - last ? "last":""); + dout(30, "put_cap_refs %p had %d %s\n", inode, had, last ? "last":""); if (last) ceph_check_caps(ci, 0); + if (wake) + wake_up(&ci->i_cap_wq); } void ceph_put_wrbuffer_cap_refs(struct ceph_inode_info *ci, int nr) diff --git a/src/kernel/snap.c b/src/kernel/snap.c index a2036989d4149..fc3277ce42312 100644 --- a/src/kernel/snap.c +++ b/src/kernel/snap.c @@ -187,7 +187,7 @@ static int dup_array(u64 **dst, u64 *src, int num) } -static void queue_cap_snap(struct ceph_inode_info *ci, u64 seq) +void ceph_queue_cap_snap(struct ceph_inode_info *ci, u64 seq) { struct inode *inode = &ci->vfs_inode; int used; @@ -218,7 +218,8 @@ static void queue_cap_snap(struct ceph_inode_info *ci, u64 seq) capsnap->mtime = inode->i_mtime; capsnap->atime = inode->i_atime; capsnap->ctime = inode->i_ctime; - if (used & CEPH_CAP_WRBUFFER) { + /* FIXME disabled for now, until snap-ordered writeback works */ + if (false && (used & CEPH_CAP_WRBUFFER)) { dout(10, "queue_cap_snap %p seq %llu used WRBUFFER," " delaying\n", inode, seq); capsnap->flushing = 1; @@ -226,10 +227,9 @@ static void queue_cap_snap(struct ceph_inode_info *ci, u64 seq) capsnap->flushing = 0; __ceph_flush_snaps(ci); } - list_add(&capsnap->ci_item, &ci->i_snap_caps); + list_add(&capsnap->ci_item, &ci->i_cap_snaps); } -out: spin_unlock(&inode->i_lock); } @@ -273,7 +273,7 @@ more: struct ceph_inode_info *ci = list_entry(p, struct ceph_inode_info, i_snap_realm_item); - queue_cap_snap(ci, realm->cached_context->seq); + ceph_queue_cap_snap(ci, realm->cached_context->seq); } dout(20, "update_snap_trace cap flush done\n"); @@ -417,7 +417,7 @@ void ceph_handle_snap(struct ceph_mds_client *mdsc, list_del_init(&ci->i_snap_realm_item); spin_unlock(&inode->i_lock); - queue_cap_snap(ci, + ceph_queue_cap_snap(ci, ci->i_snap_realm->cached_context->seq); iput(inode); diff --git a/src/kernel/super.h b/src/kernel/super.h index f04eaed2b7e07..ff0307c55d66e 100644 --- a/src/kernel/super.h +++ b/src/kernel/super.h @@ -512,6 +512,7 @@ extern struct ceph_snap_realm *ceph_update_snap_trace(struct ceph_mds_client *m, int must_flush); extern void ceph_handle_snap(struct ceph_mds_client *mdsc, struct ceph_msg *msg); +extern void ceph_queue_cap_snap(struct ceph_inode_info *ci, u64 seq); /* -- 2.39.5