aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ceph/inode.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2011-07-26 16:38:50 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2011-07-26 16:38:50 -0400
commitba5b56cb3e3d2cab73d4fee9a022bb69462a8cd9 (patch)
treeeda7ea059a41ae5d68e2ad5a36a87069187ef22a /fs/ceph/inode.c
parent243dd2809a5edd2e0e3e62781083aa44049af37d (diff)
parentd79698da32b317e96216236f265a9b72b78ae568 (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/sage/ceph-client
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/sage/ceph-client: (23 commits) ceph: document unlocked d_parent accesses ceph: explicitly reference rename old_dentry parent dir in request ceph: document locking for ceph_set_dentry_offset ceph: avoid d_parent in ceph_dentry_hash; fix ceph_encode_fh() hashing bug ceph: protect d_parent access in ceph_d_revalidate ceph: protect access to d_parent ceph: handle racing calls to ceph_init_dentry ceph: set dir complete frag after adding capability rbd: set blk_queue request sizes to object size ceph: set up readahead size when rsize is not passed rbd: cancel watch request when releasing the device ceph: ignore lease mask ceph: fix ceph_lookup_open intent usage ceph: only link open operations to directory unsafe list if O_CREAT|O_TRUNC ceph: fix bad parent_inode calc in ceph_lookup_open ceph: avoid carrying Fw cap during write into page cache libceph: don't time out osd requests that haven't been received ceph: report f_bfree based on kb_avail rather than diffing. ceph: only queue capsnap if caps are dirty ceph: fix snap writeback when racing with writes ...
Diffstat (limited to 'fs/ceph/inode.c')
-rw-r--r--fs/ceph/inode.c48
1 files changed, 27 insertions, 21 deletions
diff --git a/fs/ceph/inode.c b/fs/ceph/inode.c
index dfb2831d8d85..095799ba9dd1 100644
--- a/fs/ceph/inode.c
+++ b/fs/ceph/inode.c
@@ -560,7 +560,8 @@ static int fill_inode(struct inode *inode,
560 struct ceph_mds_reply_inode *info = iinfo->in; 560 struct ceph_mds_reply_inode *info = iinfo->in;
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, implemented; 563 int issued = 0, implemented;
564 int updating_inode = 0;
564 struct timespec mtime, atime, ctime; 565 struct timespec mtime, atime, ctime;
565 u32 nsplits; 566 u32 nsplits;
566 struct ceph_buffer *xattr_blob = NULL; 567 struct ceph_buffer *xattr_blob = NULL;
@@ -599,7 +600,8 @@ static int fill_inode(struct inode *inode,
599 if (le64_to_cpu(info->version) > 0 && 600 if (le64_to_cpu(info->version) > 0 &&
600 (ci->i_version & ~1) >= le64_to_cpu(info->version)) 601 (ci->i_version & ~1) >= le64_to_cpu(info->version))
601 goto no_change; 602 goto no_change;
602 603
604 updating_inode = 1;
603 issued = __ceph_caps_issued(ci, &implemented); 605 issued = __ceph_caps_issued(ci, &implemented);
604 issued |= implemented | __ceph_caps_dirty(ci); 606 issued |= implemented | __ceph_caps_dirty(ci);
605 607
@@ -707,17 +709,6 @@ static int fill_inode(struct inode *inode,
707 ci->i_rfiles = le64_to_cpu(info->rfiles); 709 ci->i_rfiles = le64_to_cpu(info->rfiles);
708 ci->i_rsubdirs = le64_to_cpu(info->rsubdirs); 710 ci->i_rsubdirs = le64_to_cpu(info->rsubdirs);
709 ceph_decode_timespec(&ci->i_rctime, &info->rctime); 711 ceph_decode_timespec(&ci->i_rctime, &info->rctime);
710
711 /* set dir completion flag? */
712 if (ci->i_files == 0 && ci->i_subdirs == 0 &&
713 ceph_snap(inode) == CEPH_NOSNAP &&
714 (le32_to_cpu(info->cap.caps) & CEPH_CAP_FILE_SHARED) &&
715 (issued & CEPH_CAP_FILE_EXCL) == 0 &&
716 (ci->i_ceph_flags & CEPH_I_COMPLETE) == 0) {
717 dout(" marking %p complete (empty)\n", inode);
718 /* ci->i_ceph_flags |= CEPH_I_COMPLETE; */
719 ci->i_max_offset = 2;
720 }
721 break; 712 break;
722 default: 713 default:
723 pr_err("fill_inode %llx.%llx BAD mode 0%o\n", 714 pr_err("fill_inode %llx.%llx BAD mode 0%o\n",
@@ -774,6 +765,19 @@ no_change:
774 __ceph_get_fmode(ci, cap_fmode); 765 __ceph_get_fmode(ci, cap_fmode);
775 } 766 }
776 767
768 /* set dir completion flag? */
769 if (S_ISDIR(inode->i_mode) &&
770 updating_inode && /* didn't jump to no_change */
771 ci->i_files == 0 && ci->i_subdirs == 0 &&
772 ceph_snap(inode) == CEPH_NOSNAP &&
773 (le32_to_cpu(info->cap.caps) & CEPH_CAP_FILE_SHARED) &&
774 (issued & CEPH_CAP_FILE_EXCL) == 0 &&
775 (ci->i_ceph_flags & CEPH_I_COMPLETE) == 0) {
776 dout(" marking %p complete (empty)\n", inode);
777 /* ci->i_ceph_flags |= CEPH_I_COMPLETE; */
778 ci->i_max_offset = 2;
779 }
780
777 /* update delegation info? */ 781 /* update delegation info? */
778 if (dirinfo) 782 if (dirinfo)
779 ceph_fill_dirfrag(inode, dirinfo); 783 ceph_fill_dirfrag(inode, dirinfo);
@@ -805,14 +809,14 @@ static void update_dentry_lease(struct dentry *dentry,
805 return; 809 return;
806 810
807 spin_lock(&dentry->d_lock); 811 spin_lock(&dentry->d_lock);
808 dout("update_dentry_lease %p mask %d duration %lu ms ttl %lu\n", 812 dout("update_dentry_lease %p duration %lu ms ttl %lu\n",
809 dentry, le16_to_cpu(lease->mask), duration, ttl); 813 dentry, duration, ttl);
810 814
811 /* make lease_rdcache_gen match directory */ 815 /* make lease_rdcache_gen match directory */
812 dir = dentry->d_parent->d_inode; 816 dir = dentry->d_parent->d_inode;
813 di->lease_shared_gen = ceph_inode(dir)->i_shared_gen; 817 di->lease_shared_gen = ceph_inode(dir)->i_shared_gen;
814 818
815 if (lease->mask == 0) 819 if (duration == 0)
816 goto out_unlock; 820 goto out_unlock;
817 821
818 if (di->lease_gen == session->s_cap_gen && 822 if (di->lease_gen == session->s_cap_gen &&
@@ -839,11 +843,13 @@ out_unlock:
839/* 843/*
840 * Set dentry's directory position based on the current dir's max, and 844 * Set dentry's directory position based on the current dir's max, and
841 * order it in d_subdirs, so that dcache_readdir behaves. 845 * order it in d_subdirs, so that dcache_readdir behaves.
846 *
847 * Always called under directory's i_mutex.
842 */ 848 */
843static void ceph_set_dentry_offset(struct dentry *dn) 849static void ceph_set_dentry_offset(struct dentry *dn)
844{ 850{
845 struct dentry *dir = dn->d_parent; 851 struct dentry *dir = dn->d_parent;
846 struct inode *inode = dn->d_parent->d_inode; 852 struct inode *inode = dir->d_inode;
847 struct ceph_dentry_info *di; 853 struct ceph_dentry_info *di;
848 854
849 BUG_ON(!inode); 855 BUG_ON(!inode);
@@ -1022,9 +1028,7 @@ int ceph_fill_trace(struct super_block *sb, struct ceph_mds_request *req,
1022 1028
1023 /* do we have a dn lease? */ 1029 /* do we have a dn lease? */
1024 have_lease = have_dir_cap || 1030 have_lease = have_dir_cap ||
1025 (le16_to_cpu(rinfo->dlease->mask) & 1031 le32_to_cpu(rinfo->dlease->duration_ms);
1026 CEPH_LOCK_DN);
1027
1028 if (!have_lease) 1032 if (!have_lease)
1029 dout("fill_trace no dentry lease or dir cap\n"); 1033 dout("fill_trace no dentry lease or dir cap\n");
1030 1034
@@ -1560,7 +1564,7 @@ int ceph_setattr(struct dentry *dentry, struct iattr *attr)
1560{ 1564{
1561 struct inode *inode = dentry->d_inode; 1565 struct inode *inode = dentry->d_inode;
1562 struct ceph_inode_info *ci = ceph_inode(inode); 1566 struct ceph_inode_info *ci = ceph_inode(inode);
1563 struct inode *parent_inode = dentry->d_parent->d_inode; 1567 struct inode *parent_inode;
1564 const unsigned int ia_valid = attr->ia_valid; 1568 const unsigned int ia_valid = attr->ia_valid;
1565 struct ceph_mds_request *req; 1569 struct ceph_mds_request *req;
1566 struct ceph_mds_client *mdsc = ceph_sb_to_client(dentry->d_sb)->mdsc; 1570 struct ceph_mds_client *mdsc = ceph_sb_to_client(dentry->d_sb)->mdsc;
@@ -1743,7 +1747,9 @@ int ceph_setattr(struct dentry *dentry, struct iattr *attr)
1743 req->r_inode_drop = release; 1747 req->r_inode_drop = release;
1744 req->r_args.setattr.mask = cpu_to_le32(mask); 1748 req->r_args.setattr.mask = cpu_to_le32(mask);
1745 req->r_num_caps = 1; 1749 req->r_num_caps = 1;
1750 parent_inode = ceph_get_dentry_parent_inode(dentry);
1746 err = ceph_mdsc_do_request(mdsc, parent_inode, req); 1751 err = ceph_mdsc_do_request(mdsc, parent_inode, req);
1752 iput(parent_inode);
1747 } 1753 }
1748 dout("setattr %p result=%d (%s locally, %d remote)\n", inode, err, 1754 dout("setattr %p result=%d (%s locally, %d remote)\n", inode, err,
1749 ceph_cap_string(dirtied), mask); 1755 ceph_cap_string(dirtied), mask);