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