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