diff options
-rw-r--r-- | fs/ceph/file.c | 5 | ||||
-rw-r--r-- | fs/ceph/inode.c | 10 | ||||
-rw-r--r-- | fs/ceph/ioctl.c | 4 | ||||
-rw-r--r-- | fs/ceph/super.h | 2 | ||||
-rw-r--r-- | fs/ceph/xattr.c | 29 |
5 files changed, 20 insertions, 30 deletions
diff --git a/fs/ceph/file.c b/fs/ceph/file.c index 2eb02f80a0ab..e5203174634d 100644 --- a/fs/ceph/file.c +++ b/fs/ceph/file.c | |||
@@ -826,8 +826,7 @@ again: | |||
826 | ceph_put_cap_refs(ci, got); | 826 | ceph_put_cap_refs(ci, got); |
827 | 827 | ||
828 | if (checkeof && ret >= 0) { | 828 | if (checkeof && ret >= 0) { |
829 | int statret = ceph_do_getattr(inode, | 829 | int statret = ceph_do_getattr(inode, CEPH_STAT_CAP_SIZE, false); |
830 | CEPH_STAT_CAP_SIZE); | ||
831 | 830 | ||
832 | /* hit EOF or hole? */ | 831 | /* hit EOF or hole? */ |
833 | if (statret == 0 && iocb->ki_pos < inode->i_size && | 832 | if (statret == 0 && iocb->ki_pos < inode->i_size && |
@@ -995,7 +994,7 @@ static loff_t ceph_llseek(struct file *file, loff_t offset, int whence) | |||
995 | mutex_lock(&inode->i_mutex); | 994 | mutex_lock(&inode->i_mutex); |
996 | 995 | ||
997 | if (whence == SEEK_END || whence == SEEK_DATA || whence == SEEK_HOLE) { | 996 | if (whence == SEEK_END || whence == SEEK_DATA || whence == SEEK_HOLE) { |
998 | ret = ceph_do_getattr(inode, CEPH_STAT_CAP_SIZE); | 997 | ret = ceph_do_getattr(inode, CEPH_STAT_CAP_SIZE, false); |
999 | if (ret < 0) { | 998 | if (ret < 0) { |
1000 | offset = ret; | 999 | offset = ret; |
1001 | goto out; | 1000 | goto out; |
diff --git a/fs/ceph/inode.c b/fs/ceph/inode.c index 04c89c266cec..5fbd0adb5724 100644 --- a/fs/ceph/inode.c +++ b/fs/ceph/inode.c | |||
@@ -766,7 +766,7 @@ static int fill_inode(struct inode *inode, | |||
766 | 766 | ||
767 | /* xattrs */ | 767 | /* xattrs */ |
768 | /* note that if i_xattrs.len <= 4, i_xattrs.data will still be NULL. */ | 768 | /* note that if i_xattrs.len <= 4, i_xattrs.data will still be NULL. */ |
769 | if ((issued & CEPH_CAP_XATTR_EXCL) == 0 && | 769 | if ((ci->i_xattrs.version == 0 || !(issued & CEPH_CAP_XATTR_EXCL)) && |
770 | le64_to_cpu(info->xattr_version) > ci->i_xattrs.version) { | 770 | le64_to_cpu(info->xattr_version) > ci->i_xattrs.version) { |
771 | if (ci->i_xattrs.blob) | 771 | if (ci->i_xattrs.blob) |
772 | ceph_buffer_put(ci->i_xattrs.blob); | 772 | ceph_buffer_put(ci->i_xattrs.blob); |
@@ -1907,7 +1907,7 @@ out_put: | |||
1907 | * Verify that we have a lease on the given mask. If not, | 1907 | * Verify that we have a lease on the given mask. If not, |
1908 | * do a getattr against an mds. | 1908 | * do a getattr against an mds. |
1909 | */ | 1909 | */ |
1910 | int ceph_do_getattr(struct inode *inode, int mask) | 1910 | int ceph_do_getattr(struct inode *inode, int mask, bool force) |
1911 | { | 1911 | { |
1912 | struct ceph_fs_client *fsc = ceph_sb_to_client(inode->i_sb); | 1912 | struct ceph_fs_client *fsc = ceph_sb_to_client(inode->i_sb); |
1913 | struct ceph_mds_client *mdsc = fsc->mdsc; | 1913 | struct ceph_mds_client *mdsc = fsc->mdsc; |
@@ -1920,7 +1920,7 @@ int ceph_do_getattr(struct inode *inode, int mask) | |||
1920 | } | 1920 | } |
1921 | 1921 | ||
1922 | dout("do_getattr inode %p mask %s mode 0%o\n", inode, ceph_cap_string(mask), inode->i_mode); | 1922 | dout("do_getattr inode %p mask %s mode 0%o\n", inode, ceph_cap_string(mask), inode->i_mode); |
1923 | if (ceph_caps_issued_mask(ceph_inode(inode), mask, 1)) | 1923 | if (!force && ceph_caps_issued_mask(ceph_inode(inode), mask, 1)) |
1924 | return 0; | 1924 | return 0; |
1925 | 1925 | ||
1926 | req = ceph_mdsc_create_request(mdsc, CEPH_MDS_OP_GETATTR, USE_ANY_MDS); | 1926 | req = ceph_mdsc_create_request(mdsc, CEPH_MDS_OP_GETATTR, USE_ANY_MDS); |
@@ -1948,7 +1948,7 @@ int ceph_permission(struct inode *inode, int mask) | |||
1948 | if (mask & MAY_NOT_BLOCK) | 1948 | if (mask & MAY_NOT_BLOCK) |
1949 | return -ECHILD; | 1949 | return -ECHILD; |
1950 | 1950 | ||
1951 | err = ceph_do_getattr(inode, CEPH_CAP_AUTH_SHARED); | 1951 | err = ceph_do_getattr(inode, CEPH_CAP_AUTH_SHARED, false); |
1952 | 1952 | ||
1953 | if (!err) | 1953 | if (!err) |
1954 | err = generic_permission(inode, mask); | 1954 | err = generic_permission(inode, mask); |
@@ -1966,7 +1966,7 @@ int ceph_getattr(struct vfsmount *mnt, struct dentry *dentry, | |||
1966 | struct ceph_inode_info *ci = ceph_inode(inode); | 1966 | struct ceph_inode_info *ci = ceph_inode(inode); |
1967 | int err; | 1967 | int err; |
1968 | 1968 | ||
1969 | err = ceph_do_getattr(inode, CEPH_STAT_CAP_INODE_ALL); | 1969 | err = ceph_do_getattr(inode, CEPH_STAT_CAP_INODE_ALL, false); |
1970 | if (!err) { | 1970 | if (!err) { |
1971 | generic_fillattr(inode, stat); | 1971 | generic_fillattr(inode, stat); |
1972 | stat->ino = ceph_translate_ino(inode->i_sb, inode->i_ino); | 1972 | stat->ino = ceph_translate_ino(inode->i_sb, inode->i_ino); |
diff --git a/fs/ceph/ioctl.c b/fs/ceph/ioctl.c index a822a6e58290..d7dc812a2249 100644 --- a/fs/ceph/ioctl.c +++ b/fs/ceph/ioctl.c | |||
@@ -19,7 +19,7 @@ static long ceph_ioctl_get_layout(struct file *file, void __user *arg) | |||
19 | struct ceph_ioctl_layout l; | 19 | struct ceph_ioctl_layout l; |
20 | int err; | 20 | int err; |
21 | 21 | ||
22 | err = ceph_do_getattr(file_inode(file), CEPH_STAT_CAP_LAYOUT); | 22 | err = ceph_do_getattr(file_inode(file), CEPH_STAT_CAP_LAYOUT, false); |
23 | if (!err) { | 23 | if (!err) { |
24 | l.stripe_unit = ceph_file_layout_su(ci->i_layout); | 24 | l.stripe_unit = ceph_file_layout_su(ci->i_layout); |
25 | l.stripe_count = ceph_file_layout_stripe_count(ci->i_layout); | 25 | l.stripe_count = ceph_file_layout_stripe_count(ci->i_layout); |
@@ -74,7 +74,7 @@ static long ceph_ioctl_set_layout(struct file *file, void __user *arg) | |||
74 | return -EFAULT; | 74 | return -EFAULT; |
75 | 75 | ||
76 | /* validate changed params against current layout */ | 76 | /* validate changed params against current layout */ |
77 | err = ceph_do_getattr(file_inode(file), CEPH_STAT_CAP_LAYOUT); | 77 | err = ceph_do_getattr(file_inode(file), CEPH_STAT_CAP_LAYOUT, false); |
78 | if (err) | 78 | if (err) |
79 | return err; | 79 | return err; |
80 | 80 | ||
diff --git a/fs/ceph/super.h b/fs/ceph/super.h index 12b20744e386..bbb44cdcf1ab 100644 --- a/fs/ceph/super.h +++ b/fs/ceph/super.h | |||
@@ -714,7 +714,7 @@ extern void ceph_queue_vmtruncate(struct inode *inode); | |||
714 | extern void ceph_queue_invalidate(struct inode *inode); | 714 | extern void ceph_queue_invalidate(struct inode *inode); |
715 | extern void ceph_queue_writeback(struct inode *inode); | 715 | extern void ceph_queue_writeback(struct inode *inode); |
716 | 716 | ||
717 | extern int ceph_do_getattr(struct inode *inode, int mask); | 717 | extern int ceph_do_getattr(struct inode *inode, int mask, bool force); |
718 | extern int ceph_permission(struct inode *inode, int mask); | 718 | extern int ceph_permission(struct inode *inode, int mask); |
719 | extern int ceph_setattr(struct dentry *dentry, struct iattr *attr); | 719 | extern int ceph_setattr(struct dentry *dentry, struct iattr *attr); |
720 | extern int ceph_getattr(struct vfsmount *mnt, struct dentry *dentry, | 720 | extern int ceph_getattr(struct vfsmount *mnt, struct dentry *dentry, |
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 | ||
756 | get_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 | |||
817 | list_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, | |||
968 | retry: | 959 | retry: |
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 | ||