Whamcloud - gitweb
- bug fix to unload modules with safe wait functions
[fs/lustre-release.git] / lustre / mdc / mdc_request.c
1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2  * vim:expandtab:shiftwidth=8:tabstop=8:
3  *
4  * Copyright (C) 2001, 2002 Cluster File Systems, Inc.
5  *
6  *   This file is part of Portals, http://www.sf.net/projects/lustre/
7  *
8  *   Portals is free software; you can redistribute it and/or
9  *   modify it under the terms of version 2 of the GNU General Public
10  *   License as published by the Free Software Foundation.
11  *
12  *   Portals is distributed in the hope that it will be useful,
13  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
14  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  *   GNU General Public License for more details.
16  *
17  *   You should have received a copy of the GNU General Public License
18  *   along with Portals; if not, write to the Free Software
19  *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20  *
21  */
22
23 #define EXPORT_SYMTAB
24
25 #include <linux/config.h>
26 #include <linux/module.h>
27 #include <linux/kernel.h>
28 #include <linux/mm.h>
29 #include <linux/string.h>
30 #include <linux/stat.h>
31 #include <linux/errno.h>
32 #include <linux/locks.h>
33 #include <linux/unistd.h>
34
35 #include <asm/system.h>
36 #include <asm/uaccess.h>
37 #include <linux/module.h>
38
39 #include <linux/fs.h>
40 #include <linux/stat.h>
41 #include <asm/uaccess.h>
42 #include <asm/segment.h>
43 #include <linux/miscdevice.h>
44
45 #define DEBUG_SUBSYSTEM S_MDC
46
47 #include <linux/obd_support.h>
48 #include <linux/lustre_lib.h>
49 #include <linux/lustre_idl.h>
50 #include <linux/lustre_mds.h>
51
52 #define REQUEST_MINOR 244
53
54 extern int mds_queue_req(struct ptlrpc_request *);
55
56
57 int mdc_getattr(struct ptlrpc_client *peer, ino_t ino, int type, int valid, 
58                 struct mds_rep  **rep, struct ptlrep_hdr **hdr)
59 {
60         struct ptlrpc_request *request;
61         int rc; 
62
63         request = ptlrpc_prep_req(peer, MDS_GETATTR, 0, NULL, 0, NULL); 
64         if (!request) { 
65                 CERROR("llight request: cannot pack\n");
66                 return -ENOMEM;
67         }
68
69         ll_ino2fid(&request->rq_req.mds->fid1, ino, 0, type);
70
71         request->rq_req.mds->valid = valid;
72         request->rq_replen = 
73                 sizeof(struct ptlrep_hdr) + sizeof(struct mds_rep);
74
75         rc = ptlrpc_queue_wait(request, peer);
76         if (rc) { 
77                 CERROR("llight request: error in handling %d\n", rc); 
78                 goto out;
79         }
80
81         CDEBUG(0, "mode: %o\n", request->rq_rep.mds->mode);
82
83         if (rep) { 
84                 *rep = request->rq_rep.mds;
85         }
86         if (hdr) { 
87                 *hdr = request->rq_rephdr;
88         }
89
90  out: 
91         ptlrpc_free_req(request);
92         return rc;
93 }
94
95 int mdc_readpage(struct ptlrpc_client *peer, ino_t ino, int type, __u64 offset,
96                  char *addr, struct mds_rep  **rep, struct ptlrep_hdr **hdr)
97 {
98         struct ptlrpc_request *request;
99         struct niobuf niobuf;
100         int rc; 
101
102         niobuf.addr = (__u64) (long) addr;
103
104         CDEBUG(D_INODE, "inode: %ld\n", ino);
105
106         request = ptlrpc_prep_req(peer, MDS_READPAGE, 0, NULL,
107                                sizeof(struct niobuf), (char *)&niobuf);
108         if (!request) { 
109                 CERROR("mdc request: cannot pack\n");
110                 return -ENOMEM;
111         }
112
113         request->rq_req.mds->fid1.id = ino;
114         request->rq_req.mds->fid1.f_type = type;
115         request->rq_req.mds->size = offset;
116         request->rq_req.mds->tgtlen = sizeof(niobuf); 
117
118         //request->rq_bulklen = PAGE_SIZE;
119         //request->rq_bulkbuf = (void *)(long)niobuf.addr;
120         request->rq_bulk_portal = MDS_BULK_PORTAL;
121         request->rq_replen = 
122                 sizeof(struct ptlrep_hdr) + sizeof(struct mds_rep);
123
124         rc = ptlrpc_queue_wait(request, peer);
125         if (rc) { 
126                 CERROR("mdc request: error in handling %d\n", rc); 
127                 goto out;
128         }
129
130         CDEBUG(0, "mode: %o\n", request->rq_rep.mds->mode);
131
132         if (rep) { 
133                 *rep = request->rq_rep.mds;
134         }
135         if (hdr) { 
136                 *hdr = request->rq_rephdr;
137         }
138
139  out: 
140         ptlrpc_free_req(request);
141         return rc;
142 }
143
144 int mdc_reint(struct ptlrpc_client *peer, struct ptlrpc_request *request)
145 {
146         int rc; 
147
148         rc = ptlrpc_queue_wait(request, peer);
149         if (rc) { 
150                 CERROR("mdc request: error in handling %d\n", rc); 
151         }
152
153         return rc;
154 }
155
156 int mdc_create_client(char *uuid, struct ptlrpc_client *cl)
157 {
158         int err; 
159
160         memset(cl, 0, sizeof(*cl));
161         cl->cli_xid = 0;
162         cl->cli_rep_unpack = mds_unpack_rep;
163         cl->cli_req_pack = mds_pack_req;
164         err = kportal_uuid_to_peer("mds", &cl->cli_server);
165         if (err == 0) { 
166                 cl->cli_request_portal = MDS_REQUEST_PORTAL;
167                 cl->cli_reply_portal = MDS_REPLY_PORTAL;
168                 
169         } else { 
170                 cl->cli_enqueue = mds_queue_req;
171         }
172         return 0;
173 }
174
175 static int request_ioctl(struct inode *inode, struct file *file, 
176                          unsigned int cmd, unsigned long arg)
177 {
178         int err;
179         struct ptlrpc_client peer;
180
181         ENTRY;
182
183         if (MINOR(inode->i_rdev) != REQUEST_MINOR) {
184                 EXIT;
185                 return -EINVAL;
186         }
187
188         if ( _IOC_TYPE(cmd) != IOC_REQUEST_TYPE || 
189              _IOC_NR(cmd) < IOC_REQUEST_MIN_NR  || 
190              _IOC_NR(cmd) > IOC_REQUEST_MAX_NR ) {
191                 CDEBUG(D_IOCTL, "invalid ioctl ( type %d, nr %d, size %d )\n",
192                                 _IOC_TYPE(cmd), _IOC_NR(cmd), _IOC_SIZE(cmd));
193                 EXIT;
194                 return -EINVAL;
195         }
196
197         err = mdc_create_client("mds", &peer);
198         if (err) {
199                 CERROR("cannot create client"); 
200                 return -EINVAL;
201         }
202         
203         switch (cmd) {
204         case IOC_REQUEST_GETATTR: { 
205                 struct ptlrep_hdr *hdr = NULL;
206                 CERROR("-- getting attr for ino 2\n"); 
207                 err = mdc_getattr(&peer, 2, S_IFDIR, ~0, NULL, &hdr);
208                 if (hdr) {
209                         /* FIXME: there must be a better way to get the size */
210                         OBD_FREE(hdr, sizeof(struct ptlrep_hdr) +
211                                  sizeof(struct mds_rep));
212                 }
213                 CERROR("-- done err %d\n", err);
214                 break;
215         }
216
217         case IOC_REQUEST_READPAGE: { 
218                 struct ptlrep_hdr *hdr = NULL;
219                 char *buf;
220                 OBD_ALLOC(buf, PAGE_SIZE);
221                 if (!buf) { 
222                         err = -ENOMEM;
223                         break;
224                 }
225                 CERROR("-- readpage 0 for ino 2\n"); 
226                 err = mdc_readpage(&peer, 2, S_IFDIR, 0, buf, NULL, &hdr);
227                 CERROR("-- done err %d\n", err);
228                 if (!err) { 
229                         CERROR("-- status: %d\n", hdr->status); 
230                         err = hdr->status;
231                         if (hdr)
232                                 OBD_FREE(hdr, sizeof(struct ptlrep_hdr) +
233                                          sizeof(struct mds_rep));
234                 }
235                 OBD_FREE(buf, PAGE_SIZE);
236                 break;
237         }
238
239         case IOC_REQUEST_SETATTR: { 
240                 struct inode inode;
241                 struct ptlrep_hdr *hdr;
242                 struct iattr iattr; 
243
244                 inode.i_ino = 2;
245                 iattr.ia_mode = 040777;
246                 iattr.ia_atime = 0;
247                 iattr.ia_valid = ATTR_MODE | ATTR_ATIME;
248
249                 err = mdc_setattr(&peer, &inode, &iattr, NULL, &hdr);
250                 CERROR("-- done err %d\n", err);
251                 if (!err) { 
252                         CERROR("-- status: %d\n", hdr->status); 
253                         err = hdr->status;
254                 } else {
255                         OBD_FREE(hdr, sizeof(struct ptlrep_hdr) +
256                                  sizeof(struct mds_rep));
257                 }
258                 break;
259         }
260
261         case IOC_REQUEST_CREATE: { 
262                 struct inode inode;
263                 struct ptlrep_hdr *hdr;
264                 struct iattr iattr; 
265
266                 inode.i_ino = 2;
267                 iattr.ia_mode = 040777;
268                 iattr.ia_atime = 0;
269                 iattr.ia_valid = ATTR_MODE | ATTR_ATIME;
270
271                 err = mdc_create(&peer, &inode, 
272                                  "foofile", strlen("foofile"), 
273                                  NULL, 0, 0100707, 47114711, 
274                                  11, 47, 0, NULL, &hdr);
275                 CERROR("-- done err %d\n", err);
276                 if (!err) { 
277                         CERROR("-- status: %d\n", hdr->status); 
278                         err = hdr->status;
279                 }
280                 OBD_FREE(hdr, sizeof(struct ptlrep_hdr) +
281                          sizeof(struct mds_rep));
282                 break;
283         }
284
285         default:                
286                 err = -EINVAL;
287                 EXIT;
288                 break;
289         }
290         EXIT;
291         return err;
292 }
293
294
295 static struct file_operations requestdev_fops = {
296         ioctl: request_ioctl,
297 };
298
299
300 static struct miscdevice request_dev = {
301         REQUEST_MINOR,
302         "request",
303         &requestdev_fops
304 };
305
306
307 static int __init ptlrpc_request_init(void)
308 {
309         misc_register(&request_dev);
310         return 0 ;
311 }
312
313
314 static void __exit ptlrpc_request_exit(void)
315 {
316         misc_deregister(&request_dev);
317 }
318
319 MODULE_AUTHOR("Peter J. Braam <braam@clusterfs.com>");
320 MODULE_DESCRIPTION("Lustre MDS Request Tester v1.0");
321 MODULE_LICENSE("GPL");
322
323 EXPORT_SYMBOL(mdc_create_client); 
324 EXPORT_SYMBOL(mdc_create); 
325 EXPORT_SYMBOL(mdc_unlink); 
326 EXPORT_SYMBOL(mdc_rename); 
327 EXPORT_SYMBOL(mdc_link); 
328 EXPORT_SYMBOL(mdc_getattr); 
329 EXPORT_SYMBOL(mdc_readpage); 
330 EXPORT_SYMBOL(mdc_setattr); 
331
332 module_init(ptlrpc_request_init);
333 module_exit(ptlrpc_request_exit);