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