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) {
};
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,
};
}
}
+/*
+ * 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
}
}
+/*
+ * 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,
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);
}