Whamcloud - gitweb
Changes for file creation and small fixes.
[fs/lustre-release.git] / lustre / osc / osc_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
21 #include <linux/fs.h>
22 #include <linux/stat.h>
23 #include <asm/uaccess.h>
24 #include <linux/vmalloc.h>
25 #include <asm/segment.h>
26 #include <linux/miscdevice.h>
27
28 #include <linux/obd_support.h>
29 #include <linux/obd_class.h>
30 #include <linux/lustre_lib.h>
31 #include <linux/lustre_idl.h>
32
33 extern int ost_queue_req(struct obd_device *, struct ost_request *);
34
35 struct ost_request *osc_prep_req(int size, int opcode)
36 {
37         struct ost_request *request;
38         int rc;
39         ENTRY; 
40
41         request = (struct ost_request *)kmalloc(sizeof(*request), GFP_KERNEL); 
42         if (!request) { 
43                 printk("osc_prep_req: request allocation out of memory\n");
44                 return NULL;
45         }
46
47         rc = ost_pack_req(NULL, 0, NULL, 0, 
48                           &request->rq_reqhdr, &request->rq_req, 
49                           &request->rq_reqlen, &request->rq_reqbuf);
50         if (rc) { 
51                 printk("llight request: cannot pack request %d\n", rc); 
52                 return NULL;
53         }
54         request->rq_reqhdr->opc = opcode;
55
56         EXIT;
57         return request;
58 }
59
60 extern int osc_queue_wait(struct obd_conn *conn, struct ost_request *req)
61 {
62         struct obd_device *client = conn->oc_dev;
63         struct obd_device *target = client->u.osc.osc_tgt;
64         int rc;
65
66         ENTRY;
67         /* set the connection id */
68         req->rq_req->connid = conn->oc_id;
69
70         CDEBUG(D_INODE, "tgt at %p, conn id %d, opcode %d request at: %p\n", 
71                &conn->oc_dev->u.osc.osc_tgt->u.ost, 
72                conn->oc_id, req->rq_reqhdr->opc, req);
73
74         /* XXX fix the race here (wait_for_event?)*/
75         /* hand the packet over to the server */
76         rc =  ost_queue_req(target, req); 
77         if (rc) { 
78                 printk("osc_queue_wait: error %d, opcode %d\n", rc, 
79                        req->rq_reqhdr->opc); 
80                 return -rc;
81         }
82
83         /* wait for the reply */
84         init_waitqueue_head(&req->rq_wait_for_rep);
85         interruptible_sleep_on(&req->rq_wait_for_rep);
86
87         ost_unpack_rep(req->rq_repbuf, req->rq_replen, &req->rq_rephdr, 
88                        &req->rq_rep); 
89         printk("-->osc_queue_wait: buf %p len %d status %d\n", 
90                req->rq_repbuf, req->rq_replen, req->rq_rephdr->status); 
91
92         EXIT;
93         return req->rq_rephdr->status;
94 }
95
96 void osc_free_req(struct ost_request *request)
97 {
98         if (request->rq_repbuf)
99                 kfree(request->rq_repbuf);
100         kfree(request);
101 }
102
103
104 int osc_connect(struct obd_conn *conn)
105 {
106         struct ost_request *request;
107         int rc; 
108         ENTRY;
109         
110         request = osc_prep_req(sizeof(*request), OST_CONNECT);
111         if (!request) { 
112                 printk("osc_connect: cannot pack req!\n"); 
113                 return -ENOMEM;
114         }
115
116         rc = osc_queue_wait(conn, request);
117         if (rc) { 
118                 EXIT;
119                 goto out;
120         }
121       
122         CDEBUG(D_INODE, "received connid %d\n", request->rq_rep->connid); 
123
124         conn->oc_id = request->rq_rep->connid;
125  out:
126         osc_free_req(request);
127         EXIT;
128         return rc;
129 }
130
131 int osc_disconnect(struct obd_conn *conn)
132 {
133         struct ost_request *request;
134         int rc; 
135         ENTRY;
136         
137         request = osc_prep_req(sizeof(*request), OST_DISCONNECT);
138         if (!request) { 
139                 printk("osc_connect: cannot pack req!\n"); 
140                 return -ENOMEM;
141         }
142
143         rc = osc_queue_wait(conn, request);
144         if (rc) { 
145                 EXIT;
146                 goto out;
147         }
148  out:
149         osc_free_req(request);
150         EXIT;
151         return rc;
152 }
153
154
155 int osc_getattr(struct obd_conn *conn, struct obdo *oa)
156 {
157         struct ost_request *request;
158         int rc; 
159
160         request = osc_prep_req(sizeof(*request), OST_GETATTR);
161         if (!request) { 
162                 printk("osc_connect: cannot pack req!\n"); 
163                 return -ENOMEM;
164         }
165         
166         memcpy(&request->rq_req->oa, oa, sizeof(*oa));
167         request->rq_req->oa.o_valid = ~0;
168         
169         rc = osc_queue_wait(conn, request);
170         if (rc) { 
171                 EXIT;
172                 goto out;
173         }
174
175         CDEBUG(D_INODE, "mode: %o\n", request->rq_rep->oa.o_mode); 
176         if (oa) { 
177                 memcpy(oa, &request->rq_rep->oa, sizeof(*oa));
178         }
179
180  out:
181         osc_free_req(request);
182         return 0;
183 }
184
185 int osc_create(struct obd_conn *conn, struct obdo *oa)
186 {
187         struct ost_request *request;
188         int rc; 
189
190         if (!oa) { 
191                 printk(__FUNCTION__ ": oa NULL\n"); 
192         }
193         request = osc_prep_req(sizeof(*request), OST_CREATE);
194         if (!request) { 
195                 printk("osc_connect: cannot pack req!\n"); 
196                 return -ENOMEM;
197         }
198         
199         memcpy(&request->rq_req->oa, oa, sizeof(*oa));
200         request->rq_req->oa.o_valid = ~0;
201         
202         rc = osc_queue_wait(conn, request);
203         if (rc) { 
204                 EXIT;
205                 goto out;
206         }
207         memcpy(oa, &request->rq_rep->oa, sizeof(*oa));
208
209  out:
210         osc_free_req(request);
211         return 0;
212 }
213
214
215 /* mount the file system (secretly) */
216 static int osc_setup(struct obd_device *obddev, obd_count len,
217                         void *buf)
218                         
219 {
220         struct obd_ioctl_data* data = buf;
221         struct osc_obd *osc = &obddev->u.osc;
222         ENTRY;
223
224         if (data->ioc_dev  < 0 || data->ioc_dev > MAX_OBD_DEVICES) { 
225                 EXIT;
226                 return -ENODEV;
227         }
228
229         osc->osc_tgt = &obd_dev[data->ioc_dev];
230         printk("OSC: tgt %d ost at %p\n", data->ioc_dev, &osc->osc_tgt->u.ost); 
231         if ( ! (osc->osc_tgt->obd_flags & OBD_ATTACHED) || 
232              ! (osc->osc_tgt->obd_flags & OBD_SET_UP) ){
233                 printk("device not attached or not set up (%d)\n", 
234                        data->ioc_dev);
235                 EXIT;
236                 return -EINVAL;
237         } 
238
239         MOD_INC_USE_COUNT;
240         EXIT; 
241         return 0;
242
243
244
245 static int osc_cleanup(struct obd_device * obddev)
246 {
247         ENTRY;
248
249         if ( !(obddev->obd_flags & OBD_SET_UP) ) {
250                 EXIT;
251                 return 0;
252         }
253
254         MOD_DEC_USE_COUNT;
255         EXIT;
256         return 0;
257 }
258
259
260 struct obd_ops osc_obd_ops = { 
261         o_setup:   osc_setup,
262         o_cleanup: osc_cleanup, 
263         o_create: osc_create,
264         o_getattr: osc_getattr,
265         o_connect: osc_connect,
266         o_disconnect: osc_disconnect
267 };
268
269 static int __init osc_init(void)
270 {
271         obd_register_type(&osc_obd_ops, LUSTRE_OSC_NAME);
272         return 0;
273 }
274
275 static void __exit osc_exit(void)
276 {
277         obd_unregister_type(LUSTRE_OSC_NAME);
278 }
279
280 MODULE_AUTHOR("Peter J. Braam <braam@clusterfs.com>");
281 MODULE_DESCRIPTION("Lustre Object Storage Client (OSC) v1.0");
282 MODULE_LICENSE("GPL"); 
283
284 module_init(osc_init);
285 module_exit(osc_exit);
286