Whamcloud - gitweb
assorted bug fixes and a working directory readpage routine
[fs/lustre-release.git] / lustre / mdc / mdc_request.c
1 /*
2  * Copryright (C) 2001 Cluster File Systems, Inc.
3  *
4  */
5
6 #define EXPORT_SYMTAB
7
8 #include <linux/config.h>
9 #include <linux/module.h>
10 #include <linux/kernel.h>
11 #include <linux/mm.h>
12 #include <linux/string.h>
13 #include <linux/stat.h>
14 #include <linux/errno.h>
15 #include <linux/locks.h>
16 #include <linux/unistd.h>
17
18 #include <asm/system.h>
19 #include <asm/uaccess.h>
20 #include <linux/module.h>
21
22 #include <linux/fs.h>
23 #include <linux/stat.h>
24 #include <asm/uaccess.h>
25 #include <linux/vmalloc.h>
26 #include <asm/segment.h>
27 #include <linux/miscdevice.h>
28
29 #include <linux/obd_support.h>
30 #include <linux/lustre_lib.h>
31 #include <linux/lustre_idl.h>
32 #include <linux/lustre_mds.h>
33
34 #define REQUEST_MINOR 244
35
36 extern int mds_queue_req(struct mds_request *);
37
38 struct mds_request *mds_prep_req(int size, int opcode, int namelen, char *name, int tgtlen, char *tgt)
39 {
40         struct mds_request *request;
41         int rc;
42         ENTRY; 
43
44         request = (struct mds_request *)kmalloc(sizeof(*request), GFP_KERNEL); 
45         if (!request) { 
46                 printk("mds_prep_req: request allocation out of memory\n");
47                 return NULL;
48         }
49
50         rc = mds_pack_req(name, namelen, tgt, tgtlen,
51                           &request->rq_reqhdr, &request->rq_req, 
52                           &request->rq_reqlen, &request->rq_reqbuf);
53         if (rc) { 
54                 printk("llight request: cannot pack request %d\n", rc); 
55                 return NULL;
56         }
57         request->rq_reqhdr->opc = opcode;
58
59         EXIT;
60         return request;
61 }
62
63
64
65
66 static int mds_queue_wait(struct mds_request *req)
67 {
68         int rc;
69
70         /* XXX fix the race here (wait_for_event?)*/
71         /* hand the packet over to the server */
72         rc = mds_queue_req(req); 
73         if (rc) { 
74                 printk("mdc_queue_wait: error %d, opcode %d\n", rc, 
75                        req->rq_reqhdr->opc); 
76                 return -rc;
77         }
78
79         init_waitqueue_head(&req->rq_wait_for_rep);
80         printk("-- sleeping\n");
81         interruptible_sleep_on(&req->rq_wait_for_rep);
82         printk("-- done\n");
83
84         mds_unpack_rep(req->rq_repbuf, req->rq_replen, &req->rq_rephdr, 
85                        &req->rq_rep); 
86         printk("-->mdc_queue_wait: buf %p len %d status %d\n", 
87                req->rq_repbuf, req->rq_replen, req->rq_rephdr->status); 
88
89         EXIT;
90         return req->rq_rephdr->status;
91 }
92
93 void mds_free_req(struct mds_request *request)
94 {
95         kfree(request);
96 }
97
98 int mdc_getattr(ino_t ino, int type, int valid, 
99                 struct mds_rep  **rep, struct mds_rep_hdr **hdr)
100 {
101         struct mds_request *request;
102         int rc; 
103
104         request = mds_prep_req(sizeof(*request), MDS_GETATTR, 
105                                0, NULL, 0, NULL); 
106         if (!request) { 
107                 printk("llight request: cannot pack\n");
108                 return -ENOMEM;
109         }
110
111         request->rq_req->fid1.id = ino;
112         request->rq_req->fid1.f_type = type;
113         request->rq_req->valid = valid;
114
115         rc = mds_queue_wait(request);
116         if (rc) { 
117                 printk("llight request: error in handling %d\n", rc); 
118                 goto out;
119         }
120
121         printk("mds_getattr: mode: %o\n", request->rq_rep->mode); 
122
123         if (rep) { 
124                 *rep = request->rq_rep;
125         }
126         if (hdr) { 
127                 *hdr = request->rq_rephdr;
128         }
129
130  out: 
131         mds_free_req(request);
132         return rc;
133 }
134
135 int mdc_readpage(ino_t ino, int type, __u64 offset, char *addr, 
136                 struct mds_rep  **rep, struct mds_rep_hdr **hdr)
137 {
138         struct mds_request *request;
139         struct niobuf niobuf;
140         int rc; 
141
142         niobuf.addr = (__u64) (long) addr;
143
144         printk("mdc_readpage: inode: %ld\n", ino); 
145
146         request = mds_prep_req(sizeof(*request), MDS_READPAGE, 
147                                0, NULL,
148                                sizeof(struct niobuf), (char *)&niobuf);
149         if (!request) { 
150                 printk("mdc request: cannot pack\n");
151                 return -ENOMEM;
152         }
153
154         request->rq_req->fid1.id = ino;
155         request->rq_req->fid1.f_type = type;
156         request->rq_req->size = offset;
157         request->rq_req->tgtlen = sizeof(niobuf); 
158
159         rc = mds_queue_wait(request);
160         if (rc) { 
161                 printk("mdc request: error in handling %d\n", rc); 
162                 goto out;
163         }
164
165         printk("mdc_readpage: mode: %o\n", request->rq_rep->mode); 
166
167         if (rep) { 
168                 *rep = request->rq_rep;
169         }
170         if (hdr) { 
171                 *hdr = request->rq_rephdr;
172         }
173
174  out: 
175         mds_free_req(request);
176         return rc;
177 }
178
179
180 static int request_ioctl(struct inode *inode, struct file *file, 
181                        unsigned int cmd, unsigned long arg)
182 {
183         int err;
184
185         ENTRY;
186
187         if (MINOR(inode->i_rdev) != REQUEST_MINOR) {
188                 EXIT;
189                 return -EINVAL;
190         }
191
192         if ( _IOC_TYPE(cmd) != IOC_REQUEST_TYPE || 
193              _IOC_NR(cmd) < IOC_REQUEST_MIN_NR  || 
194              _IOC_NR(cmd) > IOC_REQUEST_MAX_NR ) {
195                 CDEBUG(D_IOCTL, "invalid ioctl ( type %d, nr %d, size %d )\n",
196                                 _IOC_TYPE(cmd), _IOC_NR(cmd), _IOC_SIZE(cmd));
197                 EXIT;
198                 return -EINVAL;
199         }
200
201         
202         switch (cmd) {
203         case IOC_REQUEST_GETATTR: { 
204                 struct mds_rep_hdr *hdr;
205                 printk("-- getting attr for ino 2\n"); 
206                 err = mdc_getattr(2, S_IFDIR, ~0, NULL, &hdr);
207                 kfree(hdr);
208                 printk("-- done err %d\n", err);
209                 break;
210         }
211
212         case IOC_REQUEST_READPAGE: { 
213                 struct mds_rep_hdr *hdr;
214                 char *buf;
215                 buf = kmalloc(PAGE_SIZE, GFP_KERNEL); 
216                 if (!buf) { 
217                         err = -ENOMEM;
218                         break;
219                 }
220                 printk("-- readpage 0 for ino 2\n"); 
221                 err = mdc_readpage(2, S_IFDIR, 0, buf, NULL, &hdr);
222                 printk("-- done err %d\n", err);
223                 if (!err) { 
224                         printk("-- status: %d\n", hdr->status); 
225                         err = hdr->status;
226                         kfree(hdr);
227                 }
228                 kfree(buf); 
229                 break;
230         }
231         default:                
232                 err = -EINVAL;
233                 EXIT;
234                 break;
235         }
236         EXIT;
237         return err;
238 }
239
240
241 static struct file_operations requestdev_fops = {
242         ioctl: request_ioctl,
243 };
244
245
246 static struct miscdevice request_dev = {
247         REQUEST_MINOR,
248         "request",
249         &requestdev_fops
250 };
251
252
253 static int __init mds_request_init(void)
254 {
255         misc_register(&request_dev);
256         return 0 ;
257 }
258
259
260 static void __exit mds_request_exit(void)
261 {
262         misc_deregister(&request_dev);
263 }
264
265 MODULE_AUTHOR("Peter J. Braam <braam@clusterfs.com>");
266 MODULE_DESCRIPTION("Lustre MDS Request Tester v1.0");
267 MODULE_LICENSE("GPL");
268
269 EXPORT_SYMBOL(mdc_getattr); 
270 EXPORT_SYMBOL(mdc_readpage); 
271
272 module_init(mds_request_init);
273 module_exit(mds_request_exit);