From: Sage Weil Date: Fri, 4 Apr 2008 20:12:41 +0000 (-0700) Subject: kclient: factor out dentry and inode lease validation X-Git-Tag: v0.3~239^2~86 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=c6e1401b0639ce5552068c19b1a6872a441ab546;p=ceph.git kclient: factor out dentry and inode lease validation --- diff --git a/src/kernel/dir.c b/src/kernel/dir.c index 0b2b81387c9..e9ed828b0c8 100644 --- a/src/kernel/dir.c +++ b/src/kernel/dir.c @@ -493,52 +493,32 @@ static int ceph_dir_rename(struct inode *old_dir, struct dentry *old_dentry, return err; } + + /* * check if dentry lease, or parent directory inode lease or cap says * this dentry is still valid */ -static int ceph_d_revalidate(struct dentry *dentry, struct nameidata *nd) +static int ceph_dentry_revalidate(struct dentry *dentry, struct nameidata *nd) { struct inode *dir = dentry->d_parent->d_inode; - struct ceph_inode_info *dirci = ceph_inode(dir); - struct ceph_dentry_info *di; - /* does dir inode lease or cap cover it? */ - spin_lock(&dirci->vfs_inode.i_lock); - if (dirci->i_lease_session && - time_after(dirci->i_lease_ttl, jiffies) && - (dirci->i_lease_mask & CEPH_LOCK_ICONTENT)) { - dout(20, "d_revalidate have ICONTENT on dir inode %p, ok\n", + if (ceph_inode_lease_valid(dir, CEPH_LOCK_ICONTENT)) { + dout(20, "dentry_revalidate have ICONTENT on dir inode %p\n", dir); - goto inode_ok; - } - if (__ceph_caps_issued(dirci) & (CEPH_CAP_EXCL|CEPH_CAP_RDCACHE)) { - dout(20, "d_revalidate have EXCL|RDCACHE caps on dir inode %p" - ", ok\n", dir); - goto inode_ok; + return 1; } - spin_unlock(&dirci->vfs_inode.i_lock); - - /* dentry lease? */ - spin_lock(&dentry->d_lock); - di = ceph_dentry(dentry); - if (di && time_after(dentry->d_time, jiffies)) { - dout(20, "d_revalidate - dentry %p lease valid\n", dentry); - spin_unlock(&dentry->d_lock); + if (ceph_dentry_lease_valid(dentry)) { + dout(20, "dentry_revalidate - dentry %p lease valid\n", dentry); return 1; } - spin_unlock(&dentry->d_lock); - dout(20, "d_revalidate - dentry %p expired\n", dentry); + dout(20, "dentry_revalidate - dentry %p expired\n", dentry); d_drop(dentry); return 0; - -inode_ok: - spin_unlock(&dirci->vfs_inode.i_lock); - return 1; } -static void ceph_d_release(struct dentry *dentry) +static void ceph_dentry_release(struct dentry *dentry) { struct ceph_dentry_info *di; if (dentry->d_fsdata) { @@ -564,7 +544,7 @@ const struct inode_operations ceph_dir_iops = { }; struct dentry_operations ceph_dentry_ops = { - .d_revalidate = ceph_d_revalidate, - .d_release = ceph_d_release, + .d_revalidate = ceph_dentry_revalidate, + .d_release = ceph_dentry_release, }; diff --git a/src/kernel/inode.c b/src/kernel/inode.c index ae1de3f587a..b5177f7bad4 100644 --- a/src/kernel/inode.c +++ b/src/kernel/inode.c @@ -244,6 +244,36 @@ void ceph_revoke_inode_lease(struct ceph_inode_info *ci, int mask) } } +/* + * check if inode lease is valid for a given mask + */ +int ceph_inode_lease_valid(struct inode *inode, int mask) +{ + struct ceph_inode_info *ci = ceph_inode(inode); + int havemask; + int valid = 0; + + spin_lock(&inode->i_lock); + havemask = ci->i_lease_mask; + /* EXCL cap counts for an ICONTENT lease */ + if (__ceph_caps_issued(ci) & CEPH_CAP_EXCL) { + dout(20, "lease_valid inode %p EXCL cap -> ICONTENT\n", inode); + havemask |= CEPH_LOCK_ICONTENT; + } + /* any ICONTENT bits imply all bits */ + if (havemask & CEPH_LOCK_ICONTENT) + havemask |= CEPH_LOCK_ICONTENT; + + if ((havemask & mask) != mask) + goto out; + + valid = time_before(jiffies, ci->i_lease_ttl); +out: + spin_unlock(&inode->i_lock); + dout(10, "lease_valid inode %p mask %d = %d\n", inode, mask, valid); + return valid; +} + /* * dentry lease lock order is @@ -339,6 +369,23 @@ void ceph_revoke_dentry_lease(struct dentry *dentry) } } +/* + * check if dentry lease is valid + */ +int ceph_dentry_lease_valid(struct dentry *dentry) +{ + struct ceph_dentry_info *di; + int valid = 0; + spin_lock(&dentry->d_lock); + di = ceph_dentry(dentry); + if (di && time_after(dentry->d_time, jiffies)) + valid = 1; + spin_unlock(&dentry->d_lock); + dout(20, "dentry_lease_valid - dentry %p = %d\n", dentry, valid); + return valid; +} + + int ceph_fill_trace(struct super_block *sb, struct ceph_mds_request *req, @@ -1122,36 +1169,11 @@ int ceph_setattr(struct dentry *dentry, struct iattr *attr) return 0; } + int ceph_inode_revalidate(struct inode *inode, int mask) { - struct ceph_inode_info *ci = ceph_inode(inode); - int havemask; - int valid; - - spin_lock(&inode->i_lock); - havemask = ci->i_lease_mask; - /* EXCL cap counts for an ICONTENT lease */ - if (__ceph_caps_issued(ci) & CEPH_CAP_EXCL) - havemask |= CEPH_LOCK_ICONTENT; - /* any ICONTENT bits imply all bits */ - if (havemask & CEPH_LOCK_ICONTENT) - havemask |= CEPH_LOCK_ICONTENT; - valid = time_before(jiffies, ci->i_lease_ttl); - spin_unlock(&inode->i_lock); - - if (valid) { - if ((havemask & mask) == mask) { - dout(10, "inode_revalidate %p mask %d still valid\n", - inode, mask); - return 0; - } - dout(10, "inode_revalidate %p mask %d by only have %d\n", inode, - mask, havemask); - } else { - dout(10, "inode_revalidate %p have %d want %d, lease expired\n", - inode, havemask, mask); - } - + if (ceph_inode_lease_valid(inode, mask)) + return 0; return ceph_do_lookup(inode->i_sb, d_find_alias(inode), mask); } diff --git a/src/kernel/super.h b/src/kernel/super.h index 9f4960879a3..1826233fa35 100644 --- a/src/kernel/super.h +++ b/src/kernel/super.h @@ -354,6 +354,8 @@ extern void ceph_update_dentry_lease(struct dentry *dentry, struct ceph_mds_reply_lease *lease, struct ceph_mds_session *session, unsigned long from_time); +extern int ceph_inode_lease_valid(struct inode *inode, int mask); +extern int ceph_dentry_lease_valid(struct dentry *dentry); extern struct ceph_inode_cap *ceph_add_cap(struct inode *inode, struct ceph_mds_session *session,