diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-07-26 16:38:50 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-07-26 16:38:50 -0400 |
commit | ba5b56cb3e3d2cab73d4fee9a022bb69462a8cd9 (patch) | |
tree | eda7ea059a41ae5d68e2ad5a36a87069187ef22a /fs/ceph/inode.c | |
parent | 243dd2809a5edd2e0e3e62781083aa44049af37d (diff) | |
parent | d79698da32b317e96216236f265a9b72b78ae568 (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.c | 48 |
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 | */ |
843 | static void ceph_set_dentry_offset(struct dentry *dn) | 849 | static 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); |