+ if (copy_from_user(lk, data, size))
+ GOTO(out_lk, rc = -EFAULT);
+
+ if (lk->lk_flags & LK_FLG_STOP)
+ goto do_ioctl;
+
+ if (!(lk->lk_flags & LK_FLG_DATANR)) {
+ __u32 archive_mask = lk->lk_data_count;
+ int count;
+
+ /* old hsm agent to old MDS */
+ if (!exp_connect_archive_id_array(exp))
+ goto do_ioctl;
+
+ /* old hsm agent to new MDS */
+ lk->lk_flags |= LK_FLG_DATANR;
+
+ if (archive_mask == 0)
+ goto do_ioctl;
+
+ count = hweight32(archive_mask);
+ new_size = offsetof(struct lustre_kernelcomm, lk_data[count]);
+ OBD_ALLOC(tmp, new_size);
+ if (tmp == NULL)
+ GOTO(out_lk, rc = -ENOMEM);
+
+ memcpy(tmp, lk, size);
+ tmp->lk_data_count = count;
+ OBD_FREE(lk, size);
+ lk = tmp;
+ size = new_size;
+
+ count = 0;
+ for (i = 0; i < sizeof(archive_mask) * 8; i++) {
+ if ((1 << i) & archive_mask) {
+ lk->lk_data[count] = i + 1;
+ count++;
+ }
+ }
+ goto do_ioctl;
+ }
+
+ /* new hsm agent to new mds */
+ if (lk->lk_data_count > 0) {
+ new_size = offsetof(struct lustre_kernelcomm,
+ lk_data[lk->lk_data_count]);
+ OBD_ALLOC(tmp, new_size);
+ if (tmp == NULL)
+ GOTO(out_lk, rc = -ENOMEM);
+
+ OBD_FREE(lk, size);
+ lk = tmp;
+ size = new_size;
+
+ if (copy_from_user(lk, data, size))
+ GOTO(out_lk, rc = -EFAULT);