Example #1
0
/**
 * 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;
}
Example #2
0
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);
}
Example #3
0
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);
	}
}
Example #4
0
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;
}
Example #5
0
static uint64_t
getUnalignedLE64(const __le64 *src)
{
	__le64 b;

	memcpy(&b, src, sizeof b);
	return __le64_to_cpu(b);
}
Example #6
0
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);
}
Example #7
0
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;
}
Example #8
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;
}
Example #9
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;
}
Example #10
0
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;
}
Example #11
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;
}
Example #12
0
File: gpt.c Project: btian1/efivar
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;
}
Example #13
0
/**
 * 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;
}
Example #14
0
/*
 * 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
}
Example #15
0
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;
}
Example #16
0
File: dir.c Project: NVSL/NOVA
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;
}
Example #17
0
File: gpt.c Project: btian1/efivar
/**
 * 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;
}
Example #18
0
uint64_t xle64dec(const uint8_t *d) {
    return __le64_to_cpu(*(uint64_t*)d);
}
Example #19
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)
{
        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;
}
Example #20
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;
}
Example #21
0
/**
 * 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;
}
Example #22
0
File: dir.c Project: NVSL/NOVA
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;
}
Example #23
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;
}