diff options
author | Sage Weil <sage@inktank.com> | 2013-01-20 22:02:39 -0800 |
---|---|---|
committer | Sage Weil <sage@inktank.com> | 2013-02-13 18:26:06 -0800 |
commit | b65917dd2700b7d12e25e2e0bbfd58eb3c932158 (patch) | |
tree | 7384c28c58c3ac3bb88533ed4e45f9bdfa6bd0a6 /fs/ceph/xattr.c | |
parent | 0bee82fb4b8d49541fe474ed460d2b917f329568 (diff) | |
download | linux-next-b65917dd2700b7d12e25e2e0bbfd58eb3c932158.tar.gz |
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.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: 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); |