Whamcloud - gitweb
LU-14645 utils: setstripe cleanup 65/43465/3
authorVitaly Fertman <c17818@cray.com>
Tue, 27 Apr 2021 19:15:30 +0000 (22:15 +0300)
committerOleg Drokin <green@whamcloud.com>
Thu, 27 May 2021 18:42:46 +0000 (18:42 +0000)
lfs setstripe checks stripe parameters differently for PFL and !PFL
layouts. Whereas the PFL layout is checked in comp_args_to_layout()
individually and in llapi_layout_sanity_cb() in pairs, !PFL layout
verification is done partially in several places. Create a common
llapi_stripe_param_verify() for this purpose. Make the checks for
both cases symmetric.

Signed-off-by: Vitaly Fertman <c17818@cray.com>
Change-Id: I456b1b2e876229ac1a354d4e3879624325856574
HPE-bug-id: LUS-9886
Reviewed-on: https://es-gerrit.dev.cray.com/158589
Reviewed-by: Andriy Skulysh <c17819@cray.com>
Reviewed-by: Alexander Boyko <c17825@cray.com>
Tested-by: Alexander Lezhoev <c17454@cray.com>
Reviewed-on: https://review.whamcloud.com/43465
Tested-by: jenkins <devops@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
Reviewed-by: Alexander Boyko <alexander.boyko@hpe.com>
Reviewed-by: Andriy Skulysh <askulysh@gmail.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
lustre/include/lustre/lustreapi.h
lustre/tests/llapi_layout_test.c
lustre/utils/lfs.c
lustre/utils/liblustreapi.c
lustre/utils/liblustreapi_layout.c
lustre/utils/lustreapi_internal.h

index 4d7c299..af0587f 100644 (file)
@@ -837,6 +837,10 @@ int llapi_layout_stripe_count_get(const struct llapi_layout *layout,
  */
 int llapi_layout_stripe_count_set(struct llapi_layout *layout, uint64_t count);
 
+/**
+ * Check if the stripe count \a stripe_count \a is valid.
+ */
+bool llapi_layout_stripe_count_is_valid(int64_t stripe_count);
 /******************** Stripe Size ********************/
 
 /**
@@ -968,7 +972,7 @@ int llapi_layout_pool_name_get(const struct llapi_layout *layout,
  * \retval -1  Invalid argument, errno set to EINVAL.
  */
 int llapi_layout_pool_name_set(struct llapi_layout *layout,
-                             const char *pool_name);
+                              char *pool_name);
 
 /******************** File Creation ********************/
 
@@ -1189,7 +1193,8 @@ int llapi_mirror_punch(int fd, unsigned int id, off_t start, size_t length);
 int llapi_heat_get(int fd, struct lu_heat *heat);
 int llapi_heat_set(int fd, __u64 flags);
 
-int llapi_layout_sanity(struct llapi_layout *layout, bool incomplete, bool flr);
+int llapi_layout_sanity(struct llapi_layout *layout, const char *fname,
+                       bool incomplete, bool flr);
 void llapi_layout_sanity_perror(int error);
 int llapi_layout_dom_size(struct llapi_layout *layout, uint64_t *size);
 
index f875f91..890dd8d 100644 (file)
@@ -932,7 +932,7 @@ void test21(void)
        ASSERTF(layout != NULL, "errno = %d", errno);
 
        fd = llapi_layout_file_create(template, 0, 0640, layout);
-       ASSERTF(fd == -1 && errno == ENOTTY,
+       ASSERTF(fd == -1 && errno == ENOENT,
                "fd = %d, errno = %d, template = %s", fd, errno, template);
        llapi_layout_free(layout);
 }
@@ -1366,7 +1366,7 @@ void test30(void)
        /* set non-contiguous extent will fail */
        rc = llapi_layout_comp_extent_set(layout, start[1] * 2, end[1]);
        ASSERTF(rc == 0, "errno %d", errno);
