/* * Extended attribute LIST operations */ static ssize_t listxattr(struct dentry *d, char __user *list, size_t size) { ssize_t error; char *klist = NULL; if (size) { if (size > XATTR_LIST_MAX) size = XATTR_LIST_MAX; klist = kmalloc(size, GFP_KERNEL); if (!klist) return -ENOMEM; } error = -EOPNOTSUPP; if (d->d_inode->i_op && d->d_inode->i_op->listxattr) { error = security_inode_listxattr(d); if (error) goto out; error = d->d_inode->i_op->listxattr(d, klist, size); if (error > 0) { if (size && copy_to_user(list, klist, error)) error = -EFAULT; } else if (error == -ERANGE && size >= XATTR_LIST_MAX) { /* The file system tried to returned a list bigger than XATTR_LIST_MAX bytes. Not possible. */ error = -E2BIG; } } out: if (klist) kfree(klist); return error; }
ssize_t vfs_listxattr(struct dentry *d, char *list, size_t size) { ssize_t error; error = security_inode_listxattr(d); if (error) return error; error = -EOPNOTSUPP; if (d->d_inode->i_op && d->d_inode->i_op->listxattr) { error = d->d_inode->i_op->listxattr(d, list, size); } else { error = security_inode_listsecurity(d->d_inode, list, size); if (size && error > size) error = -ERANGE; } return error; }