Lines Matching refs:jnl
97 static void abort_transaction(journal *jnl, transaction *tr);
98 static void dump_journal(journal *jnl);
100 static __inline__ void lock_journal(journal *jnl);
101 static __inline__ void unlock_journal(journal *jnl);
102 static __inline__ void lock_oldstart(journal *jnl);
103 static __inline__ void unlock_oldstart(journal *jnl);
121 static int add_block(journal *jnl, struct bucket **buf_ptr, off_t block_num, size_t size, size_t offset, int32_t cksum, int *num_buckets_ptr, int *num_full_ptr);
124 static int do_overlap(journal *jnl, struct bucket **buf_ptr, int blk_index, off_t block_num, size_t size, size_t offset, int32_t cksum, int *num_buckets_ptr, int *num_full_ptr);
125 static int insert_block(journal *jnl, struct bucket **buf_ptr, int blk_index, off_t num, size_t size, size_t offset, int32_t cksum, int *num_buckets_ptr, int *num_full_ptr, int overwriting);
127 #define CHECK_JOURNAL(jnl) \
129 if (jnl == NULL) {\
132 if (jnl->jdev == NULL) { \
135 if (jnl->fsdev == NULL) { \
138 if (jnl->jhdr->magic != JOURNAL_HEADER_MAGIC) {\
140 __FILE__, __LINE__, jnl->jhdr->magic, JOURNAL_HEADER_MAGIC);\
142 if ( jnl->jhdr->start <= 0 \
143 || jnl->jhdr->start > jnl->jhdr->size\
144 || jnl->jhdr->start > 1024*1024*1024) {\
146 __FILE__, __LINE__, jnl->jhdr->start, jnl->jhdr->size);\
148 if ( jnl->jhdr->end <= 0 \
149 || jnl->jhdr->end > jnl->jhdr->size\
150 || jnl->jhdr->end > 1024*1024*1024) {\
152 __FILE__, __LINE__, jnl->jhdr->end, jnl->jhdr->size);\
154 if (jnl->jhdr->size > 1024*1024*1024) {\
156 __FILE__, __LINE__, jnl->jhdr->size);\
165 if (tr->jnl == NULL) {\
166 panic("%s:%d: null tr->jnl ptr?\n", __FILE__, __LINE__);\
180 if (tr->blhdr && (tr->blhdr->max_blocks <= 0 || tr->blhdr->max_blocks > (tr->jnl->jhdr->size/tr->jnl->jhdr->jhdr_size))) {\
217 jnl_mutex_group = lck_grp_alloc_init("jnl-mutex", jnl_group_attr);
221 lock_journal(journal *jnl)
223 lck_mtx_lock(&jnl->jlock);
227 unlock_journal(journal *jnl)
229 lck_mtx_unlock(&jnl->jlock);
233 lock_oldstart(journal *jnl)
235 lck_mtx_lock(&jnl->old_start_lock);
239 unlock_oldstart(journal *jnl)
241 lck_mtx_unlock(&jnl->old_start_lock);
260 do_journal_io(journal *jnl, off_t *offset, void *data, size_t len, int direction)
267 if (*offset < 0 || *offset > jnl->jhdr->size) {
268 panic("jnl: do_jnl_io: bad offset 0x%llx (max 0x%llx)\n", *offset, jnl->jhdr->size);
272 max_iosize = jnl->max_write_size;
274 max_iosize = jnl->max_read_size;
279 bp = alloc_io_buf(jnl->jdev, 1);
281 if (*offset + (off_t)curlen > jnl->jhdr->size && *offset != 0 && jnl->jhdr->size != 0) {
282 if (*offset == jnl->jhdr->size) {
283 *offset = jnl->jhdr->jhdr_size;
285 curlen = (off_t)jnl->jhdr->size - *offset;
294 panic("jnl: do_jnl_io: curlen == %d, offset 0x%llx len %lu\n", curlen, *offset, len);
298 panic("jnl: request for i/o to jnl-header without JNL_HEADER flag set! (len %d, data %p)\n", curlen, data);
307 vnode_startwrite(jnl->jdev);
312 buf_setblkno(bp, (daddr64_t) ((jnl->jdev_offset + *offset) / (off_t)jnl->jhdr->jhdr_size));
313 buf_setlblkno(bp, (daddr64_t) ((jnl->jdev_offset + *offset) / (off_t)jnl->jhdr->jhdr_size));
314 if ((direction & JNL_WRITE) && (jnl->flags & JOURNAL_DO_FUA_WRITES)) {
325 printf("jnl: %s: do_jnl_io: strategy err 0x%x\n", jnl->jdev_name, err);
335 if (*offset >= jnl->jhdr->size) {
336 *offset = jnl->jhdr->jhdr_size;
345 read_journal_data(journal *jnl, off_t *offset, void *data, size_t len)
347 return do_journal_io(jnl, offset, data, len, JNL_READ);
351 write_journal_data(journal *jnl, off_t *offset, void *data, size_t len)
353 return do_journal_io(jnl, offset, data, len, JNL_WRITE);
358 read_journal_header(journal *jnl, void *data, size_t len)
362 return do_journal_io(jnl, &hdr_offset, data, len, JNL_READ|JNL_HEADER);
366 write_journal_header(journal *jnl)
379 if ((jnl->flags & JOURNAL_DO_FUA_WRITES) == 0) {
380 ret = VNOP_IOCTL(jnl->jdev, DKIOCSYNCHRONIZECACHE, NULL, FWRITE, &context);
392 if ( ret != jnl->last_flush_err
393 || (jnl->flags & JOURNAL_FLUSHCACHE_ERR) == 0
396 printf("jnl: %s: flushing fs disk buffer returned 0x%x\n", jnl->jdev_name, ret);
398 jnl->flags |= JOURNAL_FLUSHCACHE_ERR;
399 jnl->last_flush_err = ret;
403 jnl->jhdr->checksum = 0;
404 jnl->jhdr->checksum = calc_checksum((char *)jnl->jhdr, JOURNAL_HEADER_CKSUM_SIZE);
405 if (do_journal_io(jnl, &jhdr_offset, jnl->header_buf, jnl->jhdr->jhdr_size, JNL_WRITE|JNL_HEADER) != (size_t)jnl->jhdr->jhdr_size) {
406 printf("jnl: %s: write_journal_header: error writing the journal header!\n", jnl->jdev_name);
407 jnl->flags |= JOURNAL_INVALID;
419 if ((jnl->flags & JOURNAL_DO_FUA_WRITES) == 0) {
420 VNOP_IOCTL(jnl->jdev, DKIOCSYNCHRONIZECACHE, NULL, FWRITE, &context);
437 free_old_stuff(journal *jnl)
441 lock_oldstart(jnl);
442 tr = jnl->tr_freeme;
443 jnl->tr_freeme = NULL;
444 unlock_oldstart(jnl);
465 journal *jnl;
471 //printf("jnl: buf flush: bp @ 0x%x l/blkno %qd/%qd vp 0x%x tr @ 0x%x\n",
485 jnl = tr->jnl;
486 if (jnl->flags & JOURNAL_INVALID) {
490 CHECK_JOURNAL(jnl);
517 lock_oldstart(jnl);
521 unlock_oldstart(jnl);
529 //printf("jnl: tr 0x%x (0x%llx 0x%llx) in jnl 0x%x completed.\n",
530 // tr, tr->journal_start, tr->journal_end, jnl);
533 for(i=0; i < sizeof(jnl->old_start)/sizeof(jnl->old_start[0]); i++) {
535 if ((off_t)(jnl->old_start[i] & ~(0x8000000000000000ULL)) == tr->journal_start) {
536 jnl->old_start[i] &= ~(0x8000000000000000ULL);
541 if (i >= sizeof(jnl->old_start)/sizeof(jnl->old_start[0])) {
542 panic("jnl: buffer_flushed: did not find tr w/start @ %lld (tr %p, jnl %p)\n",
543 tr->journal_start, tr, jnl);
549 if (tr->journal_start == jnl->active_start) {
550 jnl->active_start = tr->journal_end;
556 for(ctr=jnl->completed_trs; ctr; prev=ctr, ctr=next) {
557 if (ctr->journal_start == jnl->active_start) {
558 jnl->active_start = ctr->journal_end;
562 if (ctr == jnl->completed_trs) {
563 jnl->completed_trs = ctr->next;
566 next = jnl->completed_trs; // this starts us over again
567 ctr->next = jnl->tr_freeme;
568 jnl->tr_freeme = ctr;
572 next = jnl->completed_trs; // this starts us over again
585 next->next = jnl->tr_freeme; // link in the next guy at the head of the tr_freeme list
586 jnl->tr_freeme = next;
588 next = jnl->completed_trs; // this starts us over again
604 for(ctr=jnl->completed_trs; ctr && tr->journal_start > ctr->journal_start; prev=ctr, ctr=ctr->next) {
609 jnl->completed_trs = tr;
611 } else if (ctr == jnl->completed_trs) {
612 tr->next = jnl->completed_trs;
613 jnl->completed_trs = tr;
621 tr->next = jnl->tr_freeme;
622 jnl->tr_freeme = tr;
624 unlock_oldstart(jnl);
636 swap_journal_header(journal *jnl)
638 jnl->jhdr->magic = SWAP32(jnl->jhdr->magic);
639 jnl->jhdr->endian = SWAP32(jnl->jhdr->endian);
640 jnl->jhdr->start = SWAP64(jnl->jhdr->start);
641 jnl->jhdr->end = SWAP64(jnl->jhdr->end);
642 jnl->jhdr->size = SWAP64(jnl->jhdr->size);
643 jnl->jhdr->blhdr_size = SWAP32(jnl->jhdr->blhdr_size);
644 jnl->jhdr->checksum = SWAP32(jnl->jhdr->checksum);
645 jnl->jhdr->jhdr_size = SWAP32(jnl->jhdr->jhdr_size);
646 jnl->jhdr->sequence_num = SWAP32(jnl->jhdr->sequence_num);
650 swap_block_list_header(journal *jnl, block_list_header *blhdr)
660 if (blhdr->num_blocks >= ((jnl->jhdr->blhdr_size / sizeof(block_info)) - 1)) {
661 printf("jnl: %s: blhdr num blocks looks suspicious (%d / blhdr size %d). not swapping.\n", jnl->jdev_name, blhdr->num_blocks, jnl->jhdr->blhdr_size);
674 update_fs_block(journal *jnl, void *block_ptr, off_t fs_block, size_t bsize)
680 ret = buf_meta_bread(jnl->fsdev, (daddr64_t)fs_block, bsize, NOCRED, &oblock_bp);
682 printf("jnl: %s: update_fs_block: error reading fs block # %lld! (ret %d)\n", jnl->jdev_name, fs_block, ret);
690 oblock_bp = buf_getblk(jnl->fsdev, (daddr64_t)fs_block, bsize, 0, 0, BLK_META);
692 printf("jnl: %s: update_fs_block: buf_getblk() for %lld failed! failing update.\n", jnl->jdev_name, fs_block);
707 printf("jnl: %s: update_fs_block: failed to update block %lld (ret %d)\n", jnl->jdev_name, fs_block,ret);
713 ret = buf_meta_bread(jnl->fsdev, (daddr64_t)fs_block, bsize, NOCRED, &oblock_bp);
734 printf("jnl: grow_table: no memory to expand coalesce buffer!\n");
738 // printf("jnl: lookup_bucket: expanded co_buf to %d elems\n", new_size);
815 insert_block(journal *jnl, struct bucket **buf_ptr, int blk_index, off_t num, size_t size, size_t offset, int32_t cksum, int *num_buckets_ptr, int *num_full_ptr, int overwriting)
824 printf("jnl: %s: add_block: grow_table returned an error!\n", jnl->jdev_name);
840 if (offset >= jnl->jhdr->size) {
841 offset = jnl->jhdr->jhdr_size + (offset - jnl->jhdr->size);
844 panic("jnl: insert_block: bad size in insert_block (%lu)\n", size);
856 do_overlap(journal *jnl, struct bucket **buf_ptr, int blk_index, off_t block_num, size_t size, __unused size_t offset, int32_t cksum, int *num_buckets_ptr, int *num_full_ptr)
859 size_t jhdr_size = jnl->jhdr->jhdr_size, new_offset;
873 panic("jnl: do_overlap: overlap with previous entry not a multiple of %lu\n", jhdr_size);
883 err = insert_block(jnl, buf_ptr, blk_index, new_num, new_size, new_offset, cksum, num_buckets_ptr, num_full_ptr, 0);
885 panic("jnl: do_overlap: error inserting during pre-overlap\n");
918 panic("jnl: do_overlap: overlap of %lld is not multiple of %lu\n", overlap, jhdr_size);
921 // if we partially overlap this entry, adjust its block number, jnl offset, and size
926 if (new_offset >= jnl->jhdr->size) {
927 new_offset = jhdr_size + (new_offset - jnl->jhdr->size);
933 panic("jnl: do_overlap: after overlap, new block size is invalid (%lu)\n", (*buf_ptr)[index].block_size);
974 add_block(journal *jnl, struct bucket **buf_ptr, off_t block_num, size_t size, __unused size_t offset, int32_t cksum, int *num_buckets_ptr, int *num_full_ptr)
985 //printf("jnl: add_block: trouble adding block to co_buf\n");
987 } // else printf("jnl: add_block: adding block 0x%llx at i=%d\n", block_num, blk_index);
990 overwriting = do_overlap(jnl, buf_ptr, blk_index, block_num, size, offset, cksum, num_buckets_ptr, num_full_ptr);
996 blk_index = insert_block(jnl, buf_ptr, blk_index, block_num, size, offset, cksum, num_buckets_ptr, num_full_ptr, overwriting);
1002 replay_journal(journal *jnl)
1015 if (jnl->jhdr->start == jnl->jhdr->size) {
1016 jnl->jhdr->start = jnl->jhdr->jhdr_size;
1018 if (jnl->jhdr->end == jnl->jhdr->size) {
1019 jnl->jhdr->end = jnl->jhdr->jhdr_size;
1022 if (jnl->jhdr->start == jnl->jhdr->end) {
1026 orig_jnl_start = jnl->jhdr->start;
1029 if (kmem_alloc(kernel_map, (vm_offset_t *)&buff, jnl->jhdr->blhdr_size)) {
1030 printf("jnl: %s: replay_journal: no memory for block buffer! (%d bytes)\n",
1031 jnl->jdev_name, jnl->jhdr->blhdr_size);
1037 printf("jnl: %s: replay_journal: no memory for coalesce buffer!\n", jnl->jdev_name);
1050 printf("jnl: %s: replay_journal: from: %lld to: %lld (joffset 0x%llx)\n",
1051 jnl->jdev_name, jnl->jhdr->start, jnl->jhdr->end, jnl->jdev_offset);
1053 while(check_past_jnl_end || jnl->jhdr->start != jnl->jhdr->end) {
1054 offset = blhdr_offset = jnl->jhdr->start;
1055 ret = read_journal_data(jnl, &offset, buff, jnl->jhdr->blhdr_size);
1056 if (ret != (size_t)jnl->jhdr->blhdr_size) {
1057 printf("jnl: %s: replay_journal: Could not read block list header block @ 0x%llx!\n", jnl->jdev_name, offset);
1066 if (jnl->flags & JOURNAL_NEED_SWAP) {
1071 swap_block_list_header(jnl, blhdr);
1086 if (blhdr_offset != jnl->jhdr->end) {
1087 printf("jnl: %s: Extra txn replay stopped @ %lld / 0x%llx\n", jnl->jdev_name, blhdr_offset, blhdr_offset);
1091 jnl->jhdr->end = blhdr_offset;
1095 printf("jnl: %s: replay_journal: bad block list header @ 0x%llx (checksum 0x%x != 0x%x)\n",
1096 jnl->jdev_name, blhdr_offset, orig_checksum, checksum);
1112 txn_start_offset = jnl->jhdr->end = blhdr_offset;
1116 printf("jnl: %s: 2: extra replay stopped @ %lld / 0x%llx (seq %d < %d)\n",
1117 jnl->jdev_name, blhdr_offset, blhdr_offset, blhdr->binfo[0].b.sequence_num, last_sequence_num);
1121 printf("jnl: %s: txn sequence numbers out of order in txn @ %lld / %llx! (%d < %d)\n",
1122 jnl->jdev_name, blhdr_offset, blhdr_offset, blhdr->binfo[0].b.sequence_num, last_sequence_num);
1128 if (blhdr_offset >= jnl->jhdr->end && jnl->jhdr->start <= jnl->jhdr->end) {
1131 printf("jnl: %s: pre-sequence-num-enabled txn's - can not go further than end (%lld %lld).\n",
1132 jnl->jdev_name, jnl->jhdr->start, jnl->jhdr->end);
1133 if (jnl->jhdr->start != jnl->jhdr->end) {
1134 jnl->jhdr->start = jnl->jhdr->end;
1138 printf("jnl: %s: examining extra transactions starting @ %lld / 0x%llx\n", jnl->jdev_name, blhdr_offset, blhdr_offset);
1143 printf("jnl: %s: replay_journal: bad looking journal entry: max: %d num: %d\n",
1144 jnl->jdev_name, blhdr->max_blocks, blhdr->num_blocks);
1152 printf("jnl: %s: replay_journal: bogus block number 0x%llx\n", jnl->jdev_name, blhdr->binfo[i].bnum);
1175 //printf("jnl: replay_journal: adding %d blocks in journal entry @ 0x%llx to co_buf\n",
1176 // blhdr->num_blocks-1, jnl->jhdr->start);
1187 //printf("jnl: replay_journal: skipping killed fs block (index %d)\n", i);
1197 ret = read_journal_data(jnl, &block_offset, block_ptr, size);
1199 printf("jnl: %s: replay_journal: Could not read journal entry data @ offset 0x%llx!\n", jnl->jdev_name, offset);
1209 printf("jnl: %s: txn starting at %lld (%lld) @ index %3d bnum %lld (%d) with disk cksum != blhdr cksum (0x%.8x 0x%.8x)\n",
1210 jnl->jdev_name, txn_start_offset, blhdr_offset, i, number, size, disk_cksum, blhdr->binfo[i].b.cksum);
1211 printf("jnl: 0x%.8x 0x%.8x 0x%.8x 0x%.8x 0x%.8x 0x%.8x 0x%.8x 0x%.8x\n",
1222 // printf("jnl: replay_journal: adding block 0x%llx\n", number);
1223 ret_val = add_block(jnl, &co_buf, number, size, (size_t) offset, blhdr->binfo[i].b.cksum, &num_buckets, &num_full);
1226 printf("jnl: %s: replay_journal: trouble adding block to co_buf\n", jnl->jdev_name);
1228 } // else printf("jnl: replay_journal: added block 0x%llx at i=%d\n", number);
1234 // check if the last block added puts us off the end of the jnl.
1238 if (offset >= jnl->jhdr->size) {
1239 offset = jnl->jhdr->jhdr_size + (offset - jnl->jhdr->size);
1251 printf("jnl: %s: no known good txn start offset! aborting journal replay.\n", jnl->jdev_name);
1255 jnl->jhdr->start = orig_jnl_start;
1256 jnl->jhdr->end = txn_start_offset;
1259 printf("jnl: %s: restarting journal replay (%lld - %lld)!\n", jnl->jdev_name, jnl->jhdr->start, jnl->jhdr->end);
1263 jnl->jhdr->start += blhdr->bytes_used;
1264 if (jnl->jhdr->start >= jnl->jhdr->size) {
1266 jnl->jhdr->start = (jnl->jhdr->start % jnl->jhdr->size) + jnl->jhdr->jhdr_size;
1269 if (jnl->jhdr->start == jnl->jhdr->end) {
1274 if (jnl->jhdr->start != jnl->jhdr->end) {
1275 printf("jnl: %s: start %lld != end %lld. resetting end.\n", jnl->jdev_name, jnl->jhdr->start, jnl->jhdr->end);
1276 jnl->jhdr->end = jnl->jhdr->start;
1279 //printf("jnl: replay_journal: replaying %d blocks\n", num_full);
1315 // printf("jnl: replay_journal: skipping killed fs block\n");
1319 ret = read_journal_data(jnl, &jnl_offset, block_ptr, size);
1321 printf("jnl: %s: replay_journal: Could not read journal entry data @ offset 0x%llx!\n", jnl->jdev_name, offset);
1325 if (update_fs_block(jnl, block_ptr, number, size) != 0) {
1332 // done replaying; update jnl header
1333 if (write_journal_header(jnl) != 0) {
1337 printf("jnl: %s: journal replay done.\n", jnl->jdev_name);
1349 kmem_free(kernel_map, (vm_offset_t)buff, jnl->jhdr->blhdr_size);
1359 kmem_free(kernel_map, (vm_offset_t)buff, jnl->jhdr->blhdr_size);
1375 // size of the blhdr. It assumes that jnl->jhdr->size
1376 // and jnl->jhdr->jhdr_size are already valid.
1379 size_up_tbuffer(journal *jnl, int tbuffer_size, int phys_blksz)
1400 jnl->tbuffer_size = def_tbuffer_size;
1403 if (tbuffer_size < jnl->jhdr->blhdr_size * 2) {
1404 tbuffer_size = jnl->jhdr->blhdr_size * 2;
1407 if ((tbuffer_size % jnl->jhdr->jhdr_size) != 0) {
1408 tbuffer_size -= (tbuffer_size % jnl->jhdr->jhdr_size);
1411 jnl->tbuffer_size = tbuffer_size;
1414 if (jnl->tbuffer_size > (jnl->jhdr->size / 2)) {
1415 jnl->tbuffer_size = (jnl->jhdr->size / 2);
1418 if (jnl->tbuffer_size > MAX_TRANSACTION_BUFFER_SIZE) {
1419 jnl->tbuffer_size = MAX_TRANSACTION_BUFFER_SIZE;
1422 jnl->jhdr->blhdr_size = (jnl->tbuffer_size / jnl->jhdr->jhdr_size) * sizeof(block_info);
1423 if (jnl->jhdr->blhdr_size < phys_blksz) {
1424 jnl->jhdr->blhdr_size = phys_blksz;
1425 } else if ((jnl->jhdr->blhdr_size % phys_blksz) != 0) {
1427 jnl->jhdr->blhdr_size = (jnl->jhdr->blhdr_size + (phys_blksz - 1)) & ~(phys_blksz - 1);
1434 get_io_info(struct vnode *devvp, size_t phys_blksz, journal *jnl, struct vfs_context *context)
1445 jnl->flags |= JOURNAL_DO_FUA_WRITES;
1446 printf("jnl: %s: enabling FUA writes (features 0x%x)\n", name ? name : "no-name-dev", features);
1475 jnl->max_read_size = readmaxcnt;
1476 jnl->max_write_size = writemaxcnt;
1479 if (jnl->max_read_size == 0) {
1480 jnl->max_read_size = 128 * 1024;
1481 jnl->max_write_size = 128 * 1024;
1514 journal *jnl;
1530 printf("jnl: %s: create: error: phys blksize %lu bigger than min fs blksize %lu\n",
1536 printf("jnl: %s: create: journal size 0x%llx is not an even multiple of block size 0x%lx\n",
1542 MALLOC_ZONE(jnl, struct journal *, sizeof(struct journal), M_JNL_JNL, M_WAITOK);
1543 memset(jnl, 0, sizeof(*jnl));
1545 jnl->jdev = jvp;
1546 jnl->jdev_offset = offset;
1547 jnl->fsdev = fsvp;
1548 jnl->flush = flush;
1549 jnl->flush_arg = arg;
1550 jnl->flags = (flags & JOURNAL_OPTION_FLAGS_MASK);
1551 jnl->jdev_name = jdev_name;
1552 lck_mtx_init(&jnl->old_start_lock, jnl_mutex_group, jnl_lock_attr);
1554 get_io_info(jvp, phys_blksz, jnl, &context);
1556 if (kmem_alloc(kernel_map, (vm_offset_t *)&jnl->header_buf, phys_blksz)) {
1557 printf("jnl: %s: create: could not allocate space for header buffer (%lu bytes)\n", jdev_name, phys_blksz);
1561 memset(jnl->header_buf, 0, phys_blksz);
1563 jnl->jhdr = (journal_header *)jnl->header_buf;
1564 jnl->jhdr->magic = JOURNAL_HEADER_MAGIC;
1565 jnl->jhdr->endian = ENDIAN_MAGIC;
1566 jnl->jhdr->start = phys_blksz; // start at block #1, block #0 is for the jhdr itself
1567 jnl->jhdr->end = phys_blksz;
1568 jnl->jhdr->size = journal_size;
1569 jnl->jhdr->jhdr_size = phys_blksz;
1570 size_up_tbuffer(jnl, tbuffer_size, phys_blksz);
1572 jnl->active_start = jnl->jhdr->start;
1575 // jnl->jhdr->start = jnl->jhdr->size - (phys_blksz*3);
1576 // jnl->jhdr->end = jnl->jhdr->size - (phys_blksz*3);
1578 jnl->jhdr->sequence_num = random() & 0x00ffffff;
1580 lck_mtx_init(&jnl->jlock, jnl_mutex_group, jnl_lock_attr);
1582 if (write_journal_header(jnl) != 0) {
1583 printf("jnl: %s: journal_create: failed to write journal header.\n", jdev_name);
1587 return jnl;
1591 kmem_free(kernel_map, (vm_offset_t)jnl->header_buf, phys_blksz);
1596 jnl->jhdr = NULL;
1597 FREE_ZONE(jnl, sizeof(struct journal), M_JNL_JNL);
1613 journal *jnl;
1629 printf("jnl: %s: open: error: phys blksize %lu bigger than min fs blksize %lu\n",
1635 printf("jnl: %s: open: journal size 0x%llx is not an even multiple of block size 0x%lx\n",
1640 MALLOC_ZONE(jnl, struct journal *, sizeof(struct journal), M_JNL_JNL, M_WAITOK);
1641 memset(jnl, 0, sizeof(*jnl));
1643 jnl->jdev = jvp;
1644 jnl->jdev_offset = offset;
1645 jnl->fsdev = fsvp;
1646 jnl->flush = flush;
1647 jnl->flush_arg = arg;
1648 jnl->flags = (flags & JOURNAL_OPTION_FLAGS_MASK);
1649 jnl->jdev_name = jdev_name;
1650 lck_mtx_init(&jnl->old_start_lock, jnl_mutex_group, jnl_lock_attr);
1652 get_io_info(jvp, phys_blksz, jnl, &context);
1654 if (kmem_alloc(kernel_map, (vm_offset_t *)&jnl->header_buf, phys_blksz)) {
1655 printf("jnl: %s: create: could not allocate space for header buffer (%lu bytes)\n", jdev_name, phys_blksz);
1659 jnl->jhdr = (journal_header *)jnl->header_buf;
1660 memset(jnl->jhdr, 0, sizeof(journal_header));
1663 jnl->jhdr->jhdr_size = phys_blksz;
1665 if (read_journal_header(jnl, jnl->jhdr, phys_blksz) != phys_blksz) {
1666 printf("jnl: %s: open: could not read %lu bytes for the journal header.\n",
1671 orig_checksum = jnl->jhdr->checksum;
1672 jnl->jhdr->checksum = 0;
1674 if (jnl->jhdr->magic == SWAP32(JOURNAL_HEADER_MAGIC)) {
1677 checksum = calc_checksum((char *)jnl->jhdr, JOURNAL_HEADER_CKSUM_SIZE);
1678 swap_journal_header(jnl);
1679 jnl->flags |= JOURNAL_NEED_SWAP;
1681 checksum = calc_checksum((char *)jnl->jhdr, JOURNAL_HEADER_CKSUM_SIZE);
1684 if (jnl->jhdr->magic != JOURNAL_HEADER_MAGIC && jnl->jhdr->magic != OLD_JOURNAL_HEADER_MAGIC) {
1685 printf("jnl: %s: open: journal magic is bad (0x%x != 0x%x)\n",
1686 jnl->jdev_name, jnl->jhdr->magic, JOURNAL_HEADER_MAGIC);
1691 if (jnl->jhdr->magic == JOURNAL_HEADER_MAGIC) {
1694 printf("jnl: %s: open: journal checksum is bad (0x%x != 0x%x)\n",
1702 if (jnl->jhdr->magic == OLD_JOURNAL_HEADER_MAGIC) {
1703 jnl->jhdr->magic = JOURNAL_HEADER_MAGIC;
1706 if (phys_blksz != (size_t)jnl->jhdr->jhdr_size && jnl->jhdr->jhdr_size != 0) {
1715 if (jnl->jhdr->start == jnl->jhdr->end) {
1717 printf("jnl: %s: open: changing journal header size from %d to %lu\n",
1718 jdev_name, jnl->jhdr->jhdr_size, phys_blksz);
1719 jnl->jhdr->jhdr_size = phys_blksz;
1720 if (write_journal_header(jnl)) {
1721 printf("jnl: %s: open: failed to update journal header size\n", jdev_name);
1725 printf("jnl: %s: open: phys_blksz %lu does not match journal header size %d, and journal is not empty!\n",
1726 jdev_name, phys_blksz, jnl->jhdr->jhdr_size);
1731 if ( jnl->jhdr->start <= 0
1732 || jnl->jhdr->start > jnl->jhdr->size
1733 || jnl->jhdr->start > 1024*1024*1024) {
1734 printf("jnl: %s: open: jhdr start looks bad (0x%llx max size 0x%llx)\n",
1735 jdev_name, jnl->jhdr->start, jnl->jhdr->size);
1739 if ( jnl->jhdr->end <= 0
1740 || jnl->jhdr->end > jnl->jhdr->size
1741 || jnl->jhdr->end > 1024*1024*1024) {
1742 printf("jnl: %s: open: jhdr end looks bad (0x%llx max size 0x%llx)\n",
1743 jdev_name, jnl->jhdr->end, jnl->jhdr->size);
1747 if (jnl->jhdr->size > 1024*1024*1024) {
1748 printf("jnl: %s: open: jhdr size looks bad (0x%llx)\n", jdev_name, jnl->jhdr->size);
1757 // XXXdbg if ((jnl->jhdr->start % jnl->jhdr->jhdr_size) != 0) {
1758 if ((jnl->jhdr->start % 512) != 0) {
1759 printf("jnl: %s: open: journal start (0x%llx) not a multiple of 512?\n",
1760 jdev_name, jnl->jhdr->start);
1764 //XXXdbg if ((jnl->jhdr->end % jnl->jhdr->jhdr_size) != 0) {
1765 if ((jnl->jhdr->end % 512) != 0) {
1766 printf("jnl: %s: open: journal end (0x%llx) not a multiple of block size (0x%x)?\n",
1767 jdev_name, jnl->jhdr->end, jnl->jhdr->jhdr_size);
1773 printf("jnl: %s: journal start/end pointers reset! (jnl %p; s 0x%llx e 0x%llx)\n",
1774 jdev_name, jnl, jnl->jhdr->start, jnl->jhdr->end);
1775 jnl->jhdr->start = jnl->jhdr->end;
1776 } else if (replay_journal(jnl) != 0) {
1777 printf("jnl: %s: journal_open: Error replaying the journal!\n", jdev_name);
1784 if (orig_blksz < jnl->jhdr->jhdr_size) {
1785 printf("jnl: %s: open: jhdr_size is %d but orig phys blk size is %d. switching.\n",
1786 jdev_name, jnl->jhdr->jhdr_size, orig_blksz);
1788 jnl->jhdr->jhdr_size = orig_blksz;
1793 jnl->active_start = jnl->jhdr->start;
1796 size_up_tbuffer(jnl, tbuffer_size, phys_blksz);
1798 lck_mtx_init(&jnl->jlock, jnl_mutex_group, jnl_lock_attr);
1800 return jnl;
1807 kmem_free(kernel_map, (vm_offset_t)jnl->header_buf, phys_blksz);
1812 FREE_ZONE(jnl, sizeof(struct journal), M_JNL_JNL);
1824 journal jnl;
1835 printf("jnl: %s: is_clean: failed to get device block size.\n", jdev_name);
1840 printf("jnl: %s: is_clean: error: phys blksize %d bigger than min fs blksize %lu\n",
1846 printf("jnl: %s: is_clean: journal size 0x%llx is not an even multiple of block size 0x%x\n",
1851 memset(&jnl, 0, sizeof(jnl));
1853 if (kmem_alloc(kernel_map, (vm_offset_t *)&jnl.header_buf, phys_blksz)) {
1854 printf("jnl: %s: is_clean: could not allocate space for header buffer (%d bytes)\n", jdev_name, phys_blksz);
1858 get_io_info(jvp, phys_blksz, &jnl, &context);
1860 jnl.jhdr = (journal_header *)jnl.header_buf;
1861 memset(jnl.jhdr, 0, sizeof(journal_header));
1863 jnl.jdev = jvp;
1864 jnl.jdev_offset = offset;
1865 jnl.fsdev = fsvp;
1868 jnl.jhdr->jhdr_size = phys_blksz;
1870 if (read_journal_header(&jnl, jnl.jhdr, phys_blksz) != (unsigned)phys_blksz) {
1871 printf("jnl: %s: is_clean: could not read %d bytes for the journal header.\n",
1877 orig_checksum = jnl.jhdr->checksum;
1878 jnl.jhdr->checksum = 0;
1880 if (jnl.jhdr->magic == SWAP32(JOURNAL_HEADER_MAGIC)) {
1883 checksum = calc_checksum((char *)jnl.jhdr, JOURNAL_HEADER_CKSUM_SIZE);
1884 swap_journal_header(&jnl);
1885 jnl.flags |= JOURNAL_NEED_SWAP;
1887 checksum = calc_checksum((char *)jnl.jhdr, JOURNAL_HEADER_CKSUM_SIZE);
1890 if (jnl.jhdr->magic != JOURNAL_HEADER_MAGIC && jnl.jhdr->magic != OLD_JOURNAL_HEADER_MAGIC) {
1891 printf("jnl: %s: is_clean: journal magic is bad (0x%x != 0x%x)\n",
1892 jdev_name, jnl.jhdr->magic, JOURNAL_HEADER_MAGIC);
1898 printf("jnl: %s: is_clean: journal checksum is bad (0x%x != 0x%x)\n", jdev_name, orig_checksum, checksum);
1907 if (jnl.jhdr->start == jnl.jhdr->end) {
1914 kmem_free(kernel_map, (vm_offset_t)jnl.header_buf, phys_blksz);
1926 journal_close(journal *jnl)
1931 CHECK_JOURNAL(jnl);
1936 jnl->flags |= JOURNAL_CLOSE_PENDING;
1938 if (jnl->owner != current_thread()) {
1939 lock_journal(jnl);
1945 if ((jnl->flags & JOURNAL_INVALID) == 0) {
1947 if (jnl->active_tr) {
1948 journal_end_transaction(jnl);
1952 if (jnl->cur_tr) {
1953 transaction *tr = jnl->cur_tr;
1955 jnl->cur_tr = NULL;
1959 //start = &jnl->jhdr->start;
1960 start = &jnl->active_start;
1961 end = &jnl->jhdr->end;
1964 //printf("jnl: close: flushing the buffer cache (start 0x%llx end 0x%llx)\n", *start, *end);
1965 if (jnl->flush) {
1966 jnl->flush(jnl->flush_arg);
1968 tsleep((caddr_t)jnl, PRIBIO, "jnl_close", 2);
1972 printf("jnl: %s: close: buffer flushing didn't seem to flush out all the transactions! (0x%llx - 0x%llx)\n",
1973 jnl->jdev_name, *start, *end);
1977 jnl->jhdr->start = jnl->active_start;
1980 write_journal_header(jnl);
1984 printf("jnl: %s: close: journal %p, is invalid. aborting outstanding transactions\n", jnl->jdev_name, jnl);
1985 if (jnl->active_tr || jnl->cur_tr) {
1987 if (jnl->active_tr) {
1988 tr = jnl->active_tr;
1989 jnl->active_tr = NULL;
1991 tr = jnl->cur_tr;
1992 jnl->cur_tr = NULL;
1995 abort_transaction(jnl, tr);
1996 if (jnl->active_tr || jnl->cur_tr) {
1997 panic("jnl: %s: close: jnl @ %p had both an active and cur tr\n", jnl->jdev_name, jnl);
2002 free_old_stuff(jnl);
2004 kmem_free(kernel_map, (vm_offset_t)jnl->header_buf, jnl->jhdr->jhdr_size);
2005 jnl->jhdr = (void *)0xbeefbabe;
2007 if (jnl->jdev_name) {
2008 vfs_removename(jnl->jdev_name);
2011 FREE_ZONE(jnl, sizeof(struct journal), M_JNL_JNL);
2015 dump_journal(journal *jnl)
2019 printf("journal for dev %s:", jnl->jdev_name);
2020 printf(" jdev_offset %.8llx\n", jnl->jdev_offset);
2021 printf(" magic: 0x%.8x\n", jnl->jhdr->magic);
2022 printf(" start: 0x%.8llx\n", jnl->jhdr->start);
2023 printf(" end: 0x%.8llx\n", jnl->jhdr->end);
2024 printf(" size: 0x%.8llx\n", jnl->jhdr->size);
2025 printf(" blhdr size: %d\n", jnl->jhdr->blhdr_size);
2026 printf(" jhdr size: %d\n", jnl->jhdr->jhdr_size);
2027 printf(" chksum: 0x%.8x\n", jnl->jhdr->checksum);
2030 for(ctr=jnl->completed_trs; ctr; ctr=ctr->next) {
2038 free_space(journal *jnl)
2042 if (jnl->jhdr->start < jnl->jhdr->end) {
2043 free_space_offset = jnl->jhdr->size - (jnl->jhdr->end - jnl->jhdr->start) - jnl->jhdr->jhdr_size;
2044 } else if (jnl->jhdr->start > jnl->jhdr->end) {
2045 free_space_offset = jnl->jhdr->start - jnl->jhdr->end;
2048 free_space_offset = jnl->jhdr->size - jnl->jhdr->jhdr_size;
2060 check_free_space(journal *jnl, int desired_size)
2065 //printf("jnl: check free space (desired 0x%x, avail 0x%Lx)\n",
2066 // desired_size, free_space(jnl));
2072 dump_journal(jnl);
2073 panic("jnl: check_free_space: buffer flushing isn't working "
2074 "(jnl @ %p s %lld e %lld f %lld [active start %lld]).\n", jnl,
2075 jnl->jhdr->start, jnl->jhdr->end, free_space(jnl), jnl->active_start);
2078 printf("jnl: %s: check_free_space: giving up waiting for free space.\n", jnl->jdev_name);
2083 if (free_space(jnl) > desired_size && jnl->old_start[0] == 0) {
2087 // here's where we lazily bump up jnl->jhdr->start. we'll consume
2091 lock_oldstart(jnl);
2092 for(i=0; i < sizeof(jnl->old_start)/sizeof(jnl->old_start[0]); i++) {
2096 while (jnl->old_start[i] & 0x8000000000000000LL) {
2098 panic("jnl: check_free_space: tr starting @ 0x%llx not flushing (jnl %p).\n",
2099 jnl->old_start[i], jnl);
2102 unlock_oldstart(jnl);
2103 if (jnl->flush) {
2104 jnl->flush(jnl->flush_arg);
2106 tsleep((caddr_t)jnl, PRIBIO, "check_free_space1", 1);
2107 lock_oldstart(jnl);
2110 if (jnl->old_start[i] == 0) {
2115 jnl->jhdr->start = jnl->old_start[i];
2116 jnl->old_start[i] = 0;
2117 if (free_space(jnl) > desired_size) {
2118 unlock_oldstart(jnl);
2119 write_journal_header(jnl);
2120 lock_oldstart(jnl);
2124 unlock_oldstart(jnl);
2127 if (i < sizeof(jnl->old_start)/sizeof(jnl->old_start[0])) {
2139 jnl->jhdr->start = jnl->active_start;
2140 write_journal_header(jnl);
2148 if (jnl->flush) {
2149 jnl->flush(jnl->flush_arg);
2154 tsleep((caddr_t)jnl, PRIBIO, "check_free_space2", 1);
2164 journal_allocate_transaction(journal *jnl)
2171 tr->tbuffer_size = jnl->tbuffer_size;
2175 jnl->active_tr = NULL;
2182 memset(tr->tbuffer + BLHDR_CHECKSUM_SIZE, 0x5a, jnl->jhdr->blhdr_size - BLHDR_CHECKSUM_SIZE);
2185 tr->blhdr->max_blocks = (jnl->jhdr->blhdr_size / sizeof(block_info)) - 1;
2187 tr->blhdr->bytes_used = jnl->jhdr->blhdr_size;
2190 tr->sequence_num = ++jnl->jhdr->sequence_num;
2192 tr->total_bytes = jnl->jhdr->blhdr_size;
2193 tr->jnl = jnl;
2195 jnl->active_tr = tr;
2201 journal_start_transaction(journal *jnl)
2205 CHECK_JOURNAL(jnl);
2207 if (jnl->flags & JOURNAL_INVALID) {
2211 if (jnl->owner == current_thread()) {
2212 if (jnl->active_tr == NULL) {
2213 panic("jnl: start_tr: active_tr is NULL (jnl @ %p, owner %p, current_thread %p\n",
2214 jnl, jnl->owner, current_thread());
2216 jnl->nested_count++;
2220 lock_journal(jnl);
2222 if (jnl->owner != NULL || jnl->nested_count != 0 || jnl->active_tr != NULL) {
2223 panic("jnl: start_tr: owner %p, nested count %d, active_tr %p jnl @ %p\n",
2224 jnl->owner, jnl->nested_count, jnl->active_tr, jnl);
2227 jnl->owner = current_thread();
2228 jnl->nested_count = 1;
2230 free_old_stuff(jnl);
2233 if (free_space(jnl) < jnl->tbuffer_size) {
2235 // as well as updating jnl->jhdr->start
2236 if (check_free_space(jnl, jnl->tbuffer_size) != 0) {
2237 printf("jnl: %s: start transaction failed: no space\n", jnl->jdev_name);
2244 if (jnl->cur_tr) {
2245 jnl->active_tr = jnl->cur_tr;
2246 jnl->cur_tr = NULL;
2251 ret = journal_allocate_transaction(jnl);
2256 // printf("jnl: start_tr: owner 0x%x new tr @ 0x%x\n", jnl->owner, jnl->active_tr);
2261 jnl->owner = NULL;
2262 jnl->nested_count = 0;
2263 unlock_journal(jnl);
2269 journal_modify_block_start(journal *jnl, struct buf *bp)
2273 CHECK_JOURNAL(jnl);
2275 if (jnl->flags & JOURNAL_INVALID) {
2282 panic("jnl: modify_block_start: bp @ %p is not a meta-data block! (jnl %p)\n", bp, jnl);
2285 tr = jnl->active_tr;
2288 if (jnl->owner != current_thread()) {
2289 panic("jnl: modify_block_start: called w/out a transaction! jnl %p, owner %p, curact %p\n",
2290 jnl, jnl->owner, current_thread());
2293 free_old_stuff(jnl);
2295 //printf("jnl: mod block start (bp 0x%x vp 0x%x l/blkno %qd/%qd bsz %d; total bytes %d)\n",
2300 if ((buf_size(bp) % jnl->jhdr->jhdr_size) != 0) {
2301 panic("jnl: mod block start: bufsize %d not a multiple of block size %d\n",
2302 buf_size(bp), jnl->jhdr->jhdr_size);
2307 if (tr->total_bytes+buf_size(bp) >= (jnl->jhdr->size - jnl->jhdr->jhdr_size)) {
2308 panic("jnl: transaction too big (%d >= %lld bytes, bufsize %d, tr %p bp %p)\n",
2309 tr->total_bytes, (tr->jnl->jhdr->size - jnl->jhdr->jhdr_size), buf_size(bp), tr, bp);
2333 journal_modify_block_abort(journal *jnl, struct buf *bp)
2339 CHECK_JOURNAL(jnl);
2341 tr = jnl->active_tr;
2353 if (jnl->flags & JOURNAL_INVALID) {
2359 if (jnl->owner != current_thread()) {
2360 panic("jnl: modify_block_abort: called w/out a transaction! jnl %p, owner %p, curact %p\n",
2361 jnl, jnl->owner, current_thread());
2364 free_old_stuff(jnl);
2366 // printf("jnl: modify_block_abort: tr 0x%x bp 0x%x\n", jnl->active_tr, bp);
2373 panic("jnl: bp @ %p changed size on me! (%d vs. %lu, jnl %p)\n",
2374 bp, buf_size(bp), blhdr->binfo[i].bsize, jnl);
2402 journal_modify_block_end(journal *jnl, struct buf *bp, void (*func)(struct buf *bp, void *arg), void *arg)
2410 CHECK_JOURNAL(jnl);
2412 if (jnl->flags & JOURNAL_INVALID) {
2416 tr = jnl->active_tr;
2419 if (jnl->owner != current_thread()) {
2420 panic("jnl: modify_block_end: called w/out a transaction! jnl %p, owner %p, curact %p\n",
2421 jnl, jnl->owner, current_thread());
2424 free_old_stuff(jnl);
2426 //printf("jnl: mod block end: (bp 0x%x vp 0x%x l/blkno %qd/%qd bsz %d, total bytes %d)\n",
2430 panic("jnl: modify_block_end: bp %p not locked! jnl @ %p\n", bp, jnl);
2435 tbuffer_offset = jnl->jhdr->blhdr_size;
2440 panic("jnl: bp @ %p changed size on me! (%d vs. %lu, jnl %p)\n",
2441 bp, buf_size(bp), blhdr->binfo[i].bsize, jnl);
2462 panic("jnl: modify block end: no way man, prev == NULL?!?, jnl %p, bp %p\n", jnl, bp);
2473 panic("jnl: end_tr: no space for new block tr @ %p (total bytes: %d)!\n",
2480 memset(nblhdr + BLHDR_CHECKSUM_SIZE, 0x5a, jnl->jhdr->blhdr_size - BLHDR_CHECKSUM_SIZE);
2483 nblhdr->max_blocks = (jnl->jhdr->blhdr_size / sizeof(block_info)) - 1;
2485 nblhdr->bytes_used = jnl->jhdr->blhdr_size;
2489 tr->total_bytes += jnl->jhdr->blhdr_size;
2496 tbuffer_offset = jnl->jhdr->blhdr_size;
2502 panic("jnl: modify_block_end: i = %d, max_blocks %d\n", i, blhdr->max_blocks);
2532 panic("jnl: modify_block_end: old func %p / arg %p", old_func, old_arg);
2547 journal_kill_block(journal *jnl, struct buf *bp)
2554 CHECK_JOURNAL(jnl);
2556 if (jnl->flags & JOURNAL_INVALID) {
2560 tr = jnl->active_tr;
2563 if (jnl->owner != current_thread()) {
2564 panic("jnl: modify_block_end: called w/out a transaction! jnl %p, owner %p, curact %p\n",
2565 jnl, jnl->owner, current_thread());
2568 free_old_stuff(jnl);
2573 panic("jnl: modify_block_end: called with bp not B_LOCKED");
2597 // panic("jnl: kill block: this defies all logic! bp 0x%x\n", bp);
2679 journal *jnl = tr->jnl;
2684 if (jnl->cur_tr) {
2685 panic("jnl: jnl @ %p already has cur_tr %p, new tr: %p\n",
2686 jnl, jnl->cur_tr, tr);
2691 if (tr->total_bytes == jnl->jhdr->blhdr_size) {
2692 jnl->cur_tr = tr;
2703 && (jnl->flags & JOURNAL_NO_GROUP_COMMIT) == 0
2707 jnl->cur_tr = tr;
2714 check_free_space(jnl, tr->total_bytes);
2717 if (jnl->jhdr->end <= 0 || jnl->jhdr->end > jnl->jhdr->size) {
2718 panic("jnl: end_transaction: end is bogus 0x%llx (sz 0x%llx)\n",
2719 jnl->jhdr->end, jnl->jhdr->size);
2723 tr->journal_start = jnl->jhdr->end;
2724 end = jnl->jhdr->end;
2731 lock_oldstart(jnl);
2732 while ((jnl->old_start[0] & 0x8000000000000000LL) != 0) {
2733 if (jnl->flush) {
2734 unlock_oldstart(jnl);
2736 if (jnl->flush) {
2737 jnl->flush(jnl->flush_arg);
2741 (void)tsleep((void *)jnl, PRIBIO, "jnl-old-start-sleep", 1);
2743 lock_oldstart(jnl);
2746 panic("jnl: transaction that started at 0x%llx is not completing! jnl %p\n",
2747 jnl->old_start[0] & (~0x8000000000000000LL), jnl);
2755 memcpy(&jnl->old_start[0], &jnl->old_start[1], sizeof(jnl->old_start)-sizeof(jnl->old_start[0]));
2756 jnl->old_start[sizeof(jnl->old_start)/sizeof(jnl->old_start[0]) - 1] = tr->journal_start | 0x8000000000000000LL;
2758 unlock_oldstart(jnl);
2765 tbuffer_offset = jnl->jhdr->blhdr_size;
2808 panic("jnl: inconsistent binfo (NULL bp w/bnum %lld; jnl @ %p, tr %p)\n",
2809 blhdr->binfo[i].bnum, jnl, tr);
2823 printf("jnl: %s: end_tr: bad news! bp @ %p w/null vp and l/blkno = %qd/%qd. aborting the transaction (tr %p jnl %p).\n",
2824 jnl->jdev_name, bp, lblkno, blkno, tr, jnl);
2832 if ((lblkno == blkno) && (vp != jnl->fsdev)) {
2837 printf("jnl: %s: end_tr: vnop_blktooff failed @ %p, jnl %p\n", jnl->jdev_name, bp, jnl);
2841 printf("jnl: %s: end_tr: can't blockmap the bp @ %p, jnl %p\n", jnl->jdev_name, bp, jnl);
2845 printf("jnl: %s: end_tr: blk not physically contiguous on disk@ %p, jnl %p\n", jnl->jdev_name, bp, jnl);
2872 tbuffer_offset = jnl->jhdr->blhdr_size;
2884 ret = write_journal_data(jnl, &end, blhdr, amt);
2894 printf("jnl: %s: end_transaction: only wrote %d of %d bytes to the journal!\n",
2895 jnl->jdev_name, ret, amt);
2901 jnl->jhdr->end = end; // update where the journal now ends
2904 panic("jnl: end_transaction: bad tr journal start/end: 0x%llx 0x%llx\n",
2908 if (write_journal_header(jnl) != 0) {
2933 tr->num_flushed = tr->num_blhdrs * jnl->jhdr->blhdr_size;
2959 if (jnl->flags & JOURNAL_CLOSE_PENDING) {
2964 panic("jnl: end_tr: !!!DANGER!!! bp %p flags (0x%x) not LOCKED & DELWRI\n", bp, buf_flags(bp));
2972 panic("jnl: bp @ %p (blkno %qd, vp %p) has non-null iodone (%p) buffflushcb %p\n",
2985 printf("jnl: %s: end_transaction: could not acquire block %p (errno %d)!\n",
2986 jnl->jdev_name,bp, errno);
2997 //printf("jnl: end_tr: tr @ 0x%x, jnl-blocks: 0x%llx - 0x%llx. exit!\n",
3003 jnl->flags |= JOURNAL_INVALID;
3004 jnl->old_start[sizeof(jnl->old_start)/sizeof(jnl->old_start[0]) - 1] &= ~0x8000000000000000LL;
3005 abort_transaction(jnl, tr);
3010 abort_transaction(journal *jnl, transaction *tr)
3041 panic("jnl: abort_tr: got back a different bp! (bp %p should be %p, jnl %p\n",
3042 bp, blhdr->binfo[i].b.bp, jnl);
3054 printf("jnl: %s: abort_tr: could not find block %Ld vp %p!\n",
3055 jnl->jdev_name, blhdr->binfo[i].bnum, blhdr->binfo[i].b.bp);
3077 journal_end_transaction(journal *jnl)
3082 CHECK_JOURNAL(jnl);
3084 if ((jnl->flags & JOURNAL_INVALID) && jnl->owner == NULL) {
3088 if (jnl->owner != current_thread()) {
3089 panic("jnl: end_tr: I'm not the owner! jnl %p, owner %p, curact %p\n",
3090 jnl, jnl->owner, current_thread());
3093 free_old_stuff(jnl);
3095 jnl->nested_count--;
3096 if (jnl->nested_count > 0) {
3098 } else if (jnl->nested_count < 0) {
3099 panic("jnl: jnl @ %p has negative nested count (%d). bad boy.\n", jnl, jnl->nested_count);
3102 if (jnl->flags & JOURNAL_INVALID) {
3103 if (jnl->active_tr) {
3104 if (jnl->cur_tr != NULL) {
3105 panic("jnl: journal @ %p has active tr (%p) and cur tr (%p)\n",
3106 jnl, jnl->active_tr, jnl->cur_tr);
3109 tr = jnl->active_tr;
3110 jnl->active_tr = NULL;
3111 abort_transaction(jnl, tr);
3114 jnl->owner = NULL;
3115 unlock_journal(jnl);
3120 tr = jnl->active_tr;
3128 jnl->active_tr = NULL;
3131 jnl->owner = NULL;
3132 unlock_journal(jnl);
3139 journal_flush(journal *jnl)
3143 CHECK_JOURNAL(jnl);
3145 if (jnl->flags & JOURNAL_INVALID) {
3152 if (jnl->owner != current_thread()) {
3153 lock_journal(jnl);
3157 free_old_stuff(jnl);
3160 if (jnl->active_tr == NULL && jnl->cur_tr) {
3161 transaction *tr = jnl->cur_tr;
3163 jnl->cur_tr = NULL;
3168 unlock_journal(jnl);
3178 journal_active(journal *jnl)
3180 if (jnl->flags & JOURNAL_INVALID) {
3184 return (jnl->active_tr == NULL) ? 0 : 1;
3188 journal_owner(journal *jnl)
3190 return jnl->owner;
3193 int journal_uses_fua(journal *jnl)
3195 if (jnl->flags & JOURNAL_DO_FUA_WRITES)
3236 * jnl The (opened) journal to relocate.
3256 int journal_relocate(journal *jnl, off_t offset, off_t journal_size, int32_t tbuffer_size,
3265 if ((offset % jnl->jhdr->jhdr_size) != 0) {
3266 printf("jnl: %s: relocate: offset 0x%llx is not an even multiple of block size 0x%x\n",
3267 jnl->jdev_name, offset, jnl->jhdr->jhdr_size);
3270 if ((journal_size % jnl->jhdr->jhdr_size) != 0) {
3271 printf("jnl: %s: relocate: journal size 0x%llx is not an even multiple of block size 0x%x\n",
3272 jnl->jdev_name, journal_size, jnl->jhdr->jhdr_size);
3276 CHECK_JOURNAL(jnl);
3279 if (jnl->flags & JOURNAL_INVALID) {
3282 if (jnl->owner != current_thread()) {
3283 panic("jnl: relocate: Not the owner! jnl %p, owner %p, curact %p\n",
3284 jnl, jnl->owner, current_thread());
3288 tbuffer_size = jnl->tbuffer_size;
3289 size_up_tbuffer(jnl, tbuffer_size, jnl->jhdr->jhdr_size);
3296 tr = jnl->active_tr;
3298 jnl->active_tr = NULL;
3299 ret = journal_flush(jnl);
3300 jnl->active_tr = tr;
3306 jnl->jdev_offset = offset;
3307 jnl->jhdr->start = jnl->jhdr->end = jnl->jhdr->jhdr_size;
3308 jnl->jhdr->size = journal_size;
3309 jnl->active_start = jnl->jhdr->start;
3316 jnl->active_tr = NULL;
3319 printf("jnl: %s: relocate: end_transaction failed (%d)\n", jnl->jdev_name, ret);
3327 ret = journal_allocate_transaction(jnl);
3329 printf("jnl: %s: relocate: could not allocate new transaction (%d)\n", jnl->jdev_name, ret);
3336 jnl->flags |= JOURNAL_INVALID;
3337 abort_transaction(jnl, tr);