staging: lustre: fix 'NULL pointer dereference' errors
[cascardo/linux.git] / drivers / staging / lustre / lnet / selftest / conctl.c
1 /*
2  * GPL HEADER START
3  *
4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5  *
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.
9  *
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).
15  *
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.sun.com/software/products/lustre/docs/GPLv2.pdf
19  *
20  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
21  * CA 95054 USA or visit www.sun.com if you need additional information or
22  * have any questions.
23  *
24  * GPL HEADER END
25  */
26 /*
27  * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
28  * Use is subject to license terms.
29  *
30  * Copyright (c) 2012, Intel Corporation.
31  */
32 /*
33  * This file is part of Lustre, http://www.lustre.org/
34  * Lustre is a trademark of Sun Microsystems, Inc.
35  *
36  * lnet/selftest/conctl.c
37  *
38  * IOC handle in kernel
39  *
40  * Author: Liang Zhen <liangzhen@clusterfs.com>
41  */
42
43 #include "../../include/linux/libcfs/libcfs.h"
44 #include "../../include/linux/lnet/lib-lnet.h"
45 #include "../../include/linux/lnet/lnetst.h"
46 #include "console.h"
47
48 static int
49 lst_session_new_ioctl(lstio_session_new_args_t *args)
50 {
51         char *name;
52         int rc;
53
54         if (!args->lstio_ses_idp || /* address for output sid */
55             !args->lstio_ses_key ||    /* no key is specified */
56             !args->lstio_ses_namep || /* session name */
57             args->lstio_ses_nmlen <= 0 ||
58             args->lstio_ses_nmlen > LST_NAME_SIZE)
59                 return -EINVAL;
60
61         LIBCFS_ALLOC(name, args->lstio_ses_nmlen + 1);
62         if (!name)
63                 return -ENOMEM;
64
65         if (copy_from_user(name, args->lstio_ses_namep,
66                            args->lstio_ses_nmlen)) {
67                 LIBCFS_FREE(name, args->lstio_ses_nmlen + 1);
68                 return -EFAULT;
69         }
70
71         name[args->lstio_ses_nmlen] = 0;
72
73         rc = lstcon_session_new(name,
74                                 args->lstio_ses_key,
75                                 args->lstio_ses_feats,
76                                 args->lstio_ses_force,
77                                 args->lstio_ses_timeout,
78                                 args->lstio_ses_idp);
79
80         LIBCFS_FREE(name, args->lstio_ses_nmlen + 1);
81         return rc;
82 }
83
84 static int
85 lst_session_end_ioctl(lstio_session_end_args_t *args)
86 {
87         if (args->lstio_ses_key != console_session.ses_key)
88                 return -EACCES;
89
90         return lstcon_session_end();
91 }
92
93 static int
94 lst_session_info_ioctl(lstio_session_info_args_t *args)
95 {
96         /* no checking of key */
97
98         if (!args->lstio_ses_idp || /* address for output sid */
99             !args->lstio_ses_keyp || /* address for output key */
100             !args->lstio_ses_featp || /* address for output features */
101             !args->lstio_ses_ndinfo || /* address for output ndinfo */
102             !args->lstio_ses_namep || /* address for output name */
103             args->lstio_ses_nmlen  <= 0 ||
104             args->lstio_ses_nmlen > LST_NAME_SIZE)
105                 return -EINVAL;
106
107         return lstcon_session_info(args->lstio_ses_idp,
108                                    args->lstio_ses_keyp,
109                                    args->lstio_ses_featp,
110                                    args->lstio_ses_ndinfo,
111                                    args->lstio_ses_namep,
112                                    args->lstio_ses_nmlen);
113 }
114
115 static int
116 lst_debug_ioctl(lstio_debug_args_t *args)
117 {
118         char   *name   = NULL;
119         int     client = 1;
120         int     rc;
121
122         if (args->lstio_dbg_key != console_session.ses_key)
123                 return -EACCES;
124
125         if (!args->lstio_dbg_resultp)
126                 return -EINVAL;
127
128         if (args->lstio_dbg_namep && /* name of batch/group */
129             (args->lstio_dbg_nmlen <= 0 ||
130              args->lstio_dbg_nmlen > LST_NAME_SIZE))
131                 return -EINVAL;
132
133         if (args->lstio_dbg_namep) {
134                 LIBCFS_ALLOC(name, args->lstio_dbg_nmlen + 1);
135                 if (!name)
136                         return -ENOMEM;
137
138                 if (copy_from_user(name, args->lstio_dbg_namep,
139                                    args->lstio_dbg_nmlen)) {
140                         LIBCFS_FREE(name, args->lstio_dbg_nmlen + 1);
141
142                         return -EFAULT;
143                 }
144
145                 name[args->lstio_dbg_nmlen] = 0;
146         }
147
148         rc = -EINVAL;
149
150         switch (args->lstio_dbg_type) {
151         case LST_OPC_SESSION:
152                 rc = lstcon_session_debug(args->lstio_dbg_timeout,
153                                           args->lstio_dbg_resultp);
154                 break;
155
156         case LST_OPC_BATCHSRV:
157                 client = 0;
158         case LST_OPC_BATCHCLI:
159                 if (!name)
160                         goto out;
161
162                 rc = lstcon_batch_debug(args->lstio_dbg_timeout,
163                                         name, client, args->lstio_dbg_resultp);
164                 break;
165
166         case LST_OPC_GROUP:
167                 if (!name)
168                         goto out;
169
170                 rc = lstcon_group_debug(args->lstio_dbg_timeout,
171                                         name, args->lstio_dbg_resultp);
172                 break;
173
174         case LST_OPC_NODES:
175                 if (args->lstio_dbg_count <= 0 ||
176                     !args->lstio_dbg_idsp)
177                         goto out;
178
179                 rc = lstcon_nodes_debug(args->lstio_dbg_timeout,
180                                         args->lstio_dbg_count,
181                                         args->lstio_dbg_idsp,
182                                         args->lstio_dbg_resultp);
183                 break;
184
185         default:
186                 break;
187         }
188
189 out:
190         if (name)
191                 LIBCFS_FREE(name, args->lstio_dbg_nmlen + 1);
192
193         return rc;
194 }
195
196 static int
197 lst_group_add_ioctl(lstio_group_add_args_t *args)
198 {
199         char *name;
200         int rc;
201
202         if (args->lstio_grp_key != console_session.ses_key)
203                 return -EACCES;
204
205         if (!args->lstio_grp_namep ||
206             args->lstio_grp_nmlen <= 0 ||
207             args->lstio_grp_nmlen > LST_NAME_SIZE)
208                 return -EINVAL;
209
210         LIBCFS_ALLOC(name, args->lstio_grp_nmlen + 1);
211         if (!name)
212                 return -ENOMEM;
213
214         if (copy_from_user(name, args->lstio_grp_namep,
215                            args->lstio_grp_nmlen)) {
216                 LIBCFS_FREE(name, args->lstio_grp_nmlen);
217                 return -EFAULT;
218         }
219
220         name[args->lstio_grp_nmlen] = 0;
221
222         rc = lstcon_group_add(name);
223
224         LIBCFS_FREE(name, args->lstio_grp_nmlen + 1);
225
226         return rc;
227 }
228
229 static int
230 lst_group_del_ioctl(lstio_group_del_args_t *args)
231 {
232         int     rc;
233         char   *name;
234
235         if (args->lstio_grp_key != console_session.ses_key)
236                 return -EACCES;
237
238         if (!args->lstio_grp_namep ||
239             args->lstio_grp_nmlen <= 0 ||
240             args->lstio_grp_nmlen > LST_NAME_SIZE)
241                 return -EINVAL;
242
243         LIBCFS_ALLOC(name, args->lstio_grp_nmlen + 1);
244         if (!name)
245                 return -ENOMEM;
246
247         if (copy_from_user(name, args->lstio_grp_namep,
248                            args->lstio_grp_nmlen)) {
249                 LIBCFS_FREE(name, args->lstio_grp_nmlen + 1);
250                 return -EFAULT;
251         }
252
253         name[args->lstio_grp_nmlen] = 0;
254
255         rc = lstcon_group_del(name);
256
257         LIBCFS_FREE(name, args->lstio_grp_nmlen + 1);
258
259         return rc;
260 }
261
262 static int
263 lst_group_update_ioctl(lstio_group_update_args_t *args)
264 {
265         int     rc;
266         char   *name;
267
268         if (args->lstio_grp_key != console_session.ses_key)
269                 return -EACCES;
270
271         if (!args->lstio_grp_resultp ||
272             !args->lstio_grp_namep ||
273             args->lstio_grp_nmlen <= 0 ||
274             args->lstio_grp_nmlen > LST_NAME_SIZE)
275                 return -EINVAL;
276
277         LIBCFS_ALLOC(name, args->lstio_grp_nmlen + 1);
278         if (!name)
279                 return -ENOMEM;
280
281         if (copy_from_user(name,
282                            args->lstio_grp_namep,
283                            args->lstio_grp_nmlen)) {
284                 LIBCFS_FREE(name, args->lstio_grp_nmlen + 1);
285                 return -EFAULT;
286         }
287
288         name[args->lstio_grp_nmlen] = 0;
289
290         switch (args->lstio_grp_opc) {
291         case LST_GROUP_CLEAN:
292                 rc = lstcon_group_clean(name, args->lstio_grp_args);
293                 break;
294
295         case LST_GROUP_REFRESH:
296                 rc = lstcon_group_refresh(name, args->lstio_grp_resultp);
297                 break;
298
299         case LST_GROUP_RMND:
300                 if (args->lstio_grp_count  <= 0 ||
301                     !args->lstio_grp_idsp) {
302                         rc = -EINVAL;
303                         break;
304                 }
305                 rc = lstcon_nodes_remove(name, args->lstio_grp_count,
306                                          args->lstio_grp_idsp,
307                                          args->lstio_grp_resultp);
308                 break;
309
310         default:
311                 rc = -EINVAL;
312                 break;
313         }
314
315         LIBCFS_FREE(name, args->lstio_grp_nmlen + 1);
316
317         return rc;
318 }
319
320 static int
321 lst_nodes_add_ioctl(lstio_group_nodes_args_t *args)
322 {
323         unsigned feats;
324         int rc;
325         char *name;
326
327         if (args->lstio_grp_key != console_session.ses_key)
328                 return -EACCES;
329
330         if (!args->lstio_grp_idsp || /* array of ids */
331             args->lstio_grp_count <= 0 ||
332             !args->lstio_grp_resultp ||
333             !args->lstio_grp_featp ||
334             !args->lstio_grp_namep ||
335             args->lstio_grp_nmlen <= 0 ||
336             args->lstio_grp_nmlen > LST_NAME_SIZE)
337                 return -EINVAL;
338
339         LIBCFS_ALLOC(name, args->lstio_grp_nmlen + 1);
340         if (!name)
341                 return -ENOMEM;
342
343         if (copy_from_user(name, args->lstio_grp_namep,
344                            args->lstio_grp_nmlen)) {
345                 LIBCFS_FREE(name, args->lstio_grp_nmlen + 1);
346
347                 return -EFAULT;
348         }
349
350         name[args->lstio_grp_nmlen] = 0;
351
352         rc = lstcon_nodes_add(name, args->lstio_grp_count,
353                               args->lstio_grp_idsp, &feats,
354                               args->lstio_grp_resultp);
355
356         LIBCFS_FREE(name, args->lstio_grp_nmlen + 1);
357         if (!rc &&
358             copy_to_user(args->lstio_grp_featp, &feats, sizeof(feats))) {
359                 return -EINVAL;
360         }
361
362         return rc;
363 }
364
365 static int
366 lst_group_list_ioctl(lstio_group_list_args_t *args)
367 {
368         if (args->lstio_grp_key != console_session.ses_key)
369                 return -EACCES;
370
371         if (args->lstio_grp_idx   < 0 ||
372             !args->lstio_grp_namep ||
373             args->lstio_grp_nmlen <= 0 ||
374             args->lstio_grp_nmlen > LST_NAME_SIZE)
375                 return -EINVAL;
376
377         return lstcon_group_list(args->lstio_grp_idx,
378                               args->lstio_grp_nmlen,
379                               args->lstio_grp_namep);
380 }
381
382 static int
383 lst_group_info_ioctl(lstio_group_info_args_t *args)
384 {
385         char *name;
386         int ndent;
387         int index;
388         int rc;
389
390         if (args->lstio_grp_key != console_session.ses_key)
391                 return -EACCES;
392
393         if (!args->lstio_grp_namep ||
394             args->lstio_grp_nmlen <= 0 ||
395             args->lstio_grp_nmlen > LST_NAME_SIZE)
396                 return -EINVAL;
397
398         if (!args->lstio_grp_entp &&  /* output: group entry */
399             !args->lstio_grp_dentsp)  /* output: node entry */
400                 return -EINVAL;
401
402         if (args->lstio_grp_dentsp) { /* have node entry */
403                 if (!args->lstio_grp_idxp || /* node index */
404                     !args->lstio_grp_ndentp) /* # of node entry */
405                         return -EINVAL;
406
407                 if (copy_from_user(&ndent, args->lstio_grp_ndentp,
408                                    sizeof(ndent)) ||
409                     copy_from_user(&index, args->lstio_grp_idxp,
410                                    sizeof(index)))
411                         return -EFAULT;
412
413                 if (ndent <= 0 || index < 0)
414                         return -EINVAL;
415         }
416
417         LIBCFS_ALLOC(name, args->lstio_grp_nmlen + 1);
418         if (!name)
419                 return -ENOMEM;
420
421         if (copy_from_user(name, args->lstio_grp_namep,
422                            args->lstio_grp_nmlen)) {
423                 LIBCFS_FREE(name, args->lstio_grp_nmlen + 1);
424                 return -EFAULT;
425         }
426
427         name[args->lstio_grp_nmlen] = 0;
428
429         rc = lstcon_group_info(name, args->lstio_grp_entp,
430                                &index, &ndent, args->lstio_grp_dentsp);
431
432         LIBCFS_FREE(name, args->lstio_grp_nmlen + 1);
433
434         if (rc)
435                 return rc;
436
437         if (args->lstio_grp_dentsp &&
438             (copy_to_user(args->lstio_grp_idxp, &index, sizeof(index)) ||
439              copy_to_user(args->lstio_grp_ndentp, &ndent, sizeof(ndent))))
440                 return -EFAULT;
441
442         return 0;
443 }
444
445 static int
446 lst_batch_add_ioctl(lstio_batch_add_args_t *args)
447 {
448         int rc;
449         char *name;
450
451         if (args->lstio_bat_key != console_session.ses_key)
452                 return -EACCES;
453
454         if (!args->lstio_bat_namep ||
455             args->lstio_bat_nmlen <= 0 ||
456             args->lstio_bat_nmlen > LST_NAME_SIZE)
457                 return -EINVAL;
458
459         LIBCFS_ALLOC(name, args->lstio_bat_nmlen + 1);
460         if (!name)
461                 return -ENOMEM;
462
463         if (copy_from_user(name, args->lstio_bat_namep,
464                            args->lstio_bat_nmlen)) {
465                 LIBCFS_FREE(name, args->lstio_bat_nmlen + 1);
466                 return -EFAULT;
467         }
468
469         name[args->lstio_bat_nmlen] = 0;
470
471         rc = lstcon_batch_add(name);
472
473         LIBCFS_FREE(name, args->lstio_bat_nmlen + 1);
474
475         return rc;
476 }
477
478 static int
479 lst_batch_run_ioctl(lstio_batch_run_args_t *args)
480 {
481         int rc;
482         char *name;
483
484         if (args->lstio_bat_key != console_session.ses_key)
485                 return -EACCES;
486
487         if (!args->lstio_bat_namep ||
488             args->lstio_bat_nmlen <= 0 ||
489             args->lstio_bat_nmlen > LST_NAME_SIZE)
490                 return -EINVAL;
491
492         LIBCFS_ALLOC(name, args->lstio_bat_nmlen + 1);
493         if (!name)
494                 return -ENOMEM;
495
496         if (copy_from_user(name, args->lstio_bat_namep,
497                            args->lstio_bat_nmlen)) {
498                 LIBCFS_FREE(name, args->lstio_bat_nmlen + 1);
499                 return -EFAULT;
500         }
501
502         name[args->lstio_bat_nmlen] = 0;
503
504         rc = lstcon_batch_run(name, args->lstio_bat_timeout,
505                               args->lstio_bat_resultp);
506
507         LIBCFS_FREE(name, args->lstio_bat_nmlen + 1);
508
509         return rc;
510 }
511
512 static int
513 lst_batch_stop_ioctl(lstio_batch_stop_args_t *args)
514 {
515         int rc;
516         char *name;
517
518         if (args->lstio_bat_key != console_session.ses_key)
519                 return -EACCES;
520
521         if (!args->lstio_bat_resultp ||
522             !args->lstio_bat_namep ||
523             args->lstio_bat_nmlen <= 0 ||
524             args->lstio_bat_nmlen > LST_NAME_SIZE)
525                 return -EINVAL;
526
527         LIBCFS_ALLOC(name, args->lstio_bat_nmlen + 1);
528         if (!name)
529                 return -ENOMEM;
530
531         if (copy_from_user(name, args->lstio_bat_namep,
532                            args->lstio_bat_nmlen)) {
533                 LIBCFS_FREE(name, args->lstio_bat_nmlen + 1);
534                 return -EFAULT;
535         }
536
537         name[args->lstio_bat_nmlen] = 0;
538
539         rc = lstcon_batch_stop(name, args->lstio_bat_force,
540                                args->lstio_bat_resultp);
541
542         LIBCFS_FREE(name, args->lstio_bat_nmlen + 1);
543
544         return rc;
545 }
546
547 static int
548 lst_batch_query_ioctl(lstio_batch_query_args_t *args)
549 {
550         char   *name;
551         int     rc;
552
553         if (args->lstio_bat_key != console_session.ses_key)
554                 return -EACCES;
555
556         if (!args->lstio_bat_resultp ||
557             !args->lstio_bat_namep ||
558             args->lstio_bat_nmlen <= 0 ||
559             args->lstio_bat_nmlen > LST_NAME_SIZE)
560                 return -EINVAL;
561
562         if (args->lstio_bat_testidx < 0)
563                 return -EINVAL;
564
565         LIBCFS_ALLOC(name, args->lstio_bat_nmlen + 1);
566         if (!name)
567                 return -ENOMEM;
568
569         if (copy_from_user(name, args->lstio_bat_namep,
570                            args->lstio_bat_nmlen)) {
571                 LIBCFS_FREE(name, args->lstio_bat_nmlen + 1);
572                 return -EFAULT;
573         }
574
575         name[args->lstio_bat_nmlen] = 0;
576
577         rc = lstcon_test_batch_query(name,
578                                      args->lstio_bat_testidx,
579                                      args->lstio_bat_client,
580                                      args->lstio_bat_timeout,
581                                      args->lstio_bat_resultp);
582
583         LIBCFS_FREE(name, args->lstio_bat_nmlen + 1);
584
585         return rc;
586 }
587
588 static int
589 lst_batch_list_ioctl(lstio_batch_list_args_t *args)
590 {
591         if (args->lstio_bat_key != console_session.ses_key)
592                 return -EACCES;
593
594         if (args->lstio_bat_idx   < 0 ||
595             !args->lstio_bat_namep ||
596             args->lstio_bat_nmlen <= 0 ||
597             args->lstio_bat_nmlen > LST_NAME_SIZE)
598                 return -EINVAL;
599
600         return lstcon_batch_list(args->lstio_bat_idx,
601                               args->lstio_bat_nmlen,
602                               args->lstio_bat_namep);
603 }
604
605 static int
606 lst_batch_info_ioctl(lstio_batch_info_args_t *args)
607 {
608         char *name;
609         int rc;
610         int index;
611         int ndent;
612
613         if (args->lstio_bat_key != console_session.ses_key)
614                 return -EACCES;
615
616         if (!args->lstio_bat_namep || /* batch name */
617             args->lstio_bat_nmlen <= 0 ||
618             args->lstio_bat_nmlen > LST_NAME_SIZE)
619                 return -EINVAL;
620
621         if (!args->lstio_bat_entp && /* output: batch entry */
622             !args->lstio_bat_dentsp) /* output: node entry */
623                 return -EINVAL;
624
625         if (args->lstio_bat_dentsp) { /* have node entry */
626                 if (!args->lstio_bat_idxp || /* node index */
627                     !args->lstio_bat_ndentp) /* # of node entry */
628                         return -EINVAL;
629
630                 if (copy_from_user(&index, args->lstio_bat_idxp,
631                                    sizeof(index)) ||
632                     copy_from_user(&ndent, args->lstio_bat_ndentp,
633                                    sizeof(ndent)))
634                         return -EFAULT;
635
636                 if (ndent <= 0 || index < 0)
637                         return -EINVAL;
638         }
639
640         LIBCFS_ALLOC(name, args->lstio_bat_nmlen + 1);
641         if (!name)
642                 return -ENOMEM;
643
644         if (copy_from_user(name, args->lstio_bat_namep,
645                            args->lstio_bat_nmlen)) {
646                 LIBCFS_FREE(name, args->lstio_bat_nmlen + 1);
647                 return -EFAULT;
648         }
649
650         name[args->lstio_bat_nmlen] = 0;
651
652         rc = lstcon_batch_info(name, args->lstio_bat_entp,
653                                args->lstio_bat_server, args->lstio_bat_testidx,
654                                &index, &ndent, args->lstio_bat_dentsp);
655
656         LIBCFS_FREE(name, args->lstio_bat_nmlen + 1);
657
658         if (rc)
659                 return rc;
660
661         if (args->lstio_bat_dentsp &&
662             (copy_to_user(args->lstio_bat_idxp, &index, sizeof(index)) ||
663              copy_to_user(args->lstio_bat_ndentp, &ndent, sizeof(ndent))))
664                 rc = -EFAULT;
665
666         return rc;
667 }
668
669 static int
670 lst_stat_query_ioctl(lstio_stat_args_t *args)
671 {
672         int rc;
673         char *name = NULL;
674
675         /* TODO: not finished */
676         if (args->lstio_sta_key != console_session.ses_key)
677                 return -EACCES;
678
679         if (!args->lstio_sta_resultp)
680                 return -EINVAL;
681
682         if (args->lstio_sta_idsp) {
683                 if (args->lstio_sta_count <= 0)
684                         return -EINVAL;
685
686                 rc = lstcon_nodes_stat(args->lstio_sta_count,
687                                        args->lstio_sta_idsp,
688                                        args->lstio_sta_timeout,
689                                        args->lstio_sta_resultp);
690         } else if (args->lstio_sta_namep) {
691                 if (args->lstio_sta_nmlen <= 0 ||
692                     args->lstio_sta_nmlen > LST_NAME_SIZE)
693                         return -EINVAL;
694
695                 LIBCFS_ALLOC(name, args->lstio_sta_nmlen + 1);
696                 if (!name)
697                         return -ENOMEM;
698
699                 rc = copy_from_user(name, args->lstio_sta_namep,
700                                     args->lstio_sta_nmlen);
701                 if (!rc)
702                         rc = lstcon_group_stat(name, args->lstio_sta_timeout,
703                                                args->lstio_sta_resultp);
704                 else
705                         rc = -EFAULT;
706         } else {
707                 rc = -EINVAL;
708         }
709
710         if (name)
711                 LIBCFS_FREE(name, args->lstio_sta_nmlen + 1);
712         return rc;
713 }
714
715 static int lst_test_add_ioctl(lstio_test_args_t *args)
716 {
717         char            *batch_name;
718         char            *src_name = NULL;
719         char            *dst_name = NULL;
720         void            *param = NULL;
721         int             ret = 0;
722         int             rc = -ENOMEM;
723
724         if (!args->lstio_tes_resultp ||
725             !args->lstio_tes_retp ||
726             !args->lstio_tes_bat_name || /* no specified batch */
727             args->lstio_tes_bat_nmlen <= 0 ||
728             args->lstio_tes_bat_nmlen > LST_NAME_SIZE ||
729             !args->lstio_tes_sgrp_name || /* no source group */
730             args->lstio_tes_sgrp_nmlen <= 0 ||
731             args->lstio_tes_sgrp_nmlen > LST_NAME_SIZE ||
732             !args->lstio_tes_dgrp_name || /* no target group */
733             args->lstio_tes_dgrp_nmlen <= 0 ||
734             args->lstio_tes_dgrp_nmlen > LST_NAME_SIZE)
735                 return -EINVAL;
736
737         if (!args->lstio_tes_loop || /* negative is infinite */
738             args->lstio_tes_concur <= 0 ||
739             args->lstio_tes_dist <= 0 ||
740             args->lstio_tes_span <= 0)
741                 return -EINVAL;
742
743         /* have parameter, check if parameter length is valid */
744         if (args->lstio_tes_param &&
745             (args->lstio_tes_param_len <= 0 ||
746              args->lstio_tes_param_len > PAGE_CACHE_SIZE - sizeof(lstcon_test_t)))
747                 return -EINVAL;
748
749         LIBCFS_ALLOC(batch_name, args->lstio_tes_bat_nmlen + 1);
750         if (!batch_name)
751                 return rc;
752
753         LIBCFS_ALLOC(src_name, args->lstio_tes_sgrp_nmlen + 1);
754         if (!src_name)
755                 goto out;
756
757         LIBCFS_ALLOC(dst_name, args->lstio_tes_dgrp_nmlen + 1);
758          if (!dst_name)
759                 goto out;
760
761         if (args->lstio_tes_param) {
762                 LIBCFS_ALLOC(param, args->lstio_tes_param_len);
763                 if (!param)
764                         goto out;
765                 if (copy_from_user(param, args->lstio_tes_param,
766                                    args->lstio_tes_param_len)) {
767                         rc = -EFAULT;
768                         goto out;
769                 }
770         }
771
772         rc = -EFAULT;
773         if (copy_from_user(batch_name, args->lstio_tes_bat_name,
774                            args->lstio_tes_bat_nmlen) ||
775             copy_from_user(src_name, args->lstio_tes_sgrp_name,
776                            args->lstio_tes_sgrp_nmlen) ||
777             copy_from_user(dst_name, args->lstio_tes_dgrp_name,
778                            args->lstio_tes_dgrp_nmlen))
779                 goto out;
780
781         rc = lstcon_test_add(batch_name, args->lstio_tes_type,
782                              args->lstio_tes_loop, args->lstio_tes_concur,
783                              args->lstio_tes_dist, args->lstio_tes_span,
784                              src_name, dst_name, param,
785                              args->lstio_tes_param_len,
786                              &ret, args->lstio_tes_resultp);
787
788         if (ret)
789                 rc = (copy_to_user(args->lstio_tes_retp, &ret,
790                                    sizeof(ret))) ? -EFAULT : 0;
791 out:
792         if (batch_name)
793                 LIBCFS_FREE(batch_name, args->lstio_tes_bat_nmlen + 1);
794
795         if (src_name)
796                 LIBCFS_FREE(src_name, args->lstio_tes_sgrp_nmlen + 1);
797
798         if (dst_name)
799                 LIBCFS_FREE(dst_name, args->lstio_tes_dgrp_nmlen + 1);
800
801         if (param)
802                 LIBCFS_FREE(param, args->lstio_tes_param_len);
803
804         return rc;
805 }
806
807 int
808 lstcon_ioctl_entry(unsigned int cmd, struct libcfs_ioctl_hdr *hdr)
809 {
810         char   *buf;
811         struct libcfs_ioctl_data *data;
812         int     opc;
813         int     rc;
814
815         if (cmd != IOC_LIBCFS_LNETST)
816                 return -EINVAL;
817
818         data = container_of(hdr, struct libcfs_ioctl_data, ioc_hdr);
819
820         opc = data->ioc_u32[0];
821
822         if (data->ioc_plen1 > PAGE_CACHE_SIZE)
823                 return -EINVAL;
824
825         LIBCFS_ALLOC(buf, data->ioc_plen1);
826         if (!buf)
827                 return -ENOMEM;
828
829         /* copy in parameter */
830         if (copy_from_user(buf, data->ioc_pbuf1, data->ioc_plen1)) {
831                 LIBCFS_FREE(buf, data->ioc_plen1);
832                 return -EFAULT;
833         }
834
835         mutex_lock(&console_session.ses_mutex);
836
837         console_session.ses_laststamp = ktime_get_real_seconds();
838
839         if (console_session.ses_shutdown) {
840                 rc = -ESHUTDOWN;
841                 goto out;
842         }
843
844         if (console_session.ses_expired)
845                 lstcon_session_end();
846
847         if (opc != LSTIO_SESSION_NEW &&
848             console_session.ses_state == LST_SESSION_NONE) {
849                 CDEBUG(D_NET, "LST no active session\n");
850                 rc = -ESRCH;
851                 goto out;
852         }
853
854         memset(&console_session.ses_trans_stat, 0, sizeof(lstcon_trans_stat_t));
855
856         switch (opc) {
857         case LSTIO_SESSION_NEW:
858                 rc = lst_session_new_ioctl((lstio_session_new_args_t *)buf);
859                 break;
860         case LSTIO_SESSION_END:
861                 rc = lst_session_end_ioctl((lstio_session_end_args_t *)buf);
862                 break;
863         case LSTIO_SESSION_INFO:
864                 rc = lst_session_info_ioctl((lstio_session_info_args_t *)buf);
865                 break;
866         case LSTIO_DEBUG:
867                 rc = lst_debug_ioctl((lstio_debug_args_t *)buf);
868                 break;
869         case LSTIO_GROUP_ADD:
870                 rc = lst_group_add_ioctl((lstio_group_add_args_t *)buf);
871                 break;
872         case LSTIO_GROUP_DEL:
873                 rc = lst_group_del_ioctl((lstio_group_del_args_t *)buf);
874                 break;
875         case LSTIO_GROUP_UPDATE:
876                 rc = lst_group_update_ioctl((lstio_group_update_args_t *)buf);
877                 break;
878         case LSTIO_NODES_ADD:
879                 rc = lst_nodes_add_ioctl((lstio_group_nodes_args_t *)buf);
880                 break;
881         case LSTIO_GROUP_LIST:
882                 rc = lst_group_list_ioctl((lstio_group_list_args_t *)buf);
883                 break;
884         case LSTIO_GROUP_INFO:
885                 rc = lst_group_info_ioctl((lstio_group_info_args_t *)buf);
886                 break;
887         case LSTIO_BATCH_ADD:
888                 rc = lst_batch_add_ioctl((lstio_batch_add_args_t *)buf);
889                 break;
890         case LSTIO_BATCH_START:
891                 rc = lst_batch_run_ioctl((lstio_batch_run_args_t *)buf);
892                 break;
893         case LSTIO_BATCH_STOP:
894                 rc = lst_batch_stop_ioctl((lstio_batch_stop_args_t *)buf);
895                 break;
896         case LSTIO_BATCH_QUERY:
897                 rc = lst_batch_query_ioctl((lstio_batch_query_args_t *)buf);
898                 break;
899         case LSTIO_BATCH_LIST:
900                 rc = lst_batch_list_ioctl((lstio_batch_list_args_t *)buf);
901                 break;
902         case LSTIO_BATCH_INFO:
903                 rc = lst_batch_info_ioctl((lstio_batch_info_args_t *)buf);
904                 break;
905         case LSTIO_TEST_ADD:
906                 rc = lst_test_add_ioctl((lstio_test_args_t *)buf);
907                 break;
908         case LSTIO_STAT_QUERY:
909                 rc = lst_stat_query_ioctl((lstio_stat_args_t *)buf);
910                 break;
911         default:
912                 rc = -EINVAL;
913         }
914
915         if (copy_to_user(data->ioc_pbuf2, &console_session.ses_trans_stat,
916                          sizeof(lstcon_trans_stat_t)))
917                 rc = -EFAULT;
918 out:
919         mutex_unlock(&console_session.ses_mutex);
920
921         LIBCFS_FREE(buf, data->ioc_plen1);
922
923         return rc;
924 }