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