-       rc = llapi_layout_sanity(layout, false, false);
+       rc = llapi_layout_sanity(layout, NULL, false, false);
        ASSERTF(rc == 12 /*LSE_NOT_ADJACENT_PREV*/, "rc %d", rc);
 
        rc = llapi_layout_comp_extent_set(layout, start[1], end[1]);
@@ -1734,7 +1734,7 @@ void test34(void)
        layout = llapi_layout_get_by_path(path, 0);
        ASSERTF(layout != NULL, "errno = %d", errno);
 
-       rc = llapi_layout_sanity(layout, false, false);
+       rc = llapi_layout_sanity(layout, NULL, false, false);
        ASSERTF(rc == 0, "errno %d", errno);
 }
 
index 9ce1585..479c2be 100644 (file)
@@ -1189,7 +1189,7 @@ int lfs_layout_compid_by_pool(char *fname, const char *pool, int *comp_id)
                rc = -errno;
                goto free_layout;
        }
-       rc = llapi_layout_sanity(layout, false, true);
+       rc = llapi_layout_sanity(layout, fname, false, true);
        if (rc < 0) {
                llapi_layout_sanity_perror(errno);
                goto free_layout;
@@ -1619,7 +1619,8 @@ enum mirror_flags {
  * Return: 0 on success or a negative error code on failure.
  */
 static int mirror_create_sanity_check(const char *fname,
-                                     struct mirror_args *list)
+                                     struct mirror_args *list,
+                                     bool check_fname)
 {
        int rc = 0;
        bool has_m_file = false;
@@ -1628,7 +1629,7 @@ static int mirror_create_sanity_check(const char *fname,
        if (!list)
                return -EINVAL;
 
-       if (fname) {
+       if (fname && check_fname) {
                struct llapi_layout *layout;
 
                layout = llapi_layout_get_by_path(fname, 0);
@@ -1639,7 +1640,7 @@ static int mirror_create_sanity_check(const char *fname,
                        return -ENODATA;
                }
 
-               rc = llapi_layout_sanity(layout, false, true);
+               rc = llapi_layout_sanity(layout, fname, false, true);
 
                llapi_layout_free(layout);
 
@@ -1671,7 +1672,7 @@ static int mirror_create_sanity_check(const char *fname,
                        }
                }
 
-               rc = llapi_layout_sanity(list->m_layout, false, true);
+               rc = llapi_layout_sanity(list->m_layout, fname, false, true);
                if (rc) {
                        llapi_layout_sanity_perror(rc);
                        return rc;
@@ -1727,7 +1728,7 @@ static int mirror_create(char *fname, struct mirror_args *mirror_list)
        int i = 0;
        int rc = 0;
 
-       rc = mirror_create_sanity_check(NULL, mirror_list);
+       rc = mirror_create_sanity_check(fname, mirror_list, false);
        if (rc)
                return rc;
 
@@ -2028,7 +2029,7 @@ static int mirror_extend(char *fname, struct mirror_args *mirror_list,
 {
        int rc;
 
-       rc = mirror_create_sanity_check(fname, mirror_list);
+       rc = mirror_create_sanity_check(fname, mirror_list, true);
        if (rc)
                return rc;
 
@@ -2229,7 +2230,7 @@ static int mirror_split(const char *fname, __u32 id, const char *pool,
                return -EINVAL;
        }
 
-       rc = llapi_layout_sanity(layout, false, true);
+       rc = llapi_layout_sanity(layout, fname, false, true);
        if (rc) {
                llapi_layout_sanity_perror(rc);
                goto free_layout;
@@ -2644,6 +2645,33 @@ static inline bool setstripe_args_specified(struct lfs_setstripe_args *lsa)
                lsa->lsa_comp_end != 0);
 }
 
+static int lsa_args_stripe_count_check(struct lfs_setstripe_args *lsa)
+{
+       if (lsa->lsa_nr_tgts) {
+               if (lsa->lsa_nr_tgts < 0 ||
+                   lsa->lsa_nr_tgts >= LOV_MAX_STRIPE_COUNT) {
+                       fprintf(stderr, "Invalid nr_tgts(%d)\n",
+                               lsa->lsa_nr_tgts);
+                       errno = EINVAL;
+                       return -1;
+               }
+
+               if (lsa->lsa_stripe_count > 0 &&
+                   lsa->lsa_stripe_count != LLAPI_LAYOUT_DEFAULT &&
+                   lsa->lsa_stripe_count != LLAPI_LAYOUT_WIDE &&
+                   lsa->lsa_nr_tgts != lsa->lsa_stripe_count) {
+                       fprintf(stderr, "stripe_count(%lld) != nr_tgts(%d)\n",
+                               lsa->lsa_stripe_count,
+                               lsa->lsa_nr_tgts);
+                       errno = EINVAL;
+                       return -1;
+               }
+       }
+
+       return 0;
+
+}
+
 /**
  * comp_args_to_layout() - Create or extend a composite layout.
  * @composite:       Pointer to the composite layout.
@@ -2652,6 +2680,8 @@ static inline bool setstripe_args_specified(struct lfs_setstripe_args *lsa)
  * This function creates or extends a composite layout by adding a new
  * component with stripe options from @lsa.
  *
+ * When modified, adjust llapi_stripe_param_verify() if needed as well.
+ *
  * Return: 0 on success or an error code on failure.
  */
 static int comp_args_to_layout(struct llapi_layout **composite,
@@ -2827,22 +2857,28 @@ new_comp:
                }
        }
 
+       rc = lsa_args_stripe_count_check(lsa);
+       if (rc)
+               return rc;
+
        if (lsa->lsa_nr_tgts > 0) {
-               if (lsa->lsa_stripe_count > 0 &&
-                   lsa->lsa_stripe_count != LLAPI_LAYOUT_DEFAULT &&
-                   lsa->lsa_stripe_count != LLAPI_LAYOUT_WIDE &&
-                   lsa->lsa_nr_tgts != lsa->lsa_stripe_count) {
-                       fprintf(stderr, "stripe_count(%lld) != nr_tgts(%d)\n",
-                               lsa->lsa_stripe_count,
-                               lsa->lsa_nr_tgts);
-                       errno = EINVAL;
-                       return -1;
-               }
+               bool found = false;
+
                for (i = 0; i < lsa->lsa_nr_tgts; i++) {
                        rc = llapi_layout_ost_index_set(layout, i,
                                                        lsa->lsa_tgts[i]);
                        if (rc)
                                break;
+
+                       /* Make sure stripe offset is in OST list. */
+                       if (lsa->lsa_tgts[i] == lsa->lsa_stripe_off)
+                               found = true;
+               }
+               if (!found) {
+                       fprintf(stderr, "Invalid stripe offset '%lld', not in the target list",
+                               lsa->lsa_stripe_off);
+                       errno = EINVAL;
+                       return -1;
                }
        } else if (lsa->lsa_stripe_off != LLAPI_LAYOUT_DEFAULT &&
                   lsa->lsa_stripe_off != -1) {
@@ -4217,6 +4253,9 @@ static int lfs_setstripe_internal(int argc, char **argv,
                migrate_mdt_param.fp_lmv_md = lmu;
                migrate_mdt_param.fp_migrate = 1;
        } else if (!layout) {
+               if (lsa_args_stripe_count_check(&lsa))
+                       goto usage_error;
+
                /* initialize stripe parameters */
                param = calloc(1, offsetof(typeof(*param),
                               lsp_osts[lsa.lsa_nr_tgts]));
@@ -4250,19 +4289,8 @@ static int lfs_setstripe_internal(int argc, char **argv,
                }
                param->lsp_pool = lsa.lsa_pool_name;
                param->lsp_is_specific = false;
-               if (lsa.lsa_nr_tgts > 0) {
-                       if (lsa.lsa_stripe_count > 0 &&
-                           lsa.lsa_stripe_count != LLAPI_LAYOUT_DEFAULT &&
-                           lsa.lsa_stripe_count != LLAPI_LAYOUT_WIDE &&
-                           lsa.lsa_nr_tgts != lsa.lsa_stripe_count) {
-                               fprintf(stderr,
-                                       "error: %s: stripe count %lld doesn't match the number of OSTs: %d\n",
-                                       argv[0], lsa.lsa_stripe_count,
-                                       lsa.lsa_nr_tgts);
-                               free(param);
-                               goto usage_error;
-                       }
 
+               if (lsa.lsa_nr_tgts > 0) {
                        param->lsp_is_specific = true;
                        param->lsp_stripe_count = lsa.lsa_nr_tgts;
                        memcpy(param->lsp_osts, tgts,
index 14263ac..ff645c2 100644 (file)
@@ -400,9 +400,54 @@ int llapi_ioctl_unpack(struct obd_ioctl_data *data, char *pbuf, int max_len)
 
 /* XXX: llapi_xxx() functions return negative values upon failure */
 
-int llapi_stripe_limit_check(unsigned long long stripe_size, int stripe_offset,
-                               int stripe_count, int stripe_pattern)
+int llapi_layout_search_ost(__u32 ost, char *pname, char *fsname)
 {
+       char ostname[MAX_OBD_NAME + 64];
+       char *pool_name = pname;
+       int rc = 0;
+
+       /**
+        * The current policy is that the pool does not have to exist at the
+        * setstripe time, see sanity-pfl/-flr tests.
+        * If this logic will change, re-enable it.
+        *
+        * if (pname && strlen(pname) == 0)
+        */
+               pool_name = NULL;
+
+       snprintf(ostname, sizeof(ostname), "%s-OST%04x_UUID",
+                fsname, ost);
+       rc = llapi_search_ost(fsname, pool_name, ostname);
+       if (rc <= 0) {
+               if (rc == 0)
+                       rc = -ENODEV;
+
+               llapi_error(LLAPI_MSG_ERROR, rc,
+                           "%s: cannot find OST %s in %s", __func__, ostname,
+                           pool_name != NULL ? "pool" : "system");
+               return rc;
+       }
+
+       return 0;
+}
+
+/**
+ * Verify the setstripe parameters before using.
+ * This is a pair method for comp_args_to_layout()/llapi_layout_sanity_cb()
+ * when just 1 component or a non-PFL layout is given.
+ *
+ * \param[in] param            stripe parameters
+ * \param[in] pool_name                pool name
+ * \param[in] fsname           lustre FS name
+ *
+ * \retval                     0, success
+ *                             < 0, error code on failre
+ */
+static int llapi_stripe_param_verify(const struct llapi_stripe_param *param,
+                                    char **pool_name,
+                                    char *fsname)
+{
+       int count;
        static int page_size;
        int rc = 0;
 
@@ -420,33 +465,94 @@ int llapi_stripe_limit_check(unsigned long long stripe_size, int stripe_offset,
                                          page_size, LOV_MIN_STRIPE_SIZE);
                }
        }
-       if (!llapi_stripe_size_is_aligned(stripe_size)) {
+       if (!llapi_stripe_size_is_aligned(param->lsp_stripe_size)) {
                rc = -EINVAL;
                llapi_error(LLAPI_MSG_ERROR, rc,
                            "error: bad stripe_size %llu, must be an even multiple of %d bytes",
-                           (unsigned long long)stripe_size, page_size);
+                           param->lsp_stripe_size, page_size);
                goto out;
        }
-       if (!llapi_stripe_index_is_valid(stripe_offset)) {
+       if (!llapi_stripe_index_is_valid(param->lsp_stripe_offset)) {
                rc = -EINVAL;
                llapi_error(LLAPI_MSG_ERROR, rc, "error: bad stripe offset %d",
-                               stripe_offset);
+                           param->lsp_stripe_offset);
                goto out;
        }
-       if (!llapi_stripe_count_is_valid(stripe_count)) {
+       if (llapi_stripe_size_is_too_big(param->lsp_stripe_size)) {
                rc = -EINVAL;
-               llapi_error(LLAPI_MSG_ERROR, rc, "error: bad stripe count %d",
-                               stripe_count);
+               llapi_error(LLAPI_MSG_ERROR, rc,
+                           "error: stripe size '%llu' over 4GB limit",
+                           param->lsp_stripe_size);
                goto out;
        }
-       if (llapi_stripe_size_is_too_big(stripe_size)) {
+
+       count = param->lsp_stripe_count;
+       if (param->lsp_stripe_pattern == LOV_PATTERN_MDT) {
                rc = -EINVAL;
                llapi_error(LLAPI_MSG_ERROR, rc,
-                           "error: stripe size '%llu' over 4GB limit",
-                           (unsigned long long)stripe_size);
+                           "Invalid pattern: %d, must be specified with -E\n",
+                           param->lsp_stripe_pattern);
                goto out;
+       } else {
+               if (!llapi_stripe_count_is_valid(count)) {
+                       rc = -EINVAL;
+                       llapi_error(LLAPI_MSG_ERROR, rc,
+                                   "Invalid stripe count %d\n", count);
+                       goto out;
+               }
+       }
+
+       /* Make sure we have a good pool */
+       if (*pool_name != NULL) {
+               if (!llapi_pool_name_is_valid(pool_name, fsname)) {
+                       rc = -EINVAL;
+                       llapi_error(LLAPI_MSG_ERROR, rc,
+                                   "Pool '%s' is not on filesystem '%s'",
+                                   *pool_name, fsname);
+                       goto out;
+               }
+
+               /* Make sure the pool exists and is non-empty */
+               rc = llapi_search_ost(fsname, *pool_name, NULL);
+               if (rc < 1) {
+                       char *err = rc == 0 ? "has no OSTs" : "does not exist";
+
+                       rc = -EINVAL;
+                       llapi_error(LLAPI_MSG_ERROR, rc, "pool '%s.%s' %s",
+                                   fsname, *pool_name, err);
+                       goto out;
+               }
+               rc = 0;
        }
 
+       /* sanity check of target list */
+       if (param->lsp_is_specific) {
+               bool found = false;
+               int i;
+
+               for (i = 0; i < count; i++) {
+                       rc = llapi_layout_search_ost(param->lsp_osts[i],
+                                                    *pool_name, fsname);
+                       if (rc)
+                               goto out;
+
+                       /* Make sure stripe offset is in OST list. */
+                       if (param->lsp_osts[i] == param->lsp_stripe_offset)
+                               found = true;
+               }
+               if (!found) {
+                       rc = -EINVAL;
+                       llapi_error(LLAPI_MSG_ERROR, rc,
+                                   "%s: stripe offset '%d' is not in the target list",
+                                   __func__, param->lsp_stripe_offset);
+                       goto out;
+               }
+       } else if (param->lsp_stripe_offset != -1) {
+               rc = llapi_layout_search_ost(param->lsp_stripe_offset,
+                                            *pool_name, fsname);
+               if (rc)
+                       goto out;
+       }
 out:
        errno = -rc;
        return rc;
@@ -570,9 +676,9 @@ int llapi_file_open_param(const char *name, int flags, mode_t mode,
                          const struct llapi_stripe_param *param)
 {
        char fsname[MAX_OBD_NAME + 1] = { 0 };
-       char *pool_name = param->lsp_pool;
        struct lov_user_md *lum = NULL;
-       size_t lum_size = sizeof(*lum);
+       char *pool_name = param->lsp_pool;
+       size_t lum_size;
        int fd, rc;
 
        /* Make sure we are on a Lustre file system */
@@ -585,82 +691,17 @@ int llapi_file_open_param(const char *name, int flags, mode_t mode,
        }
 
        /* Check if the stripe pattern is sane. */
-       rc = llapi_stripe_limit_check(param->lsp_stripe_size,
-                                     param->lsp_stripe_offset,
-                                     param->lsp_stripe_count,
-                                     param->lsp_stripe_pattern);
+       rc = llapi_stripe_param_verify(param, &pool_name, fsname);
        if (rc != 0)
                return rc;
 
-       /* Make sure we have a good pool */
-       if (pool_name != NULL) {
-               /*
-                * in case user gives the full pool name <fsname>.<poolname>,
-                * strip the fsname
-                */
-               char *ptr = strchr(pool_name, '.');
-
-               if (ptr != NULL) {
-                       *ptr = '\0';
-                       if (strcmp(pool_name, fsname) != 0) {
-                               *ptr = '.';
-                               llapi_err_noerrno(LLAPI_MSG_ERROR,
-                                       "Pool '%s' is not on filesystem '%s'",
-                                       pool_name, fsname);
-                               return -EINVAL;
-                       }
-                       pool_name = ptr + 1;
-               }
-
-               /* Make sure the pool exists and is non-empty */
-               rc = llapi_search_ost(fsname, pool_name, NULL);
-               if (rc < 1) {
-                       char *err = rc == 0 ? "has no OSTs" : "does not exist";
-
-                       llapi_err_noerrno(LLAPI_MSG_ERROR, "pool '%s.%s' %s",
-                                         fsname, pool_name, err);
-                       return -EINVAL;
-               }
-
-               lum_size = sizeof(struct lov_user_md_v3);
-       }
-
-       /* sanity check of target list */
-       if (param->lsp_is_specific) {
-               char ostname[MAX_OBD_NAME + 64];
-               bool found = false;
-               int i;
-
-               for (i = 0; i < param->lsp_stripe_count; i++) {
-                       snprintf(ostname, sizeof(ostname), "%s-OST%04x_UUID",
-                                fsname, param->lsp_osts[i]);
-                       rc = llapi_search_ost(fsname, pool_name, ostname);
-                       if (rc <= 0) {
-                               if (rc == 0)
-                                       rc = -ENODEV;
-
-                               llapi_error(LLAPI_MSG_ERROR, rc,
-                                           "%s: cannot find OST %s in %s",
-                                           __func__, ostname,
-                                           pool_name != NULL ?
-                                           "pool" : "system");
-                               return rc;
-                       }
-
-                       /* Make sure stripe offset is in OST list. */
-                       if (param->lsp_osts[i] == param->lsp_stripe_offset)
-                               found = true;
-               }
-               if (!found) {
-                       llapi_error(LLAPI_MSG_ERROR, -EINVAL,
-                                   "%s: stripe offset '%d' is not in the target list",
-                                   __func__, param->lsp_stripe_offset);
-                       return -EINVAL;
-               }
-
+       if (param->lsp_is_specific)
                lum_size = lov_user_md_size(param->lsp_stripe_count,
                                            LOV_USER_MAGIC_SPECIFIC);
-       }
+       else if (pool_name)
+               lum_size = sizeof(struct lov_user_md_v3);
+       else
+               lum_size = sizeof(*lum);
 
        lum = calloc(1, lum_size);
        if (lum == NULL)
index 8cc4606..8753998 100644 (file)
@@ -1157,7 +1157,7 @@ int llapi_layout_stripe_count_get(const struct llapi_layout *layout,
  * the old API uses 0 and -1.
  */
 
-static bool llapi_layout_stripe_count_is_valid(int64_t stripe_count)
+bool llapi_layout_stripe_count_is_valid(int64_t stripe_count)
 {
        return stripe_count == LLAPI_LAYOUT_DEFAULT ||
                stripe_count == LLAPI_LAYOUT_WIDE ||
@@ -1526,32 +1526,20 @@ int llapi_layout_pool_name_get(const struct llapi_layout *layout, char *dest,
  * \retval     -1 if arguments are invalid or pool name is too long
  */
 int llapi_layout_pool_name_set(struct llapi_layout *layout,
-                              const char *pool_name)
+                              char *pool_name)
 {
        struct llapi_layout_comp *comp;
-       char *ptr;
 
        comp = __llapi_layout_cur_comp(layout);
        if (comp == NULL)
                return -1;
 
-       if (pool_name == NULL) {
-               errno = EINVAL;
-               return -1;
-       }
-
-       /* Strip off any 'fsname.' portion. */
-       ptr = strchr(pool_name, '.');
-       if (ptr != NULL)
-               pool_name = ptr + 1;
-
-       if (strlen(pool_name) > LOV_MAXPOOLNAME) {
+       if (!llapi_pool_name_is_valid(&pool_name, NULL)) {
                errno = EINVAL;
                return -1;
        }
 
        strncpy(comp->llc_pool_name, pool_name, sizeof(comp->llc_pool_name));
-
        return 0;
 }
 
@@ -1586,7 +1574,8 @@ int llapi_layout_file_open(const char *path, int open_flags, mode_t mode,
        }
 
        if (layout) {
-               rc = llapi_layout_sanity((struct llapi_layout *)layout, false,
+               rc = llapi_layout_sanity((struct llapi_layout *)layout,
+                                        path, false,
                                         !!(layout->llot_mirror_count > 1));
                if (rc) {
                        llapi_layout_sanity_perror(rc);
@@ -2217,7 +2206,7 @@ int llapi_layout_file_comp_add(const char *path,
                goto out;
        }
 
-       rc = llapi_layout_sanity(existing_layout, false, false);
+       rc = llapi_layout_sanity(existing_layout, path, false, false);
        if (rc) {
                tmp_errno = errno;
                llapi_layout_sanity_perror(rc);
@@ -2352,7 +2341,7 @@ int llapi_layout_file_comp_del(const char *path, uint32_t id, uint32_t flags)
                goto out;
        }
 
-       rc = llapi_layout_sanity(existing_layout, false, false);
+       rc = llapi_layout_sanity(existing_layout, path, false, false);
        if (rc) {
                tmp_errno = errno;
                llapi_layout_sanity_perror(rc);
@@ -2512,7 +2501,7 @@ int llapi_layout_file_comp_set(const char *path, uint32_t *ids, uint32_t *flags,
                goto out;
        }
 
-       rc = llapi_layout_sanity(existing_layout, false, false);
+       rc = llapi_layout_sanity(existing_layout, path, false, false);
        if (rc) {
                tmp_errno = errno;
                llapi_layout_sanity_perror(rc);
@@ -3149,6 +3138,7 @@ enum llapi_layout_comp_sanity_error {
        LSE_START_GT_END,
        LSE_ALIGN_END,
        LSE_ALIGN_EXT,
+       LSE_UNKNOWN_OST,
        LSE_LAST,
 };
 
@@ -3185,9 +3175,12 @@ const char *const llapi_layout_strerror[] =
                "The component end must be aligned by the stripe size",
        [LSE_ALIGN_EXT] =
                "The extension size must be aligned by the stripe size",
+       [LSE_UNKNOWN_OST] =
+               "An unknown OST idx is specified",
 };
 
 struct llapi_layout_sanity_args {
+       char lsa_fsname[MAX_OBD_NAME + 1];
        bool lsa_incomplete;
        bool lsa_flr;
        bool lsa_ondisk;
@@ -3198,6 +3191,9 @@ struct llapi_layout_sanity_args {
 #define LCME_USER_COMP_FLAGS   (LCME_FL_PREF_RW | LCME_FL_NOSYNC | \
                                 LCME_FL_EXTENSION)
 
+/**
+ * When modified, adjust llapi_stripe_param_verify() if needed as well.
+ */
 static int llapi_layout_sanity_cb(struct llapi_layout *layout,
                                  void *arg)
 {
@@ -3364,6 +3360,34 @@ static int llapi_layout_sanity_cb(struct llapi_layout *layout,
                goto out_err;
        }
 
+       if (args->lsa_fsname[0] != '\0') {
+               int i, rc = 0;
+
+               if (comp->llc_pattern & LLAPI_LAYOUT_SPECIFIC) {
+                       assert(comp->llc_stripe_count <=
+                              comp->llc_objects_count);
+
+                       for (i = 0; i < comp->llc_stripe_count && rc == 0; i++){
+                               if (comp->llc_objects[i].l_ost_idx ==
+                                   LLAPI_LAYOUT_IDX_MAX) {
+                                       args->lsa_rc = -1;
+                                       goto out_err;
+                               }
+                               rc = llapi_layout_search_ost(
+                                       comp->llc_objects[i].l_ost_idx,
+                                       comp->llc_pool_name, args->lsa_fsname);
+                       }
+               } else if (comp->llc_stripe_offset != LLAPI_LAYOUT_DEFAULT) {
+                       rc = llapi_layout_search_ost(
+                               comp->llc_stripe_offset,
+                               comp->llc_pool_name, args->lsa_fsname);
+               }
+               if (rc) {
+                       args->lsa_rc = LSE_UNKNOWN_OST;
+                       goto out_err;
+               }
+       }
+
        return LLAPI_LAYOUT_ITER_CONT;
 
 out_err:
@@ -3398,6 +3422,7 @@ void llapi_layout_sanity_perror(int error)
  * components"?
  *
  * \param[in] layout            component layout list.
+ * \param[in] fname            file the layout to be checked for
  * \param[in] incomplete        if layout is complete or not - some checks can
  *                              only be done on complete layouts.
  * \param[in] flr              set when this is called from FLR mirror create
@@ -3405,9 +3430,12 @@ void llapi_layout_sanity_perror(int error)
  * \retval                      0, success, positive: various errors, see
  *                              llapi_layout_sanity_perror, -1, failure
  */
-int llapi_layout_sanity(struct llapi_layout *layout, bool incomplete, bool flr)
+int llapi_layout_sanity(struct llapi_layout *layout,
+                       const char *fname,
+                       bool incomplete,
+                       bool flr)
 {
-       struct llapi_layout_sanity_args args;
+       struct llapi_layout_sanity_args args = { { 0 } };
        struct llapi_layout_comp *curr;
        int rc = 0;
 
@@ -3418,6 +3446,17 @@ int llapi_layout_sanity(struct llapi_layout *layout, bool incomplete, bool flr)
        if (!curr)
                return 0;
 
+       /* Make sure we are on a Lustre file system */
+       if (fname) {
+               rc = llapi_search_fsname(fname, args.lsa_fsname);
+               if (rc) {
+                       llapi_error(LLAPI_MSG_ERROR, rc,
+                                   "'%s' is not on a Lustre filesystem",
+                                   fname);
+                       return rc;
+               }
+       }
+
        /* Set up args */
        args.lsa_rc = 0;
        args.lsa_flr = flr;
index 367393d..522b8c3 100644 (file)
@@ -126,6 +126,37 @@ static inline bool llapi_stripe_index_is_valid(int64_t index)
        return index >= -1 && index <= LOV_V1_INSANE_STRIPE_COUNT;
 }
 
+static inline bool llapi_pool_name_is_valid(char **pool_name,
+                                           const char *fsname)
+{
+       char *ptr;
+
+       if (*pool_name == NULL)
+               return false;
+
+       /**
+        * in case user gives the full pool name <fsname>.<poolname>,
+        * strip the fsname
+        */
+       ptr = strchr(*pool_name, '.');
+       if (ptr != NULL) {
+               *ptr = '\0';
+               if (fsname != NULL && strcmp(*pool_name, fsname) != 0) {
+                       *ptr = '.';
+                       return false;
+               }
+               *pool_name = ptr + 1;
+       }
+
+       if (strlen(*pool_name) > LOV_MAXPOOLNAME)
+               return false;
+
+       return true;
+}
+
+
+int llapi_layout_search_ost(__u32 ost, char *pname, char *fsname);
+
 /* Compatibility macro for legacy llapi functions that use "offset"
  * terminology instead of the preferred "index". */
 #define llapi_stripe_offset_is_valid(os) llapi_stripe_index_is_valid(os)