+/**
+ * Return the current HSM states and HSM requests related to file pointed by \a
+ * path.
+ *
+ * \param hus Should be allocated by caller. Will be filled with current file
+ * states.
+ *
+ * \retval 0 on success.
+ * \retval -errno on error.
+ */
+int llapi_hsm_state_get_fd(int fd, struct hsm_user_state *hus)
+{
+ int rc;
+
+ rc = ioctl(fd, LL_IOC_HSM_STATE_GET, hus);
+ /* If error, save errno value */
+ rc = rc ? -errno : 0;
+
+ return rc;
+}
+
+/**
+ * Return the current HSM states and HSM requests related to file pointed by \a
+ * path.
+ *
+ * see llapi_hsm_state_get_fd() for args use and return
+ */
+int llapi_hsm_state_get(const char *path, struct hsm_user_state *hus)
+{
+ int fd;
+ int rc;
+
+ fd = open(path, O_RDONLY | O_NONBLOCK);
+ if (fd < 0)
+ return -errno;
+
+ rc = llapi_hsm_state_get_fd(fd, hus);
+
+ close(fd);
+ return rc;
+}
+
+/**
+ * Set HSM states of file pointed by \a fd
+ *
+ * Using the provided bitmasks, the current HSM states for this file will be
+ * changed. \a archive_id could be used to change the archive number also. Set
+ * it to 0 if you do not want to change it.
+ *
+ * \param setmask Bitmask for flag to be set.
+ * \param clearmask Bitmask for flag to be cleared.
+ * \param archive_id Archive number identifier to use. 0 means no change.
+ *
+ * \retval 0 on success.
+ * \retval -errno on error.
+ */
+int llapi_hsm_state_set_fd(int fd, __u64 setmask, __u64 clearmask,
+ __u32 archive_id)
+{
+ struct hsm_state_set hss;
+ int rc;
+
+ hss.hss_valid = HSS_SETMASK|HSS_CLEARMASK;
+ hss.hss_setmask = setmask;
+ hss.hss_clearmask = clearmask;
+ /* Change archive_id if provided. We can only change
+ * to set something different than 0. */
+ if (archive_id > 0) {
+ hss.hss_valid |= HSS_ARCHIVE_ID;
+ hss.hss_archive_id = archive_id;
+ }
+ rc = ioctl(fd, LL_IOC_HSM_STATE_SET, &hss);
+ /* If error, save errno value */
+ rc = rc ? -errno : 0;
+
+ return rc;
+}
+
+/**
+ * Set HSM states of file pointed by \a path.
+ *
+ * see llapi_hsm_state_set_fd() for args use and return
+ */
+int llapi_hsm_state_set(const char *path, __u64 setmask, __u64 clearmask,
+ __u32 archive_id)
+{
+ int fd;
+ int rc;
+
+ fd = open(path, O_WRONLY | O_LOV_DELAY_CREATE | O_NONBLOCK);
+ if (fd < 0)
+ return -errno;
+
+ rc = llapi_hsm_state_set_fd(fd, setmask, clearmask, archive_id);
+
+ close(fd);
+ return rc;
+}
+
+/**
+ * Return the current HSM request related to file pointed by \a path.
+ *
+ * \param hca Should be allocated by caller. Will be filled with current file
+ * actions.
+ *
+ * \retval 0 on success.
+ * \retval -errno on error.
+ */
+int llapi_hsm_current_action(const char *path, struct hsm_current_action *hca)
+{
+ int fd;
+ int rc;
+
+ fd = open(path, O_RDONLY | O_NONBLOCK);
+ if (fd < 0)
+ return -errno;
+
+ rc = ioctl(fd, LL_IOC_HSM_ACTION, hca);
+ /* If error, save errno value */
+ rc = rc ? -errno : 0;
+
+ close(fd);
+ return rc;
+}
+
+/**
+ * Allocate a hsm_user_request with the specified carateristics.
+ * This structure should be freed with free().
+ *
+ * \return an allocated structure on success, NULL otherwise.
+ */
+struct hsm_user_request *llapi_hsm_user_request_alloc(int itemcount,
+ int data_len)
+{
+ int len = 0;
+
+ len += sizeof(struct hsm_user_request);
+ len += sizeof(struct hsm_user_item) * itemcount;
+ len += data_len;
+
+ return (struct hsm_user_request *)malloc(len);
+}
+
+/**
+ * Send a HSM request to Lustre, described in \param request.
+ *
+ * \param path Fullpath to the file to operate on.
+ * \param request The request, allocated with llapi_hsm_user_request_alloc().
+ *
+ * \return 0 on success, an error code otherwise.
+ */
+int llapi_hsm_request(const char *path, const struct hsm_user_request *request)
+{
+ int rc;
+ int fd;
+
+ rc = get_root_path(WANT_FD, NULL, &fd, (char *)path, -1);
+ if (rc)
+ return rc;
+
+ rc = ioctl(fd, LL_IOC_HSM_REQUEST, request);
+ /* If error, save errno value */
+ rc = rc ? -errno : 0;
+
+ close(fd);
+ return rc;
+}
+