Whamcloud - gitweb
LU-1146 build: batch update copyright messages
[fs/lustre-release.git] / lustre / obdclass / darwin / darwin-module.c
1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2  * vim:expandtab:shiftwidth=8:tabstop=8:
3  *
4  * GPL HEADER START
5  *
6  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License version 2 only,
10  * as published by the Free Software Foundation.
11  *
12  * This program is distributed in the hope that it will be useful, but
13  * WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * General Public License version 2 for more details (a copy is included
16  * in the LICENSE file that accompanied this code).
17  *
18  * You should have received a copy of the GNU General Public License
19  * version 2 along with this program; If not, see
20  * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
21  *
22  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
23  * CA 95054 USA or visit www.sun.com if you need additional information or
24  * have any questions.
25  *
26  * GPL HEADER END
27  */
28 /*
29  * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
30  * Use is subject to license terms.
31  *
32  * Copyright (c) 2011, Whamcloud, Inc.
33  */
34 /*
35  * This file is part of Lustre, http://www.lustre.org/
36  * Lustre is a trademark of Sun Microsystems, Inc.
37  */
38
39 #define DEBUG_SUBSYSTEM S_CLASS
40 #ifndef EXPORT_SYMTAB
41 # define EXPORT_SYMTAB
42 #endif
43
44 #include <mach/mach_types.h>
45 #include <string.h>
46 #include <sys/file.h>
47 #include <sys/conf.h>
48 #include <miscfs/devfs/devfs.h>
49
50 #include <libcfs/libcfs.h>
51 #include <obd_support.h>
52 #include <obd_class.h>
53 #include <lprocfs_status.h>
54
55 #ifndef OBD_MAX_IOCTL_BUFFER
56 #define OBD_MAX_IOCTL_BUFFER 8192
57 #endif
58
59 /* buffer MUST be at least the size of obd_ioctl_hdr */
60 int obd_ioctl_getdata(char **buf, int *len, void *arg)
61 {
62         struct obd_ioctl_hdr *hdr;
63         struct obd_ioctl_data *data;
64         int err = 0;
65         int offset = 0;
66         ENTRY;
67
68         hdr = (struct obd_ioctl_hdr *)arg;
69         if (hdr->ioc_version != OBD_IOCTL_VERSION) {
70                 CERROR("Version mismatch kernel vs application\n");
71                 RETURN(-EINVAL);
72         }
73
74         if (hdr->ioc_len > OBD_MAX_IOCTL_BUFFER) {
75                 CERROR("User buffer len %d exceeds %d max buffer\n",
76                        hdr->ioc_len, OBD_MAX_IOCTL_BUFFER);
77                 RETURN(-EINVAL);
78         }
79
80         if (hdr->ioc_len < sizeof(struct obd_ioctl_data)) {
81                 CERROR("OBD: user buffer too small for ioctl (%d)\n", hdr->ioc_len);
82                 RETURN(-EINVAL);
83         }
84
85         OBD_ALLOC_LARGE(*buf, hdr->ioc_len);
86         if (*buf == NULL) {
87                 CERROR("Cannot allocate control buffer of len %d\n",
88                        hdr->ioc_len);
89                 RETURN(-EINVAL);
90         }
91         *len = hdr->ioc_len;
92         data = (struct obd_ioctl_data *)*buf;
93
94         bzero(data, hdr->ioc_len);
95         memcpy(data, (void *)arg, sizeof(struct obd_ioctl_data));
96         if (data->ioc_inlbuf1)
97                 err = copy_from_user(&data->ioc_bulk[0], (void *)data->ioc_inlbuf1,
98                                      hdr->ioc_len - ((void *)&data->ioc_bulk[0] - (void *)data));
99
100         if (obd_ioctl_is_invalid(data)) {
101                 CERROR("ioctl not correctly formatted\n");
102                 OBD_FREE_LARGE(*buf, hdr->ioc_len);
103                 return -EINVAL;
104         }
105
106         if (data->ioc_inllen1) {
107                 data->ioc_inlbuf1 = &data->ioc_bulk[0];
108                 offset += size_round(data->ioc_inllen1);
109         }
110
111         if (data->ioc_inllen2) {
112                 data->ioc_inlbuf2 = &data->ioc_bulk[0] + offset;
113                 offset += size_round(data->ioc_inllen2);
114         }
115
116         if (data->ioc_inllen3) {
117                 data->ioc_inlbuf3 = &data->ioc_bulk[0] + offset;
118                 offset += size_round(data->ioc_inllen3);
119         }
120
121         if (data->ioc_inllen4) {
122                 data->ioc_inlbuf4 = &data->ioc_bulk[0] + offset;
123         }
124
125         EXIT;
126         return 0;
127 }
128
129 int obd_ioctl_popdata(void *arg, void *data, int len)
130 {
131         /* 
132          * Xnu ioctl copyout(uaddr, arg, sizeof(struct obd_ioctl_data)),
133          * we have to copyout data exceed sizeof(struct obd_ioctl_data)
134          * by ourself.
135          */
136         if (len <= sizeof(struct obd_ioctl_data)) {
137                 memcpy(arg, data, len);
138                 return 0;
139         } else {
140                 int err;
141                 struct obd_ioctl_data *u = (struct obd_ioctl_data *)arg;
142                 struct obd_ioctl_data *k = (struct obd_ioctl_data *)data;
143                 err = copy_to_user((void *)u->ioc_inlbuf1, &k->ioc_bulk[0],
144                                     len -((void *)&k->ioc_bulk[0] -(void *)k));
145                 memcpy(arg, data, sizeof(struct obd_ioctl_data));
146                 return err;
147         }
148 }
149
150 static int
151 obd_class_open(dev_t dev, int flags, int devtype, struct proc *p)
152 {
153         ENTRY;
154
155         RETURN(0);
156 }
157
158 /*  closing /dev/obd */
159 static int
160 obd_class_release(dev_t dev, int flags, int mode, struct proc *p)
161 {
162         ENTRY;
163
164         RETURN(0);
165 }
166
167 static int
168 obd_class_ioctl(dev_t dev, u_long cmd, caddr_t arg, int flag, struct proc *p)
169 {
170         int err = 0;
171         ENTRY;
172
173         if (!is_suser())
174                 RETURN (EPERM);
175
176         err = class_handle_ioctl(cmd, (unsigned long)arg);
177
178         RETURN(err);
179 }
180
181 static struct cdevsw obd_psdevsw = {
182         obd_class_open,
183         obd_class_release,
184         NULL,
185         NULL,
186         obd_class_ioctl,
187         NULL,
188         NULL,
189         NULL,
190         NULL,
191         NULL,
192         NULL,
193         NULL,
194         NULL,
195 };
196
197 cfs_psdev_t obd_psdev = {
198         -1,
199         NULL,
200         "obd",
201         &obd_psdevsw
202 };
203
204 int class_procfs_init(void)
205 {
206         return 0;
207 }
208
209 int class_procfs_clean(void)
210 {
211         return 0;
212 }