From 26901950d3263722df4824a60770e69d559eb425 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Tue, 15 Apr 2008 19:41:27 -0700 Subject: [PATCH] kclient: invalidate pages outside i_lock; carry inode ref for delayed work --- src/kernel/dir.c | 2 ++ src/kernel/inode.c | 52 ++++++++++++++++++++++++----------------- src/kernel/mds_client.c | 6 ++--- src/kernel/super.c | 5 ++-- src/psim.cc | 2 +- 5 files changed, 39 insertions(+), 28 deletions(-) diff --git a/src/kernel/dir.c b/src/kernel/dir.c index 7689bf7431650..d5e5a90ca2671 100644 --- a/src/kernel/dir.c +++ b/src/kernel/dir.c @@ -511,6 +511,8 @@ static int ceph_dentry_revalidate(struct dentry *dentry, struct nameidata *nd) { struct inode *dir = dentry->d_parent->d_inode; + dout(10, "nd flags %d chdir=%d\n", nd->flags, nd->flags & LOOKUP_CHDIR); + if (ceph_inode_lease_valid(dir, CEPH_LOCK_ICONTENT)) { dout(20, "dentry_revalidate %p have ICONTENT on dir inode %p\n", dentry, dir); diff --git a/src/kernel/inode.c b/src/kernel/inode.c index 9daee6381b840..0c3905ddb42ef 100644 --- a/src/kernel/inode.c +++ b/src/kernel/inode.c @@ -763,15 +763,19 @@ void ceph_cap_delayed_work(struct work_struct *work) i_cap_dwork.work); spin_lock(&ci->vfs_inode.i_lock); if (ci->i_hold_caps_until > jiffies) { - dout(10, "cap_dwork on %p -- rescheduling\n", &ci->vfs_inode); - schedule_delayed_work(&ci->i_cap_dwork, - ci->i_hold_caps_until - jiffies); + dout(-10, "cap_dwork on %p -- rescheduling\n", &ci->vfs_inode); + if (schedule_delayed_work(&ci->i_cap_dwork, + ci->i_hold_caps_until - jiffies)) + igrab(&ci->vfs_inode); spin_unlock(&ci->vfs_inode.i_lock); - return; + goto out; } - dout(10, "cap_dwork on %p\n", &ci->vfs_inode); + dout(-10, "cap_dwork on %p\n", &ci->vfs_inode); spin_unlock(&ci->vfs_inode.i_lock); ceph_check_caps(ci, 0); +out: + iput(&ci->vfs_inode); + dout(-10, "cap_dwork on %p done\n", &ci->vfs_inode); } /* @@ -783,6 +787,7 @@ void ceph_check_caps(struct ceph_inode_info *ci, int was_last) { struct ceph_client *client = ceph_inode_to_client(&ci->vfs_inode); struct ceph_mds_client *mdsc = &client->mdsc; + struct inode *inode = &ci->vfs_inode; struct ceph_inode_cap *cap; struct list_head *p; int wanted, used; @@ -794,10 +799,10 @@ void ceph_check_caps(struct ceph_inode_info *ci, int was_last) struct ceph_mds_session *session = 0; /* if non-NULL, i hold s_mutex */ retry: - spin_lock(&ci->vfs_inode.i_lock); + spin_lock(&inode->i_lock); wanted = __ceph_caps_wanted(ci); used = __ceph_caps_used(ci); - dout(10, "check_caps %p wanted %d used %d issued %d\n", &ci->vfs_inode, + dout(10, "check_caps %p wanted %d used %d issued %d\n", inode, wanted, used, __ceph_caps_issued(ci)); if (was_last) { @@ -805,8 +810,9 @@ retry: if (until > ci->i_hold_caps_until) { ci->i_hold_caps_until = until; dout(10, "hold_caps_until %lu\n", until); - schedule_delayed_work(&ci->i_cap_dwork, - until - jiffies); + if (schedule_delayed_work(&ci->i_cap_dwork, + until - jiffies)) + igrab(inode); } } @@ -830,7 +836,7 @@ retry: /* approaching file_max? */ if ((cap->issued & CEPH_CAP_WR) && - (ci->vfs_inode.i_size << 1) >= ci->i_max_size && + (inode->i_size << 1) >= ci->i_max_size && (ci->i_reported_size << 1) < ci->i_max_size) { dout(10, "i_size approaching max_size\n"); goto ack; @@ -856,7 +862,7 @@ retry: session = cap->session; if (down_trylock(&session->s_mutex) != 0) { dout(10, "inverting session/inode locking\n"); - spin_unlock(&ci->vfs_inode.i_lock); + spin_unlock(&inode->i_lock); down(&session->s_mutex); goto retry; } @@ -864,10 +870,6 @@ retry: /* ok */ dropping = cap->issued & ~wanted; - if (dropping & CEPH_CAP_RDCACHE) { - dout(20, "invalidating pages on %p\n", &ci->vfs_inode); - invalidate_mapping_pages(&ci->vfs_inode.i_data, 0, -1); - } cap->issued &= wanted; /* drop bits we don't want */ if (revoking && (revoking && used) == 0) @@ -875,29 +877,35 @@ retry: keep = cap->issued; seq = cap->seq; - size = ci->vfs_inode.i_size; + size = inode->i_size; ci->i_reported_size = size; max_size = ci->i_wanted_max_size; ci->i_requested_max_size = max_size; - mtime = ci->vfs_inode.i_mtime; - atime = ci->vfs_inode.i_atime; + mtime = inode->i_mtime; + atime = inode->i_atime; mds = cap->mds; if (wanted == 0) __ceph_remove_cap(cap); - spin_unlock(&ci->vfs_inode.i_lock); + spin_unlock(&inode->i_lock); - ceph_mdsc_send_cap_ack(mdsc, ceph_ino(&ci->vfs_inode), + if (dropping & CEPH_CAP_RDCACHE) { + dout(20, "invalidating pages on %p\n", inode); + invalidate_mapping_pages(&inode->i_data, 0, -1); + dout(20, "done invalidating pages on %p\n", inode); + } + + ceph_mdsc_send_cap_ack(mdsc, ceph_ino(inode), keep, wanted, seq, size, max_size, &mtime, &atime, mds); if (wanted == 0) - iput(&ci->vfs_inode); /* removed cap */ + iput(inode); /* removed cap */ up(&session->s_mutex); goto retry; } /* okay */ - spin_unlock(&ci->vfs_inode.i_lock); + spin_unlock(&inode->i_lock); if (session) up(&session->s_mutex); diff --git a/src/kernel/mds_client.c b/src/kernel/mds_client.c index 5ca332b0a16c9..3403b56689bbd 100644 --- a/src/kernel/mds_client.c +++ b/src/kernel/mds_client.c @@ -656,7 +656,7 @@ void ceph_mdsc_handle_session(struct ceph_mds_client *mdsc, session = __get_session(mdsc, mds); down(&session->s_mutex); - dout(1, "handle_session %p op %d seq %llu\n", session, op, seq); + dout(-1, "handle_session %p op %d seq %llu\n", session, op, seq); switch (op) { case CEPH_SESSION_OPEN: dout(1, "session open from mds%d\n", mds); @@ -1542,7 +1542,7 @@ void schedule_delayed(struct ceph_mds_client *mdsc) int delay = mdsc->mdsmap->m_cap_bit_timeout >> 1; unsigned hz = round_jiffies_relative(HZ * delay); int r; - dout(10, "schedule_delayed for %d seconds (%u hz)\n", delay, hz); + dout(-10, "schedule_delayed for %d seconds (%u hz)\n", delay, hz); r = schedule_delayed_work(&mdsc->delayed_work, hz); } @@ -1552,7 +1552,7 @@ void delayed_work(struct work_struct *work) struct ceph_mds_client *mdsc = container_of(work, struct ceph_mds_client, delayed_work.work); - dout(10, "delayed_work on %p\n", mdsc); + dout(-10, "delayed_work on %p\n", mdsc); /* renew caps */ spin_lock(&mdsc->lock); diff --git a/src/kernel/super.c b/src/kernel/super.c index b2b651879a31b..0627352302e03 100644 --- a/src/kernel/super.c +++ b/src/kernel/super.c @@ -163,8 +163,9 @@ static struct inode *ceph_alloc_inode(struct super_block *sb) static void ceph_destroy_inode(struct inode *inode) { struct ceph_inode_info *ci = ceph_inode(inode); - dout(30, "destroy_inode %p ino %llx\n", inode, ceph_ino(inode)); - cancel_delayed_work_sync(&ci->i_cap_dwork); + dout(-30, "destroy_inode %p ino %llx\n", inode, ceph_ino(inode)); + if (cancel_delayed_work_sync(&ci->i_cap_dwork)) + iput(inode); kfree(ci->i_symlink); kmem_cache_free(ceph_inode_cachep, ci); } diff --git a/src/psim.cc b/src/psim.cc index deab7c8aa0dd0..b21610db00dbe 100644 --- a/src/psim.cc +++ b/src/psim.cc @@ -25,7 +25,7 @@ int main() count[i] = 0; } - for (int f = 1; f < 1000; f++) { // files + for (int f = 1; f < 10000; f++) { // files for (int b = 0; b < 4; b++) { // blocks object_t oid(f, b); //cout << "oid " << oid << std::endl; -- 2.39.5