+int llapi_dir_set_default_lmv_stripe(const char *name, int stripe_offset,
+ int stripe_count, int stripe_pattern,
+ const char *pool_name)
+{
+ struct lmv_user_md lum = { 0 };
+ int fd;
+ int rc = 0;
+
+ lum.lum_magic = LMV_USER_MAGIC;
+ lum.lum_stripe_offset = stripe_offset;
+ lum.lum_stripe_count = stripe_count;
+ lum.lum_hash_type = stripe_pattern;
+ if (pool_name != NULL) {
+ if (strlen(pool_name) >= sizeof(lum.lum_pool_name)) {
+ llapi_err_noerrno(LLAPI_MSG_ERROR,
+ "error LL_IOC_LMV_SET_DEFAULT_STRIPE '%s'"
+ ": too large pool name: %s", name, pool_name);
+ return -E2BIG;
+ }
+ strncpy(lum.lum_pool_name, pool_name,
+ sizeof(lum.lum_pool_name));
+ }
+
+ fd = open(name, O_DIRECTORY | O_RDONLY);
+ if (fd < 0) {
+ rc = -errno;
+ llapi_error(LLAPI_MSG_ERROR, rc, "unable to open '%s'", name);
+ return rc;
+ }
+
+ rc = ioctl(fd, LL_IOC_LMV_SET_DEFAULT_STRIPE, &lum);
+ if (rc < 0) {
+ char *errmsg = "stripe already set";
+ rc = -errno;
+ if (errno != EEXIST && errno != EALREADY)
+ errmsg = strerror(errno);
+
+ llapi_err_noerrno(LLAPI_MSG_ERROR,
+ "error on LL_IOC_LMV_SETSTRIPE '%s' (%d): %s",
+ name, fd, errmsg);
+ }
+ close(fd);
+ return rc;
+}
+
+int llapi_dir_create_pool(const char *name, int mode, int stripe_offset,
+ int stripe_count, int stripe_pattern,
+ const char *pool_name)
+{
+ struct lmv_user_md lmu = { 0 };
+ struct obd_ioctl_data data = { 0 };
+ char rawbuf[8192];
+ char *buf = rawbuf;
+ char *dirpath = NULL;
+ char *namepath = NULL;
+ char *dir;
+ char *filename;
+ int fd = -1;
+ int rc;
+
+ dirpath = strdup(name);
+ namepath = strdup(name);
+ if (!dirpath || !namepath)
+ return -ENOMEM;
+
+ lmu.lum_magic = LMV_USER_MAGIC;
+ lmu.lum_stripe_offset = stripe_offset;
+ lmu.lum_stripe_count = stripe_count;
+ lmu.lum_hash_type = stripe_pattern;
+ if (pool_name != NULL) {
+ if (strlen(pool_name) > LOV_MAXPOOLNAME) {
+ llapi_err_noerrno(LLAPI_MSG_ERROR,
+ "error LL_IOC_LMV_SETSTRIPE '%s' : too large"
+ "pool name: %s", name, pool_name);
+ rc = -E2BIG;
+ goto out;
+ }
+ memcpy(lmu.lum_pool_name, pool_name, strlen(pool_name));
+ }
+
+ filename = basename(namepath);
+ dir = dirname(dirpath);
+
+ data.ioc_inlbuf1 = (char *)filename;
+ data.ioc_inllen1 = strlen(filename) + 1;
+ data.ioc_inlbuf2 = (char *)&lmu;
+ data.ioc_inllen2 = sizeof(struct lmv_user_md);
+ data.ioc_type = mode;
+ rc = obd_ioctl_pack(&data, &buf, sizeof(rawbuf));
+ if (rc) {
+ llapi_error(LLAPI_MSG_ERROR, rc,
+ "error: LL_IOC_LMV_SETSTRIPE pack failed '%s'.",
+ name);
+ goto out;
+ }
+
+ fd = open(dir, O_DIRECTORY | O_RDONLY);
+ if (fd < 0) {
+ rc = -errno;
+ llapi_error(LLAPI_MSG_ERROR, rc, "unable to open '%s'", name);
+ goto out;
+ }
+
+ if (ioctl(fd, LL_IOC_LMV_SETSTRIPE, buf)) {
+ char *errmsg = "stripe already set";
+ rc = -errno;
+ if (errno != EEXIST && errno != EALREADY)
+ errmsg = strerror(errno);
+
+ llapi_err_noerrno(LLAPI_MSG_ERROR,
+ "error on LL_IOC_LMV_SETSTRIPE '%s' (%d): %s",
+ name, fd, errmsg);
+ }
+ close(fd);
+out:
+ free(dirpath);
+ free(namepath);
+ return rc;
+}
+
+int llapi_direntry_remove(char *dname)
+{
+ char *dirpath = NULL;
+ char *namepath = NULL;
+ char *dir;
+ char *filename;
+ int fd = -1;
+ int rc = 0;
+
+ dirpath = strdup(dname);
+ namepath = strdup(dname);
+ if (!dirpath || !namepath)
+ return -ENOMEM;
+
+ filename = basename(namepath);
+
+ dir = dirname(dirpath);
+
+ fd = open(dir, O_DIRECTORY | O_RDONLY);
+ if (fd < 0) {
+ rc = -errno;
+ llapi_error(LLAPI_MSG_ERROR, rc, "unable to open '%s'",
+ filename);
+ goto out;
+ }
+
+ if (ioctl(fd, LL_IOC_REMOVE_ENTRY, filename)) {
+ char *errmsg = strerror(errno);
+ llapi_err_noerrno(LLAPI_MSG_ERROR,
+ "error on ioctl "LPX64" for '%s' (%d): %s",
+ (__u64)LL_IOC_LMV_SETSTRIPE, filename,
+ fd, errmsg);
+ }
+out:
+ free(dirpath);
+ free(namepath);
+ if (fd != -1)
+ close(fd);
+ return rc;
+}
+