diff options
author | Sage Weil <sage@inktank.com> | 2013-01-21 01:02:39 -0500 |
---|---|---|
committer | Sage Weil <sage@inktank.com> | 2013-02-13 21:26:06 -0500 |
commit | b65917dd2700b7d12e25e2e0bbfd58eb3c932158 (patch) | |
tree | 7384c28c58c3ac3bb88533ed4e45f9bdfa6bd0a6 /fs/ceph | |
parent | 0bee82fb4b8d49541fe474ed460d2b917f329568 (diff) |
ceph: fix listxattr handling for vxattrs
Only include vxattrs in the result if they are not hidden and exist
(as determined by the exists_cb callback).
Note that the buffer size we return when 0 is passed in always includes
vxattrs that *might* exist, forming an upper bound.
Signed-off-by: Sage Weil <sage@inktank.com>
Reviewed-by: Sam Lang <sam.lang@inktank.com>
Diffstat (limited to 'fs/ceph')
-rw-r--r-- | fs/ceph/xattr.c | 19 |
1 files changed, 13 insertions, 6 deletions
diff --git a/fs/ceph/xattr.c b/fs/ceph/xattr.c index 87b85f3403d4..ec09ea5c4f07 100644 --- a/fs/ceph/xattr.c +++ b/fs/ceph/xattr.c | |||
@@ -657,23 +657,30 @@ list_xattr: | |||
657 | vir_namelen = ceph_vxattrs_name_size(vxattrs); | 657 | vir_namelen = ceph_vxattrs_name_size(vxattrs); |
658 | 658 | ||
659 | /* adding 1 byte per each variable due to the null termination */ | 659 | /* adding 1 byte per each variable due to the null termination */ |
660 | namelen = vir_namelen + ci->i_xattrs.names_size + ci->i_xattrs.count; | 660 | namelen = ci->i_xattrs.names_size + ci->i_xattrs.count; |
661 | err = -ERANGE; | 661 | err = -ERANGE; |
662 | if (size && namelen > size) | 662 | if (size && vir_namelen + namelen > size) |
663 | goto out; | 663 | goto out; |
664 | 664 | ||
665 | err = namelen; | 665 | err = namelen + vir_namelen; |
666 | if (size == 0) | 666 | if (size == 0) |
667 | goto out; | 667 | goto out; |
668 | 668 | ||
669 | names = __copy_xattr_names(ci, names); | 669 | names = __copy_xattr_names(ci, names); |
670 | 670 | ||
671 | /* virtual xattr names, too */ | 671 | /* virtual xattr names, too */ |
672 | if (vxattrs) | 672 | err = namelen; |
673 | if (vxattrs) { | ||
673 | for (i = 0; vxattrs[i].name; i++) { | 674 | for (i = 0; vxattrs[i].name; i++) { |
674 | len = sprintf(names, "%s", vxattrs[i].name); | 675 | if (!vxattrs[i].hidden && |
675 | names += len + 1; | 676 | !(vxattrs[i].exists_cb && |
677 | !vxattrs[i].exists_cb(ci))) { | ||
678 | len = sprintf(names, "%s", vxattrs[i].name); | ||
679 | names += len + 1; | ||
680 | err += len + 1; | ||
681 | } | ||
676 | } | 682 | } |
683 | } | ||
677 | 684 | ||
678 | out: | 685 | out: |
679 | spin_unlock(&ci->i_ceph_lock); | 686 | spin_unlock(&ci->i_ceph_lock); |