diff options
Diffstat (limited to 'fs/ceph/inode.c')
-rw-r--r-- | fs/ceph/inode.c | 41 |
1 files changed, 22 insertions, 19 deletions
diff --git a/fs/ceph/inode.c b/fs/ceph/inode.c index 6b5173605154..119c43c80638 100644 --- a/fs/ceph/inode.c +++ b/fs/ceph/inode.c | |||
@@ -82,8 +82,8 @@ struct inode *ceph_get_snapdir(struct inode *parent) | |||
82 | inode->i_mode = parent->i_mode; | 82 | inode->i_mode = parent->i_mode; |
83 | inode->i_uid = parent->i_uid; | 83 | inode->i_uid = parent->i_uid; |
84 | inode->i_gid = parent->i_gid; | 84 | inode->i_gid = parent->i_gid; |
85 | inode->i_op = &ceph_dir_iops; | 85 | inode->i_op = &ceph_snapdir_iops; |
86 | inode->i_fop = &ceph_dir_fops; | 86 | inode->i_fop = &ceph_snapdir_fops; |
87 | ci->i_snap_caps = CEPH_CAP_PIN; /* so we can open */ | 87 | ci->i_snap_caps = CEPH_CAP_PIN; /* so we can open */ |
88 | ci->i_rbytes = 0; | 88 | ci->i_rbytes = 0; |
89 | return inode; | 89 | return inode; |
@@ -838,30 +838,31 @@ static int fill_inode(struct inode *inode, struct page *locked_page, | |||
838 | ceph_vinop(inode), inode->i_mode); | 838 | ceph_vinop(inode), inode->i_mode); |
839 | } | 839 | } |
840 | 840 | ||
841 | /* set dir completion flag? */ | ||
842 | if (S_ISDIR(inode->i_mode) && | ||
843 | ci->i_files == 0 && ci->i_subdirs == 0 && | ||
844 | ceph_snap(inode) == CEPH_NOSNAP && | ||
845 | (le32_to_cpu(info->cap.caps) & CEPH_CAP_FILE_SHARED) && | ||
846 | (issued & CEPH_CAP_FILE_EXCL) == 0 && | ||
847 | !__ceph_dir_is_complete(ci)) { | ||
848 | dout(" marking %p complete (empty)\n", inode); | ||
849 | __ceph_dir_set_complete(ci, atomic_read(&ci->i_release_count), | ||
850 | ci->i_ordered_count); | ||
851 | } | ||
852 | |||
853 | /* were we issued a capability? */ | 841 | /* were we issued a capability? */ |
854 | if (info->cap.caps) { | 842 | if (info->cap.caps) { |
855 | if (ceph_snap(inode) == CEPH_NOSNAP) { | 843 | if (ceph_snap(inode) == CEPH_NOSNAP) { |
844 | unsigned caps = le32_to_cpu(info->cap.caps); | ||
856 | ceph_add_cap(inode, session, | 845 | ceph_add_cap(inode, session, |
857 | le64_to_cpu(info->cap.cap_id), | 846 | le64_to_cpu(info->cap.cap_id), |
858 | cap_fmode, | 847 | cap_fmode, caps, |
859 | le32_to_cpu(info->cap.caps), | ||
860 | le32_to_cpu(info->cap.wanted), | 848 | le32_to_cpu(info->cap.wanted), |
861 | le32_to_cpu(info->cap.seq), | 849 | le32_to_cpu(info->cap.seq), |
862 | le32_to_cpu(info->cap.mseq), | 850 | le32_to_cpu(info->cap.mseq), |
863 | le64_to_cpu(info->cap.realm), | 851 | le64_to_cpu(info->cap.realm), |
864 | info->cap.flags, &new_cap); | 852 | info->cap.flags, &new_cap); |
853 | |||
854 | /* set dir completion flag? */ | ||
855 | if (S_ISDIR(inode->i_mode) && | ||
856 | ci->i_files == 0 && ci->i_subdirs == 0 && | ||
857 | (caps & CEPH_CAP_FILE_SHARED) && | ||
858 | (issued & CEPH_CAP_FILE_EXCL) == 0 && | ||
859 | !__ceph_dir_is_complete(ci)) { | ||
860 | dout(" marking %p complete (empty)\n", inode); | ||
861 | __ceph_dir_set_complete(ci, | ||
862 | atomic_read(&ci->i_release_count), | ||
863 | ci->i_ordered_count); | ||
864 | } | ||
865 | |||
865 | wake = true; | 866 | wake = true; |
866 | } else { | 867 | } else { |
867 | dout(" %p got snap_caps %s\n", inode, | 868 | dout(" %p got snap_caps %s\n", inode, |
@@ -1446,12 +1447,14 @@ retry_lookup: | |||
1446 | } | 1447 | } |
1447 | 1448 | ||
1448 | if (!dn->d_inode) { | 1449 | if (!dn->d_inode) { |
1449 | dn = splice_dentry(dn, in, NULL); | 1450 | struct dentry *realdn = splice_dentry(dn, in, NULL); |
1450 | if (IS_ERR(dn)) { | 1451 | if (IS_ERR(realdn)) { |
1451 | err = PTR_ERR(dn); | 1452 | err = PTR_ERR(realdn); |
1453 | d_drop(dn); | ||
1452 | dn = NULL; | 1454 | dn = NULL; |
1453 | goto next_item; | 1455 | goto next_item; |
1454 | } | 1456 | } |
1457 | dn = realdn; | ||
1455 | } | 1458 | } |
1456 | 1459 | ||
1457 | di = dn->d_fsdata; | 1460 | di = dn->d_fsdata; |