Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/sage/ceph...
authorLinus Torvalds <torvalds@linux-foundation.org>
Fri, 28 Jan 2011 02:12:58 +0000 (12:12 +1000)
committerLinus Torvalds <torvalds@linux-foundation.org>
Fri, 28 Jan 2011 02:12:58 +0000 (12:12 +1000)
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/sage/ceph-client:
  ceph: avoid picking MDS that is not active
  ceph: avoid immediate cap check after import
  ceph: fix flushing of caps vs cap import
  ceph: fix erroneous cap flush to non-auth mds
  ceph: fix cap_wanted_delay_{min,max} mount option initialization
  ceph: fix xattr rbtree search
  ceph: fix getattr on directory when using norbytes

1  2 
fs/ceph/inode.c
fs/ceph/mds_client.c

diff --combined fs/ceph/inode.c
index e835eff551e342156ff1f1b1f1e657c089f435eb,50001de66c69ae02494838e567112b797e0a982c..5625463aa4796f3df3678dd29ed1bfb1135a32af
@@@ -370,15 -370,6 +370,15 @@@ struct inode *ceph_alloc_inode(struct s
        return &ci->vfs_inode;
  }
  
 +static void ceph_i_callback(struct rcu_head *head)
 +{
 +      struct inode *inode = container_of(head, struct inode, i_rcu);
 +      struct ceph_inode_info *ci = ceph_inode(inode);
 +
 +      INIT_LIST_HEAD(&inode->i_dentry);
 +      kmem_cache_free(ceph_inode_cachep, ci);
 +}
 +
  void ceph_destroy_inode(struct inode *inode)
  {
        struct ceph_inode_info *ci = ceph_inode(inode);
        if (ci->i_xattrs.prealloc_blob)
                ceph_buffer_put(ci->i_xattrs.prealloc_blob);
  
 -      kmem_cache_free(ceph_inode_cachep, ci);
 +      call_rcu(&inode->i_rcu, ceph_i_callback);
  }
  
  
@@@ -710,10 -701,6 +710,6 @@@ static int fill_inode(struct inode *ino
                        ci->i_ceph_flags |= CEPH_I_COMPLETE;
                        ci->i_max_offset = 2;
                }
-               /* it may be better to set st_size in getattr instead? */
-               if (ceph_test_mount_opt(ceph_sb_to_client(inode->i_sb), RBYTES))
-                       inode->i_size = ci->i_rbytes;
                break;
        default:
                pr_err("fill_inode %llx.%llx BAD mode 0%o\n",
@@@ -854,13 -841,13 +850,13 @@@ static void ceph_set_dentry_offset(stru
        di->offset = ceph_inode(inode)->i_max_offset++;
        spin_unlock(&inode->i_lock);
  
 -      spin_lock(&dcache_lock);
 -      spin_lock(&dn->d_lock);
 +      spin_lock(&dir->d_lock);
 +      spin_lock_nested(&dn->d_lock, DENTRY_D_LOCK_NESTED);
        list_move(&dn->d_u.d_child, &dir->d_subdirs);
        dout("set_dentry_offset %p %lld (%p %p)\n", dn, di->offset,
             dn->d_u.d_child.prev, dn->d_u.d_child.next);
        spin_unlock(&dn->d_lock);
 -      spin_unlock(&dcache_lock);
 +      spin_unlock(&dir->d_lock);
  }
  
  /*
@@@ -892,8 -879,8 +888,8 @@@ static struct dentry *splice_dentry(str
        } else if (realdn) {
                dout("dn %p (%d) spliced with %p (%d) "
                     "inode %p ino %llx.%llx\n",
 -                   dn, atomic_read(&dn->d_count),
 -                   realdn, atomic_read(&realdn->d_count),
 +                   dn, dn->d_count,
 +                   realdn, realdn->d_count,
                     realdn->d_inode, ceph_vinop(realdn->d_inode));
                dput(dn);
                dn = realdn;
@@@ -1244,11 -1231,11 +1240,11 @@@ retry_lookup
                        goto retry_lookup;
                } else {
                        /* reorder parent's d_subdirs */
 -                      spin_lock(&dcache_lock);
 -                      spin_lock(&dn->d_lock);
 +                      spin_lock(&parent->d_lock);
 +                      spin_lock_nested(&dn->d_lock, DENTRY_D_LOCK_NESTED);
                        list_move(&dn->d_u.d_child, &parent->d_subdirs);
                        spin_unlock(&dn->d_lock);
 -                      spin_unlock(&dcache_lock);
 +                      spin_unlock(&parent->d_lock);
                }
  
                di = dn->d_fsdata;
@@@ -1785,17 -1772,12 +1781,17 @@@ int ceph_do_getattr(struct inode *inode
   * Check inode permissions.  We verify we have a valid value for
   * the AUTH cap, then call the generic handler.
   */
 -int ceph_permission(struct inode *inode, int mask)
 +int ceph_permission(struct inode *inode, int mask, unsigned int flags)
  {
 -      int err = ceph_do_getattr(inode, CEPH_CAP_AUTH_SHARED);
 +      int err;
 +
 +      if (flags & IPERM_FLAG_RCU)
 +              return -ECHILD;
 +
 +      err = ceph_do_getattr(inode, CEPH_CAP_AUTH_SHARED);
  
        if (!err)
 -              err = generic_permission(inode, mask, NULL);
 +              err = generic_permission(inode, mask, flags, NULL);
        return err;
  }
  
@@@ -1819,7 -1801,11 +1815,11 @@@ int ceph_getattr(struct vfsmount *mnt, 
                else
                        stat->dev = 0;
                if (S_ISDIR(inode->i_mode)) {
-                       stat->size = ci->i_rbytes;
+                       if (ceph_test_mount_opt(ceph_sb_to_client(inode->i_sb),
+                                               RBYTES))
+                               stat->size = ci->i_rbytes;
+                       else
+                               stat->size = ci->i_files + ci->i_subdirs;
                        stat->blocks = 0;
                        stat->blksize = 65536;
                }
diff --combined fs/ceph/mds_client.c
index 1e30d194a8e349f4f8a2bc951681a63c9c8d70b3,a6949cc7c69a3e2faef2eba265a45d32c25240bc..a1ee8fa3a8e7a4e8778fa624ef44154f67e2acf9
@@@ -693,9 -693,11 +693,11 @@@ static int __choose_mds(struct ceph_mds
                                dout("choose_mds %p %llx.%llx "
                                     "frag %u mds%d (%d/%d)\n",
                                     inode, ceph_vinop(inode),
-                                    frag.frag, frag.mds,
+                                    frag.frag, mds,
                                     (int)r, frag.ndist);
-                               return mds;
+                               if (ceph_mdsmap_get_state(mdsc->mdsmap, mds) >=
+                                   CEPH_MDS_STATE_ACTIVE)
+                                       return mds;
                        }
  
                        /* since this file/dir wasn't known to be
                                dout("choose_mds %p %llx.%llx "
                                     "frag %u mds%d (auth)\n",
                                     inode, ceph_vinop(inode), frag.frag, mds);
-                               return mds;
+                               if (ceph_mdsmap_get_state(mdsc->mdsmap, mds) >=
+                                   CEPH_MDS_STATE_ACTIVE)
+                                       return mds;
                        }
                }
        }
@@@ -1498,7 -1502,7 +1502,7 @@@ retry
        *base = ceph_ino(temp->d_inode);
        *plen = len;
        dout("build_path on %p %d built %llx '%.*s'\n",
 -           dentry, atomic_read(&dentry->d_count), *base, len, path);
 +           dentry, dentry->d_count, *base, len, path);
        return path;
  }