/** * read_gpt_pt() * @fd * @all - slice with start/size of whole disk * * 0 if this isn't our partition table * number of partitions if successful * */ int read_gpt_pt (int fd, struct slice all, struct slice *sp, int ns) { gpt_header *gpt = NULL; gpt_entry *ptes = NULL; uint32_t i; int n = 0; int last_used_index=-1; if (!find_valid_gpt (fd, &gpt, &ptes) || !gpt || !ptes) { if (gpt) free (gpt); if (ptes) free (ptes); return 0; } for (i = 0; i < __le32_to_cpu(gpt->num_partition_entries) && i < ns; i++) { if (!efi_guidcmp (NULL_GUID, ptes[i].partition_type_guid)) { sp[n].start = 0; sp[n].size = 0; n++; } else { sp[n].start = __le64_to_cpu(ptes[i].starting_lba); sp[n].size = __le64_to_cpu(ptes[i].ending_lba) - __le64_to_cpu(ptes[i].starting_lba) + 1; last_used_index=n; n++; } } free (ptes); free (gpt); return last_used_index+1; }
inline void sb_le_to_cpu(bitmap_super_t *sb) { sb->magic = __le32_to_cpu(sb->magic); sb->version = __le32_to_cpu(sb->version); /* uuid gets no translation */ sb->events = __le64_to_cpu(sb->events); sb->events_cleared = __le64_to_cpu(sb->events_cleared); sb->state = __le32_to_cpu(sb->state); sb->chunksize = __le32_to_cpu(sb->chunksize); sb->daemon_sleep = __le32_to_cpu(sb->daemon_sleep); sb->sync_size = __le64_to_cpu(sb->sync_size); }
void hfi_flush_egr_bufs(struct _hfi_ctrl *ctrl) { uint64_t head = __le64_to_cpu(*ctrl->__hfi_rcvegrhead); uint64_t tail = __le64_to_cpu(*ctrl->__hfi_rcvegrtail); if ((head % ctrl->__hfi_tidegrcnt) == ((tail + 1) % ctrl->__hfi_tidegrcnt)) { _HFI_DBG ("eager array full after overflow, flushing (head %llx, tail %llx\n", (long long)head, (long long)tail); *ctrl->__hfi_rcvegrhead = __cpu_to_le64(tail); } }
static ssize_t size_show(struct device *dev, struct device_attribute *attr, char *buf) { struct nd_pfn *nd_pfn = to_nd_pfn_safe(dev); ssize_t rc; device_lock(dev); if (dev->driver) { struct nd_pfn_sb *pfn_sb = nd_pfn->pfn_sb; u64 offset = __le64_to_cpu(pfn_sb->dataoff); struct nd_namespace_common *ndns = nd_pfn->ndns; u32 start_pad = __le32_to_cpu(pfn_sb->start_pad); u32 end_trunc = __le32_to_cpu(pfn_sb->end_trunc); struct nd_namespace_io *nsio = to_nd_namespace_io(&ndns->dev); rc = sprintf(buf, "%llu\n", (unsigned long long) resource_size(&nsio->res) - start_pad - end_trunc - offset); } else { /* no size to convey if the pfn instance is disabled */ rc = -ENXIO; } device_unlock(dev); return rc; }
static uint64_t getUnalignedLE64(const __le64 *src) { __le64 b; memcpy(&b, src, sizeof b); return __le64_to_cpu(b); }
uint64_t fw_cfg_read_i64(uint16_t cmd) { uint64_t buf; fw_cfg_read(cmd, (char *)&buf, sizeof(uint64_t)); return __le64_to_cpu(buf); }
static int read_firmware(unsigned char* data, off_t size, struct firmware** f_res) { char *name = malloc(33); unsigned char *p = data; struct firmware* f = alloc_firmware(); unsigned int i; if(size < HEADER_LENGTH) { printf("Invalid firmware header length.\n"); free_firmware(f); return -1; } name[32] = 0; memcpy(name, data, 32); f->name = name; p += 32; f->version = __le16_to_cpu(*(__u16*)p); p += sizeof(f->version); f->nr_desc = __le16_to_cpu(*(__u16*)p); p += sizeof(f->nr_desc); f->desc = malloc(f->nr_desc * sizeof(*(f->desc))); for(i = 0; i < f->nr_desc; ++i) { if(p + DESC_HEADER_LENGTH > data + size) { printf("Invalid description header length.\n"); free_firmware(f); return -1; } f->desc[i].type = __le32_to_cpu(*(__u32*) p); p += sizeof(f->desc[i].type); f->desc[i].id = __le64_to_cpu(*(__u64*) p); p += sizeof(f->desc[i].id); if (f->desc[i].type & HAS_IF) { f->desc[i].int_freq = __le16_to_cpu(*(__u16 *) p); p += sizeof(f->desc[i].int_freq); } f->desc[i].size = __le32_to_cpu(*(__u32*) p); p += sizeof(f->desc[i].size); if(p + f->desc[i].size > data + size) { printf("Invalid firmware standard length.\n"); f->nr_desc = (f->nr_desc == 0) ? 0 : f->nr_desc -1; free_firmware(f); return -1; } f->desc[i].data = malloc(f->desc[i].size); memcpy(f->desc[i].data, p, f->desc[i].size); p += f->desc[i].size; } *f_res = f; return 0; }
static int jfs_image(const void *buf, unsigned long long *bytes) { const struct jfs_superblock *sb = (const struct jfs_superblock *)buf; if (!memcmp(sb->s_magic, JFS_MAGIC, 4)) { *bytes = __le64_to_cpu(sb->s_size) << __le16_to_cpu(sb->s_l2pbsize); return 1; } return 0; }
static bool getSparseExtentHeader(SparseExtentHeader *dst, const SparseExtentHeaderOnDisk *src) { if (src->magicNumber != __cpu_to_le32(SPARSE_MAGICNUMBER)) { return false; } dst->version = __le32_to_cpu(src->version); if (dst->version > SPARSE_VERSION_INCOMPAT_FLAGS) { return false; } dst->flags = __le32_to_cpu(src->flags); if (dst->flags & (SPARSEFLAG_INCOMPAT_FLAGS & ~SPARSEFLAG_COMPRESSED & ~SPARSEFLAG_EMBEDDED_LBA)) { return false; } if (dst->flags & SPARSEFLAG_VALID_NEWLINE_DETECTOR) { if (src->singleEndLineChar != SPARSE_SINGLE_END_LINE_CHAR || src->nonEndLineChar != SPARSE_NON_END_LINE_CHAR || src->doubleEndLineChar1 != SPARSE_DOUBLE_END_LINE_CHAR1 || src->doubleEndLineChar2 != SPARSE_DOUBLE_END_LINE_CHAR2) { return false; } } /* Embedded LBA is allowed with compressed flag only. */ if (dst->flags & SPARSEFLAG_EMBEDDED_LBA) { if (!(dst->flags & SPARSEFLAG_COMPRESSED)) { return false; } } dst->compressAlgorithm = getUnalignedLE16(&src->compressAlgorithm); dst->uncleanShutdown = src->uncleanShutdown; dst->reserved = 0; dst->capacity = getUnalignedLE64(&src->capacity); dst->grainSize = getUnalignedLE64(&src->grainSize); dst->descriptorOffset = getUnalignedLE64(&src->descriptorOffset); dst->descriptorSize = getUnalignedLE64(&src->descriptorSize); dst->numGTEsPerGT = __le32_to_cpu(src->numGTEsPerGT); dst->rgdOffset = __le64_to_cpu(src->rgdOffset); dst->gdOffset = __le64_to_cpu(src->gdOffset); dst->overHead = __le64_to_cpu(src->overHead); return true; }
static int btrfs_image(const void *buf, unsigned long long *bytes) { const struct btrfs_super_block *sb = (const struct btrfs_super_block *)buf; if (!memcmp(sb->magic, BTRFS_MAGIC, BTRFS_MAGIC_L)) { *bytes = (unsigned long long)__le64_to_cpu(sb->total_bytes); return 1; } return 0; }
static int nilfs2_image(const void *buf, unsigned long long *bytes) { const struct nilfs_super_block *sb = (const struct nilfs_super_block *)buf; if (sb->s_magic == __cpu_to_le16(NILFS_SUPER_MAGIC) && sb->s_rev_level == __cpu_to_le32(2)) { *bytes = (unsigned long long)__le64_to_cpu(sb->s_dev_size); return 1; } return 0; }
gpt_disk_get_partition_info(int fd, uint32_t num, uint64_t * start, uint64_t * size, uint8_t *signature, uint8_t * mbr_type, uint8_t * signature_type, int ignore_pmbr_error) { gpt_header *gpt = NULL; gpt_entry *ptes = NULL, *p; int rc = 0; char *report=getenv("LIBEFIBOOT_REPORT_GPT_ERRORS"); if (report) report_errors = 1; rc = find_valid_gpt(fd, &gpt, &ptes, ignore_pmbr_error); if (rc < 0) return rc; *mbr_type = 0x02; *signature_type = 0x02; if (num > 0 && num <= __le32_to_cpu(gpt->num_partition_entries)) { p = &ptes[num - 1]; *start = __le64_to_cpu(p->starting_lba); *size = __le64_to_cpu(p->ending_lba) - __le64_to_cpu(p->starting_lba) + 1; memcpy(signature, &p->unique_partition_guid, sizeof (p->unique_partition_guid)); } else { if (report_errors) fprintf(stderr, "partition %d is not valid\n", num); errno = EINVAL; return -1; } if (ptes) free(ptes); if (gpt) free(gpt); return rc; }
/** * alloc_read_gpt_entries(): reads partition entries from disk * @fd is an open file descriptor to the whole disk * @gpt is a buffer into which the GPT will be put * Description: Returns ptes on success, NULL on error. * Allocates space for PTEs based on information found in @gpt. * Notes: remember to free pte when you're done! */ static gpt_entry * alloc_read_gpt_entries(int fd, gpt_header * gpt) { gpt_entry *pte; size_t count = __le32_to_cpu(gpt->num_partition_entries) * __le32_to_cpu(gpt->sizeof_partition_entry); if (!count) return NULL; pte = (gpt_entry *)malloc(count); if (!pte) return NULL; memset(pte, 0, count); if (!read_lba(fd, __le64_to_cpu(gpt->partition_entry_lba), pte, count)) { free(pte); return NULL; } return pte; }
/* * Beginning of Taskfile OPCODE Library and feature sets. */ void ide_fix_driveid (struct hd_driveid *id) { #ifndef __LITTLE_ENDIAN # ifdef __BIG_ENDIAN int i; u16 *stringcast; #ifdef __mc68000__ if (!MACH_IS_AMIGA && !MACH_IS_MAC && !MACH_IS_Q40 && !MACH_IS_ATARI) return; #ifdef M68K_IDE_SWAPW if (M68K_IDE_SWAPW) { /* fix bus byteorder first */ u_char *p = (u_char *)id; u_char t; for (i = 0; i < 512; i += 2) { t = p[i]; p[i] = p[i+1]; p[i+1] = t; } } #endif #endif /* __mc68000__ */ id->config = __le16_to_cpu(id->config); id->cyls = __le16_to_cpu(id->cyls); id->reserved2 = __le16_to_cpu(id->reserved2); id->heads = __le16_to_cpu(id->heads); id->track_bytes = __le16_to_cpu(id->track_bytes); id->sector_bytes = __le16_to_cpu(id->sector_bytes); id->sectors = __le16_to_cpu(id->sectors); id->vendor0 = __le16_to_cpu(id->vendor0); id->vendor1 = __le16_to_cpu(id->vendor1); id->vendor2 = __le16_to_cpu(id->vendor2); stringcast = (u16 *)&id->serial_no[0]; for (i = 0; i < (20/2); i++) stringcast[i] = __le16_to_cpu(stringcast[i]); id->buf_type = __le16_to_cpu(id->buf_type); id->buf_size = __le16_to_cpu(id->buf_size); id->ecc_bytes = __le16_to_cpu(id->ecc_bytes); stringcast = (u16 *)&id->fw_rev[0]; for (i = 0; i < (8/2); i++) stringcast[i] = __le16_to_cpu(stringcast[i]); stringcast = (u16 *)&id->model[0]; for (i = 0; i < (40/2); i++) stringcast[i] = __le16_to_cpu(stringcast[i]); id->dword_io = __le16_to_cpu(id->dword_io); id->reserved50 = __le16_to_cpu(id->reserved50); id->field_valid = __le16_to_cpu(id->field_valid); id->cur_cyls = __le16_to_cpu(id->cur_cyls); id->cur_heads = __le16_to_cpu(id->cur_heads); id->cur_sectors = __le16_to_cpu(id->cur_sectors); id->cur_capacity0 = __le16_to_cpu(id->cur_capacity0); id->cur_capacity1 = __le16_to_cpu(id->cur_capacity1); id->lba_capacity = __le32_to_cpu(id->lba_capacity); id->dma_1word = __le16_to_cpu(id->dma_1word); id->dma_mword = __le16_to_cpu(id->dma_mword); id->eide_pio_modes = __le16_to_cpu(id->eide_pio_modes); id->eide_dma_min = __le16_to_cpu(id->eide_dma_min); id->eide_dma_time = __le16_to_cpu(id->eide_dma_time); id->eide_pio = __le16_to_cpu(id->eide_pio); id->eide_pio_iordy = __le16_to_cpu(id->eide_pio_iordy); for (i = 0; i < 2; ++i) id->words69_70[i] = __le16_to_cpu(id->words69_70[i]); for (i = 0; i < 4; ++i) id->words71_74[i] = __le16_to_cpu(id->words71_74[i]); id->queue_depth = __le16_to_cpu(id->queue_depth); for (i = 0; i < 4; ++i) id->words76_79[i] = __le16_to_cpu(id->words76_79[i]); id->major_rev_num = __le16_to_cpu(id->major_rev_num); id->minor_rev_num = __le16_to_cpu(id->minor_rev_num); id->command_set_1 = __le16_to_cpu(id->command_set_1); id->command_set_2 = __le16_to_cpu(id->command_set_2); id->cfsse = __le16_to_cpu(id->cfsse); id->cfs_enable_1 = __le16_to_cpu(id->cfs_enable_1); id->cfs_enable_2 = __le16_to_cpu(id->cfs_enable_2); id->csf_default = __le16_to_cpu(id->csf_default); id->dma_ultra = __le16_to_cpu(id->dma_ultra); id->trseuc = __le16_to_cpu(id->trseuc); id->trsEuc = __le16_to_cpu(id->trsEuc); id->CurAPMvalues = __le16_to_cpu(id->CurAPMvalues); id->mprc = __le16_to_cpu(id->mprc); id->hw_config = __le16_to_cpu(id->hw_config); id->acoustic = __le16_to_cpu(id->acoustic); id->msrqs = __le16_to_cpu(id->msrqs); id->sxfert = __le16_to_cpu(id->sxfert); id->sal = __le16_to_cpu(id->sal); id->spg = __le32_to_cpu(id->spg); id->lba_capacity_2 = __le64_to_cpu(id->lba_capacity_2); for (i = 0; i < 22; i++) id->words104_125[i] = __le16_to_cpu(id->words104_125[i]); id->last_lun = __le16_to_cpu(id->last_lun); id->word127 = __le16_to_cpu(id->word127); id->dlf = __le16_to_cpu(id->dlf); id->csfo = __le16_to_cpu(id->csfo); for (i = 0; i < 26; i++) id->words130_155[i] = __le16_to_cpu(id->words130_155[i]); id->word156 = __le16_to_cpu(id->word156); for (i = 0; i < 3; i++) id->words157_159[i] = __le16_to_cpu(id->words157_159[i]); id->cfa_power = __le16_to_cpu(id->cfa_power); for (i = 0; i < 14; i++) id->words161_175[i] = __le16_to_cpu(id->words161_175[i]); for (i = 0; i < 31; i++) id->words176_205[i] = __le16_to_cpu(id->words176_205[i]); for (i = 0; i < 48; i++) id->words206_254[i] = __le16_to_cpu(id->words206_254[i]); id->integrity_word = __le16_to_cpu(id->integrity_word); # else # error "Please fix <asm/byteorder.h>" # endif #endif }
int main(int argc, char *const argv[]) { char tmpdir[] = "/tmp/dirXXXXXX"; char cmd[128]; char filepnm[128] = ""; char *dev; struct lr_server_data lsd; FILE *filep = NULL; int ret; int c; int opt_client = 0; int opt_reply = 0; progname = argv[0]; while ((c = getopt_long(argc, argv, "chr", longopts, NULL)) != -1) { switch (c) { case 'c': opt_client = 1; break; case 'r': opt_reply = 1; break; case 'h': default: display_usage(); return -1; } } dev = argv[optind]; if (!dev) { display_usage(); return -1; } /* Make a temporary directory to hold Lustre data files. */ if (!mkdtemp(tmpdir)) { fprintf(stderr, "%s: Can't create temporary directory %s: %s\n", progname, tmpdir, strerror(errno)); return errno; } memset(cmd, 0, sizeof(cmd)); snprintf(cmd, sizeof(cmd), "%s -c -R 'dump /%s %s/%s' %s", DEBUGFS, LAST_RCVD, tmpdir, LAST_RCVD, dev); ret = run_command(cmd, sizeof(cmd)); if (ret) { fprintf(stderr, "%s: Unable to dump %s file\n", progname, LAST_RCVD); goto out_rmdir; } snprintf(filepnm, 128, "%s/%s", tmpdir, LAST_RCVD); filep = fopen(filepnm, "r"); if (!filep) { fprintf(stderr, "%s: Unable to read old data\n", progname); ret = -errno; goto out_rmdir; } unlink(filepnm); /* read lr_server_data structure */ printf("%s:\n", LAST_RCVD); ret = fread(&lsd, 1, sizeof(lsd), filep); if (ret < sizeof(lsd)) { fprintf(stderr, "%s: Short read (%d of %d)\n", progname, ret, (int)sizeof(lsd)); ret = -ferror(filep); if (ret) goto out_close; } /* swab structure fields of interest */ lsd.lsd_feature_compat = __le32_to_cpu(lsd.lsd_feature_compat); lsd.lsd_feature_incompat = __le32_to_cpu(lsd.lsd_feature_incompat); lsd.lsd_feature_rocompat = __le32_to_cpu(lsd.lsd_feature_rocompat); lsd.lsd_last_transno = __le64_to_cpu(lsd.lsd_last_transno); lsd.lsd_osd_index = __le32_to_cpu(lsd.lsd_osd_index); lsd.lsd_mount_count = __le64_to_cpu(lsd.lsd_mount_count); /* display */ printf(" uuid: %.40s\n", lsd.lsd_uuid); printf(" feature_compat: %#x\n", lsd.lsd_feature_compat); printf(" feature_incompat: %#x\n", lsd.lsd_feature_incompat); printf(" feature_rocompat: %#x\n", lsd.lsd_feature_rocompat); printf(" last_transaction: %llu\n", lsd.lsd_last_transno); printf(" target_index: %u\n", lsd.lsd_osd_index); printf(" mount_count: %llu\n", lsd.lsd_mount_count); /* read client information */ if (opt_client) { lsd.lsd_client_start = __le32_to_cpu(lsd.lsd_client_start); lsd.lsd_client_size = __le16_to_cpu(lsd.lsd_client_size); printf(" client_area_start: %u\n", lsd.lsd_client_start); printf(" client_area_size: %hu\n", lsd.lsd_client_size); /* seek to per-client data area */ ret = fseek(filep, lsd.lsd_client_start, SEEK_SET); if (ret) { fprintf(stderr, "%s: seek failed. %s\n", progname, strerror(errno)); ret = errno; goto out_close; } /* walk throuh the per-client data area */ while (true) { struct lsd_client_data lcd; /* read a per-client data area */ ret = fread(&lcd, 1, sizeof(lcd), filep); if (ret < sizeof(lcd)) { if (feof(filep)) break; fprintf(stderr, "%s: Short read (%d of %d)\n", progname, ret, (int)sizeof(lcd)); ret = -ferror(filep); goto out_close; } if (lcd.lcd_uuid[0] == '\0') continue; /* swab structure fields */ lcd.lcd_last_transno = __le64_to_cpu(lcd.lcd_last_transno); lcd.lcd_last_xid = __le64_to_cpu(lcd.lcd_last_xid); lcd.lcd_last_result = __le32_to_cpu(lcd.lcd_last_result); lcd.lcd_last_data = __le32_to_cpu(lcd.lcd_last_data); lcd.lcd_generation = __le32_to_cpu(lcd.lcd_generation); /* display per-client data area */ printf("\n %.40s:\n", lcd.lcd_uuid); printf(" generation: %u\n", lcd.lcd_generation); printf(" last_transaction: %llu\n", lcd.lcd_last_transno); printf(" last_xid: %llu\n", lcd.lcd_last_xid); printf(" last_result: %u\n", lcd.lcd_last_result); printf(" last_data: %u\n", lcd.lcd_last_data); if (lcd.lcd_last_close_transno != 0 && lcd.lcd_last_close_xid != 0) { lcd.lcd_last_close_transno = __le64_to_cpu(lcd.lcd_last_close_transno); lcd.lcd_last_close_xid = __le64_to_cpu(lcd.lcd_last_close_xid); lcd.lcd_last_close_result = __le32_to_cpu(lcd.lcd_last_close_result); lcd.lcd_last_close_data = __le32_to_cpu(lcd.lcd_last_close_data); printf(" last_close_transation: %llu\n", lcd.lcd_last_close_transno); printf(" last_close_xid: %llu\n", lcd.lcd_last_close_xid); printf(" last_close_result: %u\n", lcd.lcd_last_close_result); printf(" last_close_data: %u\n", lcd.lcd_last_close_data); } } } fclose(filep); filep = NULL; /* read reply data information */ if (opt_reply) { struct lsd_reply_header lrh; struct lsd_reply_data lrd; unsigned long long slot; snprintf(cmd, sizeof(cmd), "%s -c -R 'dump /%s %s/%s' %s", DEBUGFS, REPLY_DATA, tmpdir, REPLY_DATA, dev); ret = run_command(cmd, sizeof(cmd)); if (ret) { fprintf(stderr, "%s: Unable to dump %s file\n", progname, REPLY_DATA); goto out_rmdir; } snprintf(filepnm, sizeof(filepnm), "%s/%s", tmpdir, REPLY_DATA); filep = fopen(filepnm, "r"); if (!filep) { fprintf(stderr, "%s: Unable to read reply data\n", progname); ret = -errno; goto out_rmdir; } unlink(filepnm); /* read reply_data header */ printf("\n%s:\n", REPLY_DATA); ret = fread(&lrh, 1, sizeof(lrh), filep); if (ret < sizeof(lrh)) { fprintf(stderr, "%s: Short read (%d of %d)\n", progname, ret, (int)sizeof(lrh)); ret = -ferror(filep); if (ret) goto out_close; } /* check header */ lrh.lrh_magic = __le32_to_cpu(lrh.lrh_magic); lrh.lrh_header_size = __le32_to_cpu(lrh.lrh_header_size); lrh.lrh_reply_size = __le32_to_cpu(lrh.lrh_reply_size); if (lrh.lrh_magic != LRH_MAGIC) { fprintf(stderr, "%s: invalid %s header: " "lrh_magic=%08x expected %08x\n", progname, REPLY_DATA, lrh.lrh_magic, LRH_MAGIC); goto out_close; } if (lrh.lrh_header_size != sizeof(struct lsd_reply_header)) { fprintf(stderr, "%s: invalid %s header: " "lrh_header_size=%08x expected %08x\n", progname, REPLY_DATA, lrh.lrh_header_size, (unsigned int)sizeof(struct lsd_reply_header)); goto out_close; } if (lrh.lrh_reply_size != sizeof(struct lsd_reply_data)) { fprintf(stderr, "%s: invalid %s header: " "lrh_reply_size=%08x expected %08x\n", progname, REPLY_DATA, lrh.lrh_reply_size, (unsigned int)sizeof(struct lsd_reply_data)); goto out_close; } /* walk throuh the reply data */ for (slot = 0; ; slot++) { /* read a reply data */ ret = fread(&lrd, 1, sizeof(lrd), filep); if (ret < sizeof(lrd)) { if (feof(filep)) break; fprintf(stderr, "%s: Short read (%d of %d)\n", progname, ret, (int)sizeof(lrd)); ret = -ferror(filep); goto out_close; } /* display reply data */ lrd.lrd_transno = __le64_to_cpu(lrd.lrd_transno); lrd.lrd_xid = __le64_to_cpu(lrd.lrd_xid); lrd.lrd_data = __le64_to_cpu(lrd.lrd_data); lrd.lrd_result = __le32_to_cpu(lrd.lrd_result); lrd.lrd_client_gen = __le32_to_cpu(lrd.lrd_client_gen); printf(" %lld:\n", slot); printf(" client_generation: %u\n", lrd.lrd_client_gen); printf(" last_transaction: %llu\n", lrd.lrd_transno); printf(" last_xid: %llu\n", lrd.lrd_xid); printf(" last_result: %u\n", lrd.lrd_result); printf(" last_data: %llu\n\n", lrd.lrd_data); } } out_close: if (filep != NULL) fclose(filep); out_rmdir: rmdir(tmpdir); return ret; }
static int nova_readdir(struct file *file, struct dir_context *ctx) { struct inode *inode = file_inode(file); struct super_block *sb = inode->i_sb; struct nova_inode *pidir; struct nova_inode_info *si = NOVA_I(inode); struct nova_inode_info_header *sih = &si->header; struct nova_inode *child_pi; struct nova_inode *prev_child_pi = NULL; struct nova_dentry *entry = NULL; struct nova_dentry *prev_entry = NULL; unsigned short de_len; u64 pi_addr; unsigned long pos = 0; ino_t ino; void *addr; u64 curr_p; u8 type; int ret; timing_t readdir_time; NOVA_START_TIMING(readdir_t, readdir_time); pidir = nova_get_inode(sb, inode); nova_dbgv("%s: ino %llu, size %llu, pos 0x%llx\n", __func__, (u64)inode->i_ino, pidir->i_size, ctx->pos); if (pidir->log_head == 0) { nova_err(sb, "Dir %lu log is NULL!\n", inode->i_ino); BUG(); return -EINVAL; } pos = ctx->pos; if (pos == 0) { curr_p = pidir->log_head; } else if (pos == READDIR_END) { goto out; } else { curr_p = nova_find_next_dentry_addr(sb, sih, pos); if (curr_p == 0) goto out; } while (curr_p != pidir->log_tail) { if (goto_next_page(sb, curr_p)) { curr_p = next_log_page(sb, curr_p); } if (curr_p == 0) { nova_err(sb, "Dir %lu log is NULL!\n", inode->i_ino); BUG(); return -EINVAL; } addr = (void *)nova_get_block(sb, curr_p); type = nova_get_entry_type(addr); switch (type) { case SET_ATTR: curr_p += sizeof(struct nova_setattr_logentry); continue; case LINK_CHANGE: curr_p += sizeof(struct nova_link_change_entry); continue; case DIR_LOG: break; default: nova_dbg("%s: unknown type %d, 0x%llx\n", __func__, type, curr_p); BUG(); return -EINVAL; } entry = (struct nova_dentry *)nova_get_block(sb, curr_p); nova_dbgv("curr_p: 0x%llx, type %d, ino %llu, " "name %s, namelen %u, rec len %u\n", curr_p, entry->entry_type, le64_to_cpu(entry->ino), entry->name, entry->name_len, le16_to_cpu(entry->de_len)); de_len = le16_to_cpu(entry->de_len); if (entry->ino > 0 && entry->invalid == 0) { ino = __le64_to_cpu(entry->ino); pos = BKDRHash(entry->name, entry->name_len); ret = nova_get_inode_address(sb, ino, &pi_addr, 0); if (ret) { nova_dbg("%s: get child inode %lu address " "failed %d\n", __func__, ino, ret); ctx->pos = READDIR_END; return ret; } child_pi = nova_get_block(sb, pi_addr); nova_dbgv("ctx: ino %llu, name %s, " "name_len %u, de_len %u\n", (u64)ino, entry->name, entry->name_len, entry->de_len); if (prev_entry && !dir_emit(ctx, prev_entry->name, prev_entry->name_len, ino, IF2DT(le16_to_cpu(prev_child_pi->i_mode)))) { nova_dbgv("Here: pos %llu\n", ctx->pos); return 0; } prev_entry = entry; prev_child_pi = child_pi; } ctx->pos = pos; curr_p += de_len; } if (prev_entry && !dir_emit(ctx, prev_entry->name, prev_entry->name_len, ino, IF2DT(le16_to_cpu(prev_child_pi->i_mode)))) return 0; ctx->pos = READDIR_END; out: NOVA_END_TIMING(readdir_t, readdir_time); nova_dbgv("%s return\n", __func__); return 0; }
/** * find_valid_gpt() - Search disk for valid GPT headers and PTEs * @fd is an open file descriptor to the whole disk * @gpt is a GPT header ptr, filled on return. * @ptes is a PTEs ptr, filled on return. * Description: Returns 1 if valid, 0 on error. * If valid, returns pointers to newly allocated GPT header and PTEs. * Validity depends on finding either the Primary GPT header and PTEs valid, * or the Alternate GPT header and PTEs valid, and the PMBR valid. */ static int find_valid_gpt(int fd, gpt_header ** gpt, gpt_entry ** ptes, int ignore_pmbr_err) { int good_pgpt = 0, good_agpt = 0, good_pmbr = 0; gpt_header *pgpt = NULL, *agpt = NULL; gpt_entry *pptes = NULL, *aptes = NULL; legacy_mbr *legacymbr = NULL; uint64_t lastlba; int ret = -1; errno = EINVAL; if (!gpt || !ptes) return -1; lastlba = last_lba(fd); good_pgpt = is_gpt_valid(fd, GPT_PRIMARY_PARTITION_TABLE_LBA, &pgpt, &pptes); if (good_pgpt) { good_agpt = is_gpt_valid(fd, __le64_to_cpu(pgpt->alternate_lba), &agpt, &aptes); if (!good_agpt) { good_agpt = is_gpt_valid(fd, lastlba, &agpt, &aptes); } } else { good_agpt = is_gpt_valid(fd, lastlba, &agpt, &aptes); } /* The obviously unsuccessful case */ if (!good_pgpt && !good_agpt) { goto fail; } /* This will be added to the EFI Spec. per Intel after v1.02. */ legacymbr = malloc(sizeof (*legacymbr)); if (legacymbr) { memset(legacymbr, 0, sizeof (*legacymbr)); read_lba(fd, 0, (uint8_t *) legacymbr, sizeof (*legacymbr)); good_pmbr = is_pmbr_valid(legacymbr); free(legacymbr); legacymbr=NULL; } /* Failure due to bad PMBR */ if ((good_pgpt || good_agpt) && !good_pmbr && !ignore_pmbr_err) { if (report_errors) fprintf(stderr, "Primary GPT is invalid, using alternate GPT.\n"); goto fail; } /* Would fail due to bad PMBR, but force GPT anyhow */ if ((good_pgpt || good_agpt) && !good_pmbr && ignore_pmbr_err && report_errors) { fprintf(stderr, " Warning: Disk has a valid GPT signature but invalid PMBR.\n" " Use GNU Parted to correct disk.\n" " gpt option taken, disk treated as GPT.\n"); } compare_gpts(pgpt, agpt, lastlba); /* The good cases */ if (good_pgpt && (good_pmbr || ignore_pmbr_err)) { *gpt = pgpt; *ptes = pptes; } else if (good_agpt && (good_pmbr || ignore_pmbr_err)) { *gpt = agpt; *ptes = aptes; } ret = 0; errno = 0; fail: if (pgpt && (pgpt != *gpt || ret < 0)) { free(pgpt); pgpt=NULL; } if (pptes && (pptes != *ptes || ret < 0)) { free(pptes); pptes=NULL; } if (agpt && (agpt != *gpt || ret < 0)) { free(agpt); agpt=NULL; } if (aptes && (aptes != *ptes || ret < 0)) { free(aptes); aptes=NULL; } if (ret < 0) { *gpt = NULL; *ptes = NULL; } return ret; }
uint64_t xle64dec(const uint8_t *d) { return __le64_to_cpu(*(uint64_t*)d); }
/** * find_valid_gpt() - Search disk for valid GPT headers and PTEs * @fd is an open file descriptor to the whole disk * @gpt is a GPT header ptr, filled on return. * @ptes is a PTEs ptr, filled on return. * Description: Returns 1 if valid, 0 on error. * If valid, returns pointers to newly allocated GPT header and PTEs. * Validity depends on finding either the Primary GPT header and PTEs valid, * or the Alternate GPT header and PTEs valid, and the PMBR valid. */ static int find_valid_gpt(int fd, gpt_header ** gpt, gpt_entry ** ptes) { extern int force_gpt; int good_pgpt = 0, good_agpt = 0, good_pmbr = 0; gpt_header *pgpt = NULL, *agpt = NULL; gpt_entry *pptes = NULL, *aptes = NULL; legacy_mbr *legacymbr = NULL; uint64_t lastlba; if (!gpt || !ptes) return 0; lastlba = last_lba(fd); good_pgpt = is_gpt_valid(fd, GPT_PRIMARY_PARTITION_TABLE_LBA, &pgpt, &pptes); if (good_pgpt) { good_agpt = is_gpt_valid(fd, __le64_to_cpu(pgpt->alternate_lba), &agpt, &aptes); if (!good_agpt) { good_agpt = is_gpt_valid(fd, lastlba, &agpt, &aptes); } } else { good_agpt = is_gpt_valid(fd, lastlba, &agpt, &aptes); } /* The obviously unsuccessful case */ if (!good_pgpt && !good_agpt) { goto fail; } /* This will be added to the EFI Spec. per Intel after v1.02. */ legacymbr = malloc(sizeof (*legacymbr)); if (legacymbr) { memset(legacymbr, 0, sizeof (*legacymbr)); read_lba(fd, 0, (uint8_t *) legacymbr, sizeof (*legacymbr)); good_pmbr = is_pmbr_valid(legacymbr); free(legacymbr); legacymbr=NULL; } /* Failure due to bad PMBR */ if ((good_pgpt || good_agpt) && !good_pmbr && !force_gpt) { fprintf(stderr, " Warning: Disk has a valid GPT signature " "but invalid PMBR.\n" " Assuming this disk is *not* a GPT disk anymore.\n" " Use gpt kernel option to override. " "Use GNU Parted to correct disk.\n"); goto fail; } /* Would fail due to bad PMBR, but force GPT anyhow */ if ((good_pgpt || good_agpt) && !good_pmbr && force_gpt) { fprintf(stderr, " Warning: Disk has a valid GPT signature but " "invalid PMBR.\n" " Use GNU Parted to correct disk.\n" " gpt option taken, disk treated as GPT.\n"); } compare_gpts(pgpt, agpt, lastlba); /* The good cases */ if (good_pgpt && (good_pmbr || force_gpt)) { *gpt = pgpt; *ptes = pptes; if (agpt) { free(agpt); agpt = NULL; } if (aptes) { free(aptes); aptes = NULL; } if (!good_agpt) { fprintf(stderr, "Alternate GPT is invalid, " "using primary GPT.\n"); } return 1; } else if (good_agpt && (good_pmbr || force_gpt)) { *gpt = agpt; *ptes = aptes; if (pgpt) { free(pgpt); pgpt = NULL; } if (pptes) { free(pptes); pptes = NULL; } fprintf(stderr, "Primary GPT is invalid, using alternate GPT.\n"); return 1; } fail: if (pgpt) { free(pgpt); pgpt=NULL; } if (agpt) { free(agpt); agpt=NULL; } if (pptes) { free(pptes); pptes=NULL; } if (aptes) { free(aptes); aptes=NULL; } *gpt = NULL; *ptes = NULL; return 0; }
/** * compare_gpts() - Search disk for valid GPT headers and PTEs * @pgpt is the primary GPT header * @agpt is the alternate GPT header * @lastlba is the last LBA number * Description: Returns nothing. Sanity checks pgpt and agpt fields * and prints warnings on discrepancies. * */ static void compare_gpts(gpt_header *pgpt, gpt_header *agpt, uint64_t lastlba) { int error_found = 0; if (!pgpt || !agpt) return; if (__le64_to_cpu(pgpt->my_lba) != __le64_to_cpu(agpt->alternate_lba)) { fprintf(stderr, "GPT:Primary header LBA != Alt. header alternate_lba\n"); fprintf(stderr, "GPT:%" PRIx64 "x != %" PRIx64 "x\n", __le64_to_cpu(pgpt->my_lba), __le64_to_cpu(agpt->alternate_lba)); error_found++; } if (__le64_to_cpu(pgpt->alternate_lba) != __le64_to_cpu(agpt->my_lba)) { fprintf(stderr, "GPT:Primary header alternate_lba != Alt. header my_lba\n"); fprintf(stderr, "GPT:%" PRIx64 " != %" PRIx64 "\n", __le64_to_cpu(pgpt->alternate_lba), __le64_to_cpu(agpt->my_lba)); error_found++; } if (__le64_to_cpu(pgpt->first_usable_lba) != __le64_to_cpu(agpt->first_usable_lba)) { fprintf(stderr, "GPT:first_usable_lbas don't match.\n"); fprintf(stderr, "GPT:%" PRIx64 " != %" PRIx64 "\n", __le64_to_cpu(pgpt->first_usable_lba), __le64_to_cpu(agpt->first_usable_lba)); error_found++; } if (__le64_to_cpu(pgpt->last_usable_lba) != __le64_to_cpu(agpt->last_usable_lba)) { fprintf(stderr, "GPT:last_usable_lbas don't match.\n"); fprintf(stderr, "GPT:%" PRIx64 " != %" PRIx64 "\n", __le64_to_cpu(pgpt->last_usable_lba), __le64_to_cpu(agpt->last_usable_lba)); error_found++; } if (efi_guidcmp(pgpt->disk_guid, agpt->disk_guid)) { fprintf(stderr, "GPT:disk_guids don't match.\n"); error_found++; } if (__le32_to_cpu(pgpt->num_partition_entries) != __le32_to_cpu(agpt->num_partition_entries)) { fprintf(stderr, "GPT:num_partition_entries don't match: " "0x%x != 0x%x\n", __le32_to_cpu(pgpt->num_partition_entries), __le32_to_cpu(agpt->num_partition_entries)); error_found++; } if (__le32_to_cpu(pgpt->sizeof_partition_entry) != __le32_to_cpu(agpt->sizeof_partition_entry)) { fprintf(stderr, "GPT:sizeof_partition_entry values don't match: " "0x%x != 0x%x\n", __le32_to_cpu(pgpt->sizeof_partition_entry), __le32_to_cpu(agpt->sizeof_partition_entry)); error_found++; } if (__le32_to_cpu(pgpt->partition_entry_array_crc32) != __le32_to_cpu(agpt->partition_entry_array_crc32)) { fprintf(stderr, "GPT:partition_entry_array_crc32 values don't match: " "0x%x != 0x%x\n", __le32_to_cpu(pgpt->partition_entry_array_crc32), __le32_to_cpu(agpt->partition_entry_array_crc32)); error_found++; } if (__le64_to_cpu(pgpt->alternate_lba) != lastlba) { fprintf(stderr, "GPT:Primary header thinks Alt. header is not at the end of the disk.\n"); fprintf(stderr, "GPT:%" PRIx64 " != %" PRIx64 "\n", __le64_to_cpu(pgpt->alternate_lba), lastlba); error_found++; } if (__le64_to_cpu(agpt->my_lba) != lastlba) { fprintf(stderr, "GPT:Alternate GPT header not at the end of the disk.\n"); fprintf(stderr, "GPT:%" PRIx64 " != %" PRIx64 "\n", __le64_to_cpu(agpt->my_lba), lastlba); error_found++; } if (error_found) fprintf(stderr, "GPT: Use GNU Parted to correct GPT errors.\n"); return; }
/** * is_gpt_valid() - tests one GPT header and PTEs for validity * @fd is an open file descriptor to the whole disk * @lba is the logical block address of the GPT header to test * @gpt is a GPT header ptr, filled on return. * @ptes is a PTEs ptr, filled on return. * * Description: returns 1 if valid, 0 on error. * If valid, returns pointers to newly allocated GPT header and PTEs. */ static int is_gpt_valid(int fd, uint64_t lba, gpt_header ** gpt, gpt_entry ** ptes) { int rc = 0; /* default to not valid */ uint32_t crc, origcrc; if (!gpt || !ptes) return 0; if (!(*gpt = alloc_read_gpt_header(fd, lba))) return 0; /* Check the GUID Partition Table signature */ if (__le64_to_cpu((*gpt)->signature) != GPT_HEADER_SIGNATURE) { /* printf("GUID Partition Table Header signature is wrong: %" PRIx64" != %" PRIx64 "\n", __le64_to_cpu((*gpt)->signature), GUID_PT_HEADER_SIGNATURE); */ free(*gpt); *gpt = NULL; return rc; } /* Check the GUID Partition Table Header CRC */ origcrc = __le32_to_cpu((*gpt)->header_crc32); (*gpt)->header_crc32 = 0; crc = efi_crc32(*gpt, __le32_to_cpu((*gpt)->header_size)); if (crc != origcrc) { // printf( "GPTH CRC check failed, %x != %x.\n", origcrc, crc); (*gpt)->header_crc32 = __cpu_to_le32(origcrc); free(*gpt); *gpt = NULL; return 0; } (*gpt)->header_crc32 = __cpu_to_le32(origcrc); /* Check that the my_lba entry points to the LBA * that contains the GPT we read */ if (__le64_to_cpu((*gpt)->my_lba) != lba) { // printf( "my_lba % PRIx64 "x != lba %"PRIx64 "x.\n", __le64_to_cpu((*gpt)->my_lba), lba); free(*gpt); *gpt = NULL; return 0; } if (!(*ptes = alloc_read_gpt_entries(fd, *gpt))) { free(*gpt); *gpt = NULL; return 0; } /* Check the GUID Partition Entry Array CRC */ crc = efi_crc32(*ptes, __le32_to_cpu((*gpt)->num_partition_entries) * __le32_to_cpu((*gpt)->sizeof_partition_entry)); if (crc != __le32_to_cpu((*gpt)->partition_entry_array_crc32)) { // printf("GUID Partitition Entry Array CRC check failed.\n"); free(*gpt); *gpt = NULL; free(*ptes); *ptes = NULL; return 0; } /* We're done, all's well */ return 1; }
static int nova_readdir(struct file *file, struct dir_context *ctx) { struct inode *inode = file_inode(file); struct super_block *sb = inode->i_sb; struct nova_inode *pidir; struct nova_inode_info *si = NOVA_I(inode); struct nova_inode_info_header *sih = &si->header; struct nova_inode *child_pi; struct nova_dentry *entry; struct nova_dentry *entries[FREE_BATCH]; int nr_entries; u64 pi_addr; unsigned long pos = 0; ino_t ino; int i; int ret; timing_t readdir_time; NOVA_START_TIMING(readdir_t, readdir_time); pidir = nova_get_inode(sb, inode); nova_dbgv("%s: ino %llu, size %llu, pos %llu\n", __func__, (u64)inode->i_ino, pidir->i_size, ctx->pos); if (!sih) { nova_dbg("%s: inode %lu sih does not exist!\n", __func__, inode->i_ino); ctx->pos = READDIR_END; return 0; } pos = ctx->pos; if (pos == READDIR_END) goto out; do { nr_entries = radix_tree_gang_lookup(&sih->tree, (void **)entries, pos, FREE_BATCH); for (i = 0; i < nr_entries; i++) { entry = entries[i]; pos = BKDRHash(entry->name, entry->name_len); ino = __le64_to_cpu(entry->ino); if (ino == 0) continue; ret = nova_get_inode_address(sb, ino, &pi_addr, 0); if (ret) { nova_dbg("%s: get child inode %lu address " "failed %d\n", __func__, ino, ret); ctx->pos = READDIR_END; return ret; } child_pi = nova_get_block(sb, pi_addr); nova_dbgv("ctx: ino %llu, name %s, " "name_len %u, de_len %u\n", (u64)ino, entry->name, entry->name_len, entry->de_len); if (!dir_emit(ctx, entry->name, entry->name_len, ino, IF2DT(le16_to_cpu(child_pi->i_mode)))) { nova_dbgv("Here: pos %llu\n", ctx->pos); return 0; } ctx->pos = pos + 1; } pos++; } while (nr_entries == FREE_BATCH); out: NOVA_END_TIMING(readdir_t, readdir_time); return 0; }
static ssize_t SparsePread(DiskInfo *self, void *buf, size_t len, off_t pos) { SparseDiskInfo *sdi = getSDI(self); uint8_t *buf8 = buf; uint32_t grainNr = pos / (sdi->diskHdr.grainSize * VMDK_SECTOR_SIZE); uint32_t readSkip = pos & (sdi->diskHdr.grainSize * VMDK_SECTOR_SIZE - 1); while (len > 0) { uint32_t readLen; uint32_t sect; uint32_t grainSize; if (grainNr < sdi->gtInfo.lastGrainNr) { grainSize = sdi->diskHdr.grainSize * VMDK_SECTOR_SIZE; } else if (grainNr == sdi->gtInfo.lastGrainNr) { grainSize = sdi->gtInfo.lastGrainSize; } else { grainSize = 0; } if (readSkip >= grainSize) { break; } readLen = grainSize - readSkip; sect = __le32_to_cpu(sdi->gtInfo.gt[grainNr]); if (sect == 0) { /* Read from parent... No parent for us... */ memset(buf8, 0, readLen); } else if (sect == 1) { memset(buf8, 0, readLen); } else { if (sdi->diskHdr.flags & SPARSEFLAG_COMPRESSED) { uint32_t hdrlen; uint32_t cmpSize; if (!safePread(sdi->fd, sdi->readBuffer, VMDK_SECTOR_SIZE, sect * VMDK_SECTOR_SIZE)) { return -1; } if (sdi->diskHdr.flags & SPARSEFLAG_EMBEDDED_LBA) { SparseGrainLBAHeaderOnDisk *hdr = (SparseGrainLBAHeaderOnDisk *)sdi->readBuffer; if (__le64_to_cpu(hdr->lba) != grainNr * sdi->diskHdr.grainSize) { return -1; } cmpSize = __le32_to_cpu(hdr->cmpSize); hdrlen = 12; } else { cmpSize = __le32_to_cpu(*(__le32*)sdi->readBuffer); hdrlen = 4; } if (cmpSize > sdi->readBufferSize - hdrlen) { return -1; } if (cmpSize + hdrlen > VMDK_SECTOR_SIZE) { size_t remainingLength = (cmpSize + hdrlen - VMDK_SECTOR_SIZE + VMDK_SECTOR_SIZE - 1) & ~(VMDK_SECTOR_SIZE - 1); if (!safePread(sdi->fd, sdi->readBuffer + VMDK_SECTOR_SIZE, remainingLength, (sect + 1) * VMDK_SECTOR_SIZE)) { return -1; } } if (inflateReset(&sdi->zstream) != Z_OK) { return -1; } sdi->zstream.next_in = sdi->readBuffer + hdrlen; sdi->zstream.avail_in = cmpSize; sdi->zstream.next_out = sdi->grainBuffer; sdi->zstream.avail_out = sdi->diskHdr.grainSize * VMDK_SECTOR_SIZE; if (inflate(&sdi->zstream, Z_FINISH) != Z_STREAM_END) { return -1; } if (sdi->diskHdr.grainSize * VMDK_SECTOR_SIZE - sdi->zstream.avail_out < grainSize) { return -1; } memcpy(buf8, sdi->grainBuffer + readSkip, readLen); } else { if (!safePread(sdi->fd, buf8, readLen, sect * VMDK_SECTOR_SIZE + readSkip)) { return -1; } } } buf8 += readLen; len -= readLen; grainNr++; readSkip = 0; } return buf8 - (uint8_t *)buf; }