Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 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) 2008, 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 | |
| 37 | #define DEBUG_SUBSYSTEM S_LNET |
| 38 | |
Greg Kroah-Hartman | 9fdaf8c | 2014-07-11 20:51:16 -0700 | [diff] [blame] | 39 | #include "../../../include/linux/libcfs/libcfs.h" |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 40 | |
| 41 | #define LNET_MINOR 240 |
| 42 | |
Amir Shehata | 1290932 | 2016-02-22 17:29:02 -0500 | [diff] [blame] | 43 | int libcfs_ioctl_data_adjust(struct libcfs_ioctl_data *data) |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 44 | { |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 45 | if (libcfs_ioctl_is_invalid(data)) { |
Liang Zhen | 6d0aeaa3 | 2016-03-22 19:03:56 -0400 | [diff] [blame] | 46 | CERROR("libcfs ioctl: parameter not correctly formatted\n"); |
Greg Kroah-Hartman | 0a3bdb0 | 2013-08-03 10:35:28 +0800 | [diff] [blame] | 47 | return -EINVAL; |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 48 | } |
| 49 | |
| 50 | if (data->ioc_inllen1) |
| 51 | data->ioc_inlbuf1 = &data->ioc_bulk[0]; |
| 52 | |
| 53 | if (data->ioc_inllen2) |
| 54 | data->ioc_inlbuf2 = &data->ioc_bulk[0] + |
| 55 | cfs_size_round(data->ioc_inllen1); |
| 56 | |
Greg Kroah-Hartman | 0a3bdb0 | 2013-08-03 10:35:28 +0800 | [diff] [blame] | 57 | return 0; |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 58 | } |
| 59 | |
Liang Zhen | e4efb34 | 2016-03-22 19:03:50 -0400 | [diff] [blame] | 60 | int libcfs_ioctl_getdata(struct libcfs_ioctl_hdr **hdr_pp, |
| 61 | const struct libcfs_ioctl_hdr __user *uhdr) |
Amir Shehata | 1290932 | 2016-02-22 17:29:02 -0500 | [diff] [blame] | 62 | { |
| 63 | struct libcfs_ioctl_hdr hdr; |
Liang Zhen | e4efb34 | 2016-03-22 19:03:50 -0400 | [diff] [blame] | 64 | int err = 0; |
Amir Shehata | 1290932 | 2016-02-22 17:29:02 -0500 | [diff] [blame] | 65 | |
Liang Zhen | e4efb34 | 2016-03-22 19:03:50 -0400 | [diff] [blame] | 66 | if (copy_from_user(&hdr, uhdr, sizeof(uhdr))) |
Amir Shehata | 1290932 | 2016-02-22 17:29:02 -0500 | [diff] [blame] | 67 | return -EFAULT; |
| 68 | |
Amir Shehata | 2e9a51b | 2016-02-22 17:29:03 -0500 | [diff] [blame] | 69 | if (hdr.ioc_version != LIBCFS_IOCTL_VERSION && |
| 70 | hdr.ioc_version != LIBCFS_IOCTL_VERSION2) { |
Liang Zhen | 6d0aeaa3 | 2016-03-22 19:03:56 -0400 | [diff] [blame] | 71 | CERROR("libcfs ioctl: version mismatch expected %#x, got %#x\n", |
Amir Shehata | 1290932 | 2016-02-22 17:29:02 -0500 | [diff] [blame] | 72 | LIBCFS_IOCTL_VERSION, hdr.ioc_version); |
| 73 | return -EINVAL; |
| 74 | } |
| 75 | |
Liang Zhen | ed2f549 | 2016-03-22 19:03:57 -0400 | [diff] [blame] | 76 | if (hdr.ioc_len < sizeof(struct libcfs_ioctl_data)) { |
| 77 | CERROR("libcfs ioctl: user buffer too small for ioctl\n"); |
| 78 | return -EINVAL; |
| 79 | } |
| 80 | |
Liang Zhen | e4efb34 | 2016-03-22 19:03:50 -0400 | [diff] [blame] | 81 | if (hdr.ioc_len > LIBCFS_IOC_DATA_MAX) { |
| 82 | CERROR("libcfs ioctl: user buffer is too large %d/%d\n", |
| 83 | hdr.ioc_len, LIBCFS_IOC_DATA_MAX); |
| 84 | return -EINVAL; |
| 85 | } |
Amir Shehata | 1290932 | 2016-02-22 17:29:02 -0500 | [diff] [blame] | 86 | |
Liang Zhen | e4efb34 | 2016-03-22 19:03:50 -0400 | [diff] [blame] | 87 | LIBCFS_ALLOC(*hdr_pp, hdr.ioc_len); |
| 88 | if (!*hdr_pp) |
| 89 | return -ENOMEM; |
| 90 | |
| 91 | if (copy_from_user(*hdr_pp, uhdr, hdr.ioc_len)) { |
| 92 | LIBCFS_FREE(*hdr_pp, hdr.ioc_len); |
| 93 | err = -EFAULT; |
| 94 | } |
| 95 | return err; |
Amir Shehata | 1290932 | 2016-02-22 17:29:02 -0500 | [diff] [blame] | 96 | } |
| 97 | |
Parinay Kondekar | ae272a4 | 2016-03-22 19:04:07 -0400 | [diff] [blame] | 98 | static long |
| 99 | libcfs_psdev_ioctl(struct file *file, unsigned int cmd, unsigned long arg) |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 100 | { |
Peng Tao | 4b1a25f | 2013-07-15 22:27:14 +0800 | [diff] [blame] | 101 | if (!capable(CAP_SYS_ADMIN)) |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 102 | return -EACCES; |
| 103 | |
Jessica Yu | 91a002c | 2014-07-28 06:33:13 -0700 | [diff] [blame] | 104 | if (_IOC_TYPE(cmd) != IOC_LIBCFS_TYPE || |
Oleg Drokin | ae0b483 | 2016-02-16 00:47:00 -0500 | [diff] [blame] | 105 | _IOC_NR(cmd) < IOC_LIBCFS_MIN_NR || |
| 106 | _IOC_NR(cmd) > IOC_LIBCFS_MAX_NR) { |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 107 | CDEBUG(D_IOCTL, "invalid ioctl ( type %d, nr %d, size %d )\n", |
| 108 | _IOC_TYPE(cmd), _IOC_NR(cmd), _IOC_SIZE(cmd)); |
Julia Lawall | fbe7c6c | 2014-08-26 22:00:33 +0200 | [diff] [blame] | 109 | return -EINVAL; |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 110 | } |
| 111 | |
Parinay Kondekar | 89010fb | 2016-03-22 19:04:08 -0400 | [diff] [blame^] | 112 | return libcfs_ioctl(cmd, (void __user *)arg); |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 113 | } |
| 114 | |
Jessica Yu | d81f9f5 | 2014-07-28 06:33:15 -0700 | [diff] [blame] | 115 | static const struct file_operations libcfs_fops = { |
Parinay Kondekar | 4678d18 | 2016-03-22 19:04:06 -0400 | [diff] [blame] | 116 | .owner = THIS_MODULE, |
Parinay Kondekar | ae272a4 | 2016-03-22 19:04:07 -0400 | [diff] [blame] | 117 | .unlocked_ioctl = libcfs_psdev_ioctl, |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 118 | }; |
| 119 | |
Greg Kroah-Hartman | c0426cf | 2013-07-24 10:21:26 -0700 | [diff] [blame] | 120 | struct miscdevice libcfs_dev = { |
| 121 | .minor = LNET_MINOR, |
| 122 | .name = "lnet", |
| 123 | .fops = &libcfs_fops, |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 124 | }; |