Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/sage/ceph...
[linux-2.6-block.git] / fs / ceph / inode.c
index 6b51736051541ea54b6956cf6dce57576f8ffe6f..119c43c80638788f648272fbd1593e6e6bdbfd94 100644 (file)
@@ -82,8 +82,8 @@ struct inode *ceph_get_snapdir(struct inode *parent)
        inode->i_mode = parent->i_mode;
        inode->i_uid = parent->i_uid;
        inode->i_gid = parent->i_gid;
-       inode->i_op = &ceph_dir_iops;
-       inode->i_fop = &ceph_dir_fops;
+       inode->i_op = &ceph_snapdir_iops;
+       inode->i_fop = &ceph_snapdir_fops;
        ci->i_snap_caps = CEPH_CAP_PIN; /* so we can open */
        ci->i_rbytes = 0;
        return inode;
@@ -838,30 +838,31 @@ static int fill_inode(struct inode *inode, struct page *locked_page,
                       ceph_vinop(inode), inode->i_mode);
        }
 
-       /* set dir completion flag? */
-       if (S_ISDIR(inode->i_mode) &&
-           ci->i_files == 0 && ci->i_subdirs == 0 &&
-           ceph_snap(inode) == CEPH_NOSNAP &&
-           (le32_to_cpu(info->cap.caps) & CEPH_CAP_FILE_SHARED) &&
-           (issued & CEPH_CAP_FILE_EXCL) == 0 &&
-           !__ceph_dir_is_complete(ci)) {
-               dout(" marking %p complete (empty)\n", inode);
-               __ceph_dir_set_complete(ci, atomic_read(&ci->i_release_count),
-                                       ci->i_ordered_count);
-       }
-
        /* were we issued a capability? */
        if (info->cap.caps) {
                if (ceph_snap(inode) == CEPH_NOSNAP) {
+                       unsigned caps = le32_to_cpu(info->cap.caps);
                        ceph_add_cap(inode, session,
                                     le64_to_cpu(info->cap.cap_id),
-                                    cap_fmode,
-                                    le32_to_cpu(info->cap.caps),
+                                    cap_fmode, caps,
                                     le32_to_cpu(info->cap.wanted),
                                     le32_to_cpu(info->cap.seq),
                                     le32_to_cpu(info->cap.mseq),
                                     le64_to_cpu(info->cap.realm),
                                     info->cap.flags, &new_cap);
+
+                       /* set dir completion flag? */
+                       if (S_ISDIR(inode->i_mode) &&
+                           ci->i_files == 0 && ci->i_subdirs == 0 &&
+                           (caps & CEPH_CAP_FILE_SHARED) &&
+                           (issued & CEPH_CAP_FILE_EXCL) == 0 &&
+                           !__ceph_dir_is_complete(ci)) {
+                               dout(" marking %p complete (empty)\n", inode);
+                               __ceph_dir_set_complete(ci,
+                                       atomic_read(&ci->i_release_count),
+                                       ci->i_ordered_count);
+                       }
+
                        wake = true;
                } else {
                        dout(" %p got snap_caps %s\n", inode,
@@ -1446,12 +1447,14 @@ retry_lookup:
                }
 
                if (!dn->d_inode) {
-                       dn = splice_dentry(dn, in, NULL);
-                       if (IS_ERR(dn)) {
-                               err = PTR_ERR(dn);
+                       struct dentry *realdn = splice_dentry(dn, in, NULL);
+                       if (IS_ERR(realdn)) {
+                               err = PTR_ERR(realdn);
+                               d_drop(dn);
                                dn = NULL;
                                goto next_item;
                        }
+                       dn = realdn;
                }
 
                di = dn->d_fsdata;