aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ceph/inode.c
diff options
context:
space:
mode:
authorYan, Zheng <zheng.z.yan@intel.com>2013-02-18 03:38:14 -0500
committerSage Weil <sage@inktank.com>2013-05-02 00:14:33 -0400
commita8673d61ad77ddf2118599507bd40cc345e95368 (patch)
tree0b8688fee3c2f6c7c35db75d42edd806df689d1d /fs/ceph/inode.c
parent964266cce94cee7e4aca42994fcda206c111e917 (diff)
ceph: use I_COMPLETE inode flag instead of D_COMPLETE flag
commit c6ffe10015 moved the flag that tracks if the dcache contents for a directory are complete to dentry. The problem is there are lots of places that use ceph_dir_{set,clear,test}_complete() while holding i_ceph_lock. but ceph_dir_{set,clear,test}_complete() may sleep because they call dput(). This patch basically reverts that commit. For ceph_d_prune(), it's called with both the dentry to prune and the parent dentry are locked. So it's safe to access the parent dentry's d_inode and clear I_COMPLETE flag. Signed-off-by: Yan, Zheng <zheng.z.yan@intel.com> Reviewed-by: Greg Farnum <greg@inktank.com> Reviewed-by: Sage Weil <sage@inktank.com>
Diffstat (limited to 'fs/ceph/inode.c')
-rw-r--r--fs/ceph/inode.c30
1 files changed, 13 insertions, 17 deletions
diff --git a/fs/ceph/inode.c b/fs/ceph/inode.c
index 851814d951cd..be2f262b822d 100644
--- a/fs/ceph/inode.c
+++ b/fs/ceph/inode.c
@@ -561,7 +561,6 @@ static int fill_inode(struct inode *inode,
561 struct ceph_inode_info *ci = ceph_inode(inode); 561 struct ceph_inode_info *ci = ceph_inode(inode);
562 int i; 562 int i;
563 int issued = 0, implemented; 563 int issued = 0, implemented;
564 int updating_inode = 0;
565 struct timespec mtime, atime, ctime; 564 struct timespec mtime, atime, ctime;
566 u32 nsplits; 565 u32 nsplits;
567 struct ceph_buffer *xattr_blob = NULL; 566 struct ceph_buffer *xattr_blob = NULL;
@@ -601,7 +600,6 @@ static int fill_inode(struct inode *inode,
601 (ci->i_version & ~1) >= le64_to_cpu(info->version)) 600 (ci->i_version & ~1) >= le64_to_cpu(info->version))
602 goto no_change; 601 goto no_change;
603 602
604 updating_inode = 1;
605 issued = __ceph_caps_issued(ci, &implemented); 603 issued = __ceph_caps_issued(ci, &implemented);
606 issued |= implemented | __ceph_caps_dirty(ci); 604 issued |= implemented | __ceph_caps_dirty(ci);
607 605
@@ -717,6 +715,17 @@ static int fill_inode(struct inode *inode,
717 ceph_vinop(inode), inode->i_mode); 715 ceph_vinop(inode), inode->i_mode);
718 } 716 }
719 717
718 /* set dir completion flag? */
719 if (S_ISDIR(inode->i_mode) &&
720 ci->i_files == 0 && ci->i_subdirs == 0 &&
721 ceph_snap(inode) == CEPH_NOSNAP &&
722 (le32_to_cpu(info->cap.caps) & CEPH_CAP_FILE_SHARED) &&
723 (issued & CEPH_CAP_FILE_EXCL) == 0 &&
724 (ci->i_ceph_flags & CEPH_I_COMPLETE) == 0) {
725 dout(" marking %p complete (empty)\n", inode);
726 ci->i_ceph_flags |= CEPH_I_COMPLETE;
727 ci->i_max_offset = 2;
728 }
720no_change: 729no_change:
721 spin_unlock(&ci->i_ceph_lock); 730 spin_unlock(&ci->i_ceph_lock);
722 731
@@ -767,19 +776,6 @@ no_change:
767 __ceph_get_fmode(ci, cap_fmode); 776 __ceph_get_fmode(ci, cap_fmode);
768 } 777 }
769 778
770 /* set dir completion flag? */
771 if (S_ISDIR(inode->i_mode) &&
772 updating_inode && /* didn't jump to no_change */
773 ci->i_files == 0 && ci->i_subdirs == 0 &&
774 ceph_snap(inode) == CEPH_NOSNAP &&
775 (le32_to_cpu(info->cap.caps) & CEPH_CAP_FILE_SHARED) &&
776 (issued & CEPH_CAP_FILE_EXCL) == 0 &&
777 !ceph_dir_test_complete(inode)) {
778 dout(" marking %p complete (empty)\n", inode);
779 ceph_dir_set_complete(inode);
780 ci->i_max_offset = 2;
781 }
782
783 /* update delegation info? */ 779 /* update delegation info? */
784 if (dirinfo) 780 if (dirinfo)
785 ceph_fill_dirfrag(inode, dirinfo); 781 ceph_fill_dirfrag(inode, dirinfo);
@@ -861,7 +857,7 @@ static void ceph_set_dentry_offset(struct dentry *dn)
861 di = ceph_dentry(dn); 857 di = ceph_dentry(dn);
862 858
863 spin_lock(&ci->i_ceph_lock); 859 spin_lock(&ci->i_ceph_lock);
864 if (!ceph_dir_test_complete(inode)) { 860 if ((ceph_inode(inode)->i_ceph_flags & CEPH_I_COMPLETE) == 0) {
865 spin_unlock(&ci->i_ceph_lock); 861 spin_unlock(&ci->i_ceph_lock);
866 return; 862 return;
867 } 863 }
@@ -1066,7 +1062,7 @@ int ceph_fill_trace(struct super_block *sb, struct ceph_mds_request *req,
1066 * d_move() puts the renamed dentry at the end of 1062 * d_move() puts the renamed dentry at the end of
1067 * d_subdirs. We need to assign it an appropriate 1063 * d_subdirs. We need to assign it an appropriate
1068 * directory offset so we can behave when holding 1064 * directory offset so we can behave when holding
1069 * D_COMPLETE. 1065 * I_COMPLETE.
1070 */ 1066 */
1071 ceph_set_dentry_offset(req->r_old_dentry); 1067 ceph_set_dentry_offset(req->r_old_dentry);
1072 dout("dn %p gets new offset %lld\n", req->r_old_dentry, 1068 dout("dn %p gets new offset %lld\n", req->r_old_dentry,