static int scan_revoke_records(journal_t *journal, struct buffer_head *bh, tid_t sequence, struct recovery_info *info) { journal_revoke_header_t *header; int offset, max; int record_len = 4; header = (journal_revoke_header_t *) bh->b_data; offset = sizeof(journal_revoke_header_t); max = be32_to_cpu(header->r_count); if (JFS_HAS_INCOMPAT_FEATURE(journal, JFS_FEATURE_INCOMPAT_64BIT)) record_len = 8; while (offset < max) { unsigned long long blocknr; int err; if (record_len == 4) blocknr = ext2fs_be32_to_cpu(*((__be32 *)(bh->b_data + offset))); else blocknr = ext2fs_be64_to_cpu(*((__be64 *)(bh->b_data + offset))); offset += record_len; err = journal_set_revoke(journal, blocknr, sequence); if (err) return err; ++info->nr_revokes; } return 0; }
static int scan_revoke_records(journal_t *journal, struct buffer_head *bh, tid_t sequence, struct recovery_info *info) { journal_revoke_header_t *header; int offset, max; int csum_size = 0; __u32 rcount; int record_len = 4; header = (journal_revoke_header_t *) bh->b_data; offset = sizeof(journal_revoke_header_t); rcount = ext2fs_be32_to_cpu(header->r_count); if (!jbd2_revoke_block_csum_verify(journal, header)) return -EFSBADCRC; if (journal_has_csum_v2or3(journal)) csum_size = sizeof(struct journal_revoke_tail); if (rcount > journal->j_blocksize - csum_size) return -EINVAL; max = rcount; if (jfs_has_feature_64bit(journal)) record_len = 8; while (offset + record_len <= max) { unsigned long long blocknr; int err; if (record_len == 4) blocknr = ext2fs_be32_to_cpu(* ((__u32 *) (bh->b_data+offset))); else blocknr = ext2fs_be64_to_cpu(* ((__u64 *) (bh->b_data+offset))); offset += record_len; err = journal_set_revoke(journal, blocknr, sequence); if (err) return err; ++info->nr_revokes; } return 0; }
int qcow2_write_raw_image(int qcow2_fd, int raw_fd, struct ext2_qcow2_hdr *hdr) { struct ext2_qcow2_image img; errcode_t ret = 0; unsigned int l1_index, l2_index; ext2_off64_t offset; blk64_t *l1_table, *l2_table = 0; void *copy_buf = NULL; size_t size; if (hdr->crypt_method) return -QCOW_ENCRYPTED; img.fd = qcow2_fd; img.hdr = hdr; img.l2_cache = NULL; img.l1_table = NULL; img.cluster_bits = ext2fs_be32_to_cpu(hdr->cluster_bits); img.cluster_size = 1 << img.cluster_bits; img.l1_size = ext2fs_be32_to_cpu(hdr->l1_size); img.l1_offset = ext2fs_be64_to_cpu(hdr->l1_table_offset); img.l2_size = 1 << (img.cluster_bits - 3); img.image_size = ext2fs_be64_to_cpu(hdr->size); ret = ext2fs_get_memzero(img.cluster_size, &l2_table); if (ret) goto out; ret = ext2fs_get_memzero(1 << img.cluster_bits, ©_buf); if (ret) goto out; if (ext2fs_llseek(raw_fd, 0, SEEK_SET) < 0) { ret = errno; goto out; } ret = qcow2_read_l1_table(&img); if (ret) goto out; l1_table = img.l1_table; /* Walk through l1 table */ for (l1_index = 0; l1_index < img.l1_size; l1_index++) { ext2_off64_t off_out; offset = ext2fs_be64_to_cpu(l1_table[l1_index]) & ~QCOW_OFLAG_COPIED; if ((offset > img.image_size) || (offset <= 0)) continue; if (offset & QCOW_OFLAG_COMPRESSED) { ret = -QCOW_COMPRESSED; goto out; } ret = qcow2_read_l2_table(&img, offset, &l2_table); if (ret) break; /* Walk through l2 table and copy data blocks into raw image */ for (l2_index = 0; l2_index < img.l2_size; l2_index++) { offset = ext2fs_be64_to_cpu(l2_table[l2_index]) & ~QCOW_OFLAG_COPIED; if (offset == 0) continue; off_out = (l1_index * img.l2_size) + l2_index; off_out <<= img.cluster_bits; ret = qcow2_copy_data(qcow2_fd, raw_fd, offset, off_out, copy_buf, img.cluster_size); if (ret) goto out; } } /* Resize the output image to the filesystem size */ if (ext2fs_llseek(raw_fd, img.image_size - 1, SEEK_SET) < 0) return errno; ((char *)copy_buf)[0] = 0; size = write(raw_fd, copy_buf, 1); if (size != 1) return errno; out: if (copy_buf) ext2fs_free_mem(©_buf); if (img.l1_table) ext2fs_free_mem(&img.l1_table); if (l2_table) ext2fs_free_mem(&l2_table); return ret; }