Whamcloud - gitweb
LU-2335 kernel: add CONFIG_ prefix to config values
[fs/lustre-release.git] / lustre / obdclass / darwin / darwin-module.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) 2011, 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_CLASS
38
39 #include <mach/mach_types.h>
40 #include <string.h>
41 #include <sys/file.h>
42 #include <sys/conf.h>
43 #include <miscfs/devfs/devfs.h>
44
45 #include <libcfs/libcfs.h>
46 #include <obd_support.h>
47 #include <obd_class.h>
48 #include <lprocfs_status.h>
49
50 #ifndef OBD_MAX_IOCTL_BUFFER
51 #ifdef CONFIG_LUSTRE_OBD_MAX_IOCTL_BUFFER
52 #define OBD_MAX_IOCTL_BUFFER    CONFIG_LUSTRE_OBD_MAX_IOCTL_BUFFER
53 #else
54 #define OBD_MAX_IOCTL_BUFFER    8192
55 #endif
56 #endif
57
58 /* buffer MUST be at least the size of obd_ioctl_hdr */
59 int obd_ioctl_getdata(char **buf, int *len, void *arg)
60 {
61         struct obd_ioctl_hdr *hdr;
62         struct obd_ioctl_data *data;
63         int err = 0;
64         int offset = 0;
65         ENTRY;
66
67         hdr = (struct obd_ioctl_hdr *)arg;
68         if (hdr->ioc_version != OBD_IOCTL_VERSION) {
69                 CERROR("Version mismatch kernel vs application\n");
70                 RETURN(-EINVAL);
71         }
72
73         if (hdr->ioc_len > OBD_MAX_IOCTL_BUFFER) {
74                 CERROR("User buffer len %d exceeds %d max buffer\n",
75                        hdr->ioc_len, OBD_MAX_IOCTL_BUFFER);
76                 RETURN(-EINVAL);
77         }
78
79         if (hdr->ioc_len < sizeof(struct obd_ioctl_data)) {
80                 CERROR("OBD: user buffer too small for ioctl (%d)\n", hdr->ioc_len);
81                 RETURN(-EINVAL);
82         }
83
84         OBD_ALLOC_LARGE(*buf, hdr->ioc_len);
85         if (*buf == NULL) {
86                 CERROR("Cannot allocate control buffer of len %d\n",
87                        hdr->ioc_len);
88                 RETURN(-EINVAL);
89         }
90         *len = hdr->ioc_len;
91         data = (struct obd_ioctl_data *)*buf;
92
93         bzero(data, hdr->ioc_len);
94         memcpy(data, (void *)arg, sizeof(struct obd_ioctl_data));
95         if (data->ioc_inlbuf1)
96                 err = copy_from_user(&data->ioc_bulk[0], (void *)data->ioc_inlbuf1,
97                                      hdr->ioc_len - ((void *)&data->ioc_bulk[0] - (void *)data));
98
99         if (obd_ioctl_is_invalid(data)) {
100                 CERROR("ioctl not correctly formatted\n");
101                 OBD_FREE_LARGE(*buf, hdr->ioc_len);
102                 return -EINVAL;
103         }
104
105         if (data->ioc_inllen1) {
106                 data->ioc_inlbuf1 = &data->ioc_bulk[0];
107                 offset += size_round(data->ioc_inllen1);
108         }
109
110         if (data->ioc_inllen2) {
111                 data->ioc_inlbuf2 = &data->ioc_bulk[0] + offset;
112                 offset += size_round(data->ioc_inllen2);
113         }
114
115         if (data->ioc_inllen3) {
116                 data->ioc_inlbuf3 = &data->ioc_bulk[0] + offset;
117                 offset += size_round(data->ioc_inllen3);
118         }
119
120         if (data->ioc_inllen4) {
121                 data->ioc_inlbuf4 = &data->ioc_bulk[0] + offset;
122         }
123
124         EXIT;
125         return 0;
126 }
127
128 int obd_ioctl_popdata(void *arg, void *data, int len)
129 {
130         /* 
131          * Xnu ioctl copyout(uaddr, arg, sizeof(struct obd_ioctl_data)),
132          * we have to copyout data exceed sizeof(struct obd_ioctl_data)
133          * by ourself.
134          */
135         if (len <= sizeof(struct obd_ioctl_data)) {
136                 memcpy(arg, data, len);
137                 return 0;
138         } else {
139                 int err;
140                 struct obd_ioctl_data *u = (struct obd_ioctl_data *)arg;
141                 struct obd_ioctl_data *k = (struct obd_ioctl_data *)data;
142                 err = copy_to_user((void *)u->ioc_inlbuf1, &k->ioc_bulk[0],
143                                     len -((void *)&k->ioc_bulk[0] -(void *)k));
144                 memcpy(arg, data, sizeof(struct obd_ioctl_data));
145                 return err;
146         }
147 }
148
149 static int
150 obd_class_open(dev_t dev, int flags, int devtype, struct proc *p)
151 {
152         ENTRY;
153
154         RETURN(0);
155 }
156
157 /*  closing /dev/obd */
158 static int
159 obd_class_release(dev_t dev, int flags, int mode, struct proc *p)
160 {
161         ENTRY;
162
163         RETURN(0);
164 }
165
166 static int
167 obd_class_ioctl(dev_t dev, u_long cmd, caddr_t arg, int flag, struct proc *p)
168 {
169         int err = 0;
170         ENTRY;
171
172         if (!is_suser())
173                 RETURN (EPERM);
174
175         err = class_handle_ioctl(cmd, (unsigned long)arg);
176
177         RETURN(err);
178 }
179
180 static struct cdevsw obd_psdevsw = {
181         obd_class_open,
182         obd_class_release,
183         NULL,
184         NULL,
185         obd_class_ioctl,
186         NULL,
187         NULL,
188         NULL,
189         NULL,
190         NULL,
191         NULL,
192         NULL,
193         NULL,
194 };
195
196 cfs_psdev_t obd_psdev = {
197         -1,
198         NULL,
199         "obd",
200         &obd_psdevsw
201 };
202
203 int class_procfs_init(void)
204 {
205         return 0;
206 }
207
208 int class_procfs_clean(void)
209 {
210         return 0;
211 }