add packaging
[platform/upstream/db4.git] / txn / txn_auto.c
1 /* Do not edit: automatically built by gen_rec.awk. */
2
3 #include "db_config.h"
4 #include "db_int.h"
5 #include "dbinc/crypto.h"
6 #include "dbinc/db_page.h"
7 #include "dbinc/db_dispatch.h"
8 #include "dbinc/db_am.h"
9 #include "dbinc/lock.h"
10 #include "dbinc/log.h"
11 #include "dbinc/txn.h"
12
13 /*
14  * PUBLIC: int __txn_regop_42_read __P((ENV *, void *,
15  * PUBLIC:     __txn_regop_42_args **));
16  */
17 int
18 __txn_regop_42_read(env, recbuf, argpp)
19         ENV *env;
20         void *recbuf;
21         __txn_regop_42_args **argpp;
22 {
23         __txn_regop_42_args *argp;
24         u_int32_t uinttmp;
25         u_int8_t *bp;
26         int ret;
27
28         if ((ret = __os_malloc(env,
29             sizeof(__txn_regop_42_args) + sizeof(DB_TXN), &argp)) != 0)
30                 return (ret);
31         bp = recbuf;
32         argp->txnp = (DB_TXN *)&argp[1];
33         memset(argp->txnp, 0, sizeof(DB_TXN));
34
35         LOGCOPY_32(env, &argp->type, bp);
36         bp += sizeof(argp->type);
37
38         LOGCOPY_32(env, &argp->txnp->txnid, bp);
39         bp += sizeof(argp->txnp->txnid);
40
41         LOGCOPY_TOLSN(env, &argp->prev_lsn, bp);
42         bp += sizeof(DB_LSN);
43
44         LOGCOPY_32(env, &argp->opcode, bp);
45         bp += sizeof(argp->opcode);
46
47         LOGCOPY_32(env, &uinttmp, bp);
48         argp->timestamp = (int32_t)uinttmp;
49         bp += sizeof(uinttmp);
50
51         memset(&argp->locks, 0, sizeof(argp->locks));
52         LOGCOPY_32(env,&argp->locks.size, bp);
53         bp += sizeof(u_int32_t);
54         argp->locks.data = bp;
55         bp += argp->locks.size;
56
57         *argpp = argp;
58         return (ret);
59 }
60
61 /*
62  * PUBLIC: int __txn_regop_read __P((ENV *, void *, __txn_regop_args **));
63  */
64 int
65 __txn_regop_read(env, recbuf, argpp)
66         ENV *env;
67         void *recbuf;
68         __txn_regop_args **argpp;
69 {
70         __txn_regop_args *argp;
71         u_int32_t uinttmp;
72         u_int8_t *bp;
73         int ret;
74
75         if ((ret = __os_malloc(env,
76             sizeof(__txn_regop_args) + sizeof(DB_TXN), &argp)) != 0)
77                 return (ret);
78         bp = recbuf;
79         argp->txnp = (DB_TXN *)&argp[1];
80         memset(argp->txnp, 0, sizeof(DB_TXN));
81
82         LOGCOPY_32(env, &argp->type, bp);
83         bp += sizeof(argp->type);
84
85         LOGCOPY_32(env, &argp->txnp->txnid, bp);
86         bp += sizeof(argp->txnp->txnid);
87
88         LOGCOPY_TOLSN(env, &argp->prev_lsn, bp);
89         bp += sizeof(DB_LSN);
90
91         LOGCOPY_32(env, &argp->opcode, bp);
92         bp += sizeof(argp->opcode);
93
94         LOGCOPY_32(env, &uinttmp, bp);
95         argp->timestamp = (int32_t)uinttmp;
96         bp += sizeof(uinttmp);
97
98         LOGCOPY_32(env, &argp->envid, bp);
99         bp += sizeof(argp->envid);
100
101         memset(&argp->locks, 0, sizeof(argp->locks));
102         LOGCOPY_32(env,&argp->locks.size, bp);
103         bp += sizeof(u_int32_t);
104         argp->locks.data = bp;
105         bp += argp->locks.size;
106
107         *argpp = argp;
108         return (ret);
109 }
110
111 /*
112  * PUBLIC: int __txn_regop_log __P((ENV *, DB_TXN *, DB_LSN *,
113  * PUBLIC:     u_int32_t, u_int32_t, int32_t, u_int32_t, const DBT *));
114  */
115 int
116 __txn_regop_log(env, txnp, ret_lsnp, flags,
117     opcode, timestamp, envid, locks)
118         ENV *env;
119         DB_TXN *txnp;
120         DB_LSN *ret_lsnp;
121         u_int32_t flags;
122         u_int32_t opcode;
123         int32_t timestamp;
124         u_int32_t envid;
125         const DBT *locks;
126 {
127         DBT logrec;
128         DB_LSN *lsnp, null_lsn, *rlsnp;
129         DB_TXNLOGREC *lr;
130         u_int32_t zero, uinttmp, rectype, txn_num;
131         u_int npad;
132         u_int8_t *bp;
133         int is_durable, ret;
134
135         COMPQUIET(lr, NULL);
136
137         rlsnp = ret_lsnp;
138         rectype = DB___txn_regop;
139         npad = 0;
140         ret = 0;
141
142         if (LF_ISSET(DB_LOG_NOT_DURABLE)) {
143                 if (txnp == NULL)
144                         return (0);
145                 is_durable = 0;
146         } else
147                 is_durable = 1;
148
149         if (txnp == NULL) {
150                 txn_num = 0;
151                 lsnp = &null_lsn;
152                 null_lsn.file = null_lsn.offset = 0;
153         } else {
154                 if (TAILQ_FIRST(&txnp->kids) != NULL &&
155                     (ret = __txn_activekids(env, rectype, txnp)) != 0)
156                         return (ret);
157                 /*
158                  * We need to assign begin_lsn while holding region mutex.
159                  * That assignment is done inside the DbEnv->log_put call,
160                  * so pass in the appropriate memory location to be filled
161                  * in by the log_put code.
162                  */
163                 DB_SET_TXN_LSNP(txnp, &rlsnp, &lsnp);
164                 txn_num = txnp->txnid;
165         }
166
167         logrec.size = sizeof(rectype) + sizeof(txn_num) + sizeof(DB_LSN)
168             + sizeof(u_int32_t)
169             + sizeof(u_int32_t)
170             + sizeof(u_int32_t)
171             + sizeof(u_int32_t) + (locks == NULL ? 0 : locks->size);
172         if (CRYPTO_ON(env)) {
173                 npad = env->crypto_handle->adj_size(logrec.size);
174                 logrec.size += npad;
175         }
176
177         if (is_durable || txnp == NULL) {
178                 if ((ret =
179                     __os_malloc(env, logrec.size, &logrec.data)) != 0)
180                         return (ret);
181         } else {
182                 if ((ret = __os_malloc(env,
183                     logrec.size + sizeof(DB_TXNLOGREC), &lr)) != 0)
184                         return (ret);
185 #ifdef DIAGNOSTIC
186                 if ((ret =
187                     __os_malloc(env, logrec.size, &logrec.data)) != 0) {
188                         __os_free(env, lr);
189                         return (ret);
190                 }
191 #else
192                 logrec.data = lr->data;
193 #endif
194         }
195         if (npad > 0)
196                 memset((u_int8_t *)logrec.data + logrec.size - npad, 0, npad);
197
198         bp = logrec.data;
199
200         LOGCOPY_32(env, bp, &rectype);
201         bp += sizeof(rectype);
202
203         LOGCOPY_32(env, bp, &txn_num);
204         bp += sizeof(txn_num);
205
206         LOGCOPY_FROMLSN(env, bp, lsnp);
207         bp += sizeof(DB_LSN);
208
209         LOGCOPY_32(env, bp, &opcode);
210         bp += sizeof(opcode);
211
212         uinttmp = (u_int32_t)timestamp;
213         LOGCOPY_32(env,bp, &uinttmp);
214         bp += sizeof(uinttmp);
215
216         LOGCOPY_32(env, bp, &envid);
217         bp += sizeof(envid);
218
219         if (locks == NULL) {
220                 zero = 0;
221                 LOGCOPY_32(env, bp, &zero);
222                 bp += sizeof(u_int32_t);
223         } else {
224                 LOGCOPY_32(env, bp, &locks->size);
225                 bp += sizeof(locks->size);
226                 memcpy(bp, locks->data, locks->size);
227                 bp += locks->size;
228         }
229
230         DB_ASSERT(env,
231             (u_int32_t)(bp - (u_int8_t *)logrec.data) <= logrec.size);
232
233         if (is_durable || txnp == NULL) {
234                 if ((ret = __log_put(env, rlsnp,(DBT *)&logrec,
235                     flags | DB_LOG_NOCOPY)) == 0 && txnp != NULL) {
236                         *lsnp = *rlsnp;
237                         if (rlsnp != ret_lsnp)
238                                  *ret_lsnp = *rlsnp;
239                 }
240         } else {
241                 ret = 0;
242 #ifdef DIAGNOSTIC
243                 /*
244                  * Set the debug bit if we are going to log non-durable
245                  * transactions so they will be ignored by recovery.
246                  */
247                 memcpy(lr->data, logrec.data, logrec.size);
248                 rectype |= DB_debug_FLAG;
249                 LOGCOPY_32(env, logrec.data, &rectype);
250
251                 if (!IS_REP_CLIENT(env))
252                         ret = __log_put(env,
253                             rlsnp, (DBT *)&logrec, flags | DB_LOG_NOCOPY);
254 #endif
255                 STAILQ_INSERT_HEAD(&txnp->logs, lr, links);
256                 F_SET((TXN_DETAIL *)txnp->td, TXN_DTL_INMEMORY);
257                 LSN_NOT_LOGGED(*ret_lsnp);
258         }
259
260 #ifdef LOG_DIAGNOSTIC
261         if (ret != 0)
262                 (void)__txn_regop_print(env,
263                     (DBT *)&logrec, ret_lsnp, DB_TXN_PRINT, NULL);
264 #endif
265
266 #ifdef DIAGNOSTIC
267         __os_free(env, logrec.data);
268 #else
269         if (is_durable || txnp == NULL)
270                 __os_free(env, logrec.data);
271 #endif
272         return (ret);
273 }
274
275 /*
276  * PUBLIC: int __txn_ckp_42_read __P((ENV *, void *, __txn_ckp_42_args **));
277  */
278 int
279 __txn_ckp_42_read(env, recbuf, argpp)
280         ENV *env;
281         void *recbuf;
282         __txn_ckp_42_args **argpp;
283 {
284         __txn_ckp_42_args *argp;
285         u_int32_t uinttmp;
286         u_int8_t *bp;
287         int ret;
288
289         if ((ret = __os_malloc(env,
290             sizeof(__txn_ckp_42_args) + sizeof(DB_TXN), &argp)) != 0)
291                 return (ret);
292         bp = recbuf;
293         argp->txnp = (DB_TXN *)&argp[1];
294         memset(argp->txnp, 0, sizeof(DB_TXN));
295
296         LOGCOPY_32(env, &argp->type, bp);
297         bp += sizeof(argp->type);
298
299         LOGCOPY_32(env, &argp->txnp->txnid, bp);
300         bp += sizeof(argp->txnp->txnid);
301
302         LOGCOPY_TOLSN(env, &argp->prev_lsn, bp);
303         bp += sizeof(DB_LSN);
304
305         LOGCOPY_TOLSN(env, &argp->ckp_lsn, bp);
306         bp += sizeof(DB_LSN);
307
308         LOGCOPY_TOLSN(env, &argp->last_ckp, bp);
309         bp += sizeof(DB_LSN);
310
311         LOGCOPY_32(env, &uinttmp, bp);
312         argp->timestamp = (int32_t)uinttmp;
313         bp += sizeof(uinttmp);
314
315         LOGCOPY_32(env, &argp->rep_gen, bp);
316         bp += sizeof(argp->rep_gen);
317
318         *argpp = argp;
319         return (ret);
320 }
321
322 /*
323  * PUBLIC: int __txn_ckp_read __P((ENV *, void *, __txn_ckp_args **));
324  */
325 int
326 __txn_ckp_read(env, recbuf, argpp)
327         ENV *env;
328         void *recbuf;
329         __txn_ckp_args **argpp;
330 {
331         __txn_ckp_args *argp;
332         u_int32_t uinttmp;
333         u_int8_t *bp;
334         int ret;
335
336         if ((ret = __os_malloc(env,
337             sizeof(__txn_ckp_args) + sizeof(DB_TXN), &argp)) != 0)
338                 return (ret);
339         bp = recbuf;
340         argp->txnp = (DB_TXN *)&argp[1];
341         memset(argp->txnp, 0, sizeof(DB_TXN));
342
343         LOGCOPY_32(env, &argp->type, bp);
344         bp += sizeof(argp->type);
345
346         LOGCOPY_32(env, &argp->txnp->txnid, bp);
347         bp += sizeof(argp->txnp->txnid);
348
349         LOGCOPY_TOLSN(env, &argp->prev_lsn, bp);
350         bp += sizeof(DB_LSN);
351
352         LOGCOPY_TOLSN(env, &argp->ckp_lsn, bp);
353         bp += sizeof(DB_LSN);
354
355         LOGCOPY_TOLSN(env, &argp->last_ckp, bp);
356         bp += sizeof(DB_LSN);
357
358         LOGCOPY_32(env, &uinttmp, bp);
359         argp->timestamp = (int32_t)uinttmp;
360         bp += sizeof(uinttmp);
361
362         LOGCOPY_32(env, &argp->envid, bp);
363         bp += sizeof(argp->envid);
364
365         LOGCOPY_32(env, &argp->spare, bp);
366         bp += sizeof(argp->spare);
367
368         *argpp = argp;
369         return (ret);
370 }
371
372 /*
373  * PUBLIC: int __txn_ckp_log __P((ENV *, DB_TXN *, DB_LSN *,
374  * PUBLIC:     u_int32_t, DB_LSN *, DB_LSN *, int32_t, u_int32_t, u_int32_t));
375  */
376 int
377 __txn_ckp_log(env, txnp, ret_lsnp, flags,
378     ckp_lsn, last_ckp, timestamp, envid, spare)
379         ENV *env;
380         DB_TXN *txnp;
381         DB_LSN *ret_lsnp;
382         u_int32_t flags;
383         DB_LSN * ckp_lsn;
384         DB_LSN * last_ckp;
385         int32_t timestamp;
386         u_int32_t envid;
387         u_int32_t spare;
388 {
389         DBT logrec;
390         DB_LSN *lsnp, null_lsn, *rlsnp;
391         DB_TXNLOGREC *lr;
392         u_int32_t uinttmp, rectype, txn_num;
393         u_int npad;
394         u_int8_t *bp;
395         int is_durable, ret;
396
397         COMPQUIET(lr, NULL);
398
399         rlsnp = ret_lsnp;
400         rectype = DB___txn_ckp;
401         npad = 0;
402         ret = 0;
403
404         if (LF_ISSET(DB_LOG_NOT_DURABLE)) {
405                 if (txnp == NULL)
406                         return (0);
407                 is_durable = 0;
408         } else
409                 is_durable = 1;
410
411         if (txnp == NULL) {
412                 txn_num = 0;
413                 lsnp = &null_lsn;
414                 null_lsn.file = null_lsn.offset = 0;
415         } else {
416                 if (TAILQ_FIRST(&txnp->kids) != NULL &&
417                     (ret = __txn_activekids(env, rectype, txnp)) != 0)
418                         return (ret);
419                 /*
420                  * We need to assign begin_lsn while holding region mutex.
421                  * That assignment is done inside the DbEnv->log_put call,
422                  * so pass in the appropriate memory location to be filled
423                  * in by the log_put code.
424                  */
425                 DB_SET_TXN_LSNP(txnp, &rlsnp, &lsnp);
426                 txn_num = txnp->txnid;
427         }
428
429         logrec.size = sizeof(rectype) + sizeof(txn_num) + sizeof(DB_LSN)
430             + sizeof(*ckp_lsn)
431             + sizeof(*last_ckp)
432             + sizeof(u_int32_t)
433             + sizeof(u_int32_t)
434             + sizeof(u_int32_t);
435         if (CRYPTO_ON(env)) {
436                 npad = env->crypto_handle->adj_size(logrec.size);
437                 logrec.size += npad;
438         }
439
440         if (is_durable || txnp == NULL) {
441                 if ((ret =
442                     __os_malloc(env, logrec.size, &logrec.data)) != 0)
443                         return (ret);
444         } else {
445                 if ((ret = __os_malloc(env,
446                     logrec.size + sizeof(DB_TXNLOGREC), &lr)) != 0)
447                         return (ret);
448 #ifdef DIAGNOSTIC
449                 if ((ret =
450                     __os_malloc(env, logrec.size, &logrec.data)) != 0) {
451                         __os_free(env, lr);
452                         return (ret);
453                 }
454 #else
455                 logrec.data = lr->data;
456 #endif
457         }
458         if (npad > 0)
459                 memset((u_int8_t *)logrec.data + logrec.size - npad, 0, npad);
460
461         bp = logrec.data;
462
463         LOGCOPY_32(env, bp, &rectype);
464         bp += sizeof(rectype);
465
466         LOGCOPY_32(env, bp, &txn_num);
467         bp += sizeof(txn_num);
468
469         LOGCOPY_FROMLSN(env, bp, lsnp);
470         bp += sizeof(DB_LSN);
471
472         if (ckp_lsn != NULL)
473                 LOGCOPY_FROMLSN(env, bp, ckp_lsn);
474         else
475                 memset(bp, 0, sizeof(*ckp_lsn));
476         bp += sizeof(*ckp_lsn);
477
478         if (last_ckp != NULL)
479                 LOGCOPY_FROMLSN(env, bp, last_ckp);
480         else
481                 memset(bp, 0, sizeof(*last_ckp));
482         bp += sizeof(*last_ckp);
483
484         uinttmp = (u_int32_t)timestamp;
485         LOGCOPY_32(env,bp, &uinttmp);
486         bp += sizeof(uinttmp);
487
488         LOGCOPY_32(env, bp, &envid);
489         bp += sizeof(envid);
490
491         LOGCOPY_32(env, bp, &spare);
492         bp += sizeof(spare);
493
494         DB_ASSERT(env,
495             (u_int32_t)(bp - (u_int8_t *)logrec.data) <= logrec.size);
496
497         if (is_durable || txnp == NULL) {
498                 if ((ret = __log_put(env, rlsnp,(DBT *)&logrec,
499                     flags | DB_LOG_NOCOPY)) == 0 && txnp != NULL) {
500                         *lsnp = *rlsnp;
501                         if (rlsnp != ret_lsnp)
502                                  *ret_lsnp = *rlsnp;
503                 }
504         } else {
505                 ret = 0;
506 #ifdef DIAGNOSTIC
507                 /*
508                  * Set the debug bit if we are going to log non-durable
509                  * transactions so they will be ignored by recovery.
510                  */
511                 memcpy(lr->data, logrec.data, logrec.size);
512                 rectype |= DB_debug_FLAG;
513                 LOGCOPY_32(env, logrec.data, &rectype);
514
515                 if (!IS_REP_CLIENT(env))
516                         ret = __log_put(env,
517                             rlsnp, (DBT *)&logrec, flags | DB_LOG_NOCOPY);
518 #endif
519                 STAILQ_INSERT_HEAD(&txnp->logs, lr, links);
520                 F_SET((TXN_DETAIL *)txnp->td, TXN_DTL_INMEMORY);
521                 LSN_NOT_LOGGED(*ret_lsnp);
522         }
523
524 #ifdef LOG_DIAGNOSTIC
525         if (ret != 0)
526                 (void)__txn_ckp_print(env,
527                     (DBT *)&logrec, ret_lsnp, DB_TXN_PRINT, NULL);
528 #endif
529
530 #ifdef DIAGNOSTIC
531         __os_free(env, logrec.data);
532 #else
533         if (is_durable || txnp == NULL)
534                 __os_free(env, logrec.data);
535 #endif
536         return (ret);
537 }
538
539 /*
540  * PUBLIC: int __txn_child_read __P((ENV *, void *, __txn_child_args **));
541  */
542 int
543 __txn_child_read(env, recbuf, argpp)
544         ENV *env;
545         void *recbuf;
546         __txn_child_args **argpp;
547 {
548         __txn_child_args *argp;
549         u_int8_t *bp;
550         int ret;
551
552         if ((ret = __os_malloc(env,
553             sizeof(__txn_child_args) + sizeof(DB_TXN), &argp)) != 0)
554                 return (ret);
555         bp = recbuf;
556         argp->txnp = (DB_TXN *)&argp[1];
557         memset(argp->txnp, 0, sizeof(DB_TXN));
558
559         LOGCOPY_32(env, &argp->type, bp);
560         bp += sizeof(argp->type);
561
562         LOGCOPY_32(env, &argp->txnp->txnid, bp);
563         bp += sizeof(argp->txnp->txnid);
564
565         LOGCOPY_TOLSN(env, &argp->prev_lsn, bp);
566         bp += sizeof(DB_LSN);
567
568         LOGCOPY_32(env, &argp->child, bp);
569         bp += sizeof(argp->child);
570
571         LOGCOPY_TOLSN(env, &argp->c_lsn, bp);
572         bp += sizeof(DB_LSN);
573
574         *argpp = argp;
575         return (ret);
576 }
577
578 /*
579  * PUBLIC: int __txn_child_log __P((ENV *, DB_TXN *, DB_LSN *,
580  * PUBLIC:     u_int32_t, u_int32_t, DB_LSN *));
581  */
582 int
583 __txn_child_log(env, txnp, ret_lsnp, flags,
584     child, c_lsn)
585         ENV *env;
586         DB_TXN *txnp;
587         DB_LSN *ret_lsnp;
588         u_int32_t flags;
589         u_int32_t child;
590         DB_LSN * c_lsn;
591 {
592         DBT logrec;
593         DB_LSN *lsnp, null_lsn, *rlsnp;
594         DB_TXNLOGREC *lr;
595         u_int32_t rectype, txn_num;
596         u_int npad;
597         u_int8_t *bp;
598         int is_durable, ret;
599
600         COMPQUIET(lr, NULL);
601
602         rlsnp = ret_lsnp;
603         rectype = DB___txn_child;
604         npad = 0;
605         ret = 0;
606
607         if (LF_ISSET(DB_LOG_NOT_DURABLE)) {
608                 if (txnp == NULL)
609                         return (0);
610                 is_durable = 0;
611         } else
612                 is_durable = 1;
613
614         if (txnp == NULL) {
615                 txn_num = 0;
616                 lsnp = &null_lsn;
617                 null_lsn.file = null_lsn.offset = 0;
618         } else {
619                 if (TAILQ_FIRST(&txnp->kids) != NULL &&
620                     (ret = __txn_activekids(env, rectype, txnp)) != 0)
621                         return (ret);
622                 /*
623                  * We need to assign begin_lsn while holding region mutex.
624                  * That assignment is done inside the DbEnv->log_put call,
625                  * so pass in the appropriate memory location to be filled
626                  * in by the log_put code.
627                  */
628                 DB_SET_TXN_LSNP(txnp, &rlsnp, &lsnp);
629                 txn_num = txnp->txnid;
630         }
631
632         logrec.size = sizeof(rectype) + sizeof(txn_num) + sizeof(DB_LSN)
633             + sizeof(u_int32_t)
634             + sizeof(*c_lsn);
635         if (CRYPTO_ON(env)) {
636                 npad = env->crypto_handle->adj_size(logrec.size);
637                 logrec.size += npad;
638         }
639
640         if (is_durable || txnp == NULL) {
641                 if ((ret =
642                     __os_malloc(env, logrec.size, &logrec.data)) != 0)
643                         return (ret);
644         } else {
645                 if ((ret = __os_malloc(env,
646                     logrec.size + sizeof(DB_TXNLOGREC), &lr)) != 0)
647                         return (ret);
648 #ifdef DIAGNOSTIC
649                 if ((ret =
650                     __os_malloc(env, logrec.size, &logrec.data)) != 0) {
651                         __os_free(env, lr);
652                         return (ret);
653                 }
654 #else
655                 logrec.data = lr->data;
656 #endif
657         }
658         if (npad > 0)
659                 memset((u_int8_t *)logrec.data + logrec.size - npad, 0, npad);
660
661         bp = logrec.data;
662
663         LOGCOPY_32(env, bp, &rectype);
664         bp += sizeof(rectype);
665
666         LOGCOPY_32(env, bp, &txn_num);
667         bp += sizeof(txn_num);
668
669         LOGCOPY_FROMLSN(env, bp, lsnp);
670         bp += sizeof(DB_LSN);
671
672         LOGCOPY_32(env, bp, &child);
673         bp += sizeof(child);
674
675         if (c_lsn != NULL)
676                 LOGCOPY_FROMLSN(env, bp, c_lsn);
677         else
678                 memset(bp, 0, sizeof(*c_lsn));
679         bp += sizeof(*c_lsn);
680
681         DB_ASSERT(env,
682             (u_int32_t)(bp - (u_int8_t *)logrec.data) <= logrec.size);
683
684         if (is_durable || txnp == NULL) {
685                 if ((ret = __log_put(env, rlsnp,(DBT *)&logrec,
686                     flags | DB_LOG_NOCOPY)) == 0 && txnp != NULL) {
687                         *lsnp = *rlsnp;
688                         if (rlsnp != ret_lsnp)
689                                  *ret_lsnp = *rlsnp;
690                 }
691         } else {
692                 ret = 0;
693 #ifdef DIAGNOSTIC
694                 /*
695                  * Set the debug bit if we are going to log non-durable
696                  * transactions so they will be ignored by recovery.
697                  */
698                 memcpy(lr->data, logrec.data, logrec.size);
699                 rectype |= DB_debug_FLAG;
700                 LOGCOPY_32(env, logrec.data, &rectype);
701
702                 if (!IS_REP_CLIENT(env))
703                         ret = __log_put(env,
704                             rlsnp, (DBT *)&logrec, flags | DB_LOG_NOCOPY);
705 #endif
706                 STAILQ_INSERT_HEAD(&txnp->logs, lr, links);
707                 F_SET((TXN_DETAIL *)txnp->td, TXN_DTL_INMEMORY);
708                 LSN_NOT_LOGGED(*ret_lsnp);
709         }
710
711 #ifdef LOG_DIAGNOSTIC
712         if (ret != 0)
713                 (void)__txn_child_print(env,
714                     (DBT *)&logrec, ret_lsnp, DB_TXN_PRINT, NULL);
715 #endif
716
717 #ifdef DIAGNOSTIC
718         __os_free(env, logrec.data);
719 #else
720         if (is_durable || txnp == NULL)
721                 __os_free(env, logrec.data);
722 #endif
723         return (ret);
724 }
725
726 /*
727  * PUBLIC: int __txn_xa_regop_42_read __P((ENV *, void *,
728  * PUBLIC:     __txn_xa_regop_42_args **));
729  */
730 int
731 __txn_xa_regop_42_read(env, recbuf, argpp)
732         ENV *env;
733         void *recbuf;
734         __txn_xa_regop_42_args **argpp;
735 {
736         __txn_xa_regop_42_args *argp;
737         u_int32_t uinttmp;
738         u_int8_t *bp;
739         int ret;
740
741         if ((ret = __os_malloc(env,
742             sizeof(__txn_xa_regop_42_args) + sizeof(DB_TXN), &argp)) != 0)
743                 return (ret);
744         bp = recbuf;
745         argp->txnp = (DB_TXN *)&argp[1];
746         memset(argp->txnp, 0, sizeof(DB_TXN));
747
748         LOGCOPY_32(env, &argp->type, bp);
749         bp += sizeof(argp->type);
750
751         LOGCOPY_32(env, &argp->txnp->txnid, bp);
752         bp += sizeof(argp->txnp->txnid);
753
754         LOGCOPY_TOLSN(env, &argp->prev_lsn, bp);
755         bp += sizeof(DB_LSN);
756
757         LOGCOPY_32(env, &argp->opcode, bp);
758         bp += sizeof(argp->opcode);
759
760         memset(&argp->xid, 0, sizeof(argp->xid));
761         LOGCOPY_32(env,&argp->xid.size, bp);
762         bp += sizeof(u_int32_t);
763         argp->xid.data = bp;
764         bp += argp->xid.size;
765
766         LOGCOPY_32(env, &uinttmp, bp);
767         argp->formatID = (int32_t)uinttmp;
768         bp += sizeof(uinttmp);
769
770         LOGCOPY_32(env, &argp->gtrid, bp);
771         bp += sizeof(argp->gtrid);
772
773         LOGCOPY_32(env, &argp->bqual, bp);
774         bp += sizeof(argp->bqual);
775
776         LOGCOPY_TOLSN(env, &argp->begin_lsn, bp);
777         bp += sizeof(DB_LSN);
778
779         memset(&argp->locks, 0, sizeof(argp->locks));
780         LOGCOPY_32(env,&argp->locks.size, bp);
781         bp += sizeof(u_int32_t);
782         argp->locks.data = bp;
783         bp += argp->locks.size;
784
785         *argpp = argp;
786         return (ret);
787 }
788
789 /*
790  * PUBLIC: int __txn_prepare_read __P((ENV *, void *, __txn_prepare_args **));
791  */
792 int
793 __txn_prepare_read(env, recbuf, argpp)
794         ENV *env;
795         void *recbuf;
796         __txn_prepare_args **argpp;
797 {
798         __txn_prepare_args *argp;
799         u_int8_t *bp;
800         int ret;
801
802         if ((ret = __os_malloc(env,
803             sizeof(__txn_prepare_args) + sizeof(DB_TXN), &argp)) != 0)
804                 return (ret);
805         bp = recbuf;
806         argp->txnp = (DB_TXN *)&argp[1];
807         memset(argp->txnp, 0, sizeof(DB_TXN));
808
809         LOGCOPY_32(env, &argp->type, bp);
810         bp += sizeof(argp->type);
811
812         LOGCOPY_32(env, &argp->txnp->txnid, bp);
813         bp += sizeof(argp->txnp->txnid);
814
815         LOGCOPY_TOLSN(env, &argp->prev_lsn, bp);
816         bp += sizeof(DB_LSN);
817
818         LOGCOPY_32(env, &argp->opcode, bp);
819         bp += sizeof(argp->opcode);
820
821         memset(&argp->gid, 0, sizeof(argp->gid));
822         LOGCOPY_32(env,&argp->gid.size, bp);
823         bp += sizeof(u_int32_t);
824         argp->gid.data = bp;
825         bp += argp->gid.size;
826
827         LOGCOPY_TOLSN(env, &argp->begin_lsn, bp);
828         bp += sizeof(DB_LSN);
829
830         memset(&argp->locks, 0, sizeof(argp->locks));
831         LOGCOPY_32(env,&argp->locks.size, bp);
832         bp += sizeof(u_int32_t);
833         argp->locks.data = bp;
834         bp += argp->locks.size;
835
836         *argpp = argp;
837         return (ret);
838 }
839
840 /*
841  * PUBLIC: int __txn_prepare_log __P((ENV *, DB_TXN *, DB_LSN *,
842  * PUBLIC:     u_int32_t, u_int32_t, const DBT *, DB_LSN *, const DBT *));
843  */
844 int
845 __txn_prepare_log(env, txnp, ret_lsnp, flags,
846     opcode, gid, begin_lsn, locks)
847         ENV *env;
848         DB_TXN *txnp;
849         DB_LSN *ret_lsnp;
850         u_int32_t flags;
851         u_int32_t opcode;
852         const DBT *gid;
853         DB_LSN * begin_lsn;
854         const DBT *locks;
855 {
856         DBT logrec;
857         DB_LSN *lsnp, null_lsn, *rlsnp;
858         DB_TXNLOGREC *lr;
859         u_int32_t zero, rectype, txn_num;
860         u_int npad;
861         u_int8_t *bp;
862         int is_durable, ret;
863
864         COMPQUIET(lr, NULL);
865
866         rlsnp = ret_lsnp;
867         rectype = DB___txn_prepare;
868         npad = 0;
869         ret = 0;
870
871         if (LF_ISSET(DB_LOG_NOT_DURABLE)) {
872                 if (txnp == NULL)
873                         return (0);
874                 is_durable = 0;
875         } else
876                 is_durable = 1;
877
878         if (txnp == NULL) {
879                 txn_num = 0;
880                 lsnp = &null_lsn;
881                 null_lsn.file = null_lsn.offset = 0;
882         } else {
883                 if (TAILQ_FIRST(&txnp->kids) != NULL &&
884                     (ret = __txn_activekids(env, rectype, txnp)) != 0)
885                         return (ret);
886                 /*
887                  * We need to assign begin_lsn while holding region mutex.
888                  * That assignment is done inside the DbEnv->log_put call,
889                  * so pass in the appropriate memory location to be filled
890                  * in by the log_put code.
891                  */
892                 DB_SET_TXN_LSNP(txnp, &rlsnp, &lsnp);
893                 txn_num = txnp->txnid;
894         }
895
896         logrec.size = sizeof(rectype) + sizeof(txn_num) + sizeof(DB_LSN)
897             + sizeof(u_int32_t)
898             + sizeof(u_int32_t) + (gid == NULL ? 0 : gid->size)
899             + sizeof(*begin_lsn)
900             + sizeof(u_int32_t) + (locks == NULL ? 0 : locks->size);
901         if (CRYPTO_ON(env)) {
902                 npad = env->crypto_handle->adj_size(logrec.size);
903                 logrec.size += npad;
904         }
905
906         if (is_durable || txnp == NULL) {
907                 if ((ret =
908                     __os_malloc(env, logrec.size, &logrec.data)) != 0)
909                         return (ret);
910         } else {
911                 if ((ret = __os_malloc(env,
912                     logrec.size + sizeof(DB_TXNLOGREC), &lr)) != 0)
913                         return (ret);
914 #ifdef DIAGNOSTIC
915                 if ((ret =
916                     __os_malloc(env, logrec.size, &logrec.data)) != 0) {
917                         __os_free(env, lr);
918                         return (ret);
919                 }
920 #else
921                 logrec.data = lr->data;
922 #endif
923         }
924         if (npad > 0)
925                 memset((u_int8_t *)logrec.data + logrec.size - npad, 0, npad);
926
927         bp = logrec.data;
928
929         LOGCOPY_32(env, bp, &rectype);
930         bp += sizeof(rectype);
931
932         LOGCOPY_32(env, bp, &txn_num);
933         bp += sizeof(txn_num);
934
935         LOGCOPY_FROMLSN(env, bp, lsnp);
936         bp += sizeof(DB_LSN);
937
938         LOGCOPY_32(env, bp, &opcode);
939         bp += sizeof(opcode);
940
941         if (gid == NULL) {
942                 zero = 0;
943                 LOGCOPY_32(env, bp, &zero);
944                 bp += sizeof(u_int32_t);
945         } else {
946                 LOGCOPY_32(env, bp, &gid->size);
947                 bp += sizeof(gid->size);
948                 memcpy(bp, gid->data, gid->size);
949                 bp += gid->size;
950         }
951
952         if (begin_lsn != NULL)
953                 LOGCOPY_FROMLSN(env, bp, begin_lsn);
954         else
955                 memset(bp, 0, sizeof(*begin_lsn));
956         bp += sizeof(*begin_lsn);
957
958         if (locks == NULL) {
959                 zero = 0;
960                 LOGCOPY_32(env, bp, &zero);
961                 bp += sizeof(u_int32_t);
962         } else {
963                 LOGCOPY_32(env, bp, &locks->size);
964                 bp += sizeof(locks->size);
965                 memcpy(bp, locks->data, locks->size);
966                 bp += locks->size;
967         }
968
969         DB_ASSERT(env,
970             (u_int32_t)(bp - (u_int8_t *)logrec.data) <= logrec.size);
971
972         if (is_durable || txnp == NULL) {
973                 if ((ret = __log_put(env, rlsnp,(DBT *)&logrec,
974                     flags | DB_LOG_NOCOPY)) == 0 && txnp != NULL) {
975                         *lsnp = *rlsnp;
976                         if (rlsnp != ret_lsnp)
977                                  *ret_lsnp = *rlsnp;
978                 }
979         } else {
980                 ret = 0;
981 #ifdef DIAGNOSTIC
982                 /*
983                  * Set the debug bit if we are going to log non-durable
984                  * transactions so they will be ignored by recovery.
985                  */
986                 memcpy(lr->data, logrec.data, logrec.size);
987                 rectype |= DB_debug_FLAG;
988                 LOGCOPY_32(env, logrec.data, &rectype);
989
990                 if (!IS_REP_CLIENT(env))
991                         ret = __log_put(env,
992                             rlsnp, (DBT *)&logrec, flags | DB_LOG_NOCOPY);
993 #endif
994                 STAILQ_INSERT_HEAD(&txnp->logs, lr, links);
995                 F_SET((TXN_DETAIL *)txnp->td, TXN_DTL_INMEMORY);
996                 LSN_NOT_LOGGED(*ret_lsnp);
997         }
998
999 #ifdef LOG_DIAGNOSTIC
1000         if (ret != 0)
1001                 (void)__txn_prepare_print(env,
1002                     (DBT *)&logrec, ret_lsnp, DB_TXN_PRINT, NULL);
1003 #endif
1004
1005 #ifdef DIAGNOSTIC
1006         __os_free(env, logrec.data);
1007 #else
1008         if (is_durable || txnp == NULL)
1009                 __os_free(env, logrec.data);
1010 #endif
1011         return (ret);
1012 }
1013
1014 /*
1015  * PUBLIC: int __txn_recycle_read __P((ENV *, void *, __txn_recycle_args **));
1016  */
1017 int
1018 __txn_recycle_read(env, recbuf, argpp)
1019         ENV *env;
1020         void *recbuf;
1021         __txn_recycle_args **argpp;
1022 {
1023         __txn_recycle_args *argp;
1024         u_int8_t *bp;
1025         int ret;
1026
1027         if ((ret = __os_malloc(env,
1028             sizeof(__txn_recycle_args) + sizeof(DB_TXN), &argp)) != 0)
1029                 return (ret);
1030         bp = recbuf;
1031         argp->txnp = (DB_TXN *)&argp[1];
1032         memset(argp->txnp, 0, sizeof(DB_TXN));
1033
1034         LOGCOPY_32(env, &argp->type, bp);
1035         bp += sizeof(argp->type);
1036
1037         LOGCOPY_32(env, &argp->txnp->txnid, bp);
1038         bp += sizeof(argp->txnp->txnid);
1039
1040         LOGCOPY_TOLSN(env, &argp->prev_lsn, bp);
1041         bp += sizeof(DB_LSN);
1042
1043         LOGCOPY_32(env, &argp->min, bp);
1044         bp += sizeof(argp->min);
1045
1046         LOGCOPY_32(env, &argp->max, bp);
1047         bp += sizeof(argp->max);
1048
1049         *argpp = argp;
1050         return (ret);
1051 }
1052
1053 /*
1054  * PUBLIC: int __txn_recycle_log __P((ENV *, DB_TXN *, DB_LSN *,
1055  * PUBLIC:     u_int32_t, u_int32_t, u_int32_t));
1056  */
1057 int
1058 __txn_recycle_log(env, txnp, ret_lsnp, flags,
1059     min, max)
1060         ENV *env;
1061         DB_TXN *txnp;
1062         DB_LSN *ret_lsnp;
1063         u_int32_t flags;
1064         u_int32_t min;
1065         u_int32_t max;
1066 {
1067         DBT logrec;
1068         DB_LSN *lsnp, null_lsn, *rlsnp;
1069         DB_TXNLOGREC *lr;
1070         u_int32_t rectype, txn_num;
1071         u_int npad;
1072         u_int8_t *bp;
1073         int is_durable, ret;
1074
1075         COMPQUIET(lr, NULL);
1076
1077         rlsnp = ret_lsnp;
1078         rectype = DB___txn_recycle;
1079         npad = 0;
1080         ret = 0;
1081
1082         if (LF_ISSET(DB_LOG_NOT_DURABLE)) {
1083                 if (txnp == NULL)
1084                         return (0);
1085                 is_durable = 0;
1086         } else
1087                 is_durable = 1;
1088
1089         if (txnp == NULL) {
1090                 txn_num = 0;
1091                 lsnp = &null_lsn;
1092                 null_lsn.file = null_lsn.offset = 0;
1093         } else {
1094                 if (TAILQ_FIRST(&txnp->kids) != NULL &&
1095                     (ret = __txn_activekids(env, rectype, txnp)) != 0)
1096                         return (ret);
1097                 /*
1098                  * We need to assign begin_lsn while holding region mutex.
1099                  * That assignment is done inside the DbEnv->log_put call,
1100                  * so pass in the appropriate memory location to be filled
1101                  * in by the log_put code.
1102                  */
1103                 DB_SET_TXN_LSNP(txnp, &rlsnp, &lsnp);
1104                 txn_num = txnp->txnid;
1105         }
1106
1107         logrec.size = sizeof(rectype) + sizeof(txn_num) + sizeof(DB_LSN)
1108             + sizeof(u_int32_t)
1109             + sizeof(u_int32_t);
1110         if (CRYPTO_ON(env)) {
1111                 npad = env->crypto_handle->adj_size(logrec.size);
1112                 logrec.size += npad;
1113         }
1114
1115         if (is_durable || txnp == NULL) {
1116                 if ((ret =
1117                     __os_malloc(env, logrec.size, &logrec.data)) != 0)
1118                         return (ret);
1119         } else {
1120                 if ((ret = __os_malloc(env,
1121                     logrec.size + sizeof(DB_TXNLOGREC), &lr)) != 0)
1122                         return (ret);
1123 #ifdef DIAGNOSTIC
1124                 if ((ret =
1125                     __os_malloc(env, logrec.size, &logrec.data)) != 0) {
1126                         __os_free(env, lr);
1127                         return (ret);
1128                 }
1129 #else
1130                 logrec.data = lr->data;
1131 #endif
1132         }
1133         if (npad > 0)
1134                 memset((u_int8_t *)logrec.data + logrec.size - npad, 0, npad);
1135
1136         bp = logrec.data;
1137
1138         LOGCOPY_32(env, bp, &rectype);
1139         bp += sizeof(rectype);
1140
1141         LOGCOPY_32(env, bp, &txn_num);
1142         bp += sizeof(txn_num);
1143
1144         LOGCOPY_FROMLSN(env, bp, lsnp);
1145         bp += sizeof(DB_LSN);
1146
1147         LOGCOPY_32(env, bp, &min);
1148         bp += sizeof(min);
1149
1150         LOGCOPY_32(env, bp, &max);
1151         bp += sizeof(max);
1152
1153         DB_ASSERT(env,
1154             (u_int32_t)(bp - (u_int8_t *)logrec.data) <= logrec.size);
1155
1156         if (is_durable || txnp == NULL) {
1157                 if ((ret = __log_put(env, rlsnp,(DBT *)&logrec,
1158                     flags | DB_LOG_NOCOPY)) == 0 && txnp != NULL) {
1159                         *lsnp = *rlsnp;
1160                         if (rlsnp != ret_lsnp)
1161                                  *ret_lsnp = *rlsnp;
1162                 }
1163         } else {
1164                 ret = 0;
1165 #ifdef DIAGNOSTIC
1166                 /*
1167                  * Set the debug bit if we are going to log non-durable
1168                  * transactions so they will be ignored by recovery.
1169                  */
1170                 memcpy(lr->data, logrec.data, logrec.size);
1171                 rectype |= DB_debug_FLAG;
1172                 LOGCOPY_32(env, logrec.data, &rectype);
1173
1174                 if (!IS_REP_CLIENT(env))
1175                         ret = __log_put(env,
1176                             rlsnp, (DBT *)&logrec, flags | DB_LOG_NOCOPY);
1177 #endif
1178                 STAILQ_INSERT_HEAD(&txnp->logs, lr, links);
1179                 F_SET((TXN_DETAIL *)txnp->td, TXN_DTL_INMEMORY);
1180                 LSN_NOT_LOGGED(*ret_lsnp);
1181         }
1182
1183 #ifdef LOG_DIAGNOSTIC
1184         if (ret != 0)
1185                 (void)__txn_recycle_print(env,
1186                     (DBT *)&logrec, ret_lsnp, DB_TXN_PRINT, NULL);
1187 #endif
1188
1189 #ifdef DIAGNOSTIC
1190         __os_free(env, logrec.data);
1191 #else
1192         if (is_durable || txnp == NULL)
1193                 __os_free(env, logrec.data);
1194 #endif
1195         return (ret);
1196 }
1197
1198 /*
1199  * PUBLIC: int __txn_init_recover __P((ENV *, DB_DISTAB *));
1200  */
1201 int
1202 __txn_init_recover(env, dtabp)
1203         ENV *env;
1204         DB_DISTAB *dtabp;
1205 {
1206         int ret;
1207
1208         if ((ret = __db_add_recovery_int(env, dtabp,
1209             __txn_regop_recover, DB___txn_regop)) != 0)
1210                 return (ret);
1211         if ((ret = __db_add_recovery_int(env, dtabp,
1212             __txn_ckp_recover, DB___txn_ckp)) != 0)
1213                 return (ret);
1214         if ((ret = __db_add_recovery_int(env, dtabp,
1215             __txn_child_recover, DB___txn_child)) != 0)
1216                 return (ret);
1217         if ((ret = __db_add_recovery_int(env, dtabp,
1218             __txn_prepare_recover, DB___txn_prepare)) != 0)
1219                 return (ret);
1220         if ((ret = __db_add_recovery_int(env, dtabp,
1221             __txn_recycle_recover, DB___txn_recycle)) != 0)
1222                 return (ret);
1223         return (0);
1224 }