1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2 * vim:expandtab:shiftwidth=8:tabstop=8:
5 * Lustre Metadata Target (mdt) request unpacking helper.
7 * Copyright (c) 2006 Cluster File Systems, Inc.
8 * Author: Peter Braam <braam@clusterfs.com>
9 * Author: Andreas Dilger <adilger@clusterfs.com>
10 * Author: Phil Schwan <phil@clusterfs.com>
11 * Author: Mike Shaver <shaver@clusterfs.com>
12 * Author: Nikita Danilov <nikita@clusterfs.com>
13 * Author: Huang Hua <huanghua@clusterfs.com>
16 * This file is part of the Lustre file system, http://www.lustre.org
17 * Lustre is a trademark of Cluster File Systems, Inc.
19 * You may have signed or agreed to another license before downloading
20 * this software. If so, you are bound by the terms and conditions
21 * of that agreement, and the following does not apply to you. See the
22 * LICENSE file included with this distribution for more information.
24 * If you did not agree to a different license, then this copy of Lustre
25 * is open source software; you can redistribute it and/or modify it
26 * under the terms of version 2 of the GNU General Public License as
27 * published by the Free Software Foundation.
29 * In either case, Lustre is distributed in the hope that it will be
30 * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
31 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
32 * license text for more details.
37 # define EXPORT_SYMTAB
39 #define DEBUG_SUBSYSTEM S_MDS
41 #include "mdt_internal.h"
44 /* copied from lov/lov_ea.c, just for debugging, will be removed later */
45 void mdt_dump_lmm(int level, const struct lov_mds_md *lmm)
47 const struct lov_ost_data_v1 *lod;
50 le16_to_cpu(((struct lov_user_md*)lmm)->lmm_stripe_count);
52 CDEBUG(level, "objid "LPX64", magic 0x%08X, pattern %#X\n",
53 le64_to_cpu(lmm->lmm_object_id), le32_to_cpu(lmm->lmm_magic),
54 le32_to_cpu(lmm->lmm_pattern));
55 CDEBUG(level,"stripe_size=0x%x, stripe_count=0x%x\n",
56 le32_to_cpu(lmm->lmm_stripe_size),
57 le32_to_cpu(lmm->lmm_stripe_count));
58 LASSERT(stripe_count < (__s16)LOV_MAX_STRIPE_COUNT);
59 for (i = 0, lod = lmm->lmm_objects; i < stripe_count; i++, lod++) {
60 CDEBUG(level, "stripe %u idx %u subobj "LPX64"/"LPX64"\n",
61 i, le32_to_cpu(lod->l_ost_idx),
62 le64_to_cpu(lod->l_object_gr),
63 le64_to_cpu(lod->l_object_id));
67 void mdt_shrink_reply(struct mdt_thread_info *info, int offset)
69 struct ptlrpc_request *req = mdt_info_req(info);
70 struct mdt_body *body;
74 body = req_capsule_server_get(&info->mti_pill, &RMF_MDT_BODY);
75 LASSERT(body != NULL);
77 md_size = body->eadatasize;
78 acl_size = body->aclsize;
80 CDEBUG(D_INFO, "Shrink to md_size %d cookie_size %d \n",
83 lustre_shrink_reply(req, offset, md_size, 1);
84 lustre_shrink_reply(req, md_size ? offset + 1: offset, acl_size, 0);
88 /* if object is dying, pack the lov/llog data,
89 * parameter info->mti_attr should be valid at this point! */
90 int mdt_handle_last_unlink(struct mdt_thread_info *info, struct mdt_object *mo,
91 const struct md_attr *ma)
93 struct mdt_body *repbody;
94 const struct lu_attr *la = &ma->ma_attr;
97 repbody = req_capsule_server_get(&info->mti_pill, &RMF_MDT_BODY);
98 LASSERT(repbody != NULL);
100 if (ma->ma_valid & MA_INODE)
101 mdt_pack_attr2body(repbody, la, mdt_object_fid(mo));
103 if (ma->ma_valid & MA_LOV) {
106 mode = lu_object_attr(&mo->mot_obj.mo_lu);
107 LASSERT(ma->ma_lmm_size);
108 mdt_dump_lmm(D_INFO, ma->ma_lmm);
109 repbody->eadatasize = ma->ma_lmm_size;
111 repbody->valid |= OBD_MD_FLEASIZE;
112 else if (S_ISDIR(mode))
113 repbody->valid |= OBD_MD_FLDIREA;
118 if (ma->ma_cookie_size && (ma->ma_valid & MA_COOKIE)) {
119 repbody->aclsize = ma->ma_cookie_size;
120 repbody->valid |= OBD_MD_FLCOOKIE;
126 static __u64 mdt_attr_valid_xlate(__u64 in, struct mdt_reint_record *rr,
140 if (in & ATTR_BLOCKS)
143 if (in & ATTR_FROM_OPEN)
144 rr->rr_flags |= MRF_SETATTR_LOCKED;
146 if (in & ATTR_ATIME_SET)
149 if (in & ATTR_CTIME_SET)
152 if (in & ATTR_MTIME_SET)
155 if (in & ATTR_ATTR_FLAG)
158 /*XXX need ATTR_RAW?*/
159 in &= ~(ATTR_MODE|ATTR_UID|ATTR_GID|ATTR_SIZE|ATTR_BLOCKS|
160 ATTR_ATIME|ATTR_MTIME|ATTR_CTIME|ATTR_FROM_OPEN|
161 ATTR_ATIME_SET|ATTR_CTIME_SET|ATTR_MTIME_SET|
162 ATTR_ATTR_FLAG|ATTR_RAW);
164 CERROR("Unknown attr bits: %#llx\n", in);
169 static int mdt_setattr_unpack_rec(struct mdt_thread_info *info)
171 struct md_attr *ma = &info->mti_attr;
172 struct lu_attr *la = &ma->ma_attr;
173 struct req_capsule *pill = &info->mti_pill;
174 struct mdt_reint_record *rr = &info->mti_rr;
175 struct mdt_rec_setattr *rec;
178 rec = req_capsule_client_get(pill, &RMF_REC_SETATTR);
182 rr->rr_fid1 = &rec->sa_fid;
183 la->la_valid = mdt_attr_valid_xlate(rec->sa_valid, rr, ma);
184 la->la_mode = rec->sa_mode;
185 la->la_flags = rec->sa_attr_flags;
186 la->la_uid = rec->sa_uid;
187 la->la_gid = rec->sa_gid;
188 la->la_size = rec->sa_size;
189 la->la_blocks = rec->sa_blocks;
190 la->la_ctime = rec->sa_ctime;
191 la->la_atime = rec->sa_atime;
192 la->la_mtime = rec->sa_mtime;
193 ma->ma_valid = MA_INODE;
197 static int mdt_epoch_unpack(struct mdt_thread_info *info)
199 struct req_capsule *pill = &info->mti_pill;
202 if (req_capsule_get_size(pill, &RMF_MDT_EPOCH, RCL_CLIENT))
203 info->mti_epoch = req_capsule_client_get(pill, &RMF_MDT_EPOCH);
205 /* it is set to NULL already.
206 info->mti_epoch = NULL;
209 RETURN(info->mti_epoch == NULL ? -EFAULT : 0);
212 static int mdt_setattr_unpack(struct mdt_thread_info *info)
214 struct md_attr *ma = &info->mti_attr;
215 struct req_capsule *pill = &info->mti_pill;
219 rc = mdt_setattr_unpack_rec(info);
223 /* Epoch may be absent */
224 mdt_epoch_unpack(info);
226 if (req_capsule_field_present(pill, &RMF_EADATA, RCL_CLIENT)) {
227 ma->ma_lmm = req_capsule_client_get(pill, &RMF_EADATA);
228 ma->ma_lmm_size = req_capsule_get_size(pill, &RMF_EADATA,
230 ma->ma_valid |= MA_LOV;
232 if (req_capsule_field_present(pill, &RMF_LOGCOOKIES, RCL_CLIENT)) {
233 ma->ma_cookie = req_capsule_client_get(pill,
235 ma->ma_cookie_size = req_capsule_get_size(pill,
238 ma->ma_valid |= MA_COOKIE;
244 int mdt_close_unpack(struct mdt_thread_info *info)
249 rc = mdt_epoch_unpack(info);
253 RETURN(mdt_setattr_unpack_rec(info));
256 static int mdt_create_unpack(struct mdt_thread_info *info)
258 struct mdt_rec_create *rec;
259 struct lu_attr *attr = &info->mti_attr.ma_attr;
260 struct mdt_reint_record *rr = &info->mti_rr;
261 struct req_capsule *pill = &info->mti_pill;
265 rec = req_capsule_client_get(pill, &RMF_REC_CREATE);
267 rr->rr_fid1 = &rec->cr_fid1;
268 rr->rr_fid2 = &rec->cr_fid2;
269 attr->la_mode = rec->cr_mode;
270 attr->la_rdev = rec->cr_rdev;
271 attr->la_uid = rec->cr_fsuid;
272 attr->la_gid = rec->cr_fsgid;
273 attr->la_ctime = rec->cr_time;
274 attr->la_mtime = rec->cr_time;
275 attr->la_atime = rec->cr_time;
276 attr->la_valid = LA_MODE | LA_RDEV | LA_UID | LA_GID |
277 LA_CTIME | LA_MTIME | LA_ATIME;
278 info->mti_spec.sp_cr_flags = rec->cr_flags;
280 rr->rr_name = req_capsule_client_get(pill, &RMF_NAME);
281 if (S_ISDIR(attr->la_mode)) {
282 struct md_create_spec *sp = &info->mti_spec;
283 /* pass parent fid for cross-ref cases */
284 sp->u.sp_pfid = rr->rr_fid1;
285 if (info->mti_spec.sp_cr_flags & MDS_CREATE_SLAVE_OBJ) {
286 /* create salve object req, need
287 * unpack split ea here
289 req_capsule_extend(pill,
290 &RQF_MDS_REINT_CREATE_SLAVE);
291 LASSERT(req_capsule_field_present(pill,
292 &RMF_EADATA, RCL_CLIENT));
293 sp->u.sp_ea.eadata = req_capsule_client_get(pill,
295 sp->u.sp_ea.eadatalen =req_capsule_get_size(pill,
296 &RMF_EADATA, RCL_CLIENT);
297 sp->u.sp_ea.fid = rr->rr_fid1;
299 } else if (S_ISLNK(attr->la_mode)) {
300 const char *tgt = NULL;
301 req_capsule_extend(pill, &RQF_MDS_REINT_CREATE_SYM);
302 if (req_capsule_field_present(pill, &RMF_SYMTGT,
304 tgt = req_capsule_client_get(pill,
306 info->mti_spec.u.sp_symname = tgt;
316 static int mdt_link_unpack(struct mdt_thread_info *info)
318 struct mdt_rec_link *rec;
319 struct lu_attr *attr = &info->mti_attr.ma_attr;
320 struct mdt_reint_record *rr = &info->mti_rr;
321 struct req_capsule *pill = &info->mti_pill;
325 rec = req_capsule_client_get(pill, &RMF_REC_LINK);
327 attr->la_uid = rec->lk_fsuid;
328 attr->la_gid = rec->lk_fsgid;
329 rr->rr_fid1 = &rec->lk_fid1;
330 rr->rr_fid2 = &rec->lk_fid2;
331 attr->la_ctime = rec->lk_time;
332 attr->la_mtime = rec->lk_time;
333 attr->la_valid = LA_UID | LA_GID | LA_CTIME | LA_MTIME;
334 rr->rr_name = req_capsule_client_get(pill, &RMF_NAME);
335 if (rr->rr_name == NULL)
342 static int mdt_unlink_unpack(struct mdt_thread_info *info)
344 struct mdt_rec_unlink *rec;
345 struct lu_attr *attr = &info->mti_attr.ma_attr;
346 struct mdt_reint_record *rr = &info->mti_rr;
347 struct req_capsule *pill = &info->mti_pill;
351 rec = req_capsule_client_get(pill, &RMF_REC_UNLINK);
353 attr->la_uid = rec->ul_fsuid;
354 attr->la_gid = rec->ul_fsgid;
355 rr->rr_fid1 = &rec->ul_fid1;
356 rr->rr_fid2 = &rec->ul_fid2;
357 attr->la_ctime = rec->ul_time;
358 attr->la_mtime = rec->ul_time;
359 attr->la_mode = rec->ul_mode;
361 attr->la_valid = LA_UID | LA_GID | LA_CTIME |
363 rr->rr_name = req_capsule_client_get(pill, &RMF_NAME);
364 if (rr->rr_name == NULL)
371 static int mdt_rename_unpack(struct mdt_thread_info *info)
373 struct mdt_rec_rename *rec;
374 struct lu_attr *attr = &info->mti_attr.ma_attr;
375 struct mdt_reint_record *rr = &info->mti_rr;
376 struct req_capsule *pill = &info->mti_pill;
380 rec = req_capsule_client_get(pill, &RMF_REC_RENAME);
382 attr->la_uid = rec->rn_fsuid;
383 attr->la_gid = rec->rn_fsgid;
384 rr->rr_fid1 = &rec->rn_fid1;
385 rr->rr_fid2 = &rec->rn_fid2;
386 attr->la_ctime = rec->rn_time;
387 attr->la_mtime = rec->rn_time;
388 attr->la_valid = LA_UID | LA_GID | LA_CTIME | LA_MTIME;
389 rr->rr_name = req_capsule_client_get(pill, &RMF_NAME);
390 rr->rr_tgt = req_capsule_client_get(pill, &RMF_SYMTGT);
391 if (rr->rr_name == NULL || rr->rr_tgt == NULL)
398 static int mdt_open_unpack(struct mdt_thread_info *info)
400 struct mdt_rec_create *rec;
401 struct lu_attr *attr = &info->mti_attr.ma_attr;
402 struct req_capsule *pill = &info->mti_pill;
403 struct mdt_reint_record *rr = &info->mti_rr;
407 rec = req_capsule_client_get(pill, &RMF_REC_CREATE);
409 rr->rr_fid1 = &rec->cr_fid1;
410 rr->rr_fid2 = &rec->cr_fid2;
411 attr->la_mode = rec->cr_mode;
412 attr->la_rdev = rec->cr_rdev;
413 attr->la_uid = rec->cr_fsuid;
414 attr->la_gid = rec->cr_fsgid;
415 attr->la_ctime = rec->cr_time;
416 attr->la_mtime = rec->cr_time;
417 attr->la_atime = rec->cr_time;
418 attr->la_valid = LA_MODE | LA_RDEV | LA_UID | LA_GID |
419 LA_CTIME | LA_MTIME | LA_ATIME;
420 info->mti_spec.sp_cr_flags = rec->cr_flags;
421 rr->rr_name = req_capsule_client_get(pill, &RMF_NAME);
422 if (rr->rr_name == NULL)
429 if (req_capsule_field_present(pill, &RMF_EADATA, RCL_CLIENT)) {
430 struct md_create_spec *sp = &info->mti_spec;
431 struct ptlrpc_request *req = mdt_info_req(info);
432 sp->u.sp_ea.eadata = req_capsule_client_get(pill,
434 sp->u.sp_ea.eadatalen = req_capsule_get_size(pill,
437 if (lustre_msg_get_flags(req->rq_reqmsg) & MSG_REPLAY)
438 sp->u.sp_ea.no_lov_create = 1;
444 typedef int (*reint_unpacker)(struct mdt_thread_info *info);
446 static reint_unpacker mdt_reint_unpackers[REINT_MAX] = {
447 [REINT_SETATTR] = mdt_setattr_unpack,
448 [REINT_CREATE] = mdt_create_unpack,
449 [REINT_LINK] = mdt_link_unpack,
450 [REINT_UNLINK] = mdt_unlink_unpack,
451 [REINT_RENAME] = mdt_rename_unpack,
452 [REINT_OPEN] = mdt_open_unpack
455 int mdt_reint_unpack(struct mdt_thread_info *info, __u32 op)
461 if (op < REINT_MAX && mdt_reint_unpackers[op] != NULL) {
462 info->mti_rr.rr_opcode = op;
463 rc = mdt_reint_unpackers[op](info);
465 CERROR("Unexpected opcode %d\n", op);