Whamcloud - gitweb
- more of the locking infrastructure.
[fs/lustre-release.git] / lustre / ldlm / ldlm_lockd.c
1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2  * vim:expandtab:shiftwidth=8:tabstop=8:
3  *
4  * Copyright (C) 2002 Cluster File Systems, Inc.
5  *
6  * This code is issued under the GNU General Public License.
7  * See the file COPYING in this distribution
8  *
9  * by Cluster File Systems, Inc.
10  */
11
12 #define EXPORT_SYMTAB
13
14 #include <linux/version.h>
15 #include <linux/module.h>
16 #include <linux/slab.h>
17 #include <asm/unistd.h>
18
19 #define DEBUG_SUBSYSTEM S_LDLM
20
21 #include <linux/obd_class.h>
22 #include <linux/lustre_dlm.h>
23 #include <linux/lustre_net.h>
24
25 extern kmem_cache_t *ldlm_resource_slab;
26 extern kmem_cache_t *ldlm_lock_slab;
27
28 static int ldlm_client_callback(struct ldlm_lock *lock, struct ldlm_lock *new,
29                                 void *data)
30 {
31         LBUG();
32         return 0;
33 }
34
35 static int ldlm_enqueue(struct ptlrpc_request *req)
36 {
37         struct ldlm_reply *dlm_rep;
38         struct ldlm_request *dlm_req;
39         struct lustre_msg *msg, *req_msg;
40         ldlm_error_t err;
41         int rc;
42         int bufsize = sizeof(*dlm_rep);
43         
44         rc = lustre_pack_msg(1, &bufsize, NULL, &req->rq_replen,
45                              &req->rq_repbuf);
46         if (rc) {
47                 CERROR("out of memory\n");
48                 req->rq_status = -ENOMEM;
49                 RETURN(0);
50         }
51         msg = (struct lustre_msg *)req->rq_repbuf;
52         req_msg = req->rq_req.lustre;
53         dlm_rep = lustre_msg_buf(0, msg);
54         dlm_req = lustre_msg_buf(0, req_msg);
55
56         msg->xid = req_msg->xid;
57
58         err = ldlm_local_lock_enqueue(req->rq_obd, dlm_req->ns_id,
59                                       &dlm_req->parent_res_handle,
60                                       &dlm_req->parent_lock_handle,
61                                       dlm_req->res_id, dlm_req->mode,
62                                       &dlm_req->flags, ldlm_client_callback,
63                                       ldlm_client_callback,
64                                       req_msg->buflens[1],
65                                       lustre_msg_buf(1, req_msg),
66                                       &dlm_rep->lock_handle);
67         msg->status = HTON__u32(err);
68
69         /* XXX unfinished */
70         return 0;
71 }
72
73 static int ldlm_handle(struct obd_device *dev, struct ptlrpc_service *svc,
74                        struct ptlrpc_request *req)
75 {
76         int rc;
77         struct ptlreq_hdr *hdr;
78
79         ENTRY;
80
81         hdr = (struct ptlreq_hdr *)req->rq_reqbuf;
82
83         if (NTOH__u32(hdr->type) != PTL_RPC_REQUEST) {
84                 CERROR("lustre_ldlm: wrong packet type sent %d\n",
85                        NTOH__u32(hdr->type));
86                 rc = -EINVAL;
87                 GOTO(out, rc);
88         }
89
90         rc = lustre_unpack_msg(req->rq_reqbuf, req->rq_reqlen);
91         req->rq_reqhdr = (void *)req->rq_reqbuf;
92         if (rc) {
93                 CERROR("lustre_ldlm: Invalid request\n");
94                 GOTO(out, rc);
95         }
96
97         switch (req->rq_reqhdr->opc) {
98         case LDLM_ENQUEUE:
99                 CDEBUG(D_INODE, "enqueue\n");
100                 OBD_FAIL_RETURN(req, OBD_FAIL_LDLM_ENQUEUE);
101                 rc = ldlm_enqueue(req);
102                 break;
103 #if 0
104         case LDLM_CONVERT:
105                 CDEBUG(D_INODE, "convert\n");
106                 OBD_FAIL_RETURN(req, OBD_FAIL_LDLM_CONVERT);
107                 rc = ldlm_convert(req);
108                 break;
109
110         case LDLM_CANCEL:
111                 CDEBUG(D_INODE, "cancel\n");
112                 OBD_FAIL_RETURN(req, OBD_FAIL_LDLM_CANCEL);
113                 rc = ldlm_cancel(req);
114                 break;
115
116         case LDLM_CALLBACK:
117                 CDEBUG(D_INODE, "callback\n");
118                 OBD_FAIL_RETURN(req, OBD_FAIL_LDLM_CALLBACK);
119                 rc = ldlm_callback(req);
120                 break;
121 #endif
122
123         default:
124                 rc = ptlrpc_error(dev, svc, req);
125                 RETURN(rc);
126         }
127
128         EXIT;
129 out:
130         if (rc) {
131                 CERROR("no header\n");
132                 return 0;
133         }
134
135         if( req->rq_status) {
136                 ptlrpc_error(dev, svc, req);
137         } else {
138                 CDEBUG(D_NET, "sending reply\n");
139                 ptlrpc_reply(dev, svc, req);
140         }
141
142         return 0;
143 }
144
145
146
147 static int ldlm_iocontrol(int cmd, struct obd_conn *conn, int len, void *karg,
148                           void *uarg)
149 {
150         struct obd_device *obddev = conn->oc_dev;
151         int err;
152
153         ENTRY;
154
155         if ( _IOC_TYPE(cmd) != IOC_LDLM_TYPE ||
156              _IOC_NR(cmd) < IOC_LDLM_MIN_NR  ||
157              _IOC_NR(cmd) > IOC_LDLM_MAX_NR ) {
158                 CDEBUG(D_IOCTL, "invalid ioctl ( type %d, nr %d, size %d )\n",
159                                 _IOC_TYPE(cmd), _IOC_NR(cmd), _IOC_SIZE(cmd));
160                 EXIT;
161                 return -EINVAL;
162         }
163
164         switch (cmd) {
165         case IOC_LDLM_TEST: {
166                 err = ldlm_test(obddev);
167                 CERROR("-- done err %d\n", err);
168                 EXIT;
169                 break;
170         }
171         default:
172                 err = -EINVAL;
173                 EXIT;
174                 break;
175         }
176
177         return err;
178 }
179
180 static int ldlm_setup(struct obd_device *obddev, obd_count len, void *data)
181 {
182         struct ldlm_obd *ldlm = &obddev->u.ldlm;
183         int err;
184         ENTRY;
185
186         INIT_LIST_HEAD(&obddev->u.ldlm.ldlm_namespaces);
187         obddev->u.ldlm.ldlm_lock = SPIN_LOCK_UNLOCKED;
188
189         ldlm->ldlm_service = ptlrpc_init_svc(64 * 1024,
190                                              LDLM_REQUEST_PORTAL,
191                                              LDLM_REPLY_PORTAL,
192                                              "self", ldlm_handle);
193
194         rpc_register_service(ldlm->ldlm_service, "self");
195
196         err = ptlrpc_start_thread(obddev, ldlm->ldlm_service, "lustre_dlm");
197         if (err)
198                 CERROR("cannot start thread\n");
199
200         MOD_INC_USE_COUNT;
201         RETURN(0);
202 }
203
204 static int ldlm_cleanup(struct obd_device *obddev)
205 {
206         struct ldlm_obd *ldlm = &obddev->u.ldlm;
207         ENTRY;
208
209         ptlrpc_stop_thread(ldlm->ldlm_service);
210         rpc_unregister_service(ldlm->ldlm_service);
211
212         if (!list_empty(&ldlm->ldlm_service->srv_reqs)) {
213                 // XXX reply with errors and clean up
214                 CERROR("Request list not empty!\n");
215         }
216
217         rpc_unregister_service(ldlm->ldlm_service);
218         OBD_FREE(ldlm->ldlm_service, sizeof(*ldlm->ldlm_service));
219
220         MOD_DEC_USE_COUNT;
221         RETURN(0);
222 }
223
224 struct obd_ops ldlm_obd_ops = {
225         o_iocontrol:   ldlm_iocontrol,
226         o_setup:       ldlm_setup,
227         o_cleanup:     ldlm_cleanup,
228         o_connect:     gen_connect,
229         o_disconnect:  gen_disconnect
230 };
231
232
233 static int __init ldlm_init(void)
234 {
235         int rc = obd_register_type(&ldlm_obd_ops, OBD_LDLM_DEVICENAME);
236         if (rc != 0)
237                 return rc;
238
239         ldlm_resource_slab = kmem_cache_create("ldlm_resources",
240                                                sizeof(struct ldlm_resource), 0,
241                                                SLAB_HWCACHE_ALIGN, NULL, NULL);
242         if (ldlm_resource_slab == NULL)
243                 return -ENOMEM;
244
245         ldlm_lock_slab = kmem_cache_create("ldlm_locks",
246                                            sizeof(struct ldlm_lock), 0,
247                                            SLAB_HWCACHE_ALIGN, NULL, NULL);
248         if (ldlm_lock_slab == NULL) {
249                 kmem_cache_destroy(ldlm_resource_slab);
250                 return -ENOMEM;
251         }
252
253         return 0;
254 }
255
256 static void __exit ldlm_exit(void)
257 {
258         obd_unregister_type(OBD_LDLM_DEVICENAME);
259         kmem_cache_destroy(ldlm_resource_slab);
260         kmem_cache_destroy(ldlm_lock_slab);
261 }
262
263 MODULE_AUTHOR("Cluster File Systems, Inc. <braam@clusterfs.com>");
264 MODULE_DESCRIPTION("Lustre Lock Management Module v0.1");
265 MODULE_LICENSE("GPL"); 
266
267 module_init(ldlm_init);
268 module_exit(ldlm_exit);