STATIC int xfs_attrlist_by_handle( xfs_mount_t *mp, unsigned long arg, struct file *parfilp, struct inode *parinode) { int error; attrlist_cursor_kern_t *cursor; xfs_fsop_attrlist_handlereq_t al_hreq; struct inode *inode; vnode_t *vp; error = xfs_vget_fsop_handlereq(mp, parinode, CAP_SYS_ADMIN, arg, sizeof(xfs_fsop_attrlist_handlereq_t), (xfs_fsop_handlereq_t *)&al_hreq, &vp, &inode); if (error) return -error; cursor = (attrlist_cursor_kern_t *)&al_hreq.pos; VOP_ATTR_LIST(vp, al_hreq.buffer, al_hreq.buflen, al_hreq.flags, cursor, NULL, error); VN_RELE(vp); if (error) return -error; return 0; }
STATIC int xfs_attrlist_by_handle( xfs_mount_t *mp, void __user *arg, struct file *parfilp, struct inode *parinode) { int error; attrlist_cursor_kern_t *cursor; xfs_fsop_attrlist_handlereq_t al_hreq; struct inode *inode; vnode_t *vp; char *kbuf; if (!capable(CAP_SYS_ADMIN)) return -XFS_ERROR(EPERM); if (copy_from_user(&al_hreq, arg, sizeof(xfs_fsop_attrlist_handlereq_t))) return -XFS_ERROR(EFAULT); if (al_hreq.buflen > XATTR_LIST_MAX) return -XFS_ERROR(EINVAL); error = xfs_vget_fsop_handlereq(mp, parinode, &al_hreq.hreq, &vp, &inode); if (error) goto out; kbuf = kmalloc(al_hreq.buflen, GFP_KERNEL); if (!kbuf) goto out_vn_rele; cursor = (attrlist_cursor_kern_t *)&al_hreq.pos; VOP_ATTR_LIST(vp, kbuf, al_hreq.buflen, al_hreq.flags, cursor, NULL, error); if (error) goto out_kfree; if (copy_to_user(al_hreq.buffer, kbuf, al_hreq.buflen)) error = -EFAULT; out_kfree: kfree(kbuf); out_vn_rele: VN_RELE(vp); out: return -error; }
STATIC ssize_t linvfs_listxattr( struct dentry *dentry, char *data, size_t size) { ssize_t error; int result = 0; int xflags = ATTR_KERNAMELS; char *k = data; attrlist_cursor_kern_t cursor; xattr_namespace_t *sys; vnode_t *vp; vp = LINVFS_GET_VP(dentry->d_inode); if (!size) xflags |= ATTR_KERNOVAL; if (capable(CAP_SYS_ADMIN)) xflags |= ATTR_KERNFULLS; memset(&cursor, 0, sizeof(cursor)); VOP_ATTR_LIST(vp, data, size, xflags, &cursor, NULL, error); if (error > 0) return -error; result += -error; k += result; /* advance start of our buffer */ for (sys = &sys_namespace_array[0]; sys->name != NULL; sys++) { if (sys->exists == NULL || !sys->exists(vp)) continue; result += xfs_namespaces[SYSTEM_NAMES].namelen; result += sys->namelen + 1; if (size) { if (result > size) return -ERANGE; strcpy(k, xfs_namespaces[SYSTEM_NAMES].name); k += xfs_namespaces[SYSTEM_NAMES].namelen; strcpy(k, sys->name); k += sys->namelen + 1; } } return result; }