diff options
-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); |