Whamcloud - gitweb
- More Peter's additions for the ha manager. This doesn't seem to break much -
[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 Lustre, http://www.sf.net/projects/lustre/
7  *
8  *   Lustre 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  *   Lustre 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 Lustre; 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/module.h>
26 #include <linux/miscdevice.h>
27
28 #define DEBUG_SUBSYSTEM S_MDC
29
30 #include <linux/lustre_mds.h>
31
32 #define REQUEST_MINOR 244
33
34 extern int mds_queue_req(struct ptlrpc_request *);
35
36 int mdc_connect(struct ptlrpc_client *cl, struct lustre_peer *peer, ino_t ino,
37                 int type, int valid, struct ptlrpc_request **request)
38 {
39         struct ptlrpc_request *req;
40         struct mds_body *body;
41         int rc, size = sizeof(*body);
42         ENTRY;
43
44         req = ptlrpc_prep_req(cl, peer, MDS_GETATTR, 1, &size, NULL);
45         if (!req)
46                 GOTO(out, rc = -ENOMEM);
47
48         body = lustre_msg_buf(req->rq_reqmsg, 0);
49         ll_ino2fid(&body->fid1, ino, 0, type);
50         body->valid = valid;
51
52         req->rq_replen = lustre_msg_size(1, &size);
53
54         rc = ptlrpc_queue_wait(cl, req);
55         rc = ptlrpc_check_status(req, rc);
56
57         if (!rc) {
58                 mds_unpack_body(req);
59                 body = lustre_msg_buf(req->rq_repmsg, 0);
60                 CDEBUG(D_NET, "mode: %o\n", body->mode);
61         }
62
63         EXIT;
64  out:
65         *request = req;
66         return rc;
67 }
68
69
70 int mdc_getattr(struct ptlrpc_client *cl, struct lustre_peer *peer, ino_t ino,
71                 int type, int valid, struct ptlrpc_request **request)
72 {
73         struct ptlrpc_request *req;
74         struct mds_body *body;
75         int rc, size = sizeof(*body);
76         ENTRY;
77
78         req = ptlrpc_prep_req(cl, peer, MDS_GETATTR, 1, &size, NULL);
79         if (!req)
80                 GOTO(out, rc = -ENOMEM);
81
82         body = lustre_msg_buf(req->rq_reqmsg, 0);
83         ll_ino2fid(&body->fid1, ino, 0, type);
84         body->valid = valid;
85
86         req->rq_replen = lustre_msg_size(1, &size);
87
88         rc = ptlrpc_queue_wait(cl, req);
89         rc = ptlrpc_check_status(req, rc);
90
91         if (!rc) {
92                 mds_unpack_body(req);
93                 body = lustre_msg_buf(req->rq_repmsg, 0);
94                 CDEBUG(D_NET, "mode: %o\n", body->mode);
95         }
96
97         EXIT;
98  out:
99         *request = req;
100         return rc;
101 }
102
103 int mdc_open(struct ptlrpc_client *cl, struct lustre_peer *peer, ino_t ino,
104              int type, int flags, __u64 *fh, struct ptlrpc_request **request)
105 {
106         struct mds_body *body;
107         int rc, size = sizeof(*body);
108         struct ptlrpc_request *req;
109
110         req = ptlrpc_prep_req(cl, peer, MDS_OPEN, 1, &size, NULL);
111         if (!req)
112                 GOTO(out, rc = -ENOMEM);
113
114         body = lustre_msg_buf(req->rq_reqmsg, 0);
115         ll_ino2fid(&body->fid1, ino, 0, type);
116         body->flags = HTON__u32(flags);
117
118         req->rq_replen = lustre_msg_size(1, &size);
119
120         rc = ptlrpc_queue_wait(cl, req);
121         rc = ptlrpc_check_status(req, rc);
122
123         if (!rc) {
124                 mds_unpack_body(req);
125                 body = lustre_msg_buf(req->rq_repmsg, 0);
126                 *fh = body->objid;
127         }
128
129         EXIT;
130  out:
131         *request = req;
132         return rc;
133 }
134
135 int mdc_close(struct ptlrpc_client *cl, struct lustre_peer *peer, ino_t ino,
136               int type, __u64 fh, struct ptlrpc_request **request)
137 {
138         struct mds_body *body;
139         int rc, size = sizeof(*body);
140         struct ptlrpc_request *req;
141
142         req = ptlrpc_prep_req(cl, peer, MDS_CLOSE, 1, &size, NULL);
143         if (!req)
144                 GOTO(out, rc = -ENOMEM);
145
146         body = lustre_msg_buf(req->rq_reqmsg, 0);
147         ll_ino2fid(&body->fid1, ino, 0, type);
148         body->objid = fh;
149
150         req->rq_replen = lustre_msg_size(1, &size);
151
152         rc = ptlrpc_queue_wait(cl, req);
153         rc = ptlrpc_check_status(req, rc);
154
155         EXIT;
156  out:
157         *request = req;
158         return rc;
159 }
160
161 int mdc_readpage(struct ptlrpc_client *cl, struct lustre_peer *peer, ino_t ino,
162                  int type, __u64 offset, char *addr,
163                  struct ptlrpc_request **request)
164 {
165         struct ptlrpc_request *req = NULL;
166         struct ptlrpc_bulk_desc *bulk = NULL;
167         struct niobuf niobuf;
168         struct mds_body *body;
169         int rc, size[2] = {sizeof(*body), sizeof(struct niobuf)};
170         char *bufs[2] = {NULL, (char *)&niobuf};
171
172         niobuf.addr = (__u64) (long) addr;
173
174         CDEBUG(D_INODE, "inode: %ld\n", ino);
175
176         bulk = ptlrpc_prep_bulk(peer);
177         if (bulk == NULL) {
178                 CERROR("%s: cannot init bulk desc\n", __FUNCTION__);
179                 rc = -ENOMEM;
180                 goto out;
181         }
182
183         req = ptlrpc_prep_req(cl, peer, MDS_READPAGE, 2, size, bufs);
184         if (!req)
185                 GOTO(out, rc = -ENOMEM);
186
187         bulk->b_buflen = PAGE_SIZE;
188         bulk->b_buf = (void *)(long)niobuf.addr;
189         bulk->b_portal = MDS_BULK_PORTAL;
190         bulk->b_xid = req->rq_xid;
191
192         rc = ptlrpc_register_bulk(bulk);
193         if (rc) {
194                 CERROR("couldn't setup bulk sink: error %d.\n", rc);
195                 GOTO(out, rc);
196         }
197
198         body = lustre_msg_buf(req->rq_reqmsg, 0);
199         body->fid1.id = ino;
200         body->fid1.f_type = type;
201         body->size = offset;
202
203         req->rq_replen = lustre_msg_size(1, size);
204
205         rc = ptlrpc_queue_wait(cl, req);
206         if (rc) {
207                 CERROR("error in handling %d\n", rc);
208                 ptlrpc_abort_bulk(bulk);
209                 GOTO(out, rc);
210         }
211
212         mds_unpack_body(req);
213         EXIT;
214
215  out:
216         *request = req;
217         if (bulk != NULL)
218                 OBD_FREE(bulk, sizeof(*bulk));
219         return rc;
220 }
221
222 static int request_ioctl(struct inode *inode, struct file *file,
223                          unsigned int cmd, unsigned long arg)
224 {
225         int err;
226         struct ptlrpc_client cl;
227         struct lustre_peer peer;
228         struct ptlrpc_request *request;
229
230         ENTRY;
231
232         if (MINOR(inode->i_rdev) != REQUEST_MINOR)
233                 RETURN(-EINVAL);
234
235         if (_IOC_TYPE(cmd) != IOC_REQUEST_TYPE ||
236             _IOC_NR(cmd) < IOC_REQUEST_MIN_NR  ||
237             _IOC_NR(cmd) > IOC_REQUEST_MAX_NR ) {
238                 CDEBUG(D_IOCTL, "invalid ioctl ( type %d, nr %d, size %d )\n",
239                        _IOC_TYPE(cmd), _IOC_NR(cmd), _IOC_SIZE(cmd));
240                 RETURN(-EINVAL);
241         }
242
243         ptlrpc_init_client(NULL, MDS_REQUEST_PORTAL, MDC_REPLY_PORTAL, &cl);
244         err = ptlrpc_connect_client("mds", &cl, &peer);
245         if (err) {
246                 CERROR("cannot create client\n");
247                 RETURN(-EINVAL);
248         }
249
250         switch (cmd) {
251         case IOC_REQUEST_GETATTR: {
252                 CERROR("-- getting attr for ino %lu\n", arg);
253                 err = mdc_getattr(&cl, &peer, arg, S_IFDIR, ~0, &request);
254                 CERROR("-- done err %d\n", err);
255
256                 GOTO(out, err);
257         }
258
259         case IOC_REQUEST_READPAGE: {
260                 char *buf;
261                 OBD_ALLOC(buf, PAGE_SIZE);
262                 if (!buf) {
263                         err = -ENOMEM;
264                         break;
265                 }
266                 CERROR("-- readpage 0 for ino %lu\n", arg);
267                 err = mdc_readpage(&cl, &peer, arg, S_IFDIR, 0, buf, &request);
268                 CERROR("-- done err %d\n", err);
269                 OBD_FREE(buf, PAGE_SIZE);
270
271                 GOTO(out, err);
272         }
273
274         case IOC_REQUEST_SETATTR: {
275                 struct inode inode;
276                 struct iattr iattr;
277
278                 inode.i_ino = arg;
279                 inode.i_generation = 0;
280                 iattr.ia_mode = 040777;
281                 iattr.ia_atime = 0;
282                 iattr.ia_valid = ATTR_MODE | ATTR_ATIME;
283
284                 err = mdc_setattr(&cl, &peer, &inode, &iattr, &request);
285                 CERROR("-- done err %d\n", err);
286
287                 GOTO(out, err);
288         }
289
290         case IOC_REQUEST_CREATE: {
291                 struct inode inode;
292                 struct iattr iattr;
293
294                 inode.i_ino = arg;
295                 inode.i_generation = 0;
296                 iattr.ia_mode = 040777;
297                 iattr.ia_atime = 0;
298                 iattr.ia_valid = ATTR_MODE | ATTR_ATIME;
299
300                 err = mdc_create(&cl, &peer, &inode,
301                                  "foofile", strlen("foofile"),
302                                  NULL, 0, 0100707, 47114711,
303                                  11, 47, 0, &request);
304                 CERROR("-- done err %d\n", err);
305
306                 GOTO(out, err);
307         }
308
309         case IOC_REQUEST_OPEN: {
310                 __u64 fh, ino;
311                 copy_from_user(&ino, (__u64 *)arg, sizeof(ino));
312                 CERROR("-- opening ino %llu\n", ino);
313                 err = mdc_open(&cl, &peer, ino, S_IFDIR, O_RDONLY, &fh,
314                                &request);
315                 copy_to_user((__u64 *)arg, &fh, sizeof(fh));
316                 CERROR("-- done err %d (fh=%Lu)\n", err, fh);
317
318                 GOTO(out, err);
319         }
320
321         case IOC_REQUEST_CLOSE: {
322                 CERROR("-- closing ino 2, filehandle %lu\n", arg);
323                 err = mdc_close(&cl, &peer, 2, S_IFDIR, arg, &request);
324                 CERROR("-- done err %d\n", err);
325
326                 GOTO(out, err);
327         }
328
329         default:
330                 RETURN(-EINVAL);
331         }
332
333  out:
334         ptlrpc_free_req(request);
335
336         RETURN(err);
337 }
338
339
340 static struct file_operations requestdev_fops = {
341         ioctl: request_ioctl,
342 };
343
344 static struct miscdevice request_dev = {
345         REQUEST_MINOR,
346         "request",
347         &requestdev_fops
348 };
349
350 static int __init ptlrpc_request_init(void)
351 {
352         misc_register(&request_dev);
353         return 0;
354 }
355
356 static void __exit ptlrpc_request_exit(void)
357 {
358         misc_deregister(&request_dev);
359 }
360
361 MODULE_AUTHOR("Peter J. Braam <braam@clusterfs.com>");
362 MODULE_DESCRIPTION("Lustre MDS Request Tester v1.0");
363 MODULE_LICENSE("GPL");
364
365 EXPORT_SYMBOL(mdc_create);
366 EXPORT_SYMBOL(mdc_unlink);
367 EXPORT_SYMBOL(mdc_rename);
368 EXPORT_SYMBOL(mdc_link);
369 EXPORT_SYMBOL(mdc_getattr);
370 EXPORT_SYMBOL(mdc_readpage);
371 EXPORT_SYMBOL(mdc_setattr);
372 EXPORT_SYMBOL(mdc_close);
373 EXPORT_SYMBOL(mdc_open);
374
375 module_init(ptlrpc_request_init);
376 module_exit(ptlrpc_request_exit);