1 /*
2  * GPL HEADER START
3  *
4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 only,
8  * as published by the Free Software Foundation.
9  *
10  * This program is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * General Public License version 2 for more details (a copy is included
14  * in the LICENSE file that accompanied this code).
15  *
16  * You should have received a copy of the GNU General Public License
17  * version 2 along with this program; If not, see
18  * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
19  *
20  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
21  * CA 95054 USA or visit www.sun.com if you need additional information or
22  * have any questions.
23  *
24  * GPL HEADER END
25  */
26 /*
27  * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
28  * Use is subject to license terms.
29  *
30  * Copyright (c) 2012, Intel Corporation.
31  */
32 /*
33  * This file is part of Lustre, http://www.lustre.org/
34  * Lustre is a trademark of Sun Microsystems, Inc.
35  *
36  * lustre/obdclass/llog_swab.c
37  *
38  * Swabbing of llog datatypes (from disk or over the wire).
39  *
40  * Author: jacob berkman  <jacob@clusterfs.com>
41  */
42 
43 #define DEBUG_SUBSYSTEM S_LOG
44 
45 
46 #include "../include/lustre_log.h"
47 
print_llogd_body(struct llogd_body * d)48 static void print_llogd_body(struct llogd_body *d)
49 {
50 	CDEBUG(D_OTHER, "llogd body: %p\n", d);
51 	CDEBUG(D_OTHER, "\tlgd_logid.lgl_oi: "DOSTID"\n",
52 	       POSTID(&d->lgd_logid.lgl_oi));
53 	CDEBUG(D_OTHER, "\tlgd_logid.lgl_ogen: %#x\n", d->lgd_logid.lgl_ogen);
54 	CDEBUG(D_OTHER, "\tlgd_ctxt_idx: %#x\n", d->lgd_ctxt_idx);
55 	CDEBUG(D_OTHER, "\tlgd_llh_flags: %#x\n", d->lgd_llh_flags);
56 	CDEBUG(D_OTHER, "\tlgd_index: %#x\n", d->lgd_index);
57 	CDEBUG(D_OTHER, "\tlgd_saved_index: %#x\n", d->lgd_saved_index);
58 	CDEBUG(D_OTHER, "\tlgd_len: %#x\n", d->lgd_len);
59 	CDEBUG(D_OTHER, "\tlgd_cur_offset: %#llx\n", d->lgd_cur_offset);
60 }
61 
lustre_swab_lu_fid(struct lu_fid * fid)62 void lustre_swab_lu_fid(struct lu_fid *fid)
63 {
64 	__swab64s(&fid->f_seq);
65 	__swab32s(&fid->f_oid);
66 	__swab32s(&fid->f_ver);
67 }
68 EXPORT_SYMBOL(lustre_swab_lu_fid);
69 
lustre_swab_ost_id(struct ost_id * oid)70 void lustre_swab_ost_id(struct ost_id *oid)
71 {
72 	if (fid_seq_is_mdt0(oid->oi.oi_seq)) {
73 		__swab64s(&oid->oi.oi_id);
74 		__swab64s(&oid->oi.oi_seq);
75 	} else {
76 		lustre_swab_lu_fid(&oid->oi_fid);
77 	}
78 }
79 EXPORT_SYMBOL(lustre_swab_ost_id);
80 
lustre_swab_llog_id(struct llog_logid * log_id)81 void lustre_swab_llog_id(struct llog_logid *log_id)
82 {
83 	__swab64s(&log_id->lgl_oi.oi.oi_id);
84 	__swab64s(&log_id->lgl_oi.oi.oi_seq);
85 	__swab32s(&log_id->lgl_ogen);
86 }
87 EXPORT_SYMBOL(lustre_swab_llog_id);
88 
lustre_swab_llogd_body(struct llogd_body * d)89 void lustre_swab_llogd_body(struct llogd_body *d)
90 {
91 	print_llogd_body(d);
92 	lustre_swab_llog_id(&d->lgd_logid);
93 	__swab32s(&d->lgd_ctxt_idx);
94 	__swab32s(&d->lgd_llh_flags);
95 	__swab32s(&d->lgd_index);
96 	__swab32s(&d->lgd_saved_index);
97 	__swab32s(&d->lgd_len);
98 	__swab64s(&d->lgd_cur_offset);
99 	print_llogd_body(d);
100 }
101 EXPORT_SYMBOL(lustre_swab_llogd_body);
102 
lustre_swab_llogd_conn_body(struct llogd_conn_body * d)103 void lustre_swab_llogd_conn_body(struct llogd_conn_body *d)
104 {
105 	__swab64s(&d->lgdc_gen.mnt_cnt);
106 	__swab64s(&d->lgdc_gen.conn_cnt);
107 	lustre_swab_llog_id(&d->lgdc_logid);
108 	__swab32s(&d->lgdc_ctxt_idx);
109 }
110 EXPORT_SYMBOL(lustre_swab_llogd_conn_body);
111 
lustre_swab_ll_fid(struct ll_fid * fid)112 void lustre_swab_ll_fid(struct ll_fid *fid)
113 {
114 	__swab64s(&fid->id);
115 	__swab32s(&fid->generation);
116 	__swab32s(&fid->f_type);
117 }
118 EXPORT_SYMBOL(lustre_swab_ll_fid);
119 
lustre_swab_lu_seq_range(struct lu_seq_range * range)120 void lustre_swab_lu_seq_range(struct lu_seq_range *range)
121 {
122 	__swab64s(&range->lsr_start);
123 	__swab64s(&range->lsr_end);
124 	__swab32s(&range->lsr_index);
125 	__swab32s(&range->lsr_flags);
126 }
127 EXPORT_SYMBOL(lustre_swab_lu_seq_range);
128 
lustre_swab_llog_rec(struct llog_rec_hdr * rec)129 void lustre_swab_llog_rec(struct llog_rec_hdr *rec)
130 {
131 	struct llog_rec_tail *tail = NULL;
132 
133 	__swab32s(&rec->lrh_len);
134 	__swab32s(&rec->lrh_index);
135 	__swab32s(&rec->lrh_type);
136 	__swab32s(&rec->lrh_id);
137 
138 	switch (rec->lrh_type) {
139 	case OST_SZ_REC:
140 	{
141 		struct llog_size_change_rec *lsc =
142 			(struct llog_size_change_rec *)rec;
143 
144 		lustre_swab_ll_fid(&lsc->lsc_fid);
145 		__swab32s(&lsc->lsc_ioepoch);
146 		tail = &lsc->lsc_tail;
147 		break;
148 	}
149 	case MDS_UNLINK_REC:
150 	{
151 		struct llog_unlink_rec *lur = (struct llog_unlink_rec *)rec;
152 
153 		__swab64s(&lur->lur_oid);
154 		__swab32s(&lur->lur_oseq);
155 		__swab32s(&lur->lur_count);
156 		tail = &lur->lur_tail;
157 		break;
158 	}
159 	case MDS_UNLINK64_REC:
160 	{
161 		struct llog_unlink64_rec *lur =
162 			(struct llog_unlink64_rec *)rec;
163 
164 		lustre_swab_lu_fid(&lur->lur_fid);
165 		__swab32s(&lur->lur_count);
166 		tail = &lur->lur_tail;
167 		break;
168 	}
169 	case CHANGELOG_REC:
170 	{
171 		struct llog_changelog_rec *cr =
172 			(struct llog_changelog_rec *)rec;
173 
174 		__swab16s(&cr->cr.cr_namelen);
175 		__swab16s(&cr->cr.cr_flags);
176 		__swab32s(&cr->cr.cr_type);
177 		__swab64s(&cr->cr.cr_index);
178 		__swab64s(&cr->cr.cr_prev);
179 		__swab64s(&cr->cr.cr_time);
180 		lustre_swab_lu_fid(&cr->cr.cr_tfid);
181 		lustre_swab_lu_fid(&cr->cr.cr_pfid);
182 		if (CHANGELOG_REC_EXTENDED(&cr->cr)) {
183 			struct llog_changelog_ext_rec *ext =
184 				(struct llog_changelog_ext_rec *)rec;
185 
186 			lustre_swab_lu_fid(&ext->cr.cr_sfid);
187 			lustre_swab_lu_fid(&ext->cr.cr_spfid);
188 			tail = &ext->cr_tail;
189 		} else {
190 			tail = &cr->cr_tail;
191 		}
192 		tail = (struct llog_rec_tail *)((char *)tail +
193 						cr->cr.cr_namelen);
194 		break;
195 	}
196 	case CHANGELOG_USER_REC:
197 	{
198 		struct llog_changelog_user_rec *cur =
199 			(struct llog_changelog_user_rec *)rec;
200 
201 		__swab32s(&cur->cur_id);
202 		__swab64s(&cur->cur_endrec);
203 		tail = &cur->cur_tail;
204 		break;
205 	}
206 
207 	case HSM_AGENT_REC: {
208 		struct llog_agent_req_rec *arr =
209 			(struct llog_agent_req_rec *)rec;
210 
211 		__swab32s(&arr->arr_hai.hai_len);
212 		__swab32s(&arr->arr_hai.hai_action);
213 		lustre_swab_lu_fid(&arr->arr_hai.hai_fid);
214 		lustre_swab_lu_fid(&arr->arr_hai.hai_dfid);
215 		__swab64s(&arr->arr_hai.hai_cookie);
216 		__swab64s(&arr->arr_hai.hai_extent.offset);
217 		__swab64s(&arr->arr_hai.hai_extent.length);
218 		__swab64s(&arr->arr_hai.hai_gid);
219 		/* no swabing for opaque data */
220 		/* hai_data[0]; */
221 		break;
222 	}
223 
224 	case MDS_SETATTR64_REC:
225 	{
226 		struct llog_setattr64_rec *lsr =
227 			(struct llog_setattr64_rec *)rec;
228 
229 		lustre_swab_ost_id(&lsr->lsr_oi);
230 		__swab32s(&lsr->lsr_uid);
231 		__swab32s(&lsr->lsr_uid_h);
232 		__swab32s(&lsr->lsr_gid);
233 		__swab32s(&lsr->lsr_gid_h);
234 		tail = &lsr->lsr_tail;
235 		break;
236 	}
237 	case OBD_CFG_REC:
238 		/* these are swabbed as they are consumed */
239 		break;
240 	case LLOG_HDR_MAGIC:
241 	{
242 		struct llog_log_hdr *llh = (struct llog_log_hdr *)rec;
243 
244 		__swab64s(&llh->llh_timestamp);
245 		__swab32s(&llh->llh_count);
246 		__swab32s(&llh->llh_bitmap_offset);
247 		__swab32s(&llh->llh_flags);
248 		__swab32s(&llh->llh_size);
249 		__swab32s(&llh->llh_cat_idx);
250 		tail = &llh->llh_tail;
251 		break;
252 	}
253 	case LLOG_LOGID_MAGIC:
254 	{
255 		struct llog_logid_rec *lid = (struct llog_logid_rec *)rec;
256 
257 		lustre_swab_llog_id(&lid->lid_id);
258 		tail = &lid->lid_tail;
259 		break;
260 	}
261 	case LLOG_GEN_REC:
262 	{
263 		struct llog_gen_rec *lgr = (struct llog_gen_rec *)rec;
264 
265 		__swab64s(&lgr->lgr_gen.mnt_cnt);
266 		__swab64s(&lgr->lgr_gen.conn_cnt);
267 		tail = &lgr->lgr_tail;
268 		break;
269 	}
270 	case LLOG_PAD_MAGIC:
271 		break;
272 	default:
273 		CERROR("Unknown llog rec type %#x swabbing rec %p\n",
274 		       rec->lrh_type, rec);
275 	}
276 
277 	if (tail) {
278 		__swab32s(&tail->lrt_len);
279 		__swab32s(&tail->lrt_index);
280 	}
281 }
282 EXPORT_SYMBOL(lustre_swab_llog_rec);
283 
print_llog_hdr(struct llog_log_hdr * h)284 static void print_llog_hdr(struct llog_log_hdr *h)
285 {
286 	CDEBUG(D_OTHER, "llog header: %p\n", h);
287 	CDEBUG(D_OTHER, "\tllh_hdr.lrh_index: %#x\n", h->llh_hdr.lrh_index);
288 	CDEBUG(D_OTHER, "\tllh_hdr.lrh_len: %#x\n", h->llh_hdr.lrh_len);
289 	CDEBUG(D_OTHER, "\tllh_hdr.lrh_type: %#x\n", h->llh_hdr.lrh_type);
290 	CDEBUG(D_OTHER, "\tllh_timestamp: %#llx\n", h->llh_timestamp);
291 	CDEBUG(D_OTHER, "\tllh_count: %#x\n", h->llh_count);
292 	CDEBUG(D_OTHER, "\tllh_bitmap_offset: %#x\n", h->llh_bitmap_offset);
293 	CDEBUG(D_OTHER, "\tllh_flags: %#x\n", h->llh_flags);
294 	CDEBUG(D_OTHER, "\tllh_size: %#x\n", h->llh_size);
295 	CDEBUG(D_OTHER, "\tllh_cat_idx: %#x\n", h->llh_cat_idx);
296 	CDEBUG(D_OTHER, "\tllh_tail.lrt_index: %#x\n", h->llh_tail.lrt_index);
297 	CDEBUG(D_OTHER, "\tllh_tail.lrt_len: %#x\n", h->llh_tail.lrt_len);
298 }
299 
lustre_swab_llog_hdr(struct llog_log_hdr * h)300 void lustre_swab_llog_hdr(struct llog_log_hdr *h)
301 {
302 	print_llog_hdr(h);
303 
304 	lustre_swab_llog_rec(&h->llh_hdr);
305 
306 	print_llog_hdr(h);
307 }
308 EXPORT_SYMBOL(lustre_swab_llog_hdr);
309 
print_lustre_cfg(struct lustre_cfg * lcfg)310 static void print_lustre_cfg(struct lustre_cfg *lcfg)
311 {
312 	int i;
313 
314 	if (!(libcfs_debug & D_OTHER)) /* don't loop on nothing */
315 		return;
316 	CDEBUG(D_OTHER, "lustre_cfg: %p\n", lcfg);
317 	CDEBUG(D_OTHER, "\tlcfg->lcfg_version: %#x\n", lcfg->lcfg_version);
318 
319 	CDEBUG(D_OTHER, "\tlcfg->lcfg_command: %#x\n", lcfg->lcfg_command);
320 	CDEBUG(D_OTHER, "\tlcfg->lcfg_num: %#x\n", lcfg->lcfg_num);
321 	CDEBUG(D_OTHER, "\tlcfg->lcfg_flags: %#x\n", lcfg->lcfg_flags);
322 	CDEBUG(D_OTHER, "\tlcfg->lcfg_nid: %s\n", libcfs_nid2str(lcfg->lcfg_nid));
323 
324 	CDEBUG(D_OTHER, "\tlcfg->lcfg_bufcount: %d\n", lcfg->lcfg_bufcount);
325 	if (lcfg->lcfg_bufcount < LUSTRE_CFG_MAX_BUFCOUNT)
326 		for (i = 0; i < lcfg->lcfg_bufcount; i++)
327 			CDEBUG(D_OTHER, "\tlcfg->lcfg_buflens[%d]: %d\n",
328 			       i, lcfg->lcfg_buflens[i]);
329 }
330 
lustre_swab_lustre_cfg(struct lustre_cfg * lcfg)331 void lustre_swab_lustre_cfg(struct lustre_cfg *lcfg)
332 {
333 	int i;
334 
335 	__swab32s(&lcfg->lcfg_version);
336 
337 	if (lcfg->lcfg_version != LUSTRE_CFG_VERSION) {
338 		CERROR("not swabbing lustre_cfg version %#x (expecting %#x)\n",
339 		       lcfg->lcfg_version, LUSTRE_CFG_VERSION);
340 		return;
341 	}
342 
343 	__swab32s(&lcfg->lcfg_command);
344 	__swab32s(&lcfg->lcfg_num);
345 	__swab32s(&lcfg->lcfg_flags);
346 	__swab64s(&lcfg->lcfg_nid);
347 	__swab32s(&lcfg->lcfg_bufcount);
348 	for (i = 0; i < lcfg->lcfg_bufcount && i < LUSTRE_CFG_MAX_BUFCOUNT; i++)
349 		__swab32s(&lcfg->lcfg_buflens[i]);
350 
351 	print_lustre_cfg(lcfg);
352 	return;
353 }
354 EXPORT_SYMBOL(lustre_swab_lustre_cfg);
355 
356 /* used only for compatibility with old on-disk cfg_marker data */
357 struct cfg_marker32 {
358 	__u32   cm_step;
359 	__u32   cm_flags;
360 	__u32   cm_vers;
361 	__u32   padding;
362 	__u32   cm_createtime;
363 	__u32   cm_canceltime;
364 	char    cm_tgtname[MTI_NAME_MAXLEN];
365 	char    cm_comment[MTI_NAME_MAXLEN];
366 };
367 
368 #define MTI_NAMELEN32    (MTI_NAME_MAXLEN - \
369 	(sizeof(struct cfg_marker) - sizeof(struct cfg_marker32)))
370 
lustre_swab_cfg_marker(struct cfg_marker * marker,int swab,int size)371 void lustre_swab_cfg_marker(struct cfg_marker *marker, int swab, int size)
372 {
373 	struct cfg_marker32 *cm32 = (struct cfg_marker32 *)marker;
374 
375 	if (swab) {
376 		__swab32s(&marker->cm_step);
377 		__swab32s(&marker->cm_flags);
378 		__swab32s(&marker->cm_vers);
379 	}
380 	if (size == sizeof(*cm32)) {
381 		__u32 createtime, canceltime;
382 		/* There was a problem with the original declaration of
383 		 * cfg_marker on 32-bit systems because it used time_t as
384 		 * a wire protocol structure, and didn't verify this in
385 		 * wirecheck.  We now have to convert the offsets of the
386 		 * later fields in order to work on 32- and 64-bit systems.
387 		 *
388 		 * Fortunately, the cm_comment field has no functional use
389 		 * so can be sacrificed when converting the timestamp size.
390 		 *
391 		 * Overwrite fields from the end first, so they are not
392 		 * clobbered, and use memmove() instead of memcpy() because
393 		 * the source and target buffers overlap.  bug 16771 */
394 		createtime = cm32->cm_createtime;
395 		canceltime = cm32->cm_canceltime;
396 		memmove(marker->cm_comment, cm32->cm_comment, MTI_NAMELEN32);
397 		marker->cm_comment[MTI_NAMELEN32 - 1] = '\0';
398 		memmove(marker->cm_tgtname, cm32->cm_tgtname,
399 			sizeof(marker->cm_tgtname));
400 		if (swab) {
401 			__swab32s(&createtime);
402 			__swab32s(&canceltime);
403 		}
404 		marker->cm_createtime = createtime;
405 		marker->cm_canceltime = canceltime;
406 		CDEBUG(D_CONFIG, "Find old cfg_marker(Srv32b,Clt64b) for target %s, converting\n",
407 		       marker->cm_tgtname);
408 	} else if (swab) {
409 		__swab64s(&marker->cm_createtime);
410 		__swab64s(&marker->cm_canceltime);
411 	}
412 
413 	return;
414 }
415 EXPORT_SYMBOL(lustre_swab_cfg_marker);
416