From 9ebccd494cbceb507b3f0e4728355b76a9b40d6d Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Tue, 24 Mar 2009 11:18:52 -0700 Subject: [PATCH] kclient: locally open file based on what MDS thinks we want, not what we still want As long as we have our interest in the caps still registered with the MDS, we can do a local open. Checking what we currently still want is only helpful if the same file still is open by another process or something. Now, we can do a local open on a close + wait + reopen, as long as we haven't done a cap release yet. --- src/kernel/caps.c | 18 ++++++++++++++++++ src/kernel/file.c | 8 ++++---- src/kernel/super.h | 3 +++ 3 files changed, 25 insertions(+), 4 deletions(-) diff --git a/src/kernel/caps.c b/src/kernel/caps.c index 88415e449e8bb..81afbb0442647 100644 --- a/src/kernel/caps.c +++ b/src/kernel/caps.c @@ -488,6 +488,24 @@ int ceph_caps_revoking(struct ceph_inode_info *ci, int mask) return ret; } +/* + * Return caps we have registered with the MDS(s) as wanted. + */ +int __ceph_caps_mds_wanted(struct ceph_inode_info *ci) +{ + struct ceph_cap *cap; + struct rb_node *p; + int mds_wanted = 0; + + for (p = rb_first(&ci->i_caps); p; p = rb_next(p)) { + cap = rb_entry(p, struct ceph_cap, ci_node); + if (!__cap_is_valid(cap)) + continue; + mds_wanted |= cap->mds_wanted; + } + return mds_wanted; +} + /* * called under i_lock */ diff --git a/src/kernel/file.c b/src/kernel/file.c index 9bd5fa7a254ae..a6c737d2281e2 100644 --- a/src/kernel/file.c +++ b/src/kernel/file.c @@ -100,7 +100,7 @@ int ceph_open(struct inode *inode, struct file *file) struct ceph_file_info *cf = file->private_data; struct inode *parent_inode = file->f_dentry->d_parent->d_inode; int err; - int flags, fmode, wanted, new_want; + int flags, fmode, mds_wanted, new_want; if (ceph_snap(inode) != CEPH_NOSNAP && (file->f_mode & FMODE_WRITE)) return -EROFS; @@ -126,8 +126,8 @@ int ceph_open(struct inode *inode, struct file *file) * registered with the MDS. */ spin_lock(&inode->i_lock); - wanted = __ceph_caps_file_wanted(ci); - if ((wanted & new_want) == new_want) { + mds_wanted = __ceph_caps_mds_wanted(ci); + if ((mds_wanted & new_want) == new_want) { dout(10, "open fmode %d caps %d using existing on %p\n", fmode, new_want, inode); __ceph_get_fmode(ci, fmode); @@ -136,7 +136,7 @@ int ceph_open(struct inode *inode, struct file *file) } spin_unlock(&inode->i_lock); dout(10, "open fmode %d wants %s, we only already want %s\n", - fmode, ceph_cap_string(new_want), ceph_cap_string(wanted)); + fmode, ceph_cap_string(new_want), ceph_cap_string(mds_wanted)); dentry = d_find_alias(inode); if (!dentry) diff --git a/src/kernel/super.h b/src/kernel/super.h index 8757ed6b9b622..4179f9ddacf48 100644 --- a/src/kernel/super.h +++ b/src/kernel/super.h @@ -497,6 +497,9 @@ static inline int __ceph_caps_wanted(struct ceph_inode_info *ci) return w; } +/* what the mds thinks we want */ +extern int __ceph_caps_mds_wanted(struct ceph_inode_info *ci); + static inline struct ceph_client *ceph_inode_to_client(struct inode *inode) { return (struct ceph_client *)inode->i_sb->s_fs_info; -- 2.39.5