Whamcloud - gitweb
LU-9537 utils: implement "lfs getstripe --fid" for directories
[fs/lustre-release.git] / lustre / utils / liblustreapi.c
index 0f85d29..03dbfad 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)
@@ -962,6 +1003,8 @@ static inline void param2lmu(struct lmv_user_md *lmu,
        lmu->lum_stripe_count = param->lsp_stripe_count;
        lmu->lum_stripe_offset = param->lsp_stripe_offset;
        lmu->lum_hash_type = param->lsp_stripe_pattern;
+       lmu->lum_max_inherit = param->lsp_max_inherit;
+       lmu->lum_max_inherit_rr = param->lsp_max_inherit_rr;
        if (param->lsp_pool != NULL)
                strncpy(lmu->lum_pool_name, param->lsp_pool, LOV_MAXPOOLNAME);
        if (param->lsp_is_specific) {
@@ -1086,6 +1129,9 @@ int llapi_dir_create(const char *name, mode_t mode,
        data.ioc_inlbuf2 = (char *)lmu;
        data.ioc_inllen2 = lmu_size;
        data.ioc_type = mode;
+       if (param->lsp_is_create)
+               /* borrow obdo1.o_flags to store this flag */
+               data.ioc_obdo1.o_flags = OBD_FL_OBDMDEXISTS;
        rc = llapi_ioctl_pack(&data, &buf, sizeof(rawbuf));
        if (rc) {
                llapi_error(LLAPI_MSG_ERROR, rc,
@@ -2873,7 +2919,8 @@ static void lov_dump_user_lmm_header(struct lov_user_md *lum, char *path,
                             space, prefix,
                             (uintmax_t)lmm_oi_id(&lum->lmm_oi));
        }
-       if ((verbose & (VERBOSE_DETAIL | VERBOSE_DFID)) && !is_dir) {
+
+       if (verbose & (VERBOSE_DETAIL | VERBOSE_DFID)) {
                __u64 seq;
                __u32 oid;
                __u32 ver;
@@ -2881,30 +2928,51 @@ static void lov_dump_user_lmm_header(struct lov_user_md *lum, char *path,
                if (verbose & ~VERBOSE_DFID)
                        llapi_printf(LLAPI_MSG_NORMAL, "%slmm_fid:           ",
                                     space);
-               /*
-                * This needs a bit of hand-holding since old 1.x lmm_oi
-                * have { oi.oi_id = mds_inum, oi.oi_seq = 0 } and 2.x lmm_oi
-                * have { oi.oi_id = mds_oid, oi.oi_seq = mds_seq } instead of
-                * a real FID.  Ideally the 2.x code would have stored this
-                * like a FID with { oi_id = mds_seq, oi_seq = mds_oid } so the
-                * ostid union lu_fid { f_seq = mds_seq, f_oid = mds_oid }
-                * worked properly (especially since IGIF FIDs use mds_inum as
-                * the FID SEQ), but unfortunately that didn't happen.
-                *
-                * Print it to look like an IGIF FID, even though the fields
-                * are reversed on disk, so that it makes sense to userspace.
-                *
-                * Don't use ostid_id() and ostid_seq(), since they assume the
-                * oi_fid fields are in the right order.  This is why there are
-                * separate lmm_oi_seq() and lmm_oi_id() routines for this.
-                *
-                * For newer layout types hopefully this will be a real FID.
-                */
-               seq = lmm_oi_seq(&lum->lmm_oi) == 0 ?
-                       lmm_oi_id(&lum->lmm_oi) : lmm_oi_seq(&lum->lmm_oi);
-               oid = lmm_oi_seq(&lum->lmm_oi) == 0 ?
-                       0 : (__u32)lmm_oi_id(&lum->lmm_oi);
-               ver = (__u32)(lmm_oi_id(&lum->lmm_oi) >> 32);
+
+               if (is_dir) {
+                       struct lu_fid dir_fid;
+
+                       rc = llapi_path2fid(path, &dir_fid);
+                       if (rc)
+                               llapi_error(LLAPI_MSG_ERROR, rc,
+                                           "Cannot determine directory fid.");
+
+                       seq = dir_fid.f_seq;
+                       oid = dir_fid.f_oid;
+                       ver = dir_fid.f_ver;
+               } else {
+                       /*
+                        * This needs a bit of hand-holding since old 1.x
+                        * lmm_oi have { oi.oi_id = mds_inum, oi.oi_seq = 0 }
+                        * and 2.x lmm_oi have { oi.oi_id = mds_oid,
+                        * oi.oi_seq = mds_seq } instead of a real FID.
+                        * Ideally the 2.x code would have stored this like a
+                        * FID with { oi_id = mds_seq, oi_seq = mds_oid } so
+                        * the ostid union lu_fid { f_seq = mds_seq,
+                        * f_oid = mds_oid } worked properly (especially since
+                        * IGIF FIDs use mds_inum as the FID SEQ), but
+                        * unfortunately that didn't happen.
+                        *
+                        * Print it to look like an IGIF FID, even though the
+                        * fields are reversed on disk, so that it makes sense
+                        * to userspace.
+                        *
+                        * Don't use ostid_id() and ostid_seq(), since they
+                        * assume the oi_fid fields are in the right order.
+                        * This is why there are separate lmm_oi_seq() and
+                        * lmm_oi_id() routines for this.
+                        *
+                        * For newer layout types hopefully this will be a
+                        * real FID.
+                        */
+                       seq = lmm_oi_seq(&lum->lmm_oi) == 0 ?
+                               lmm_oi_id(&lum->lmm_oi) :
+                               lmm_oi_seq(&lum->lmm_oi);
+                       oid = lmm_oi_seq(&lum->lmm_oi) == 0 ?
+                           0 : (__u32)lmm_oi_id(&lum->lmm_oi);
+                       ver = (__u32)(lmm_oi_id(&lum->lmm_oi) >> 32);
+               }
+
                if (yaml)
                        llapi_printf(LLAPI_MSG_NORMAL, DFID_NOBRACE"\n",
                                     (unsigned long long)seq, oid, ver);
@@ -3212,9 +3280,50 @@ void lmv_dump_user_lmm(struct lmv_user_md *lum, char *pool_name,
                if (flags & LMV_HASH_FLAG_LOST_LMV)
                        llapi_printf(LLAPI_MSG_NORMAL, ",lost_lmv");
 
-               separator = "\n";
+               if (verbose & VERBOSE_HASH_TYPE && !yaml)
+                       separator = " ";
+               else
+                       separator = "\n";
+       }
+
+       if ((verbose & VERBOSE_INHERIT) && lum->lum_magic == LMV_USER_MAGIC) {
+               llapi_printf(LLAPI_MSG_NORMAL, "%s", separator);
+               if (verbose & ~VERBOSE_INHERIT)
+                       llapi_printf(LLAPI_MSG_NORMAL, "lmv_max_inherit: ");
+               if (lum->lum_max_inherit == LMV_INHERIT_UNLIMITED)
+                       llapi_printf(LLAPI_MSG_NORMAL, "-1");
+               else if (lum->lum_max_inherit == LMV_INHERIT_NONE)
+                       llapi_printf(LLAPI_MSG_NORMAL, "0");
+               else
+                       llapi_printf(LLAPI_MSG_NORMAL, "%hhu",
+                                    lum->lum_max_inherit);
+               if (verbose & VERBOSE_INHERIT && !yaml)
+                       separator = " ";
+               else
+                       separator = "\n";
        }
 
+       if ((verbose & VERBOSE_INHERIT_RR) &&
+           lum->lum_magic == LMV_USER_MAGIC &&
+           lum->lum_stripe_offset == LMV_OFFSET_DEFAULT) {
+               llapi_printf(LLAPI_MSG_NORMAL, "%s", separator);
+               if (verbose & ~VERBOSE_INHERIT_RR)
+                       llapi_printf(LLAPI_MSG_NORMAL, "lmv_max_inherit_rr: ");
+               if (lum->lum_max_inherit_rr == LMV_INHERIT_RR_UNLIMITED)
+                       llapi_printf(LLAPI_MSG_NORMAL, "-1");
+               else if (lum->lum_max_inherit_rr == LMV_INHERIT_RR_NONE)
+                       llapi_printf(LLAPI_MSG_NORMAL, "0");
+               else
+                       llapi_printf(LLAPI_MSG_NORMAL, "%hhu",
+                                    lum->lum_max_inherit_rr);
+               if (verbose & VERBOSE_INHERIT_RR && !yaml)
+                       separator = " ";
+               else
+                       separator = "\n";
+       }
+
+       separator = "\n";
+
        if (verbose & VERBOSE_OBJID && lum->lum_magic != LMV_USER_MAGIC) {
                llapi_printf(LLAPI_MSG_NORMAL, "%s", separator);
                if (lum->lum_stripe_count > 0)
@@ -4005,7 +4114,7 @@ static void llapi_lov_dump_user_lmm(struct find_param *param, char *path,
        }
 }
 
-int llapi_file_get_stripe(const char *path, struct lov_user_md *lum)
+static int llapi_file_get_stripe1(const char *path, struct lov_user_md *lum)
 {
        const char *fname;
        char *dname;
@@ -4047,6 +4156,31 @@ out_free:
        return rc;
 }
 
+int llapi_file_get_stripe(const char *path, struct lov_user_md *lum)
+{
+       char *canon_path = NULL;
+       int rc, rc2;
+
+       rc = llapi_file_get_stripe1(path, lum);
+       if (!(rc == -ENOTTY || rc == -ENODATA))
+               goto out;
+
+       /* Handle failure due to symlinks by dereferencing path manually. */
+       canon_path = canonicalize_file_name(path);
+       if (canon_path == NULL)
+               goto out; /* Keep original rc. */
+
+       rc2 = llapi_file_get_stripe1(canon_path, lum);
+       if (rc2 < 0)
+               goto out; /* Keep original rc. */
+
+       rc = 0;
+out:
+       free(canon_path);
+
+       return rc;
+}
+
 int llapi_file_lookup(int dirfd, const char *name)
 {
        struct obd_ioctl_data data = { 0 };
@@ -5821,39 +5955,6 @@ int llapi_get_connect_flags(const char *mnt, __u64 *flags)
 }
 
 /**
- * Get a 64-bit value representing the version of file data pointed by fd.
- *
- * Each write or truncate, flushed on OST, will change this value. You can use
- * this value to verify if file data was modified. This only checks the file
- * data, not metadata.
- *
- * \param  flags  0: no flush pages, usually used it the process has already
- *                 taken locks;
- *                LL_DV_RD_FLUSH: OSTs will take LCK_PR to flush dirty pages
- *                  from clients;
- *                LL_DV_WR_FLUSH: OSTs will take LCK_PW to flush all caching
- *                  pages from clients.
- *
- * \retval 0 on success.
- * \retval -errno on error.
- */
-int llapi_get_data_version(int fd, __u64 *data_version, __u64 flags)
-{
-       int rc;
-       struct ioc_data_version idv;
-
-       idv.idv_flags = (__u32)flags;
-
-       rc = ioctl(fd, LL_IOC_DATA_VERSION, &idv);
-       if (rc)
-               rc = -errno;
-       else
-               *data_version = idv.idv_version;
-
-       return rc;
-}
-
-/**
  * Flush cached pages from all clients.
  *
  * \param fd   File descriptor
@@ -5867,301 +5968,3 @@ int llapi_file_flush(int fd)
        return llapi_get_data_version(fd, &dv, LL_DV_WR_FLUSH);
 }
 
-/*
- * Fetch layout version from OST objects. Layout version on OST objects are
- * only set when the file is a mirrored file AND after the file has been
- * written at least once.
- *
- * It actually fetches the least layout version from the objects.
- */
-int llapi_get_ost_layout_version(int fd, __u32 *layout_version)
-{
-       int rc;
-       struct ioc_data_version idv = { 0 };
-
-       rc = ioctl(fd, LL_IOC_DATA_VERSION, &idv);
-       if (rc)
-               rc = -errno;
-       else
-               *layout_version = idv.idv_layout_version;
-
-       return rc;
-}
-
-/*
- * Create a file without any name and open it for read/write
- *
- * - file is created as if it were a standard file in the given \a directory
- * - file does not appear in \a directory and mtime does not change because
- *   the filename is handled specially by the Lustre MDS.
- * - file is destroyed at final close
- *
- * \param[in]  directory       directory from which to inherit layout/MDT idx
- * \param[in]  mdt_idx         MDT index on which the file is created,
- *                             \a idx == -1 means no specific MDT is requested
- * \param[in]  mode            standard open(2) mode
- * \param[in]  stripe_param    stripe parameters. May be NULL.
- *
- * \retval     a file descriptor on success.
- * \retval     -errno on error.
- */
-int llapi_create_volatile_param(const char *directory, int mdt_idx,
-                               int open_flags, mode_t mode,
-                               const struct llapi_stripe_param *stripe_param)
-{
-       char file_path[PATH_MAX];
-       int saved_errno = errno;
-       int fd;
-       unsigned int rnumber;
-       int rc;
-
-       do {
-               rnumber = random();
-               if (mdt_idx == -1)
-                       rc = snprintf(file_path, sizeof(file_path),
-                                     "%s/" LUSTRE_VOLATILE_HDR "::%.4X",
-                                     directory, rnumber);
-               else
-                       rc = snprintf(file_path, sizeof(file_path),
-                                     "%s/" LUSTRE_VOLATILE_HDR ":%.4X:%.4X",
-                                     directory, mdt_idx, rnumber);
-
-               if (rc < 0 || rc >= sizeof(file_path))
-                       return -ENAMETOOLONG;
-
-               /*
-                * Either open O_WRONLY or O_RDWR, creating RDONLY
-                * is non-sensical here
-                */
-               if ((open_flags & O_ACCMODE) == O_RDONLY)
-                       open_flags = O_RDWR | (open_flags & ~O_ACCMODE);
-
-               open_flags |= O_CREAT | O_EXCL | O_NOFOLLOW;
-
-               if (stripe_param != NULL) {
-                       fd = llapi_file_open_param(file_path, open_flags,
-                                                  mode, stripe_param);
-                       if (fd < 0)
-                               rc = fd;
-               } else {
-                       fd = open(file_path, open_flags, mode);
-                       if (fd < 0)
-                               rc = -errno;
-               }
-       } while (fd < 0 && rc == -EEXIST);
-
-       if (fd < 0) {
-               llapi_error(LLAPI_MSG_ERROR, rc,
-                           "Cannot create volatile file '%s' in '%s'",
-                           file_path + strlen(directory) + 1 +
-                           LUSTRE_VOLATILE_HDR_LEN,
-                           directory);
-               return rc;
-       }
-
-       /*
-        * Unlink file in case this wasn't a Lustre filesystem and the magic
-        * volatile filename wasn't handled as intended. The effect is the
-        * same. If volatile open was supported then we expect unlink() to
-        * return -ENOENT.
-        */
-       (void)unlink(file_path);
-
-       /*
-        * Since we are returning successfully we restore errno (and
-        * mask out possible EEXIST from open() and ENOENT from unlink().
-        */
-       errno = saved_errno;
-
-       return fd;
-}
-
-/*
- * Create a file without any name open it for read/write
- *
- * - file is created as if it were a standard file in the given \a directory
- * - file does not appear in \a directory and mtime does not change because
- *   the filename is handled specially by the Lustre MDS.
- * - file is removed at final close
- * - file modes are rw------- since it doesn't make sense to have a read-only
- *   or write-only file that cannot be opened again.
- * - if user wants another mode it must use fchmod() on the open file, no
- *   security problems arise because it cannot be opened by another process.
- *
- * \param[in]  directory       directory from which to inherit layout/MDT idx
- * \param[in]  idx             MDT index on which the file is created,
- *                             \a idx == -1 means no specific MDT is requested
- * \param[in]  open_flags      standard open(2) flags
- *
- * \retval     a file descriptor on success.
- * \retval     -errno on error.
- */
-int llapi_create_volatile_idx(const char *directory, int mdt_idx,
-                             int open_flags)
-{
-       return llapi_create_volatile_param(directory, mdt_idx, open_flags,
-                                          S_IRUSR | S_IWUSR, NULL);
-}
-
-/**
- * Swap the layouts between 2 file descriptors
- * the 2 files must be open for writing
- * first fd received the ioctl, second fd is passed as arg
- * this is assymetric but avoid use of root path for ioctl
- */
-int llapi_fswap_layouts_grouplock(int fd1, int fd2, __u64 dv1, __u64 dv2,
-                                 int gid, __u64 flags)
-{
-       struct lustre_swap_layouts      lsl;
-       struct stat                     st1;
-       struct stat                     st2;
-       int                             rc;
-
-       if (flags & (SWAP_LAYOUTS_KEEP_ATIME | SWAP_LAYOUTS_KEEP_MTIME)) {
-               rc = fstat(fd1, &st1);
-               if (rc < 0)
-                       return -errno;
-
-               rc = fstat(fd2, &st2);
-               if (rc < 0)
-                       return -errno;
-       }
-       lsl.sl_fd = fd2;
-       lsl.sl_flags = flags;
-       lsl.sl_gid = gid;
-       lsl.sl_dv1 = dv1;
-       lsl.sl_dv2 = dv2;
-       rc = ioctl(fd1, LL_IOC_LOV_SWAP_LAYOUTS, &lsl);
-       if (rc < 0)
-               return -errno;
-
-       if (flags & (SWAP_LAYOUTS_KEEP_ATIME | SWAP_LAYOUTS_KEEP_MTIME)) {
-               struct timeval  tv1[2];
-               struct timeval  tv2[2];
-
-               memset(tv1, 0, sizeof(tv1));
-               memset(tv2, 0, sizeof(tv2));
-
-               if (flags & SWAP_LAYOUTS_KEEP_ATIME) {
-                       tv1[0].tv_sec = st1.st_atime;
-                       tv2[0].tv_sec = st2.st_atime;
-               } else {
-                       tv1[0].tv_sec = st2.st_atime;
-                       tv2[0].tv_sec = st1.st_atime;
-               }
-
-               if (flags & SWAP_LAYOUTS_KEEP_MTIME) {
-                       tv1[1].tv_sec = st1.st_mtime;
-                       tv2[1].tv_sec = st2.st_mtime;
-               } else {
-                       tv1[1].tv_sec = st2.st_mtime;
-                       tv2[1].tv_sec = st1.st_mtime;
-               }
-
-               rc = futimes(fd1, tv1);
-               if (rc < 0)
-                       return -errno;
-
-               rc = futimes(fd2, tv2);
-               if (rc < 0)
-                       return -errno;
-       }
-
-       return 0;
-}
-
-int llapi_fswap_layouts(int fd1, int fd2, __u64 dv1, __u64 dv2, __u64 flags)
-{
-       int     rc;
-       int     grp_id;
-
-       do
-               grp_id = random();
-       while (grp_id == 0);
-
-       rc = llapi_fswap_layouts_grouplock(fd1, fd2, dv1, dv2, grp_id, flags);
-       if (rc < 0)
-               return rc;
-
-       return 0;
-}
-
-/**
- * Swap the layouts between 2 files
- * the 2 files are open in write
- */
-int llapi_swap_layouts(const char *path1, const char *path2,
-                      __u64 dv1, __u64 dv2, __u64 flags)
-{
-       int     fd1, fd2, rc;
-
-       fd1 = open(path1, O_WRONLY | O_LOV_DELAY_CREATE);
-       if (fd1 < 0) {
-               rc = -errno;
-               llapi_error(LLAPI_MSG_ERROR, rc,
-                           "error: cannot open '%s' for write", path1);
-               goto out;
-       }
-
-       fd2 = open(path2, O_WRONLY | O_LOV_DELAY_CREATE);
-       if (fd2 < 0) {
-               rc = -errno;
-               llapi_error(LLAPI_MSG_ERROR, rc,
-                           "error: cannot open '%s' for write", path2);
-               goto out_close;
-       }
-
-       rc = llapi_fswap_layouts(fd1, fd2, dv1, dv2, flags);
-       if (rc < 0)
-               llapi_error(LLAPI_MSG_ERROR, rc,
-                           "error: cannot swap layout between '%s' and '%s'",
-                           path1, path2);
-
-       close(fd2);
-out_close:
-       close(fd1);
-out:
-       return rc;
-}
-
-/**
- * Take group lock.
- *
- * \param fd   File to lock.
- * \param gid  Group Identifier.
- *
- * \retval 0 on success.
- * \retval -errno on failure.
- */
-int llapi_group_lock(int fd, int gid)
-{
-       int rc;
-
-       rc = ioctl(fd, LL_IOC_GROUP_LOCK, gid);
-       if (rc < 0) {
-               rc = -errno;
-               llapi_error(LLAPI_MSG_ERROR, rc, "cannot get group lock");
-       }
-       return rc;
-}
-
-/**
- * Put group lock.
- *
- * \param fd   File to unlock.
- * \param gid  Group Identifier.
- *
- * \retval 0 on success.
- * \retval -errno on failure.
- */
-int llapi_group_unlock(int fd, int gid)
-{
-       int rc;
-
-       rc = ioctl(fd, LL_IOC_GROUP_UNLOCK, gid);
-       if (rc < 0) {
-               rc = -errno;
-               llapi_error(LLAPI_MSG_ERROR, rc, "cannot put group lock");
-       }
-       return rc;
-}