+ int rc = -1, fd = -1, i;
+ size_t lum_size;
+ struct llapi_layout *layout;
+ struct llapi_layout_comp *comp;
+ struct lov_user_md *lum = NULL;
+
+ if (path == NULL) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ if (!count)
+ return 0;
+
+ for (i = 0; i < count; i++) {
+ if (!ids[i] || !flags[i]) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ if (ids[i] > LCME_ID_MAX || (flags[i] & ~LCME_KNOWN_FLAGS)) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ /* do not allow to set or clear INIT flag */
+ if (flags[i] & LCME_FL_INIT) {
+ errno = EINVAL;
+ return -1;
+ }
+ }
+
+ layout = __llapi_layout_alloc();
+ if (layout == NULL)
+ return -1;
+
+ layout->llot_is_composite = true;
+ for (i = 0; i < count; i++) {
+ comp = __llapi_comp_alloc(0);
+ if (comp == NULL)
+ goto out;
+
+ comp->llc_id = ids[i];
+ comp->llc_flags = flags[i];
+
+ list_add_tail(&comp->llc_list, &layout->llot_comp_list);
+ layout->llot_cur_comp = comp;
+ }
+
+ lum = llapi_layout_to_lum(layout);
+ if (lum == NULL)
+ goto out;
+
+ lum_size = ((struct lov_comp_md_v1 *)lum)->lcm_size;
+
+ fd = open(path, O_RDWR);
+ if (fd < 0)
+ goto out;
+
+ /* flush cached pages from clients */
+ rc = llapi_file_flush(fd);
+ if (rc) {
+ errno = -rc;
+ rc = -1;
+ goto out_close;
+ }
+
+ rc = fsetxattr(fd, XATTR_LUSTRE_LOV".set.flags", lum, lum_size, 0);
+ if (rc < 0)
+ goto out_close;
+
+ rc = 0;
+
+out_close:
+ if (fd >= 0) {
+ int tmp_errno = errno;
+ close(fd);
+ errno = tmp_errno;
+ }
+out:
+ if (lum)
+ free(lum);
+ llapi_layout_free(layout);
+ return rc;