/* * calc_chksums calculates the checksums for the blocks described in the * descriptor block. */ static int calc_chksums(journal_t *journal, struct buffer_head *bh, unsigned long long *next_log_block, __u32 *crc32_sum) { int i, num_blks, err; unsigned long long io_block; struct buffer_head *obh; num_blks = count_tags(journal, bh); /* Calculate checksum of the descriptor block. */ *crc32_sum = crc32_be(*crc32_sum, (void *)bh->b_data, bh->b_size); for (i = 0; i < num_blks; i++) { io_block = (*next_log_block)++; wrap(journal, *next_log_block); err = jread(&obh, journal, io_block); if (err) { printk(KERN_ERR "JBD: IO error %d recovering block " "%llu in log\n", err, io_block); return 1; } else { *crc32_sum = crc32_be(*crc32_sum, (void *)obh->b_data, obh->b_size); } brelse(obh); } return 0; }
static int do_one_pass(journal_t *journal, struct recovery_info *info, enum passtype pass) { unsigned int first_commit_ID, next_commit_ID; unsigned long next_log_block; int err, success = 0; journal_superblock_t * sb; journal_header_t * tmp; struct buffer_head * bh; unsigned int sequence; int blocktype; /* Precompute the maximum metadata descriptors in a descriptor block */ int MAX_BLOCKS_PER_DESC; MAX_BLOCKS_PER_DESC = ((journal->j_blocksize-sizeof(journal_header_t)) / sizeof(journal_block_tag_t)); /* * First thing is to establish what we expect to find in the log * (in terms of transaction IDs), and where (in terms of log * block offsets): query the superblock. */ sb = journal->j_superblock; next_commit_ID = be32_to_cpu(sb->s_sequence); next_log_block = be32_to_cpu(sb->s_start); first_commit_ID = next_commit_ID; if (pass == PASS_SCAN) info->start_transaction = first_commit_ID; jbd_debug(1, "Starting recovery pass %d\n", pass); /* * Now we walk through the log, transaction by transaction, * making sure that each transaction has a commit block in the * expected place. Each complete transaction gets replayed back * into the main filesystem. */ while (1) { int flags; char * tagp; journal_block_tag_t * tag; struct buffer_head * obh; struct buffer_head * nbh; cond_resched(); /* We're under lock_kernel() */ /* If we already know where to stop the log traversal, * check right now that we haven't gone past the end of * the log. */ if (pass != PASS_SCAN) if (tid_geq(next_commit_ID, info->end_transaction)) break; jbd_debug(2, "Scanning for sequence ID %u at %lu/%lu\n", next_commit_ID, next_log_block, journal->j_last); /* Skip over each chunk of the transaction looking * either the next descriptor block or the final commit * record. */ jbd_debug(3, "JBD: checking block %ld\n", next_log_block); err = jread(&bh, journal, next_log_block); if (err) goto failed; next_log_block++; wrap(journal, next_log_block); /* What kind of buffer is it? * * If it is a descriptor block, check that it has the * expected sequence number. Otherwise, we're all done * here. */ tmp = (journal_header_t *)bh->b_data; if (tmp->h_magic != cpu_to_be32(JFS_MAGIC_NUMBER)) { brelse(bh); break; } blocktype = be32_to_cpu(tmp->h_blocktype); sequence = be32_to_cpu(tmp->h_sequence); jbd_debug(3, "Found magic %d, sequence %d\n", blocktype, sequence); if (sequence != next_commit_ID) { brelse(bh); break; } /* OK, we have a valid descriptor block which matches * all of the sequence number checks. What are we going * to do with it? That depends on the pass... */ switch(blocktype) { case JFS_DESCRIPTOR_BLOCK: /* If it is a valid descriptor block, replay it * in pass REPLAY; otherwise, just skip over the * blocks it describes. */ if (pass != PASS_REPLAY) { next_log_block += count_tags(bh, journal->j_blocksize); wrap(journal, next_log_block); brelse(bh); continue; } /* A descriptor block: we can now write all of * the data blocks. Yay, useful work is finally * getting done here! */ tagp = &bh->b_data[sizeof(journal_header_t)]; while ((tagp - bh->b_data +sizeof(journal_block_tag_t)) <= journal->j_blocksize) { unsigned long io_block; tag = (journal_block_tag_t *) tagp; flags = be32_to_cpu(tag->t_flags); io_block = next_log_block++; wrap(journal, next_log_block); err = jread(&obh, journal, io_block); if (err) { /* Recover what we can, but * report failure at the end. */ success = err; printk (KERN_ERR "JBD: IO error %d recovering " "block %ld in log\n", err, io_block); } else { unsigned long blocknr; J_ASSERT(obh != NULL); blocknr = be32_to_cpu(tag->t_blocknr); /* If the block has been * revoked, then we're all done * here. */ if (journal_test_revoke (journal, blocknr, next_commit_ID)) { brelse(obh); ++info->nr_revoke_hits; goto skip_write; } /* Find a buffer for the new * data being restored */ nbh = __getblk(journal->j_fs_dev, blocknr, journal->j_blocksize); if (nbh == NULL) { printk(KERN_ERR "JBD: Out of memory " "during recovery.\n"); err = -ENOMEM; brelse(bh); brelse(obh); goto failed; } lock_buffer(nbh); memcpy(nbh->b_data, obh->b_data, journal->j_blocksize); if (flags & JFS_FLAG_ESCAPE) { *((__be32 *)bh->b_data) = cpu_to_be32(JFS_MAGIC_NUMBER); } BUFFER_TRACE(nbh, "marking dirty"); set_buffer_uptodate(nbh); mark_buffer_dirty(nbh); BUFFER_TRACE(nbh, "marking uptodate"); ++info->nr_replays; /* ll_rw_block(WRITE, 1, &nbh); */ unlock_buffer(nbh); brelse(obh); brelse(nbh); } skip_write: tagp += sizeof(journal_block_tag_t); if (!(flags & JFS_FLAG_SAME_UUID)) tagp += 16; if (flags & JFS_FLAG_LAST_TAG) break; } brelse(bh); continue; case JFS_COMMIT_BLOCK: /* Found an expected commit block: not much to * do other than move on to the next sequence * number. */ brelse(bh); next_commit_ID++; continue; case JFS_REVOKE_BLOCK: /* If we aren't in the REVOKE pass, then we can * just skip over this block. */ if (pass != PASS_REVOKE) { brelse(bh); continue; } err = scan_revoke_records(journal, bh, next_commit_ID, info); brelse(bh); if (err) goto failed; continue; default: jbd_debug(3, "Unrecognised magic %d, end of scan.\n", blocktype); goto done; } } done: /* * We broke out of the log scan loop: either we came to the * known end of the log or we found an unexpected block in the * log. If the latter happened, then we know that the "current" * transaction marks the end of the valid log. */ if (pass == PASS_SCAN) info->end_transaction = next_commit_ID; else { /* It's really bad news if different passes end up at * different places (but possible due to IO errors). */ if (info->end_transaction != next_commit_ID) { printk (KERN_ERR "JBD: recovery pass %d ended at " "transaction %u, expected %u\n", pass, next_commit_ID, info->end_transaction); if (!success) success = -EIO; } } return success; failed: return err; }
static int do_one_pass(journal_t *journal, struct recovery_info *info, enum passtype pass) { unsigned int first_commit_ID, next_commit_ID; unsigned long long next_log_block; int err, success = 0; journal_superblock_t * sb; journal_header_t * tmp; struct buffer_head * bh; unsigned int sequence; int blocktype; int tag_bytes = journal_tag_bytes(journal); __u32 crc32_sum = ~0; /* Transactional Checksums */ /* Precompute the maximum metadata descriptors in a descriptor block */ int MAX_BLOCKS_PER_DESC; MAX_BLOCKS_PER_DESC = ((journal->j_blocksize-sizeof(journal_header_t)) / tag_bytes); /* * First thing is to establish what we expect to find in the log * (in terms of transaction IDs), and where (in terms of log * block offsets): query the superblock. */ sb = journal->j_superblock; next_commit_ID = be32_to_cpu(sb->s_sequence); next_log_block = be32_to_cpu(sb->s_start); first_commit_ID = next_commit_ID; if (pass == PASS_SCAN) info->start_transaction = first_commit_ID; jbd_debug(1, "Starting recovery pass %d\n", pass); /* * Now we walk through the log, transaction by transaction, * making sure that each transaction has a commit block in the * expected place. Each complete transaction gets replayed back * into the main filesystem. */ while (1) { int flags; char * tagp; journal_block_tag_t * tag; struct buffer_head * obh; struct buffer_head * nbh; cond_resched(); /* If we already know where to stop the log traversal, * check right now that we haven't gone past the end of * the log. */ if (pass != PASS_SCAN) if (tid_geq(next_commit_ID, info->end_transaction)) break; jbd_debug(2, "Scanning for sequence ID %u at %lu/%lu\n", next_commit_ID, next_log_block, journal->j_last); /* Skip over each chunk of the transaction looking * either the next descriptor block or the final commit * record. */ jbd_debug(3, "JBD: checking block %ld\n", next_log_block); err = jread(&bh, journal, next_log_block); if (err) goto failed; next_log_block++; wrap(journal, next_log_block); /* What kind of buffer is it? * * If it is a descriptor block, check that it has the * expected sequence number. Otherwise, we're all done * here. */ tmp = (journal_header_t *)bh->b_data; if (tmp->h_magic != cpu_to_be32(JFS_MAGIC_NUMBER)) { brelse(bh); break; } blocktype = be32_to_cpu(tmp->h_blocktype); sequence = be32_to_cpu(tmp->h_sequence); jbd_debug(3, "Found magic %d, sequence %d\n", blocktype, sequence); if (sequence != next_commit_ID) { brelse(bh); break; } /* OK, we have a valid descriptor block which matches * all of the sequence number checks. What are we going * to do with it? That depends on the pass... */ switch(blocktype) { case JFS_DESCRIPTOR_BLOCK: /* If it is a valid descriptor block, replay it * in pass REPLAY; if journal_checksums enabled, then * calculate checksums in PASS_SCAN, otherwise, * just skip over the blocks it describes. */ if (pass != PASS_REPLAY) { if (pass == PASS_SCAN && JFS_HAS_COMPAT_FEATURE(journal, JFS_FEATURE_COMPAT_CHECKSUM) && !info->end_transaction) { if (calc_chksums(journal, bh, &next_log_block, &crc32_sum)) { brelse(bh); break; } brelse(bh); continue; } next_log_block += count_tags(journal, bh); wrap(journal, next_log_block); brelse(bh); continue; } /* A descriptor block: we can now write all of * the data blocks. Yay, useful work is finally * getting done here! */ tagp = &bh->b_data[sizeof(journal_header_t)]; while ((tagp - bh->b_data + tag_bytes) <= journal->j_blocksize) { unsigned long long io_block; tag = (journal_block_tag_t *) tagp; flags = be32_to_cpu(tag->t_flags); io_block = next_log_block++; wrap(journal, next_log_block); err = jread(&obh, journal, io_block); if (err) { /* Recover what we can, but * report failure at the end. */ success = err; printk (KERN_ERR "JBD: IO error %d recovering " "block %llu in log\n", err, io_block); } else { unsigned long long blocknr; J_ASSERT(obh != NULL); blocknr = read_tag_block(tag_bytes, tag); /* If the block has been * revoked, then we're all done * here. */ if (journal_test_revoke (journal, blocknr, next_commit_ID)) { brelse(obh); ++info->nr_revoke_hits; goto skip_write; } /* Find a buffer for the new * data being restored */ nbh = __getblk(journal->j_fs_dev, blocknr, journal->j_blocksize); if (nbh == NULL) { printk(KERN_ERR "JBD: Out of memory " "during recovery.\n"); err = -ENOMEM; brelse(bh); brelse(obh); goto failed; } lock_buffer(nbh); memcpy(nbh->b_data, obh->b_data, journal->j_blocksize); if (flags & JFS_FLAG_ESCAPE) { journal_header_t *header; header = (journal_header_t *) &nbh->b_data[0]; header->h_magic = cpu_to_be32(JFS_MAGIC_NUMBER); } BUFFER_TRACE(nbh, "marking dirty"); set_buffer_uptodate(nbh); mark_buffer_dirty(nbh); BUFFER_TRACE(nbh, "marking uptodate"); ++info->nr_replays; /* ll_rw_block(WRITE, 1, &nbh); */ unlock_buffer(nbh); brelse(obh); brelse(nbh); } skip_write: tagp += tag_bytes; if (!(flags & JFS_FLAG_SAME_UUID)) tagp += 16; if (flags & JFS_FLAG_LAST_TAG) break; } brelse(bh); continue; case JFS_COMMIT_BLOCK: jbd_debug(3, "Commit block for #%u found\n", next_commit_ID); /* How to differentiate between interrupted commit * and journal corruption ? * * {nth transaction} * Checksum Verification Failed * | * ____________________ * | | * async_commit sync_commit * | | * | GO TO NEXT "Journal Corruption" * | TRANSACTION * | * {(n+1)th transanction} * | * _______|______________ * | | * Commit block found Commit block not found * | | * "Journal Corruption" | * _____________|_________ * | | * nth trans corrupt OR nth trans * and (n+1)th interrupted interrupted * before commit block * could reach the disk. * (Cannot find the difference in above * mentioned conditions. Hence assume * "Interrupted Commit".) */ /* Found an expected commit block: if checksums * are present verify them in PASS_SCAN; else not * much to do other than move on to the next sequence * number. */ if (pass == PASS_SCAN && JFS_HAS_COMPAT_FEATURE(journal, JFS_FEATURE_COMPAT_CHECKSUM)) { int chksum_err, chksum_seen; struct commit_header *cbh = (struct commit_header *)bh->b_data; unsigned found_chksum = be32_to_cpu(cbh->h_chksum[0]); chksum_err = chksum_seen = 0; jbd_debug(3, "Checksums %x %x\n", crc32_sum, found_chksum); if (info->end_transaction) { journal->j_failed_commit = info->end_transaction; brelse(bh); break; } if (crc32_sum == found_chksum && cbh->h_chksum_type == JBD2_CRC32_CHKSUM && cbh->h_chksum_size == JBD2_CRC32_CHKSUM_SIZE) chksum_seen = 1; else if (!(cbh->h_chksum_type == 0 && cbh->h_chksum_size == 0 && found_chksum == 0 && !chksum_seen)) /* * If fs is mounted using an old kernel and then * kernel with journal_chksum is used then we * get a situation where the journal flag has * checksum flag set but checksums are not * present i.e chksum = 0, in the individual * commit blocks. * Hence to avoid checksum failures, in this * situation, this extra check is added. */ chksum_err = 1; if (chksum_err) { info->end_transaction = next_commit_ID; jbd_debug(1, "Checksum_err %x %x\n", crc32_sum, found_chksum); if (!JFS_HAS_INCOMPAT_FEATURE(journal, JFS_FEATURE_INCOMPAT_ASYNC_COMMIT)){ journal->j_failed_commit = next_commit_ID; brelse(bh); break; } } crc32_sum = ~0; } brelse(bh); next_commit_ID++; continue; case JFS_REVOKE_BLOCK: /* If we aren't in the REVOKE pass, then we can * just skip over this block. */ if (pass != PASS_REVOKE) { brelse(bh); continue; } err = scan_revoke_records(journal, bh, next_commit_ID, info); brelse(bh); if (err) goto failed; continue; default: jbd_debug(3, "Unrecognised magic %d, end of scan.\n", blocktype); brelse(bh); goto done; } } done: /* * We broke out of the log scan loop: either we came to the * known end of the log or we found an unexpected block in the * log. If the latter happened, then we know that the "current" * transaction marks the end of the valid log. */ if (pass == PASS_SCAN) { if (!info->end_transaction) info->end_transaction = next_commit_ID; } else { /* It's really bad news if different passes end up at * different places (but possible due to IO errors). */ if (info->end_transaction != next_commit_ID) { printk (KERN_ERR "JBD: recovery pass %d ended at " "transaction %u, expected %u\n", pass, next_commit_ID, info->end_transaction); if (!success) success = -EIO; } } return success; failed: return err; }
static errcode_t walk_journal(ocfs2_filesys *fs, int slot, struct journal_info *ji, char *buf, int recover) { errcode_t err, ret = 0; uint32_t next_seq; uint64_t next_block, nr; journal_superblock_t *jsb = ji->ji_jsb; journal_header_t jh; next_seq = jsb->s_sequence; next_block = jsb->s_start; /* s_start == 0 when we have nothing to do */ if (next_block == 0) return 0; /* ret is set when bad tags are seen in the first scan and when there * are io errors in the recovery scan. Only stop walking the journal * when bad tags are seen in the first scan. */ while(recover || !ret) { verbosef("next_seq %"PRIu32" final_seq %"PRIu32" next_block " "%"PRIu64"\n", next_seq, ji->ji_final_seq, next_block); if (recover && seq_geq(next_seq, ji->ji_final_seq)) break; /* only mark the blocks used on the first pass */ err = read_journal_block(fs, ji, next_block, buf, !recover); if (err) { ret = err; break; } next_block = jwrap(jsb, next_block + 1); memcpy(&jh, buf, sizeof(jh)); jh.h_magic = be32_to_cpu(jh.h_magic); jh.h_blocktype = be32_to_cpu(jh.h_blocktype); jh.h_sequence = be32_to_cpu(jh.h_sequence); verbosef("jh magic %x\n", jh.h_magic); if (jh.h_magic != JBD2_MAGIC_NUMBER) break; verbosef("jh block %x\n", jh.h_blocktype); verbosef("jh seq %"PRIu32"\n", jh.h_sequence); if (jh.h_sequence != next_seq) break; switch(jh.h_blocktype) { case JBD2_DESCRIPTOR_BLOCK: verbosef("found a desc type %x\n", jh.h_blocktype); /* replay the blocks described in the desc block */ if (recover) { err = replay_blocks(fs, ji, buf, next_seq, &next_block); if (err) ret = err; continue; } /* just record the blocks as used and carry on */ err = count_tags(fs, jsb, buf, &nr); if (err) ret = err; else next_block = jwrap(jsb, next_block + nr); break; case JBD2_COMMIT_BLOCK: verbosef("found a commit type %x\n", jh.h_blocktype); next_seq++; break; case JBD2_REVOKE_BLOCK: verbosef("found a revoke type %x\n", jh.h_blocktype); add_revoke_records(ji, buf, jsb->s_blocksize, next_seq); break; default: verbosef("unknown type %x\n", jh.h_blocktype); break; } } verbosef("done scanning with seq %"PRIu32"\n", next_seq); if (!recover) { ji->ji_set_final_seq = 1; ji->ji_final_seq = next_seq; } else if (ji->ji_final_seq != next_seq) { printf("Replaying slot %d's journal stopped at seq %"PRIu32" " "but an initial scan indicated that it should have " "stopped at seq %"PRIu32"\n", ji->ji_slot, next_seq, ji->ji_final_seq); if (ret == 0) err = OCFS2_ET_IO; } return ret; }
errcode_t journal_find_head(journal_t *journal) { unsigned int next_commit_ID; blk64_t next_log_block, head_block; int err; journal_superblock_t *sb; journal_header_t *tmp; struct buffer_head *bh; unsigned int sequence; int blocktype; /* * First thing is to establish what we expect to find in the log * (in terms of transaction IDs), and where (in terms of log * block offsets): query the superblock. */ sb = journal->j_superblock; next_commit_ID = ext2fs_be32_to_cpu(sb->s_sequence); next_log_block = ext2fs_be32_to_cpu(sb->s_start); head_block = next_log_block; if (next_log_block == 0) return 0; bh = getblk(journal->j_dev, 0, journal->j_blocksize); if (bh == NULL) return ENOMEM; /* * Now we walk through the log, transaction by transaction, * making sure that each transaction has a commit block in the * expected place. Each complete transaction gets replayed back * into the main filesystem. */ while (1) { dbg_printf("Scanning for sequence ID %u at %lu/%lu\n", next_commit_ID, (unsigned long)next_log_block, journal->j_last); /* Skip over each chunk of the transaction looking * either the next descriptor block or the final commit * record. */ err = journal_bmap(journal, next_log_block, &bh->b_blocknr); if (err) goto err; mark_buffer_uptodate(bh, 0); ll_rw_block(READ, 1, &bh); err = bh->b_err; if (err) goto err; next_log_block++; wrap(journal, next_log_block); /* What kind of buffer is it? * * If it is a descriptor block, check that it has the * expected sequence number. Otherwise, we're all done * here. */ tmp = (journal_header_t *)bh->b_data; if (tmp->h_magic != ext2fs_cpu_to_be32(JFS_MAGIC_NUMBER)) { dbg_printf("JBD2: wrong magic 0x%x\n", tmp->h_magic); goto err; } blocktype = ext2fs_be32_to_cpu(tmp->h_blocktype); sequence = ext2fs_be32_to_cpu(tmp->h_sequence); dbg_printf("Found magic %d, sequence %d\n", blocktype, sequence); if (sequence != next_commit_ID) { dbg_printf("JBD2: Wrong sequence %d (wanted %d)\n", sequence, next_commit_ID); goto err; } /* OK, we have a valid descriptor block which matches * all of the sequence number checks. What are we going * to do with it? That depends on the pass... */ switch (blocktype) { case JFS_DESCRIPTOR_BLOCK: next_log_block += count_tags(journal, bh->b_data); wrap(journal, next_log_block); continue; case JFS_COMMIT_BLOCK: head_block = next_log_block; next_commit_ID++; continue; case JFS_REVOKE_BLOCK: continue; default: dbg_printf("Unrecognised magic %d, end of scan.\n", blocktype); err = -EINVAL; goto err; } } err: if (err == 0) { dbg_printf("head seq=%d blk=%llu\n", next_commit_ID, head_block); journal->j_transaction_sequence = next_commit_ID; journal->j_head = head_block; } brelse(bh); return err; }
int main(int argc, char **argv) { if (argc < 4) errx(1, "usage\t:%s <bam> <split out> <discord out> (optional #threads)", argv[0]); char *bam_file_name = argv[1]; char *split_file_name = argv[2]; char *disc_file_name = argv[3]; int threads = 2; if (argc == 5) { threads = atoi(argv[4]); } samFile *disc = sam_open(disc_file_name, "wb"); samFile *split = sam_open(split_file_name, "wb"); samFile *in = sam_open(bam_file_name, "rb"); if(in == NULL) errx(1, "Unable to open BAM/SAM file."); // TODO: handle cram. if (threads > 1) { bgzf_mt(in->fp.bgzf, threads, 256); } hts_idx_t *idx = sam_index_load(in, bam_file_name); if(idx == NULL) errx(1,"Unable to open BAM/SAM index."); bam_hdr_t *hdr = sam_hdr_read(in); int r = sam_hdr_write(disc, hdr); r = sam_hdr_write(split, hdr); bam1_t *aln = bam_init1(); int ret; while(ret = sam_read1(in, hdr, aln) >= 0) { if (((aln->core.flag) & 1294) == 0) r = sam_write1(disc, hdr, aln); uint8_t *sa = bam_aux_get(aln, "SA"); if (sa != 0) { char *sa_tag = strdup(bam_aux2Z(sa)); if ( count_tags(sa_tag) == 1) { char *chrm, strand, *cigar; uint32_t pos; split_sa_tag(sa_tag, &chrm, &pos, &strand, &cigar); struct line sa, al; calcOffsets(cigar, pos, strand, &sa); sa.chrm = chrm; sa.strand = strand; calcAlnOffsets(bam_get_cigar(aln), aln->core.n_cigar, aln->core.pos, bam_is_rev(aln) ? '-' : '+', &al); al.chrm = hdr->target_name[aln->core.tid]; al.strand = bam_is_rev(aln) ? '-' : '+'; struct line *left = &al, *right = &sa; if (left->SQO > right->SQO) { left = &sa; right = &al; } int overlap = MAX(1 + MIN(left->EQO, right->EQO) - MAX(left->SQO, right->SQO), 0); int alen1 = 1 + left->EQO - left->SQO; int alen2 = 1 + right->EQO - right->SQO; int mno = MIN(alen1-overlap, alen2-overlap); if (mno < MIN_NON_OVERLAP) continue; if ( (strcmp(left->chrm, right->chrm) == 0) && (left->strand == right->strand) ) { int leftDiag, rightDiag, insSize; if (left->strand == '-') { leftDiag = left->rapos - left->sclip; rightDiag = (right->rapos + right->raLen) - (right->sclip + right->qaLen); insSize = rightDiag - leftDiag; } else { leftDiag = (left->rapos + left->raLen) - (left->sclip + left->qaLen); rightDiag = right->rapos - right->sclip; insSize = leftDiag - rightDiag; } int desert = right->SQO - left->EQO - 1; if ((abs(insSize) < MIN_INDEL_SIZE) || ((desert > 0) && ( (desert - (int)MAX(0, insSize)) > MAX_UNMAPPED_BASES))) continue; } char *qname = bam_get_qname(aln); if ((aln->core.flag & 64) == 64) qname[0] = 'A'; else qname[0] = 'B'; r = sam_write1(split, hdr, aln); } free(sa_tag); } } bam_destroy1(aln); hts_idx_destroy(idx); bam_hdr_destroy(hdr); sam_close(in); sam_close(disc); sam_close(split); if(ret < -1) { errx(1, "lumpy_filter: error reading bam: %s\n", bam_file_name); } }
static int do_one_pass(journal_t *journal, struct recovery_info *info, enum passtype pass) { unsigned int first_commit_ID, next_commit_ID; unsigned long next_log_block; int err, success = 0; journal_superblock_t * sb; journal_header_t * tmp; struct buffer_head * bh; unsigned int sequence; int blocktype; int tag_bytes = journal_tag_bytes(journal); __u32 crc32_sum = ~0; sb = journal->j_superblock; next_commit_ID = be32_to_cpu(sb->s_sequence); next_log_block = be32_to_cpu(sb->s_start); first_commit_ID = next_commit_ID; if (pass == PASS_SCAN) info->start_transaction = first_commit_ID; jbd_debug(1, "Starting recovery pass %d\n", pass); while (1) { int flags; char * tagp; journal_block_tag_t * tag; struct buffer_head * obh; struct buffer_head * nbh; cond_resched(); if (pass != PASS_SCAN) if (tid_geq(next_commit_ID, info->end_transaction)) break; jbd_debug(2, "Scanning for sequence ID %u at %lu/%lu\n", next_commit_ID, next_log_block, journal->j_last); jbd_debug(3, "JBD2: checking block %ld\n", next_log_block); err = jread(&bh, journal, next_log_block); if (err) goto failed; next_log_block++; wrap(journal, next_log_block); tmp = (journal_header_t *)bh->b_data; if (tmp->h_magic != cpu_to_be32(JBD2_MAGIC_NUMBER)) { brelse(bh); break; } blocktype = be32_to_cpu(tmp->h_blocktype); sequence = be32_to_cpu(tmp->h_sequence); jbd_debug(3, "Found magic %d, sequence %d\n", blocktype, sequence); if (sequence != next_commit_ID) { brelse(bh); break; } switch(blocktype) { case JBD2_DESCRIPTOR_BLOCK: if (pass != PASS_REPLAY) { if (pass == PASS_SCAN && JBD2_HAS_COMPAT_FEATURE(journal, JBD2_FEATURE_COMPAT_CHECKSUM) && !info->end_transaction) { if (calc_chksums(journal, bh, &next_log_block, &crc32_sum)) { put_bh(bh); break; } put_bh(bh); continue; } next_log_block += count_tags(journal, bh); wrap(journal, next_log_block); put_bh(bh); continue; } tagp = &bh->b_data[sizeof(journal_header_t)]; while ((tagp - bh->b_data + tag_bytes) <= journal->j_blocksize) { unsigned long io_block; tag = (journal_block_tag_t *) tagp; flags = be32_to_cpu(tag->t_flags); io_block = next_log_block++; wrap(journal, next_log_block); err = jread(&obh, journal, io_block); if (err) { success = err; printk(KERN_ERR "JBD2: IO error %d recovering " "block %ld in log\n", err, io_block); } else { unsigned long long blocknr; J_ASSERT(obh != NULL); blocknr = read_tag_block(tag_bytes, tag); if (jbd2_journal_test_revoke (journal, blocknr, next_commit_ID)) { brelse(obh); ++info->nr_revoke_hits; goto skip_write; } nbh = __getblk(journal->j_fs_dev, blocknr, journal->j_blocksize); if (nbh == NULL) { printk(KERN_ERR "JBD2: Out of memory " "during recovery.\n"); err = -ENOMEM; brelse(bh); brelse(obh); goto failed; } lock_buffer(nbh); memcpy(nbh->b_data, obh->b_data, journal->j_blocksize); if (flags & JBD2_FLAG_ESCAPE) { *((__be32 *)nbh->b_data) = cpu_to_be32(JBD2_MAGIC_NUMBER); } BUFFER_TRACE(nbh, "marking dirty"); set_buffer_uptodate(nbh); mark_buffer_dirty(nbh); BUFFER_TRACE(nbh, "marking uptodate"); ++info->nr_replays; unlock_buffer(nbh); brelse(obh); brelse(nbh); } skip_write: tagp += tag_bytes; if (!(flags & JBD2_FLAG_SAME_UUID)) tagp += 16; if (flags & JBD2_FLAG_LAST_TAG) break; } brelse(bh); continue; case JBD2_COMMIT_BLOCK: if (pass == PASS_SCAN && JBD2_HAS_COMPAT_FEATURE(journal, JBD2_FEATURE_COMPAT_CHECKSUM)) { int chksum_err, chksum_seen; struct commit_header *cbh = (struct commit_header *)bh->b_data; unsigned found_chksum = be32_to_cpu(cbh->h_chksum[0]); chksum_err = chksum_seen = 0; if (info->end_transaction) { journal->j_failed_commit = info->end_transaction; brelse(bh); break; } if (crc32_sum == found_chksum && cbh->h_chksum_type == JBD2_CRC32_CHKSUM && cbh->h_chksum_size == JBD2_CRC32_CHKSUM_SIZE) chksum_seen = 1; else if (!(cbh->h_chksum_type == 0 && cbh->h_chksum_size == 0 && found_chksum == 0 && !chksum_seen)) chksum_err = 1; if (chksum_err) { info->end_transaction = next_commit_ID; if (!JBD2_HAS_INCOMPAT_FEATURE(journal, JBD2_FEATURE_INCOMPAT_ASYNC_COMMIT)){ journal->j_failed_commit = next_commit_ID; brelse(bh); break; } } crc32_sum = ~0; } brelse(bh); next_commit_ID++; continue; case JBD2_REVOKE_BLOCK: if (pass != PASS_REVOKE) { brelse(bh); continue; } err = scan_revoke_records(journal, bh, next_commit_ID, info); brelse(bh); if (err) goto failed; continue; default: jbd_debug(3, "Unrecognised magic %d, end of scan.\n", blocktype); brelse(bh); goto done; } } done: if (pass == PASS_SCAN) { if (!info->end_transaction) info->end_transaction = next_commit_ID; } else { if (info->end_transaction != next_commit_ID) { printk(KERN_ERR "JBD2: recovery pass %d ended at " "transaction %u, expected %u\n", pass, next_commit_ID, info->end_transaction); if (!success) success = -EIO; } } return success; failed: return err; }