diff options
author | Sage Weil <sage@inktank.com> | 2013-01-21 01:00:58 -0500 |
---|---|---|
committer | Sage Weil <sage@inktank.com> | 2013-02-13 21:26:03 -0500 |
commit | 0bee82fb4b8d49541fe474ed460d2b917f329568 (patch) | |
tree | ddae2af23e46cf4b11788ff29f7ebf3a75b29ee7 /fs | |
parent | f36e4472969a78ae65e514b553e9a0feacb40a28 (diff) |
ceph: fix getxattr vxattr handling
Change the vxattr handling for getxattr so that vxattrs are checked
prior to any xattr content, and never after. Enforce vxattr existence
via the exists_cb callback.
Signed-off-by: Sage Weil <sage@inktank.com>
Reviewed-by: Sam Lang <sam.lang@inktank.com>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/ceph/xattr.c | 20 |
1 files changed, 8 insertions, 12 deletions
diff --git a/fs/ceph/xattr.c b/fs/ceph/xattr.c index 06344da4e968..87b85f3403d4 100644 --- a/fs/ceph/xattr.c +++ b/fs/ceph/xattr.c | |||
@@ -569,13 +569,17 @@ ssize_t ceph_getxattr(struct dentry *dentry, const char *name, void *value, | |||
569 | if (!ceph_is_valid_xattr(name)) | 569 | if (!ceph_is_valid_xattr(name)) |
570 | return -ENODATA; | 570 | return -ENODATA; |
571 | 571 | ||
572 | /* let's see if a virtual xattr was requested */ | ||
573 | vxattr = ceph_match_vxattr(inode, name); | ||
574 | |||
575 | spin_lock(&ci->i_ceph_lock); | 572 | spin_lock(&ci->i_ceph_lock); |
576 | dout("getxattr %p ver=%lld index_ver=%lld\n", inode, | 573 | dout("getxattr %p ver=%lld index_ver=%lld\n", inode, |
577 | ci->i_xattrs.version, ci->i_xattrs.index_version); | 574 | ci->i_xattrs.version, ci->i_xattrs.index_version); |
578 | 575 | ||
576 | /* let's see if a virtual xattr was requested */ | ||
577 | vxattr = ceph_match_vxattr(inode, name); | ||
578 | if (vxattr && !(vxattr->exists_cb && !vxattr->exists_cb(ci))) { | ||
579 | err = vxattr->getxattr_cb(ci, value, size); | ||
580 | goto out; | ||
581 | } | ||
582 | |||
579 | if (__ceph_caps_issued_mask(ci, CEPH_CAP_XATTR_SHARED, 1) && | 583 | if (__ceph_caps_issued_mask(ci, CEPH_CAP_XATTR_SHARED, 1) && |
580 | (ci->i_xattrs.index_version >= ci->i_xattrs.version)) { | 584 | (ci->i_xattrs.index_version >= ci->i_xattrs.version)) { |
581 | goto get_xattr; | 585 | goto get_xattr; |
@@ -589,11 +593,6 @@ ssize_t ceph_getxattr(struct dentry *dentry, const char *name, void *value, | |||
589 | 593 | ||
590 | spin_lock(&ci->i_ceph_lock); | 594 | spin_lock(&ci->i_ceph_lock); |
591 | 595 | ||
592 | if (vxattr && vxattr->readonly) { | ||
593 | err = vxattr->getxattr_cb(ci, value, size); | ||
594 | goto out; | ||
595 | } | ||
596 | |||
597 | err = __build_xattrs(inode); | 596 | err = __build_xattrs(inode); |
598 | if (err < 0) | 597 | if (err < 0) |
599 | goto out; | 598 | goto out; |
@@ -601,11 +600,8 @@ ssize_t ceph_getxattr(struct dentry *dentry, const char *name, void *value, | |||
601 | get_xattr: | 600 | get_xattr: |
602 | err = -ENODATA; /* == ENOATTR */ | 601 | err = -ENODATA; /* == ENOATTR */ |
603 | xattr = __get_xattr(ci, name); | 602 | xattr = __get_xattr(ci, name); |
604 | if (!xattr) { | 603 | if (!xattr) |
605 | if (vxattr) | ||
606 | err = vxattr->getxattr_cb(ci, value, size); | ||
607 | goto out; | 604 | goto out; |
608 | } | ||
609 | 605 | ||
610 | err = -ERANGE; | 606 | err = -ERANGE; |
611 | if (size && size < xattr->val_len) | 607 | if (size && size < xattr->val_len) |