1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34#define DEBUG_SUBSYSTEM S_MDC
35
36# include <linux/module.h>
37# include <linux/kernel.h>
38
39#include <obd_class.h>
40#include "mdc_internal.h"
41#include <lustre_fid.h>
42
43
44static int mdc_reint(struct ptlrpc_request *request, int level)
45{
46 int rc;
47
48 request->rq_send_state = level;
49
50 mdc_get_mod_rpc_slot(request, NULL);
51 rc = ptlrpc_queue_wait(request);
52 mdc_put_mod_rpc_slot(request, NULL);
53 if (rc)
54 CDEBUG(D_INFO, "error in handling %d\n", rc);
55 else if (!req_capsule_server_get(&request->rq_pill, &RMF_MDT_BODY))
56 rc = -EPROTO;
57
58 return rc;
59}
60
61
62
63
64
65int mdc_resource_get_unused(struct obd_export *exp, const struct lu_fid *fid,
66 struct list_head *cancels, enum ldlm_mode mode,
67 __u64 bits)
68{
69 struct ldlm_namespace *ns = exp->exp_obd->obd_namespace;
70 union ldlm_policy_data policy = {};
71 struct ldlm_res_id res_id;
72 struct ldlm_resource *res;
73 int count;
74
75
76
77
78
79
80
81
82 if (exp_connect_cancelset(exp) && !ns_connect_cancelset(ns))
83 return 0;
84
85 fid_build_reg_res_name(fid, &res_id);
86 res = ldlm_resource_get(exp->exp_obd->obd_namespace,
87 NULL, &res_id, 0, 0);
88 if (IS_ERR(res))
89 return 0;
90 LDLM_RESOURCE_ADDREF(res);
91
92 policy.l_inodebits.bits = bits;
93 count = ldlm_cancel_resource_local(res, cancels, &policy,
94 mode, 0, 0, NULL);
95 LDLM_RESOURCE_DELREF(res);
96 ldlm_resource_putref(res);
97 return count;
98}
99
100int mdc_setattr(struct obd_export *exp, struct md_op_data *op_data,
101 void *ea, size_t ealen, struct ptlrpc_request **request)
102{
103 LIST_HEAD(cancels);
104 struct ptlrpc_request *req;
105 int count = 0, rc;
106 __u64 bits;
107
108 bits = MDS_INODELOCK_UPDATE;
109 if (op_data->op_attr.ia_valid & (ATTR_MODE | ATTR_UID | ATTR_GID))
110 bits |= MDS_INODELOCK_LOOKUP;
111 if ((op_data->op_flags & MF_MDC_CANCEL_FID1) &&
112 (fid_is_sane(&op_data->op_fid1)))
113 count = mdc_resource_get_unused(exp, &op_data->op_fid1,
114 &cancels, LCK_EX, bits);
115 req = ptlrpc_request_alloc(class_exp2cliimp(exp),
116 &RQF_MDS_REINT_SETATTR);
117 if (!req) {
118 ldlm_lock_list_put(&cancels, l_bl_ast, count);
119 return -ENOMEM;
120 }
121 req_capsule_set_size(&req->rq_pill, &RMF_MDT_EPOCH, RCL_CLIENT, 0);
122 req_capsule_set_size(&req->rq_pill, &RMF_EADATA, RCL_CLIENT, ealen);
123 req_capsule_set_size(&req->rq_pill, &RMF_LOGCOOKIES, RCL_CLIENT, 0);
124
125 rc = mdc_prep_elc_req(exp, req, MDS_REINT, &cancels, count);
126 if (rc) {
127 ptlrpc_request_free(req);
128 return rc;
129 }
130
131 if (op_data->op_attr.ia_valid & (ATTR_MTIME | ATTR_CTIME))
132 CDEBUG(D_INODE, "setting mtime %ld, ctime %ld\n",
133 LTIME_S(op_data->op_attr.ia_mtime),
134 LTIME_S(op_data->op_attr.ia_ctime));
135 mdc_setattr_pack(req, op_data, ea, ealen);
136
137 ptlrpc_request_set_replen(req);
138
139 rc = mdc_reint(req, LUSTRE_IMP_FULL);
140
141 if (rc == -ERESTARTSYS)
142 rc = 0;
143
144 *request = req;
145
146 return rc;
147}
148
149int mdc_create(struct obd_export *exp, struct md_op_data *op_data,
150 const void *data, size_t datalen, umode_t mode,
151 uid_t uid, gid_t gid, cfs_cap_t cap_effective,
152 __u64 rdev, struct ptlrpc_request **request)
153{
154 struct ptlrpc_request *req;
155 int level, rc;
156 int count, resends = 0;
157 struct obd_import *import = exp->exp_obd->u.cli.cl_import;
158 int generation = import->imp_generation;
159 LIST_HEAD(cancels);
160
161
162 if (!fid_is_sane(&op_data->op_fid2)) {
163
164
165
166
167 rc = mdc_fid_alloc(NULL, exp, &op_data->op_fid2, op_data);
168 if (rc < 0)
169 return rc;
170 }
171
172rebuild:
173 count = 0;
174 if ((op_data->op_flags & MF_MDC_CANCEL_FID1) &&
175 (fid_is_sane(&op_data->op_fid1)))
176 count = mdc_resource_get_unused(exp, &op_data->op_fid1,
177 &cancels, LCK_EX,
178 MDS_INODELOCK_UPDATE);
179
180 req = ptlrpc_request_alloc(class_exp2cliimp(exp),
181 &RQF_MDS_REINT_CREATE_ACL);
182 if (!req) {
183 ldlm_lock_list_put(&cancels, l_bl_ast, count);
184 return -ENOMEM;
185 }
186 req_capsule_set_size(&req->rq_pill, &RMF_NAME, RCL_CLIENT,
187 op_data->op_namelen + 1);
188 req_capsule_set_size(&req->rq_pill, &RMF_EADATA, RCL_CLIENT,
189 data && datalen ? datalen : 0);
190
191 rc = mdc_prep_elc_req(exp, req, MDS_REINT, &cancels, count);
192 if (rc) {
193 ptlrpc_request_free(req);
194 return rc;
195 }
196
197
198
199
200
201 mdc_create_pack(req, op_data, data, datalen, mode, uid,
202 gid, cap_effective, rdev);
203
204 ptlrpc_request_set_replen(req);
205
206
207
208
209 req->rq_no_retry_einprogress = 1;
210
211 if (resends) {
212 req->rq_generation_set = 1;
213 req->rq_import_generation = generation;
214 req->rq_sent = ktime_get_real_seconds() + resends;
215 }
216 level = LUSTRE_IMP_FULL;
217 resend:
218 rc = mdc_reint(req, level);
219
220
221 if (rc == -ERESTARTSYS) {
222 level = LUSTRE_IMP_RECOVER;
223 goto resend;
224 } else if (rc == -EINPROGRESS) {
225
226
227
228 ptlrpc_req_finished(req);
229 resends++;
230
231 CDEBUG(D_HA, "%s: resend:%d create on " DFID "/" DFID "\n",
232 exp->exp_obd->obd_name, resends,
233 PFID(&op_data->op_fid1), PFID(&op_data->op_fid2));
234
235 if (generation == import->imp_generation) {
236 goto rebuild;
237 } else {
238 CDEBUG(D_HA, "resend cross eviction\n");
239 return -EIO;
240 }
241 }
242
243 *request = req;
244 return rc;
245}
246
247int mdc_unlink(struct obd_export *exp, struct md_op_data *op_data,
248 struct ptlrpc_request **request)
249{
250 LIST_HEAD(cancels);
251 struct obd_device *obd = class_exp2obd(exp);
252 struct ptlrpc_request *req = *request;
253 int count = 0, rc;
254
255 LASSERT(!req);
256
257 if ((op_data->op_flags & MF_MDC_CANCEL_FID1) &&
258 (fid_is_sane(&op_data->op_fid1)))
259 count = mdc_resource_get_unused(exp, &op_data->op_fid1,
260 &cancels, LCK_EX,
261 MDS_INODELOCK_UPDATE);
262 if ((op_data->op_flags & MF_MDC_CANCEL_FID3) &&
263 (fid_is_sane(&op_data->op_fid3)))
264 count += mdc_resource_get_unused(exp, &op_data->op_fid3,
265 &cancels, LCK_EX,
266 MDS_INODELOCK_FULL);
267 req = ptlrpc_request_alloc(class_exp2cliimp(exp),
268 &RQF_MDS_REINT_UNLINK);
269 if (!req) {
270 ldlm_lock_list_put(&cancels, l_bl_ast, count);
271 return -ENOMEM;
272 }
273 req_capsule_set_size(&req->rq_pill, &RMF_NAME, RCL_CLIENT,
274 op_data->op_namelen + 1);
275
276 rc = mdc_prep_elc_req(exp, req, MDS_REINT, &cancels, count);
277 if (rc) {
278 ptlrpc_request_free(req);
279 return rc;
280 }
281
282 mdc_unlink_pack(req, op_data);
283
284 req_capsule_set_size(&req->rq_pill, &RMF_MDT_MD, RCL_SERVER,
285 obd->u.cli.cl_default_mds_easize);
286 ptlrpc_request_set_replen(req);
287
288 *request = req;
289
290 rc = mdc_reint(req, LUSTRE_IMP_FULL);
291 if (rc == -ERESTARTSYS)
292 rc = 0;
293 return rc;
294}
295
296int mdc_link(struct obd_export *exp, struct md_op_data *op_data,
297 struct ptlrpc_request **request)
298{
299 LIST_HEAD(cancels);
300 struct ptlrpc_request *req;
301 int count = 0, rc;
302
303 if ((op_data->op_flags & MF_MDC_CANCEL_FID2) &&
304 (fid_is_sane(&op_data->op_fid2)))
305 count = mdc_resource_get_unused(exp, &op_data->op_fid2,
306 &cancels, LCK_EX,
307 MDS_INODELOCK_UPDATE);
308 if ((op_data->op_flags & MF_MDC_CANCEL_FID1) &&
309 (fid_is_sane(&op_data->op_fid1)))
310 count += mdc_resource_get_unused(exp, &op_data->op_fid1,
311 &cancels, LCK_EX,
312 MDS_INODELOCK_UPDATE);
313
314 req = ptlrpc_request_alloc(class_exp2cliimp(exp), &RQF_MDS_REINT_LINK);
315 if (!req) {
316 ldlm_lock_list_put(&cancels, l_bl_ast, count);
317 return -ENOMEM;
318 }
319 req_capsule_set_size(&req->rq_pill, &RMF_NAME, RCL_CLIENT,
320 op_data->op_namelen + 1);
321
322 rc = mdc_prep_elc_req(exp, req, MDS_REINT, &cancels, count);
323 if (rc) {
324 ptlrpc_request_free(req);
325 return rc;
326 }
327
328 mdc_link_pack(req, op_data);
329 ptlrpc_request_set_replen(req);
330
331 rc = mdc_reint(req, LUSTRE_IMP_FULL);
332 *request = req;
333 if (rc == -ERESTARTSYS)
334 rc = 0;
335
336 return rc;
337}
338
339int mdc_rename(struct obd_export *exp, struct md_op_data *op_data,
340 const char *old, size_t oldlen, const char *new, size_t newlen,
341 struct ptlrpc_request **request)
342{
343 LIST_HEAD(cancels);
344 struct obd_device *obd = exp->exp_obd;
345 struct ptlrpc_request *req;
346 int count = 0, rc;
347
348 if ((op_data->op_flags & MF_MDC_CANCEL_FID1) &&
349 (fid_is_sane(&op_data->op_fid1)))
350 count = mdc_resource_get_unused(exp, &op_data->op_fid1,
351 &cancels, LCK_EX,
352 MDS_INODELOCK_UPDATE);
353 if ((op_data->op_flags & MF_MDC_CANCEL_FID2) &&
354 (fid_is_sane(&op_data->op_fid2)))
355 count += mdc_resource_get_unused(exp, &op_data->op_fid2,
356 &cancels, LCK_EX,
357 MDS_INODELOCK_UPDATE);
358 if ((op_data->op_flags & MF_MDC_CANCEL_FID3) &&
359 (fid_is_sane(&op_data->op_fid3)))
360 count += mdc_resource_get_unused(exp, &op_data->op_fid3,
361 &cancels, LCK_EX,
362 MDS_INODELOCK_LOOKUP);
363 if ((op_data->op_flags & MF_MDC_CANCEL_FID4) &&
364 (fid_is_sane(&op_data->op_fid4)))
365 count += mdc_resource_get_unused(exp, &op_data->op_fid4,
366 &cancels, LCK_EX,
367 MDS_INODELOCK_FULL);
368
369 req = ptlrpc_request_alloc(class_exp2cliimp(exp),
370 op_data->op_cli_flags & CLI_MIGRATE ?
371 &RQF_MDS_REINT_MIGRATE : &RQF_MDS_REINT_RENAME);
372 if (!req) {
373 ldlm_lock_list_put(&cancels, l_bl_ast, count);
374 return -ENOMEM;
375 }
376
377 req_capsule_set_size(&req->rq_pill, &RMF_NAME, RCL_CLIENT, oldlen + 1);
378 req_capsule_set_size(&req->rq_pill, &RMF_SYMTGT, RCL_CLIENT,
379 newlen + 1);
380
381 rc = mdc_prep_elc_req(exp, req, MDS_REINT, &cancels, count);
382 if (rc) {
383 ptlrpc_request_free(req);
384 return rc;
385 }
386
387 if (op_data->op_cli_flags & CLI_MIGRATE && op_data->op_data) {
388 struct md_open_data *mod = op_data->op_data;
389
390 LASSERTF(mod->mod_open_req &&
391 mod->mod_open_req->rq_type != LI_POISON,
392 "POISONED open %p!\n", mod->mod_open_req);
393
394 DEBUG_REQ(D_HA, mod->mod_open_req, "matched open");
395
396
397
398
399 spin_lock(&mod->mod_open_req->rq_lock);
400 mod->mod_open_req->rq_replay = 0;
401 spin_unlock(&mod->mod_open_req->rq_lock);
402 }
403
404 if (exp_connect_cancelset(exp) && req)
405 ldlm_cli_cancel_list(&cancels, count, req, 0);
406
407 mdc_rename_pack(req, op_data, old, oldlen, new, newlen);
408
409 req_capsule_set_size(&req->rq_pill, &RMF_MDT_MD, RCL_SERVER,
410 obd->u.cli.cl_default_mds_easize);
411 ptlrpc_request_set_replen(req);
412
413 rc = mdc_reint(req, LUSTRE_IMP_FULL);
414 *request = req;
415 if (rc == -ERESTARTSYS)
416 rc = 0;
417
418 return rc;
419}
420