]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
kclient: fix symlink kmalloc under spinlock
authorSage Weil <sage@newdream.net>
Fri, 18 Sep 2009 23:32:26 +0000 (16:32 -0700)
committerSage Weil <sage@newdream.net>
Fri, 18 Sep 2009 23:32:26 +0000 (16:32 -0700)
src/kernel/inode.c

index 5a68ada3289a205931d540e21b6e67517411726e..8ae6a7b65c6097156fb7aff442aa651496d5eefc 100644 (file)
@@ -591,14 +591,23 @@ static int fill_inode(struct inode *inode,
                inode->i_op = &ceph_symlink_iops;
                if (!ci->i_symlink) {
                        int symlen = iinfo->symlink_len;
+                       char *sym;
 
                        BUG_ON(symlen != inode->i_size);
+                       spin_unlock(&inode->i_lock);
+                       
                        err = -ENOMEM;
-                       ci->i_symlink = kmalloc(symlen+1, GFP_NOFS);
-                       if (!ci->i_symlink)
+                       sym = kmalloc(symlen+1, GFP_NOFS);
+                       if (!sym)
                                goto out;
-                       memcpy(ci->i_symlink, iinfo->symlink, symlen);
-                       ci->i_symlink[symlen] = 0;
+                       memcpy(sym, iinfo->symlink, symlen);
+                       sym[symlen] = 0;
+                       
+                       spin_lock(&inode->i_lock);
+                       if (!ci->i_symlink)
+                               ci->i_symlink = sym;
+                       else
+                               kfree(sym); /* lost a race */
                }
                break;
        case S_IFDIR: