Whamcloud - gitweb
e8721f0ae1fdfd6284e0afd7b96602cc32b3126a
[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_getattr: 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_getattr(struct obd_conn *conn, struct obdo *oa)
132 {
133         struct ost_request *request;
134         int rc; 
135
136         request = osc_prep_req(sizeof(*request), OST_GETATTR);
137         if (!request) { 
138                 printk("osc_connect: cannot pack req!\n"); 
139                 return -ENOMEM;
140         }
141         
142         memcpy(&request->rq_req->oa, oa, sizeof(*oa));
143         request->rq_req->oa.o_valid = ~0;
144         
145         rc = osc_queue_wait(conn, request);
146         if (rc) { 
147                 EXIT;
148                 goto out;
149         }
150
151         CDEBUG(D_INODE, "mode: %o\n", request->rq_rep->oa.o_mode); 
152         if (oa) { 
153                 memcpy(oa, &request->rq_rep->oa, sizeof(*oa));
154         }
155
156  out:
157         osc_free_req(request);
158         return 0;
159 }
160
161
162 /* mount the file system (secretly) */
163 static int osc_setup(struct obd_device *obddev, obd_count len,
164                         void *buf)
165                         
166 {
167         struct obd_ioctl_data* data = buf;
168         struct osc_obd *osc = &obddev->u.osc;
169         ENTRY;
170
171         if (data->ioc_dev  < 0 || data->ioc_dev > MAX_OBD_DEVICES) { 
172                 EXIT;
173                 return -ENODEV;
174         }
175
176         osc->osc_tgt = &obd_dev[data->ioc_dev];
177         printk("OSC: tgt %d ost at %p\n", data->ioc_dev, &osc->osc_tgt->u.ost); 
178         if ( ! (osc->osc_tgt->obd_flags & OBD_ATTACHED) || 
179              ! (osc->osc_tgt->obd_flags & OBD_SET_UP) ){
180                 printk("device not attached or not set up (%d)\n", 
181                        data->ioc_dev);
182                 EXIT;
183                 return -EINVAL;
184         } 
185
186         MOD_INC_USE_COUNT;
187         EXIT; 
188         return 0;
189
190
191
192 static int osc_cleanup(struct obd_device * obddev)
193 {
194         ENTRY;
195
196         if ( !(obddev->obd_flags & OBD_SET_UP) ) {
197                 EXIT;
198                 return 0;
199         }
200
201         MOD_DEC_USE_COUNT;
202         EXIT;
203         return 0;
204 }
205
206
207 struct obd_ops osc_obd_ops = { 
208         o_setup:   osc_setup,
209         o_cleanup: osc_cleanup, 
210         o_getattr: osc_getattr,
211         o_connect: osc_connect
212 };
213
214 static int __init osc_init(void)
215 {
216         obd_register_type(&osc_obd_ops, LUSTRE_OSC_NAME);
217         return 0;
218 }
219
220 static void __exit osc_exit(void)
221 {
222         obd_unregister_type(LUSTRE_OSC_NAME);
223 }
224
225 MODULE_AUTHOR("Peter J. Braam <braam@clusterfs.com>");
226 MODULE_DESCRIPTION("Lustre Object Storage Client (OSC) v1.0");
227 MODULE_LICENSE("GPL"); 
228
229 module_init(osc_init);
230 module_exit(osc_exit);
231