Whamcloud - gitweb
LU-10966 utils: Fix `lfs check` documentation and arguments
[fs/lustre-release.git] / lustre / utils / liblustreapi_layout.c
index a282d7a..f84b3b3 100644 (file)
@@ -60,6 +60,7 @@ struct llapi_layout_comp {
        struct lu_extent        llc_extent;     /* [start, end) of component */
        uint32_t                llc_id;         /* unique ID of component */
        uint32_t                llc_flags;      /* LCME_FL_* flags */
+       uint64_t                llc_timestamp;  /* snapshot timestamp */
        struct list_head        llc_list;       /* linked to the llapi_layout
                                                   components list */
 };
@@ -148,6 +149,7 @@ llapi_layout_swab_lov_user_md(struct lov_user_md *lum, int lum_size)
                        ent = &comp_v1->lcm_entries[i];
                        __swab32s(&ent->lcme_id);
                        __swab32s(&ent->lcme_flags);
+                       __swab64s(&ent->lcme_timestamp);
                        __swab64s(&ent->lcme_extent.e_start);
                        __swab64s(&ent->lcme_extent.e_end);
                        __swab32s(&ent->lcme_offset);
@@ -358,15 +360,16 @@ struct llapi_layout *llapi_layout_alloc(void)
  * Convert the data from a lov_user_md to a newly allocated llapi_layout.
  * The caller is responsible for freeing the returned pointer.
  *
- * \param[in] lum      LOV user metadata structure to copy data from
- * \param[in] lum_size size the the lum passed in
+ * \param[in] lov_xattr                LOV user metadata xattr to copy data from
+ * \param[in] lov_xattr_size   size the lov_xattr_size passed in
  *
  * \retval             valid llapi_layout pointer on success
  * \retval             NULL if memory allocation fails
  */
-static struct llapi_layout *
-llapi_layout_from_lum(const struct lov_user_md *lum, int lum_size)
+struct llapi_layout *llapi_layout_get_by_xattr(const void *lov_xattr,
+                                              ssize_t lov_xattr_size)
 {
+       const struct lov_user_md *lum = lov_xattr;
        struct lov_comp_md_v1 *comp_v1 = NULL;
        struct lov_comp_md_entry_v1 *ent;
        struct lov_user_md *v1;
@@ -390,6 +393,14 @@ llapi_layout_from_lum(const struct lov_user_md *lum, int lum_size)
                   lum->lmm_magic == LOV_MAGIC_V3) {
                ent_count = 1;
                layout->llot_is_composite = false;
+
+               if (lov_xattr_size <= 0) {
+                       errno = EINVAL;
+                       goto error;
+               }
+       } else {
+               errno = EOPNOTSUPP;
+               goto error;
        }
 
        if (ent_count == 0) {
@@ -403,12 +414,12 @@ llapi_layout_from_lum(const struct lov_user_md *lum, int lum_size)
                        ent = &comp_v1->lcm_entries[i];
                        v1 = (struct lov_user_md *)((char *)comp_v1 +
                                ent->lcme_offset);
-                       lum_size = ent->lcme_size;
+                       lov_xattr_size = ent->lcme_size;
                } else {
                        ent = NULL;
                }
 
-               obj_count = llapi_layout_objects_in_lum(v1, lum_size);
+               obj_count = llapi_layout_objects_in_lum(v1, lov_xattr_size);
                comp = __llapi_comp_alloc(obj_count);
                if (comp == NULL)
                        goto error;
@@ -418,6 +429,8 @@ llapi_layout_from_lum(const struct lov_user_md *lum, int lum_size)
                        comp->llc_extent.e_end = ent->lcme_extent.e_end;
                        comp->llc_id = ent->lcme_id;
                        comp->llc_flags = ent->lcme_flags;
+                       if (comp->llc_flags & LCME_FL_NOSYNC)
+                               comp->llc_timestamp = ent->lcme_timestamp;
                } else {
                        comp->llc_extent.e_start = 0;
                        comp->llc_extent.e_end = LUSTRE_EOF;
@@ -622,6 +635,8 @@ llapi_layout_to_lum(const struct llapi_layout *layout)
                        ent = &comp_v1->lcm_entries[ent_idx];
                        ent->lcme_id = comp->llc_id;
                        ent->lcme_flags = comp->llc_flags;
+                       if (ent->lcme_flags & LCME_FL_NOSYNC)
+                               ent->lcme_timestamp = comp->llc_timestamp;
                        ent->lcme_extent.e_start = comp->llc_extent.e_start;
                        ent->lcme_extent.e_end = comp->llc_extent.e_end;
                        ent->lcme_size = blob_size;
@@ -878,7 +893,7 @@ struct llapi_layout *llapi_layout_get_by_fd(int fd, uint32_t flags)
                goto out;
        }
 
-       layout = llapi_layout_from_lum(lum, bytes_read);
+       layout = llapi_layout_get_by_xattr(lum, bytes_read);
 out:
        free(lum);
        return layout;
@@ -2457,6 +2472,10 @@ int llapi_mirror_find_stale(struct llapi_layout *layout,
                        /* not in the specified mirror */
                        if (j == ids_nr)
                                goto next;
+               } else if (flags & LCME_FL_NOSYNC) {
+                       /* if not specified mirrors, do not resync "nosync"
+                        * mirrors */
+                       goto next;
                }
 
                rc = llapi_layout_comp_id_get(layout, &id);
@@ -2601,15 +2620,27 @@ int llapi_mirror_resync_many(int fd, struct llapi_layout *layout,
 
                for (i = 0; i < comp_size; i++) {
                        ssize_t written;
+                       off_t pos2 = pos;
+                       size_t to_write2 = to_write;
 
                        /* skip non-overlapped component */
-                       if (pos > comp_array[i].lrc_end ||
-                           pos + to_write < comp_array[i].lrc_start)
+                       if (pos >= comp_array[i].lrc_end ||
+                           pos + to_write <= comp_array[i].lrc_start)
                                continue;
 
+                       if (pos < comp_array[i].lrc_start)
+                               pos2 = comp_array[i].lrc_start;
+
+                       to_write2 -= pos2 - pos;
+
+                       if ((pos + to_write) > comp_array[i].lrc_end)
+                               to_write2 -= pos + to_write -
+                                            comp_array[i].lrc_end;
+
                        written = llapi_mirror_write(fd,
-                                       comp_array[i].lrc_mirror_id, buf,
-                                       to_write, pos);
+                                       comp_array[i].lrc_mirror_id,
+                                       buf + pos2 - pos,
+                                       to_write2, pos2);
                        if (written < 0) {
                                /**
                                 * this component is not written successfully,
@@ -2624,7 +2655,7 @@ int llapi_mirror_resync_many(int fd, struct llapi_layout *layout,
                                comp_array[i].lrc_synced = true;
                                continue;
                        }
-                       assert(written == to_write);
+                       assert(written == to_write2);
                }
 
                pos += bytes_read;