From fbf4b5b847c079e4c3e29fdec4ad46b8a9e0d24a Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Fri, 14 May 2010 09:35:38 -0700 Subject: [PATCH] --- yaml --- r: 198039 b: refs/heads/master c: 81a6cf2d30eac5d790f53cdff110892f7b18c7fe h: refs/heads/master i: 198037: 9d991f7fdb18ed2e71376e899fe74920da2eb81c 198035: 67ec8cdc90b79c8a40ab0c5da73e844122dd1530 198031: 7db3883e9eaca55cced9cf78d7307e8ef911a81b v: v3 --- [refs] | 2 +- trunk/fs/ceph/dir.c | 13 +++++++++++-- trunk/fs/ceph/inode.c | 13 +++++++++++-- trunk/fs/ceph/mds_client.c | 7 ++++++- trunk/fs/ceph/super.h | 1 + 5 files changed, 30 insertions(+), 6 deletions(-) diff --git a/[refs] b/[refs] index 44df94315e3f..e0c97d8f0ece 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: b4556396fac5b3f063d5b8ac54dc02f7612a75e1 +refs/heads/master: 81a6cf2d30eac5d790f53cdff110892f7b18c7fe diff --git a/trunk/fs/ceph/dir.c b/trunk/fs/ceph/dir.c index 650d2db5ed26..4b1a7a4bae0b 100644 --- a/trunk/fs/ceph/dir.c +++ b/trunk/fs/ceph/dir.c @@ -888,13 +888,22 @@ static int ceph_rename(struct inode *old_dir, struct dentry *old_dentry, /* ensure target dentry is invalidated, despite rehashing bug in vfs_rename_dir */ - new_dentry->d_time = jiffies; - ceph_dentry(new_dentry)->lease_shared_gen = 0; + ceph_invalidate_dentry_lease(new_dentry); } ceph_mdsc_put_request(req); return err; } +/* + * Ensure a dentry lease will no longer revalidate. + */ +void ceph_invalidate_dentry_lease(struct dentry *dentry) +{ + spin_lock(&dentry->d_lock); + dentry->d_time = jiffies; + ceph_dentry(dentry)->lease_shared_gen = 0; + spin_unlock(&dentry->d_lock); +} /* * Check if dentry lease is valid. If not, delete the lease. Try to diff --git a/trunk/fs/ceph/inode.c b/trunk/fs/ceph/inode.c index 85b4d2ffdeba..220a2aec0545 100644 --- a/trunk/fs/ceph/inode.c +++ b/trunk/fs/ceph/inode.c @@ -938,8 +938,15 @@ int ceph_fill_trace(struct super_block *sb, struct ceph_mds_request *req, ceph_inode(req->r_locked_dir); dout(" clearing %p complete (empty trace)\n", req->r_locked_dir); + spin_lock(&req->r_locked_dir->i_lock); ci->i_ceph_flags &= ~CEPH_I_COMPLETE; ci->i_release_count++; + spin_unlock(&req->r_locked_dir->i_lock); + + if (req->r_dentry) + ceph_invalidate_dentry_lease(req->r_dentry); + if (req->r_old_dentry) + ceph_invalidate_dentry_lease(req->r_old_dentry); } return 0; } @@ -1011,13 +1018,15 @@ int ceph_fill_trace(struct super_block *sb, struct ceph_mds_request *req, req->r_old_dentry->d_name.len, req->r_old_dentry->d_name.name, dn, dn->d_name.len, dn->d_name.name); + /* ensure target dentry is invalidated, despite rehashing bug in vfs_rename_dir */ - dn->d_time = jiffies; - ceph_dentry(dn)->lease_shared_gen = 0; + ceph_invalidate_dentry_lease(dn); + /* take overwritten dentry's readdir offset */ ceph_dentry(req->r_old_dentry)->offset = ceph_dentry(dn)->offset; + dn = req->r_old_dentry; /* use old_dentry */ in = dn->d_inode; } diff --git a/trunk/fs/ceph/mds_client.c b/trunk/fs/ceph/mds_client.c index c0568fe3c0ba..76995a960432 100644 --- a/trunk/fs/ceph/mds_client.c +++ b/trunk/fs/ceph/mds_client.c @@ -1732,12 +1732,17 @@ int ceph_mdsc_do_request(struct ceph_mds_client *mdsc, struct ceph_inode_info *ci = ceph_inode(req->r_locked_dir); - dout("aborted, clearing I_COMPLETE on %p\n", + dout("aborted, clearing I_COMPLETE on %p, leases\n", req->r_locked_dir); spin_lock(&req->r_locked_dir->i_lock); ci->i_ceph_flags &= ~CEPH_I_COMPLETE; ci->i_release_count++; spin_unlock(&req->r_locked_dir->i_lock); + + if (req->r_dentry) + ceph_invalidate_dentry_lease(req->r_dentry); + if (req->r_old_dentry) + ceph_invalidate_dentry_lease(req->r_old_dentry); } } else { err = req->r_err; diff --git a/trunk/fs/ceph/super.h b/trunk/fs/ceph/super.h index 13513b80d87f..cfe3b0834d54 100644 --- a/trunk/fs/ceph/super.h +++ b/trunk/fs/ceph/super.h @@ -871,6 +871,7 @@ extern struct dentry *ceph_finish_lookup(struct ceph_mds_request *req, extern void ceph_dentry_lru_add(struct dentry *dn); extern void ceph_dentry_lru_touch(struct dentry *dn); extern void ceph_dentry_lru_del(struct dentry *dn); +extern void ceph_invalidate_dentry_lease(struct dentry *dentry); /* * our d_ops vary depending on whether the inode is live,