]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
kclient: fix race condition
authorYehuda Sadeh <yehuda@hq.newdream.net>
Tue, 14 Oct 2008 19:34:18 +0000 (12:34 -0700)
committerYehuda Sadeh <yehuda@hq.newdream.net>
Tue, 14 Oct 2008 19:34:18 +0000 (12:34 -0700)
src/kernel/dir.c
src/kernel/inode.c
src/kernel/mds_client.c
src/kernel/super.h

index b0c2256f93e1b18ff37e176e3a6265c9a8cd8f29..f15c24816f1f8600a6b6d1a45f7f1b71092da70c 100644 (file)
@@ -153,7 +153,7 @@ nextfrag:
                int op = ceph_snap(inode) == CEPH_SNAPDIR ?
                        CEPH_MDS_OP_LSSNAP:CEPH_MDS_OP_READDIR;
 
-               frag = ceph_choose_frag(ceph_inode(inode), frag, 0);
+               frag = ceph_choose_frag(ceph_inode(inode), frag, 0, 0);
 
                /* query mds */
                dout(10, "dir_readdir querying mds for ino %llx.%llx frag %x\n",
index 732c2ecfe4735c61c7d2878833efe34eba25d6dc..f7fccb6a5f776c88d21d99dcfce85ab67605f3cd 100644 (file)
@@ -133,13 +133,17 @@ out:
 }
 
 __u32 ceph_choose_frag(struct ceph_inode_info *ci, u32 v,
-                      struct ceph_inode_frag **pfrag)
+                      struct ceph_inode_frag *pfrag,
+                      int *found)
 {
        u32 t = frag_make(0, 0);
        struct ceph_inode_frag *frag;
        unsigned nway, i;
        u32 n;
 
+       if (found)
+               *found = 0;
+
        mutex_lock(&ci->i_fragtree_mutex);
        while (1) {
                WARN_ON(!frag_contains_value(t, v));
@@ -148,7 +152,10 @@ __u32 ceph_choose_frag(struct ceph_inode_info *ci, u32 v,
                        break; /* t is a leaf */
                if (frag->split_by == 0) {
                        if (pfrag)
-                               *pfrag = frag;
+                               memcpy(pfrag, frag, sizeof(struct ceph_inode_frag));
+
+                       if (found)
+                               *found = 1;
                        break;
                }
 
index a4253a608ce20890a1264f554c0301065e8d40c5..efb670ac05a5083994062ec723695262670f3d4b 100644 (file)
@@ -486,9 +486,15 @@ static int choose_mds(struct ceph_mds_client *mdsc,
                if (is_hash &&
                    dentry->d_inode &&
                    S_ISDIR(dentry->d_inode->i_mode)) {
+                       int found;
                        ci = ceph_inode(dentry->d_inode);
-                       ceph_choose_frag(ci, hash, &frag);
-                       if (frag) {
+                       frag = kmalloc(sizeof(struct ceph_inode_frag), GFP_KERNEL);
+
+                       if (!frag)
+                               return -ENOMEM;
+
+                       ceph_choose_frag(ci, hash, frag, &found);
+                       if (found) {
                                /* avoid hitting dir replicas on dir
                                 * auth delegation point.. mds will
                                 * likely forward anyway to avoid
@@ -518,6 +524,7 @@ static int choose_mds(struct ceph_mds_client *mdsc,
                                        return mds;
                                }
                        }
+                       kfree(frag);
                }
                if (IS_ROOT(dentry))
                        break;
index d4ad676ed0028ba2e4b4591c82cf6de2ec91f109..a4769a56e7198dc242d70a5feef0c8cf9badb66e 100644 (file)
@@ -322,7 +322,8 @@ __ceph_find_frag(struct ceph_inode_info *ci, u32 f)
 }
 
 extern __u32 ceph_choose_frag(struct ceph_inode_info *ci, u32 v,
-                             struct ceph_inode_frag **pfrag);
+                             struct ceph_inode_frag *pfrag,
+                             int *found);
 
 struct ceph_dentry_info {
        struct dentry *dentry;