+ goto out_kfree;
+
+ if (copy_to_user(ubuf, kbuf, *len))
+ error = EFAULT;
+
+ out_kfree:
+ kfree(kbuf);
+ return error;
+}
+
+STATIC int
+xfs_attrmulti_attr_set(
+ struct vnode *vp,
+ char *name,
+ const char __user *ubuf,
+ __uint32_t len,
+ __uint32_t flags)
+{
+ char *kbuf;
+ int error = EFAULT;
+
+ if (IS_IMMUTABLE(&vp->v_inode) || IS_APPEND(&vp->v_inode))
+ return EPERM;
+ if (len > XATTR_SIZE_MAX)
+ return EINVAL;
+
+ kbuf = kmalloc(len, GFP_KERNEL);
+ if (!kbuf)
+ return ENOMEM;
+
+ if (copy_from_user(kbuf, ubuf, len))
+ goto out_kfree;
+
+ VOP_ATTR_SET(vp, name, kbuf, len, flags, NULL, error);
+
+ out_kfree:
+ kfree(kbuf);
+ return error;
+}
+
+STATIC int
+xfs_attrmulti_attr_remove(
+ struct vnode *vp,
+ char *name,
+ __uint32_t flags)
+{
+ int error;
+
+ if (IS_IMMUTABLE(&vp->v_inode) || IS_APPEND(&vp->v_inode))
+ return EPERM;
+
+ VOP_ATTR_REMOVE(vp, name, flags, NULL, error);
+ return error;