Whamcloud - gitweb
make fld really stand-alone service independent from mdt
[fs/lustre-release.git] / lustre / mdc / mdc_reint.c
1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2  * vim:expandtab:shiftwidth=8:tabstop=8:
3  *
4  * Copyright (C) 2001-2003 Cluster File Systems, Inc.
5  *
6  *   This file is part of the Lustre file system, http://www.lustre.org
7  *   Lustre is a trademark of Cluster File Systems, Inc.
8  *
9  *   You may have signed or agreed to another license before downloading
10  *   this software.  If so, you are bound by the terms and conditions
11  *   of that agreement, and the following does not apply to you.  See the
12  *   LICENSE file included with this distribution for more information.
13  *
14  *   If you did not agree to a different license, then this copy of Lustre
15  *   is open source software; you can redistribute it and/or modify it
16  *   under the terms of version 2 of the GNU General Public License as
17  *   published by the Free Software Foundation.
18  *
19  *   In either case, Lustre is distributed in the hope that it will be
20  *   useful, but WITHOUT ANY WARRANTY; without even the implied warranty
21  *   of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22  *   license text for more details.
23  */
24
25 #ifndef EXPORT_SYMTAB
26 # define EXPORT_SYMTAB
27 #endif
28 #define DEBUG_SUBSYSTEM S_MDC
29
30 #ifdef __KERNEL__
31 # include <linux/config.h>
32 # include <linux/module.h>
33 # include <linux/kernel.h>
34 #else
35 # include <liblustre.h>
36 #endif
37
38 #include <linux/obd_class.h>
39 #include <linux/lustre_mdc.h>
40 #include "mdc_internal.h"
41
42 /* mdc_setattr does its own semaphore handling */
43 static int mdc_reint(struct ptlrpc_request *request,
44                      struct mdc_rpc_lock *rpc_lock, int level)
45 {
46         int rc;
47
48         request->rq_send_state = level;
49
50         mdc_get_rpc_lock(rpc_lock, NULL);
51         rc = ptlrpc_queue_wait(request);
52         mdc_put_rpc_lock(rpc_lock, NULL);
53         if (rc)
54                 CDEBUG(D_INFO, "error in handling %d\n", rc);
55         else if (!lustre_swab_repbuf(request, 0, sizeof(struct mdt_body),
56                                      lustre_swab_mdt_body)) {
57                 CERROR ("Can't unpack mdt_body\n");
58                 rc = -EPROTO;
59         }
60         return rc;
61 }
62
63 /* If mdc_setattr is called with an 'iattr', then it is a normal RPC that
64  * should take the normal semaphore and go to the normal portal.
65  *
66  * If it is called with iattr->ia_valid & ATTR_FROM_OPEN, then it is a
67  * magic open-path setattr that should take the setattr semaphore and
68  * go to the setattr portal. */
69 int mdc_setattr(struct obd_export *exp, struct md_op_data *op_data,
70                 struct iattr *iattr, void *ea, int ealen, void *ea2, int ea2len,
71                 struct ptlrpc_request **request)
72 {
73         struct ptlrpc_request *req;
74         struct mdt_rec_setattr *rec;
75         struct mdc_rpc_lock *rpc_lock;
76         struct obd_device *obd = exp->exp_obd;
77         int size[] = { sizeof(*rec), ealen, ea2len};
78         int rc, bufcount = 1;
79         ENTRY;
80
81         LASSERT(iattr != NULL);
82
83         if (ealen > 0) {
84                 bufcount++;
85                 if (ea2len > 0)
86                         bufcount++;
87         }
88
89         req = ptlrpc_prep_req(class_exp2cliimp(exp), LUSTRE_MDS_VERSION,
90                               MDS_REINT, bufcount, size, NULL);
91         if (req == NULL)
92                 RETURN(-ENOMEM);
93
94         if (iattr->ia_valid & ATTR_FROM_OPEN) {
95                 req->rq_request_portal = MDS_SETATTR_PORTAL; //XXX FIXME bug 249
96                 rpc_lock = obd->u.cli.cl_setattr_lock;
97         } else {
98                 rpc_lock = obd->u.cli.cl_rpc_lock;
99         }
100
101         if (iattr->ia_valid & (ATTR_MTIME | ATTR_CTIME))
102                 CDEBUG(D_INODE, "setting mtime %lu, ctime %lu\n",
103                        LTIME_S(iattr->ia_mtime), LTIME_S(iattr->ia_ctime));
104         mdc_setattr_pack(req, MDS_REQ_REC_OFF, op_data, iattr, ea, ealen, ea2, ea2len);
105
106         size[0] = sizeof(struct mdt_body);
107         req->rq_replen = lustre_msg_size(1, size);
108
109         rc = mdc_reint(req, rpc_lock, LUSTRE_IMP_FULL);
110         *request = req;
111         if (rc == -ERESTARTSYS)
112                 rc = 0;
113
114         RETURN(rc);
115 }
116
117 int mdc_create(struct obd_export *exp, struct md_op_data *op_data,
118                const void *data, int datalen, int mode, __u32 uid, __u32 gid,
119                __u32 cap_effective, __u64 rdev, struct ptlrpc_request **request)
120 {
121         struct obd_device *obd = exp->exp_obd;
122         struct ptlrpc_request *req;
123         int size[] = { sizeof(struct mdt_rec_create), op_data->namelen + 1, 0};
124         int rc, level, bufcount = 2;
125         ENTRY;
126
127         if (data && datalen) {
128                 size[bufcount] = datalen;
129                 bufcount++;
130         }
131
132         req = ptlrpc_prep_req(class_exp2cliimp(exp), LUSTRE_MDS_VERSION,
133                               MDS_REINT, bufcount, size, NULL);
134         if (req == NULL)
135                 RETURN(-ENOMEM);
136
137         /* mdc_create_pack fills msg->bufs[1] with name
138          * and msg->bufs[2] with tgt, for symlinks or lov MD data */
139         mdc_create_pack(req, MDS_REQ_REC_OFF, op_data, data, datalen, mode,
140                         uid, gid, cap_effective, rdev);
141
142         size[0] = sizeof(struct mdt_body);
143         req->rq_replen = lustre_msg_size(1, size);
144
145         level = LUSTRE_IMP_FULL;
146  resend:
147         rc = mdc_reint(req, obd->u.cli.cl_rpc_lock, level);
148         /* Resend if we were told to. */
149         if (rc == -ERESTARTSYS) {
150                 level = LUSTRE_IMP_RECOVER;
151                 goto resend;
152         }
153
154         *request = req;
155         RETURN(rc);
156 }
157
158 int mdc_unlink(struct obd_export *exp, struct md_op_data *op_data,
159                struct ptlrpc_request **request)
160 {
161         struct obd_device *obd = class_exp2obd(exp);
162         struct ptlrpc_request *req = *request;
163         int rc, size[] = { sizeof(struct mdt_rec_unlink), op_data->namelen + 1};
164         ENTRY;
165
166         LASSERT(req == NULL);
167         req = ptlrpc_prep_req(class_exp2cliimp(exp), LUSTRE_MDS_VERSION,
168                               MDS_REINT, 2, size, NULL);
169         if (req == NULL)
170                 RETURN(-ENOMEM);
171         *request = req;
172
173         size[0] = sizeof(struct mdt_body);
174         size[1] = obd->u.cli.cl_max_mds_easize;
175         size[2] = obd->u.cli.cl_max_mds_cookiesize;
176         req->rq_replen = lustre_msg_size(3, size);
177
178         mdc_unlink_pack(req, MDS_REQ_REC_OFF, op_data);
179
180         rc = mdc_reint(req, obd->u.cli.cl_rpc_lock, LUSTRE_IMP_FULL);
181         if (rc == -ERESTARTSYS)
182                 rc = 0;
183         RETURN(rc);
184 }
185
186 int mdc_link(struct obd_export *exp, struct md_op_data *op_data,
187              struct ptlrpc_request **request)
188 {
189         struct obd_device *obd = exp->exp_obd;
190         struct ptlrpc_request *req;
191         int rc, size[] = { sizeof(struct mdt_rec_link), op_data->namelen + 1};
192         ENTRY;
193
194         req = ptlrpc_prep_req(class_exp2cliimp(exp), LUSTRE_MDS_VERSION,
195                               MDS_REINT, 2, size, NULL);
196         if (req == NULL)
197                 RETURN(-ENOMEM);
198
199         mdc_link_pack(req, MDS_REQ_REC_OFF, op_data);
200
201         size[0] = sizeof(struct mdt_body);
202         req->rq_replen = lustre_msg_size(1, size);
203
204         rc = mdc_reint(req, obd->u.cli.cl_rpc_lock, LUSTRE_IMP_FULL);
205         *request = req;
206         if (rc == -ERESTARTSYS)
207                 rc = 0;
208
209         RETURN(rc);
210 }
211
212 int mdc_rename(struct obd_export *exp, struct md_op_data *op_data,
213                const char *old, int oldlen, const char *new, int newlen,
214                struct ptlrpc_request **request)
215 {
216         struct obd_device *obd = exp->exp_obd;
217         struct ptlrpc_request *req;
218         int rc, size[] = { sizeof(struct mdt_rec_rename), oldlen +1, newlen +1};
219         ENTRY;
220
221         req = ptlrpc_prep_req(class_exp2cliimp(exp), LUSTRE_MDS_VERSION,
222                               MDS_REINT, 3, size, NULL);
223         if (req == NULL)
224                 RETURN(-ENOMEM);
225
226         mdc_rename_pack(req, MDS_REQ_REC_OFF, op_data, old, oldlen, new, newlen);
227
228         size[0] = sizeof(struct mdt_body);
229         size[1] = obd->u.cli.cl_max_mds_easize;
230         size[2] = obd->u.cli.cl_max_mds_cookiesize;
231         req->rq_replen = lustre_msg_size(3, size);
232
233         rc = mdc_reint(req, obd->u.cli.cl_rpc_lock, LUSTRE_IMP_FULL);
234         *request = req;
235         if (rc == -ERESTARTSYS)
236                 rc = 0;
237
238         RETURN(rc);
239 }