Whamcloud - gitweb
LU-9412 lfs: A invalid memory write in llapi_layout_to_lum
[fs/lustre-release.git] / lustre / utils / liblustreapi_layout.c
index 0ab8565..557765d 100644 (file)
@@ -560,6 +560,7 @@ llapi_layout_to_lum(const struct llapi_layout *layout)
                        goto error;
                } else {
                        lum = blob;
+                       comp_v1 = (struct lov_comp_md_v1 *)lum;
                        blob = (struct lov_user_md *)((char *)lum + lum_size);
                        lum_size += blob_size;
                }
@@ -611,7 +612,7 @@ llapi_layout_to_lum(const struct llapi_layout *layout)
                        lmm_objects[i].l_ost_idx =
                                comp->llc_objects[i].l_ost_idx;
 
-               if (comp_v1 != NULL) {
+               if (layout->llot_is_composite) {
                        ent = &comp_v1->lcm_entries[ent_idx];
                        ent->lcme_id = comp->llc_id;
                        ent->lcme_flags = comp->llc_flags;
@@ -647,10 +648,12 @@ static void get_parent_dir(const char *path, char *buf, size_t size)
        strncpy(buf, path, size);
        p = strrchr(buf, '/');
 
-       if (p != NULL)
+       if (p != NULL) {
                *p = '\0';
-       else if (size >= 2)
+       } else if (size >= 2) {
                strncpy(buf, ".", 2);
+               buf[size - 1] = '\0';
+       }
 }
 
 /**
@@ -1769,11 +1772,10 @@ int llapi_layout_comp_del(struct llapi_layout *layout)
                return -1;
        }
 
+       layout->llot_cur_comp =
+               list_entry(comp->llc_list.prev, typeof(*comp), llc_list);
        list_del_init(&comp->llc_list);
        __llapi_comp_free(comp);
-       layout->llot_cur_comp =
-               list_entry(comp->llc_list.prev, typeof(*comp),
-                          llc_list);
 
        return 0;
 }
@@ -1928,35 +1930,67 @@ out:
 }
 
 /**
- * Delete component(s) by the specified component id (accepting lcme_id
- * wildcards also) from an existing file.
+ * Delete component(s) by the specified component id or component flags
+ * from an existing file.
  *
  * \param[in] path     path name of the file
- * \param[in] id       unique component ID or an lcme_id
- *                     (LCME_ID_NONE | LCME_FL_* )
+ * \param[in] id       unique component ID
+ * \param[in] flags    flags: LCME_FL_* or;
+ *                     negative flags: (LCME_FL_NEG|LCME_FL_*)
  */
-int llapi_layout_file_comp_del(const char *path, uint32_t id)
+int llapi_layout_file_comp_del(const char *path, uint32_t id, uint32_t flags)
 {
-       int rc, fd;
+       int rc, fd, lum_size;
+       struct llapi_layout *layout;
+       struct llapi_layout_comp *comp;
+       struct lov_user_md *lum;
 
-       if (path == NULL || id == 0) {
+       if (path == NULL || id > LCME_ID_MAX || (flags & ~LCME_KNOWN_FLAGS)) {
                errno = EINVAL;
                return -1;
        }
 
-       fd = open(path, O_RDWR);
-       if (fd < 0)
+       /* Can only specify ID or flags, not both. */
+       if (id != 0 && flags != 0) {
+               errno = EINVAL;
+               return -1;
+       }
+
+       layout = llapi_layout_alloc();
+       if (layout == NULL)
+               return -1;
+
+       llapi_layout_comp_extent_set(layout, 0, LUSTRE_EOF);
+       comp = __llapi_layout_cur_comp(layout);
+       comp->llc_id = id;
+       comp->llc_flags = flags;
+
+       lum = llapi_layout_to_lum(layout);
+       if (lum == NULL) {
+               llapi_layout_free(layout);
                return -1;
+       }
+       lum_size = ((struct lov_comp_md_v1 *)lum)->lcm_size;
+
+       fd = open(path, O_RDWR);
+       if (fd < 0) {
+               rc = -1;
+               goto out;
+       }
 
-       rc = fsetxattr(fd, XATTR_LUSTRE_LOV".del", &id, sizeof(id), 0);
+       rc = fsetxattr(fd, XATTR_LUSTRE_LOV".del", lum, lum_size, 0);
        if (rc < 0) {
                int tmp_errno = errno;
                close(fd);
                errno = tmp_errno;
-               return -1;
+               rc = -1;
+               goto out;
        }
        close(fd);
-       return 0;
+out:
+       free(lum);
+       llapi_layout_free(layout);
+       return rc;
 }
 
 /**