summaryrefslogtreecommitdiffstats
path: root/fs/ceph/xattr.c
diff options
context:
space:
mode:
authorSage Weil <sage@inktank.com>2013-01-20 22:02:39 -0800
committerSage Weil <sage@inktank.com>2013-02-13 18:26:06 -0800
commitb65917dd2700b7d12e25e2e0bbfd58eb3c932158 (patch)
tree7384c28c58c3ac3bb88533ed4e45f9bdfa6bd0a6 /fs/ceph/xattr.c
parent0bee82fb4b8d49541fe474ed460d2b917f329568 (diff)
downloadlinux-b65917dd2700b7d12e25e2e0bbfd58eb3c932158.tar.gz
linux-b65917dd2700b7d12e25e2e0bbfd58eb3c932158.tar.bz2
linux-b65917dd2700b7d12e25e2e0bbfd58eb3c932158.zip
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/xattr.c')
-rw-r--r--fs/ceph/xattr.c19
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:
vir_namelen = ceph_vxattrs_name_size(vxattrs);
/* adding 1 byte per each variable due to the null termination */
- namelen = vir_namelen + ci->i_xattrs.names_size + ci->i_xattrs.count;
+ namelen = ci->i_xattrs.names_size + ci->i_xattrs.count;
err = -ERANGE;
- if (size && namelen > size)
+ if (size && vir_namelen + namelen > size)
goto out;
- err = namelen;
+ err = namelen + vir_namelen;
if (size == 0)
goto out;
names = __copy_xattr_names(ci, names);
/* virtual xattr names, too */
- if (vxattrs)
+ err = namelen;
+ if (vxattrs) {
for (i = 0; vxattrs[i].name; i++) {
- len = sprintf(names, "%s", vxattrs[i].name);
- names += len + 1;
+ if (!vxattrs[i].hidden &&
+ !(vxattrs[i].exists_cb &&
+ !vxattrs[i].exists_cb(ci))) {
+ len = sprintf(names, "%s", vxattrs[i].name);
+ names += len + 1;
+ err += len + 1;
+ }
}
+ }
out:
spin_unlock(&ci->i_ceph_lock);