+ param->fp_depth++;
+
+ return 0;
+}
+
+static int cb_mv_init(char *path, DIR *parent, DIR **dirp,
+ void *param_data, struct dirent64 *de)
+{
+ struct find_param *param = (struct find_param *)param_data;
+ DIR *dir = parent;
+ char raw[OBD_MAX_IOCTL_BUFFER] = {'\0'};
+ char *rawbuf = raw;
+ struct obd_ioctl_data data = { 0 };
+ int fd;
+ int ret;
+ char *filename;
+
+ LASSERT(parent != NULL || dirp != NULL);
+ if (dirp != NULL)
+ closedir(*dirp);
+
+ if (parent == NULL) {
+ dir = opendir_parent(path);
+ if (dir == NULL) {
+ *dirp = NULL;
+ ret = -errno;
+ llapi_error(LLAPI_MSG_ERROR, ret,
+ "can not open %s", path);
+ return ret;
+ }
+ }
+
+ fd = dirfd(dir);
+
+ filename = basename(path);
+ data.ioc_inlbuf1 = (char *)filename;
+ data.ioc_inllen1 = strlen(filename) + 1;
+ data.ioc_inlbuf2 = (char *)¶m->fp_mdt_index;
+ data.ioc_inllen2 = sizeof(param->fp_mdt_index);
+ ret = obd_ioctl_pack(&data, &rawbuf, sizeof(raw));
+ if (ret != 0) {
+ llapi_error(LLAPI_MSG_ERROR, ret,
+ "llapi_obd_statfs: error packing ioctl data");
+ goto out;
+ }
+
+ ret = ioctl(fd, LL_IOC_MIGRATE, rawbuf);
+ if (ret != 0) {
+ ret = -errno;
+ fprintf(stderr, "%s migrate failed %d\n", path, ret);
+ goto out;
+ } else if (param->fp_verbose & VERBOSE_DETAIL) {
+ fprintf(stdout, "migrate %s to MDT%d\n",
+ path, param->fp_mdt_index);
+ }
+
+out:
+ if (dirp != NULL) {
+ /* If the directory is being migration, we need
+ * close the directory after migration,
+ * so the old directory cache will be cleanup
+ * on the client side, and re-open to get the
+ * new directory handle */
+ *dirp = opendir(path);
+ if (dirp == NULL) {
+ ret = -errno;
+ llapi_error(LLAPI_MSG_ERROR, ret,
+ "%s: Failed to open '%s'", __func__, path);
+ return ret;
+ }
+ }
+
+ if (parent == NULL)
+ closedir(dir);
+
+ return ret;
+}
+
+int llapi_mv(char *path, struct find_param *param)
+{
+ return param_callback(path, cb_mv_init, cb_common_fini, param);