aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ceph/xattr.c
diff options
context:
space:
mode:
authorYan, Zheng <zyan@redhat.com>2014-09-16 09:46:17 -0400
committerIlya Dryomov <idryomov@redhat.com>2014-10-14 13:03:38 -0400
commit508b32d8661b12da4c9ca41a9b2054e1dc92fa7e (patch)
tree81b68ad636814b6ffbc3af1be01276a038b50759 /fs/ceph/xattr.c
parentb76f82398c1017e303d87760e22125714010207f (diff)
ceph: request xattrs if xattr_version is zero
Following sequence of events can happen. - Client releases an inode, queues cap release message. - A 'lookup' reply brings the same inode back, but the reply doesn't contain xattrs because MDS didn't receive the cap release message and thought client already has up-to-data xattrs. The fix is force sending a getattr request to MDS if xattrs_version is 0. The getattr mask is set to CEPH_STAT_CAP_XATTR, so MDS knows client does not have xattr. Signed-off-by: Yan, Zheng <zyan@redhat.com>
Diffstat (limited to 'fs/ceph/xattr.c')
-rw-r--r--fs/ceph/xattr.c29
1 files changed, 10 insertions, 19 deletions
diff --git a/fs/ceph/xattr.c b/fs/ceph/xattr.c
index 12f58d22e017..a87510f89ade 100644
--- a/fs/ceph/xattr.c
+++ b/fs/ceph/xattr.c
@@ -736,24 +736,20 @@ ssize_t __ceph_getxattr(struct inode *inode, const char *name, void *value,
736 dout("getxattr %p ver=%lld index_ver=%lld\n", inode, 736 dout("getxattr %p ver=%lld index_ver=%lld\n", inode,
737 ci->i_xattrs.version, ci->i_xattrs.index_version); 737 ci->i_xattrs.version, ci->i_xattrs.index_version);
738 738
739 if (__ceph_caps_issued_mask(ci, CEPH_CAP_XATTR_SHARED, 1) && 739 if (ci->i_xattrs.version == 0 ||
740 (ci->i_xattrs.index_version >= ci->i_xattrs.version)) { 740 !__ceph_caps_issued_mask(ci, CEPH_CAP_XATTR_SHARED, 1)) {
741 goto get_xattr;
742 } else {
743 spin_unlock(&ci->i_ceph_lock); 741 spin_unlock(&ci->i_ceph_lock);
744 /* get xattrs from mds (if we don't already have them) */ 742 /* get xattrs from mds (if we don't already have them) */
745 err = ceph_do_getattr(inode, CEPH_STAT_CAP_XATTR); 743 err = ceph_do_getattr(inode, CEPH_STAT_CAP_XATTR, true);
746 if (err) 744 if (err)
747 return err; 745 return err;
746 spin_lock(&ci->i_ceph_lock);
748 } 747 }
749 748
750 spin_lock(&ci->i_ceph_lock);
751
752 err = __build_xattrs(inode); 749 err = __build_xattrs(inode);
753 if (err < 0) 750 if (err < 0)
754 goto out; 751 goto out;
755 752
756get_xattr:
757 err = -ENODATA; /* == ENOATTR */ 753 err = -ENODATA; /* == ENOATTR */
758 xattr = __get_xattr(ci, name); 754 xattr = __get_xattr(ci, name);
759 if (!xattr) 755 if (!xattr)
@@ -798,23 +794,18 @@ ssize_t ceph_listxattr(struct dentry *dentry, char *names, size_t size)
798 dout("listxattr %p ver=%lld index_ver=%lld\n", inode, 794 dout("listxattr %p ver=%lld index_ver=%lld\n", inode,
799 ci->i_xattrs.version, ci->i_xattrs.index_version); 795 ci->i_xattrs.version, ci->i_xattrs.index_version);
800 796
801 if (__ceph_caps_issued_mask(ci, CEPH_CAP_XATTR_SHARED, 1) && 797 if (ci->i_xattrs.version == 0 ||
802 (ci->i_xattrs.index_version >= ci->i_xattrs.version)) { 798 !__ceph_caps_issued_mask(ci, CEPH_CAP_XATTR_SHARED, 1)) {
803 goto list_xattr;
804 } else {
805 spin_unlock(&ci->i_ceph_lock); 799 spin_unlock(&ci->i_ceph_lock);
806 err = ceph_do_getattr(inode, CEPH_STAT_CAP_XATTR); 800 err = ceph_do_getattr(inode, CEPH_STAT_CAP_XATTR, true);
807 if (err) 801 if (err)
808 return err; 802 return err;
803 spin_lock(&ci->i_ceph_lock);
809 } 804 }
810 805
811 spin_lock(&ci->i_ceph_lock);
812
813 err = __build_xattrs(inode); 806 err = __build_xattrs(inode);
814 if (err < 0) 807 if (err < 0)
815 goto out; 808 goto out;
816
817list_xattr:
818 /* 809 /*
819 * Start with virtual dir xattr names (if any) (including 810 * Start with virtual dir xattr names (if any) (including
820 * terminating '\0' characters for each). 811 * terminating '\0' characters for each).
@@ -968,7 +959,7 @@ int __ceph_setxattr(struct dentry *dentry, const char *name,
968retry: 959retry:
969 issued = __ceph_caps_issued(ci, NULL); 960 issued = __ceph_caps_issued(ci, NULL);
970 dout("setxattr %p issued %s\n", inode, ceph_cap_string(issued)); 961 dout("setxattr %p issued %s\n", inode, ceph_cap_string(issued));
971 if (!(issued & CEPH_CAP_XATTR_EXCL)) 962 if (ci->i_xattrs.version == 0 || !(issued & CEPH_CAP_XATTR_EXCL))
972 goto do_sync; 963 goto do_sync;
973 __build_xattrs(inode); 964 __build_xattrs(inode);
974 965
@@ -1077,7 +1068,7 @@ retry:
1077 issued = __ceph_caps_issued(ci, NULL); 1068 issued = __ceph_caps_issued(ci, NULL);
1078 dout("removexattr %p issued %s\n", inode, ceph_cap_string(issued)); 1069 dout("removexattr %p issued %s\n", inode, ceph_cap_string(issued));
1079 1070
1080 if (!(issued & CEPH_CAP_XATTR_EXCL)) 1071 if (ci->i_xattrs.version == 0 || !(issued & CEPH_CAP_XATTR_EXCL))
1081 goto do_sync; 1072 goto do_sync;
1082 __build_xattrs(inode); 1073 __build_xattrs(inode);
1083 1074