[PATCH 2/3] ceph: take inode lock when finding an inode alias

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



In the ceph_dir_*_complete() functions, a call to
__d_find_any_alias() is used to get a dentry for a inode.
Previously this was done under the inode's i_lock, but
recently this change converted things to use the ceph
inode's i_ceph_lock instead:
    be655596 ceph: use i_ceph_lock instead of i_lock

Finding an inode alias operates (only) on the Linux inode, so
we really do need to take the Linux lock for this.  Since i_lock
is ordered inside i_ceph_lock, we can safely do this for all
these ceph cases.

For now, just copy the d_find_any_alias() function from
"fs/dcache.c" and use that instead.

Signed-off-by: Alex Elder <elder@xxxxxxxxxxxxx>

---
 fs/ceph/dir.c |   18 +++++++++++++++---
 1 file changed, 15 insertions(+), 3 deletions(-)

Index: b/fs/ceph/dir.c
===================================================================
--- a/fs/ceph/dir.c
+++ b/fs/ceph/dir.c
@@ -1112,9 +1112,21 @@ static struct dentry * __d_find_any_alia
 	return alias;
 }
 
+/* The following code copied from "fs/dcache.c" */
+static struct dentry * d_find_any_alias(struct inode *inode)
+{
+	struct dentry *de;
+
+	spin_lock(&inode->i_lock);
+	de = __d_find_any_alias(inode);
+	spin_unlock(&inode->i_lock);
+	return de;
+}
+/* End of code copied from "fs/dcache.c" */
+
 void ceph_dir_set_complete(struct inode *inode)
 {
-	struct dentry *dentry = __d_find_any_alias(inode);
+	struct dentry *dentry = d_find_any_alias(inode);
 	
 	if (dentry && ceph_dentry(dentry)) {
 		struct ceph_fs_client *fsc = ceph_sb_to_client(dentry->d_sb);
@@ -1128,7 +1140,7 @@ void ceph_dir_set_complete(struct inode
 
 void ceph_dir_clear_complete(struct inode *inode)
 {
-	struct dentry *dentry = __d_find_any_alias(inode);
+	struct dentry *dentry = d_find_any_alias(inode);
 
 	if (dentry && ceph_dentry(dentry)) {
 		dout(" marking %p (%p) NOT complete\n", inode, dentry);
@@ -1138,7 +1150,7 @@ void ceph_dir_clear_complete(struct inod
 
 bool ceph_dir_test_complete(struct inode *inode)
 {
-	struct dentry *dentry = __d_find_any_alias(inode);
+	struct dentry *dentry = d_find_any_alias(inode);
 
 	if (dentry && ceph_dentry(dentry))
 		return test_bit(CEPH_D_COMPLETE, &ceph_dentry(dentry)->flags);


--
To unsubscribe from this list: send the line "unsubscribe ceph-devel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [CEPH Users]     [Ceph Large]     [Information on CEPH]     [Linux BTRFS]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]
  Powered by Linux