From ab7420b9910a881680ec0ddb6bcc9f12a8f1d672 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Mon, 30 Mar 2009 13:09:30 -0700 Subject: [PATCH] kclient: do async wanted adjustment on open if we hold any caps --- src/kernel/caps.c | 4 ++++ src/kernel/file.c | 19 +++++++++++++------ src/kernel/super.h | 6 +++++- 3 files changed, 22 insertions(+), 7 deletions(-) diff --git a/src/kernel/caps.c b/src/kernel/caps.c index 15585b158d036..17c7ebab3b332 100644 --- a/src/kernel/caps.c +++ b/src/kernel/caps.c @@ -965,6 +965,10 @@ retry_locked: if (!revoking && mdsc->stopping && (used == 0)) goto ack; + /* want more caps from mds? */ + if (want & ~cap->mds_wanted) + goto ack; + if ((cap->issued & ~retain) == 0 && cap->mds_wanted == want) continue; /* nothing extra, wanted is correct */ diff --git a/src/kernel/file.c b/src/kernel/file.c index a91d6b93e11e3..d719233ae1e3e 100644 --- a/src/kernel/file.c +++ b/src/kernel/file.c @@ -96,7 +96,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, mds_wanted, new_want; + int flags, fmode, new_want; if (ceph_snap(inode) != CEPH_NOSNAP && (file->f_mode & FMODE_WRITE)) return -EROFS; @@ -122,19 +122,26 @@ int ceph_open(struct inode *inode, struct file *file) * registered with the MDS. */ spin_lock(&inode->i_lock); - mds_wanted = __ceph_caps_mds_wanted(ci); - if ((mds_wanted & new_want) == new_want || - ceph_snap(inode) == CEPH_SNAPDIR) { + if (__ceph_is_any_real_caps(ci)) { + int mds_wanted = __ceph_caps_mds_wanted(ci); + int issued = __ceph_caps_issued(ci, NULL); + dout(10, "open fmode %d caps %d using existing on %p\n", fmode, new_want, inode); __ceph_get_fmode(ci, fmode); spin_unlock(&inode->i_lock); + + /* adjust wanted? */ + if ((issued & new_want) != new_want && + (mds_wanted & new_want) != new_want && + ceph_snap(inode) != CEPH_SNAPDIR) + ceph_check_caps(ci, 0, 0, NULL); + return ceph_init_file(inode, file, fmode); } 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(mds_wanted)); + dout(10, "open fmode %d wants %s\n", fmode, ceph_cap_string(new_want)); if (!ceph_caps_issued_mask(ceph_inode(inode), CEPH_CAP_FILE_EXCL)) ceph_release_caps(inode, CEPH_CAP_FILE_RDCACHE); req = prepare_open_request(inode->i_sb, flags, 0); diff --git a/src/kernel/super.h b/src/kernel/super.h index d22743cc3fdd6..59fcd1dacdd04 100644 --- a/src/kernel/super.h +++ b/src/kernel/super.h @@ -442,6 +442,11 @@ static inline struct inode *ceph_find_inode(struct super_block *sb, /* * caps helpers */ +static inline bool __ceph_is_any_real_caps(struct ceph_inode_info *ci) +{ + return !RB_EMPTY_ROOT(&ci->i_caps); +} + extern int __ceph_caps_issued(struct ceph_inode_info *ci, int *implemented); static inline int ceph_caps_issued(struct ceph_inode_info *ci) @@ -745,7 +750,6 @@ extern void __ceph_flush_snaps(struct ceph_inode_info *ci, extern void ceph_check_caps(struct ceph_inode_info *ci, int delayed, int drop, struct ceph_mds_session *session); extern void ceph_check_delayed_caps(struct ceph_mds_client *mdsc); -extern int __ceph_check_cap_maybe_renew(struct ceph_inode_info *ci, int mask); void ceph_trim_session_clean_caps(struct ceph_mds_session *session); -- 2.39.5