4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 only,
8 * as published by the Free Software Foundation.
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License version 2 for more details (a copy is included
14 * in the LICENSE file that accompanied this code).
16 * You should have received a copy of the GNU General Public License
17 * version 2 along with this program; If not, see
18 * http://www.gnu.org/licenses/gpl-2.0.html
23 * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
24 * Use is subject to license terms.
26 * Copyright (c) 2012, 2014, Intel Corporation.
29 * This file is part of Lustre, http://www.lustre.org/
31 * lnet/selftest/conctl.c
33 * IOC handle in kernel
35 * Author: Liang Zhen <liangzhen@clusterfs.com>
38 #include <libcfs/libcfs.h>
39 #include <lnet/lib-lnet.h>
43 lst_session_new_ioctl(struct lstio_session_new_args *args)
48 if (args->lstio_ses_idp == NULL || /* address for output sid */
49 args->lstio_ses_key == 0 || /* no key is specified */
50 args->lstio_ses_namep == NULL || /* session name */
51 args->lstio_ses_nmlen <= 0 ||
52 args->lstio_ses_nmlen > LST_NAME_SIZE)
55 LIBCFS_ALLOC(name, args->lstio_ses_nmlen + 1);
59 if (copy_from_user(name, args->lstio_ses_namep,
60 args->lstio_ses_nmlen)) {
61 LIBCFS_FREE(name, args->lstio_ses_nmlen + 1);
65 name[args->lstio_ses_nmlen] = 0;
67 rc = lstcon_session_new(name,
69 args->lstio_ses_feats,
70 args->lstio_ses_timeout,
71 args->lstio_ses_force,
74 LIBCFS_FREE(name, args->lstio_ses_nmlen + 1);
79 lst_session_end_ioctl(struct lstio_session_end_args *args)
81 if (args->lstio_ses_key != console_session.ses_key)
84 return lstcon_session_end();
88 lst_session_info_ioctl(struct lstio_session_info_args *args)
90 /* no checking of key */
92 if (args->lstio_ses_idp == NULL || /* address for ouput sid */
93 args->lstio_ses_keyp == NULL || /* address for ouput key */
94 args->lstio_ses_featp == NULL || /* address for ouput features */
95 args->lstio_ses_ndinfo == NULL || /* address for output ndinfo */
96 args->lstio_ses_namep == NULL || /* address for ouput name */
97 args->lstio_ses_nmlen <= 0 ||
98 args->lstio_ses_nmlen > LST_NAME_SIZE)
101 return lstcon_session_info(args->lstio_ses_idp,
102 args->lstio_ses_keyp,
103 args->lstio_ses_featp,
104 args->lstio_ses_ndinfo,
105 args->lstio_ses_namep,
106 args->lstio_ses_nmlen);
110 lst_debug_ioctl(struct lstio_debug_args *args)
116 if (args->lstio_dbg_key != console_session.ses_key)
119 if (args->lstio_dbg_resultp == NULL)
122 if (args->lstio_dbg_namep != NULL && /* name of batch/group */
123 (args->lstio_dbg_nmlen <= 0 ||
124 args->lstio_dbg_nmlen > LST_NAME_SIZE))
127 if (args->lstio_dbg_namep != NULL) {
128 LIBCFS_ALLOC(name, args->lstio_dbg_nmlen + 1);
132 if (copy_from_user(name, args->lstio_dbg_namep,
133 args->lstio_dbg_nmlen)) {
134 LIBCFS_FREE(name, args->lstio_dbg_nmlen + 1);
139 name[args->lstio_dbg_nmlen] = 0;
144 switch (args->lstio_dbg_type) {
145 case LST_OPC_SESSION:
146 rc = lstcon_session_debug(args->lstio_dbg_timeout,
147 args->lstio_dbg_resultp);
150 case LST_OPC_BATCHSRV:
153 case LST_OPC_BATCHCLI:
157 rc = lstcon_batch_debug(args->lstio_dbg_timeout,
158 name, client, args->lstio_dbg_resultp);
165 rc = lstcon_group_debug(args->lstio_dbg_timeout,
166 name, args->lstio_dbg_resultp);
170 if (args->lstio_dbg_count <= 0 ||
171 args->lstio_dbg_idsp == NULL)
174 rc = lstcon_nodes_debug(args->lstio_dbg_timeout,
175 args->lstio_dbg_count,
176 args->lstio_dbg_idsp,
177 args->lstio_dbg_resultp);
186 LIBCFS_FREE(name, args->lstio_dbg_nmlen + 1);
192 lst_group_add_ioctl(struct lstio_group_add_args *args)
197 if (args->lstio_grp_key != console_session.ses_key)
200 if (args->lstio_grp_namep == NULL ||
201 args->lstio_grp_nmlen <= 0 ||
202 args->lstio_grp_nmlen > LST_NAME_SIZE)
205 LIBCFS_ALLOC(name, args->lstio_grp_nmlen + 1);
209 if (copy_from_user(name, args->lstio_grp_namep,
210 args->lstio_grp_nmlen)) {
211 LIBCFS_FREE(name, args->lstio_grp_nmlen);
215 name[args->lstio_grp_nmlen] = 0;
217 rc = lstcon_group_add(name);
219 LIBCFS_FREE(name, args->lstio_grp_nmlen + 1);
225 lst_group_del_ioctl(struct lstio_group_del_args *args)
230 if (args->lstio_grp_key != console_session.ses_key)
233 if (args->lstio_grp_namep == NULL ||
234 args->lstio_grp_nmlen <= 0 ||
235 args->lstio_grp_nmlen > LST_NAME_SIZE)
238 LIBCFS_ALLOC(name, args->lstio_grp_nmlen + 1);
242 if (copy_from_user(name, args->lstio_grp_namep,
243 args->lstio_grp_nmlen)) {
244 LIBCFS_FREE(name, args->lstio_grp_nmlen + 1);
248 name[args->lstio_grp_nmlen] = 0;
250 rc = lstcon_group_del(name);
252 LIBCFS_FREE(name, args->lstio_grp_nmlen + 1);
258 lst_group_update_ioctl(struct lstio_group_update_args *args)
263 if (args->lstio_grp_key != console_session.ses_key)
266 if (args->lstio_grp_resultp == NULL ||
267 args->lstio_grp_namep == NULL ||
268 args->lstio_grp_nmlen <= 0 ||
269 args->lstio_grp_nmlen > LST_NAME_SIZE)
272 LIBCFS_ALLOC(name, args->lstio_grp_nmlen + 1);
276 if (copy_from_user(name, args->lstio_grp_namep,
277 args->lstio_grp_nmlen)) {
278 LIBCFS_FREE(name, args->lstio_grp_nmlen + 1);
282 name[args->lstio_grp_nmlen] = 0;
284 switch (args->lstio_grp_opc) {
285 case LST_GROUP_CLEAN:
286 rc = lstcon_group_clean(name, args->lstio_grp_args);
289 case LST_GROUP_REFRESH:
290 rc = lstcon_group_refresh(name, args->lstio_grp_resultp);
294 if (args->lstio_grp_count <= 0 ||
295 args->lstio_grp_idsp == NULL) {
299 rc = lstcon_nodes_remove(name, args->lstio_grp_count,
300 args->lstio_grp_idsp,
301 args->lstio_grp_resultp);
309 LIBCFS_FREE(name, args->lstio_grp_nmlen + 1);
315 lst_nodes_add_ioctl(struct lstio_group_nodes_args *args)
321 if (args->lstio_grp_key != console_session.ses_key)
324 if (args->lstio_grp_idsp == NULL || /* array of ids */
325 args->lstio_grp_count <= 0 ||
326 args->lstio_grp_resultp == NULL ||
327 args->lstio_grp_featp == NULL ||
328 args->lstio_grp_namep == NULL ||
329 args->lstio_grp_nmlen <= 0 ||
330 args->lstio_grp_nmlen > LST_NAME_SIZE)
333 LIBCFS_ALLOC(name, args->lstio_grp_nmlen + 1);
337 if (copy_from_user(name, args->lstio_grp_namep,
338 args->lstio_grp_nmlen)) {
339 LIBCFS_FREE(name, args->lstio_grp_nmlen + 1);
344 name[args->lstio_grp_nmlen] = 0;
346 rc = lstcon_nodes_add(name, args->lstio_grp_count,
347 args->lstio_grp_idsp, &feats,
348 args->lstio_grp_resultp);
350 LIBCFS_FREE(name, args->lstio_grp_nmlen + 1);
352 copy_to_user(args->lstio_grp_featp, &feats, sizeof(feats))) {
360 lst_group_list_ioctl(struct lstio_group_list_args *args)
362 if (args->lstio_grp_key != console_session.ses_key)
365 if (args->lstio_grp_idx < 0 ||
366 args->lstio_grp_namep == NULL ||
367 args->lstio_grp_nmlen <= 0 ||
368 args->lstio_grp_nmlen > LST_NAME_SIZE)
371 return lstcon_group_list(args->lstio_grp_idx,
372 args->lstio_grp_nmlen,
373 args->lstio_grp_namep);
377 lst_group_info_ioctl(struct lstio_group_info_args *args)
384 if (args->lstio_grp_key != console_session.ses_key)
387 if (args->lstio_grp_namep == NULL ||
388 args->lstio_grp_nmlen <= 0 ||
389 args->lstio_grp_nmlen > LST_NAME_SIZE)
392 if (args->lstio_grp_entp == NULL && /* output: group entry */
393 args->lstio_grp_dentsp == NULL) /* output: node entry */
396 if (args->lstio_grp_dentsp != NULL) { /* have node entry */
397 if (args->lstio_grp_idxp == NULL || /* node index */
398 args->lstio_grp_ndentp == NULL) /* # of node entry */
401 if (copy_from_user(&ndent, args->lstio_grp_ndentp,
403 copy_from_user(&index, args->lstio_grp_idxp,
407 if (ndent <= 0 || index < 0)
411 LIBCFS_ALLOC(name, args->lstio_grp_nmlen + 1);
415 if (copy_from_user(name, args->lstio_grp_namep,
416 args->lstio_grp_nmlen)) {
417 LIBCFS_FREE(name, args->lstio_grp_nmlen + 1);
421 name[args->lstio_grp_nmlen] = 0;
423 rc = lstcon_group_info(name, args->lstio_grp_entp,
424 &index, &ndent, args->lstio_grp_dentsp);
426 LIBCFS_FREE(name, args->lstio_grp_nmlen + 1);
431 if (args->lstio_grp_dentsp != NULL &&
432 (copy_to_user(args->lstio_grp_idxp, &index, sizeof(index)) ||
433 copy_to_user(args->lstio_grp_ndentp, &ndent, sizeof(ndent))))
440 lst_batch_add_ioctl(struct lstio_batch_add_args *args)
445 if (args->lstio_bat_key != console_session.ses_key)
448 if (args->lstio_bat_namep == NULL ||
449 args->lstio_bat_nmlen <= 0 ||
450 args->lstio_bat_nmlen > LST_NAME_SIZE)
453 LIBCFS_ALLOC(name, args->lstio_bat_nmlen + 1);
457 if (copy_from_user(name, args->lstio_bat_namep,
458 args->lstio_bat_nmlen)) {
459 LIBCFS_FREE(name, args->lstio_bat_nmlen + 1);
463 name[args->lstio_bat_nmlen] = 0;
465 rc = lstcon_batch_add(name);
467 LIBCFS_FREE(name, args->lstio_bat_nmlen + 1);
473 lst_batch_run_ioctl(struct lstio_batch_run_args *args)
478 if (args->lstio_bat_key != console_session.ses_key)
481 if (args->lstio_bat_namep == NULL ||
482 args->lstio_bat_nmlen <= 0 ||
483 args->lstio_bat_nmlen > LST_NAME_SIZE)
486 LIBCFS_ALLOC(name, args->lstio_bat_nmlen + 1);
490 if (copy_from_user(name, args->lstio_bat_namep,
491 args->lstio_bat_nmlen)) {
492 LIBCFS_FREE(name, args->lstio_bat_nmlen + 1);
496 name[args->lstio_bat_nmlen] = 0;
498 rc = lstcon_batch_run(name, args->lstio_bat_timeout,
499 args->lstio_bat_resultp);
501 LIBCFS_FREE(name, args->lstio_bat_nmlen + 1);
507 lst_batch_stop_ioctl(struct lstio_batch_stop_args *args)
512 if (args->lstio_bat_key != console_session.ses_key)
515 if (args->lstio_bat_resultp == NULL ||
516 args->lstio_bat_namep == NULL ||
517 args->lstio_bat_nmlen <= 0 ||
518 args->lstio_bat_nmlen > LST_NAME_SIZE)
521 LIBCFS_ALLOC(name, args->lstio_bat_nmlen + 1);
525 if (copy_from_user(name, args->lstio_bat_namep,
526 args->lstio_bat_nmlen)) {
527 LIBCFS_FREE(name, args->lstio_bat_nmlen + 1);
531 name[args->lstio_bat_nmlen] = 0;
533 rc = lstcon_batch_stop(name, args->lstio_bat_force,
534 args->lstio_bat_resultp);
536 LIBCFS_FREE(name, args->lstio_bat_nmlen + 1);
542 lst_batch_query_ioctl(struct lstio_batch_query_args *args)
547 if (args->lstio_bat_key != console_session.ses_key)
550 if (args->lstio_bat_resultp == NULL ||
551 args->lstio_bat_namep == NULL ||
552 args->lstio_bat_nmlen <= 0 ||
553 args->lstio_bat_nmlen > LST_NAME_SIZE)
556 if (args->lstio_bat_testidx < 0)
559 LIBCFS_ALLOC(name, args->lstio_bat_nmlen + 1);
563 if (copy_from_user(name, args->lstio_bat_namep,
564 args->lstio_bat_nmlen)) {
565 LIBCFS_FREE(name, args->lstio_bat_nmlen + 1);
569 name[args->lstio_bat_nmlen] = 0;
571 rc = lstcon_test_batch_query(name,
572 args->lstio_bat_testidx,
573 args->lstio_bat_client,
574 args->lstio_bat_timeout,
575 args->lstio_bat_resultp);
577 LIBCFS_FREE(name, args->lstio_bat_nmlen + 1);
583 lst_batch_list_ioctl(struct lstio_batch_list_args *args)
585 if (args->lstio_bat_key != console_session.ses_key)
588 if (args->lstio_bat_idx < 0 ||
589 args->lstio_bat_namep == NULL ||
590 args->lstio_bat_nmlen <= 0 ||
591 args->lstio_bat_nmlen > LST_NAME_SIZE)
594 return lstcon_batch_list(args->lstio_bat_idx,
595 args->lstio_bat_nmlen,
596 args->lstio_bat_namep);
600 lst_batch_info_ioctl(struct lstio_batch_info_args *args)
607 if (args->lstio_bat_key != console_session.ses_key)
610 if (args->lstio_bat_namep == NULL || /* batch name */
611 args->lstio_bat_nmlen <= 0 ||
612 args->lstio_bat_nmlen > LST_NAME_SIZE)
615 if (args->lstio_bat_entp == NULL && /* output: batch entry */
616 args->lstio_bat_dentsp == NULL) /* output: node entry */
619 if (args->lstio_bat_dentsp != NULL) { /* have node entry */
620 if (args->lstio_bat_idxp == NULL || /* node index */
621 args->lstio_bat_ndentp == NULL) /* # of node entry */
624 if (copy_from_user(&index, args->lstio_bat_idxp,
626 copy_from_user(&ndent, args->lstio_bat_ndentp,
630 if (ndent <= 0 || index < 0)
634 LIBCFS_ALLOC(name, args->lstio_bat_nmlen + 1);
638 if (copy_from_user(name, args->lstio_bat_namep,
639 args->lstio_bat_nmlen)) {
640 LIBCFS_FREE(name, args->lstio_bat_nmlen + 1);
644 name[args->lstio_bat_nmlen] = 0;
646 rc = lstcon_batch_info(name,
647 args->lstio_bat_entp, args->lstio_bat_server,
648 args->lstio_bat_testidx, &index, &ndent,
649 args->lstio_bat_dentsp);
651 LIBCFS_FREE(name, args->lstio_bat_nmlen + 1);
656 if (args->lstio_bat_dentsp != NULL &&
657 (copy_to_user(args->lstio_bat_idxp, &index, sizeof(index)) ||
658 copy_to_user(args->lstio_bat_ndentp, &ndent, sizeof(ndent))))
665 lst_stat_query_ioctl(struct lstio_stat_args *args)
670 /* TODO: not finished */
671 if (args->lstio_sta_key != console_session.ses_key)
674 if (args->lstio_sta_resultp == NULL)
677 if (args->lstio_sta_idsp != NULL) {
678 if (args->lstio_sta_count <= 0)
681 rc = lstcon_nodes_stat(args->lstio_sta_count,
682 args->lstio_sta_idsp,
683 args->lstio_sta_timeout,
684 args->lstio_sta_resultp);
685 } else if (args->lstio_sta_namep != NULL) {
686 if (args->lstio_sta_nmlen <= 0 ||
687 args->lstio_sta_nmlen > LST_NAME_SIZE)
690 LIBCFS_ALLOC(name, args->lstio_sta_nmlen + 1);
694 rc = copy_from_user(name, args->lstio_sta_namep,
695 args->lstio_sta_nmlen);
697 rc = lstcon_group_stat(name, args->lstio_sta_timeout,
698 args->lstio_sta_resultp);
707 LIBCFS_FREE(name, args->lstio_sta_nmlen + 1);
711 static int lst_test_add_ioctl(struct lstio_test_args *args)
714 char *src_name = NULL;
715 char *dst_name = NULL;
720 if (args->lstio_tes_resultp == NULL ||
721 args->lstio_tes_retp == NULL ||
722 args->lstio_tes_bat_name == NULL || /* no specified batch */
723 args->lstio_tes_bat_nmlen <= 0 ||
724 args->lstio_tes_bat_nmlen > LST_NAME_SIZE ||
725 args->lstio_tes_sgrp_name == NULL || /* no source group */
726 args->lstio_tes_sgrp_nmlen <= 0 ||
727 args->lstio_tes_sgrp_nmlen > LST_NAME_SIZE ||
728 args->lstio_tes_dgrp_name == NULL || /* no target group */
729 args->lstio_tes_dgrp_nmlen <= 0 ||
730 args->lstio_tes_dgrp_nmlen > LST_NAME_SIZE)
733 if (args->lstio_tes_loop == 0 || /* negative is infinite */
734 args->lstio_tes_concur <= 0 ||
735 args->lstio_tes_dist <= 0 ||
736 args->lstio_tes_span <= 0)
739 /* have parameter, check if parameter length is valid */
740 if (args->lstio_tes_param != NULL &&
741 (args->lstio_tes_param_len <= 0 ||
742 args->lstio_tes_param_len >
743 PAGE_SIZE - sizeof(struct lstcon_test)))
746 LIBCFS_ALLOC(batch_name, args->lstio_tes_bat_nmlen + 1);
747 if (batch_name == NULL)
750 LIBCFS_ALLOC(src_name, args->lstio_tes_sgrp_nmlen + 1);
751 if (src_name == NULL)
754 LIBCFS_ALLOC(dst_name, args->lstio_tes_dgrp_nmlen + 1);
755 if (dst_name == NULL)
758 if (args->lstio_tes_param != NULL) {
759 LIBCFS_ALLOC(param, args->lstio_tes_param_len);
762 if (copy_from_user(param, args->lstio_tes_param,
763 args->lstio_tes_param_len)) {
770 if (copy_from_user(batch_name, args->lstio_tes_bat_name,
771 args->lstio_tes_bat_nmlen) ||
772 copy_from_user(src_name, args->lstio_tes_sgrp_name,
773 args->lstio_tes_sgrp_nmlen) ||
774 copy_from_user(dst_name, args->lstio_tes_dgrp_name,
775 args->lstio_tes_dgrp_nmlen))
778 rc = lstcon_test_add(batch_name,
779 args->lstio_tes_type,
780 args->lstio_tes_loop,
781 args->lstio_tes_concur,
782 args->lstio_tes_dist, args->lstio_tes_span,
783 src_name, dst_name, param,
784 args->lstio_tes_param_len,
785 &ret, args->lstio_tes_resultp);
788 rc = (copy_to_user(args->lstio_tes_retp, &ret,
789 sizeof(ret))) ? -EFAULT : 0;
791 if (batch_name != NULL)
792 LIBCFS_FREE(batch_name, args->lstio_tes_bat_nmlen + 1);
794 if (src_name != NULL)
795 LIBCFS_FREE(src_name, args->lstio_tes_sgrp_nmlen + 1);
797 if (dst_name != NULL)
798 LIBCFS_FREE(dst_name, args->lstio_tes_dgrp_nmlen + 1);
801 LIBCFS_FREE(param, args->lstio_tes_param_len);
807 lstcon_ioctl_entry(struct notifier_block *nb,
808 unsigned long cmd, void *vdata)
810 struct libcfs_ioctl_hdr *hdr = vdata;
811 struct libcfs_ioctl_data *data;
816 if (cmd != IOC_LIBCFS_LNETST)
819 data = container_of(hdr, struct libcfs_ioctl_data, ioc_hdr);
821 opc = data->ioc_u32[0];
823 if (data->ioc_plen1 > PAGE_SIZE)
826 LIBCFS_ALLOC(buf, data->ioc_plen1);
832 /* copy in parameter */
833 if (copy_from_user(buf, data->ioc_pbuf1, data->ioc_plen1)) {
838 mutex_lock(&console_session.ses_mutex);
840 console_session.ses_laststamp = ktime_get_real_seconds();
842 if (console_session.ses_shutdown) {
847 if (console_session.ses_expired)
848 lstcon_session_end();
850 if (opc != LSTIO_SESSION_NEW &&
851 console_session.ses_state == LST_SESSION_NONE) {
852 CDEBUG(D_NET, "LST no active session\n");
857 memset(&console_session.ses_trans_stat, 0,
858 sizeof(struct lstcon_trans_stat));
861 case LSTIO_SESSION_NEW:
862 rc = lst_session_new_ioctl((struct lstio_session_new_args *)buf);
864 case LSTIO_SESSION_END:
865 rc = lst_session_end_ioctl((struct lstio_session_end_args *)buf);
867 case LSTIO_SESSION_INFO:
868 rc = lst_session_info_ioctl((struct lstio_session_info_args *)buf);
871 rc = lst_debug_ioctl((struct lstio_debug_args *)buf);
873 case LSTIO_GROUP_ADD:
874 rc = lst_group_add_ioctl((struct lstio_group_add_args *)buf);
876 case LSTIO_GROUP_DEL:
877 rc = lst_group_del_ioctl((struct lstio_group_del_args *)buf);
879 case LSTIO_GROUP_UPDATE:
880 rc = lst_group_update_ioctl((struct lstio_group_update_args *)buf);
882 case LSTIO_NODES_ADD:
883 rc = lst_nodes_add_ioctl((struct lstio_group_nodes_args *)buf);
885 case LSTIO_GROUP_LIST:
886 rc = lst_group_list_ioctl((struct lstio_group_list_args *)buf);
888 case LSTIO_GROUP_INFO:
889 rc = lst_group_info_ioctl((struct lstio_group_info_args *)buf);
891 case LSTIO_BATCH_ADD:
892 rc = lst_batch_add_ioctl((struct lstio_batch_add_args *)buf);
894 case LSTIO_BATCH_START:
895 rc = lst_batch_run_ioctl((struct lstio_batch_run_args *)buf);
897 case LSTIO_BATCH_STOP:
898 rc = lst_batch_stop_ioctl((struct lstio_batch_stop_args *)buf);
900 case LSTIO_BATCH_QUERY:
901 rc = lst_batch_query_ioctl((struct lstio_batch_query_args *)buf);
903 case LSTIO_BATCH_LIST:
904 rc = lst_batch_list_ioctl((struct lstio_batch_list_args *)buf);
906 case LSTIO_BATCH_INFO:
907 rc = lst_batch_info_ioctl((struct lstio_batch_info_args *)buf);
910 rc = lst_test_add_ioctl((struct lstio_test_args *)buf);
912 case LSTIO_STAT_QUERY:
913 rc = lst_stat_query_ioctl((struct lstio_stat_args *)buf);
920 if (copy_to_user(data->ioc_pbuf2, &console_session.ses_trans_stat,
921 sizeof(struct lstcon_trans_stat)))
924 mutex_unlock(&console_session.ses_mutex);
926 LIBCFS_FREE(buf, data->ioc_plen1);
928 return notifier_from_ioctl_errno(rc);