ceph: fix listxattr handling for vxattrs
authorSage Weil <sage@inktank.com>
Mon, 21 Jan 2013 06:02:39 +0000 (22:02 -0800)
committerSage Weil <sage@inktank.com>
Thu, 14 Feb 2013 02:26:06 +0000 (18:26 -0800)
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>
fs/ceph/xattr.c

index 87b85f3403d4d8411c1328599a6a6760d9d59c4f..ec09ea5c4f07660200cecca80419577f0e4dcbe3 100644 (file)
@@ -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);