Beispiel #1
0
int main(int argc, char *argv[])
{
  struct timeval before,after;
  int i,j;
  int n = 1000000;  /* number of strings */
  int len = 150;    /* "length" of strings (mild variation) */
  data_t* orig = create(n, len);
  naive_write("naive.bin", orig, n);
  flat_write("flat.bin", orig, n);

  gettimeofday(&before,NULL);
  data_t* naive = naive_read("naive.bin");
  gettimeofday(&after,NULL);
  printf(" naive time: %f\n", elapsed(before,after));

  gettimeofday(&before,NULL);
  data_t* onecopy = onecopy_read("flat.bin");
  gettimeofday(&after,NULL);
  printf(" 1copy time: %f\n", elapsed(before,after));

  gettimeofday(&before,NULL);
  data_t* zerocopy = zerocopy_read("flat.bin");
  gettimeofday(&after,NULL);
  printf(" 0copy time: %f\n", elapsed(before,after));
  
  compare(naive,onecopy, n);
  compare(naive,zerocopy,n);
  return 0;
}
Beispiel #2
0
/*
 * Writes out the contents of all files.
 * Does not actually do the write if 'dowrite'
 * is not set. In this case, it just checks
 * to see that the config will fit.
 * The total length of data written (or simulated) is stored
 * in *total.
 * Does not remove .flatfsd
 *
 * Note that if the flash has been erased, aborting
 * early will just lose data. So we try to work around
 * problems as much as possible.
 *
 * Returns 0 if OK, or < 0 if error.
 */
int flat1_savefs(int dowrite, unsigned *total)
{
	struct flathdr1 hdr;
	struct flatent ent;
	struct dirent *dp;
	DIR *dirp;
	int rc, ret = 0;

#ifdef DEBUG
	syslog(LOG_DEBUG, "flat1_savefs(dowrite=%d)", dowrite);
#endif

	/* Lets go, erase the flash first */
	if ((rc = flat_erase()) < 0)
		return rc;

	/* Write out contents of all files, skip over header */
	numfiles = 0;
	numbytes = 0;
	numdropped = 0;
	*total = sizeof(hdr);

#ifndef HAS_RTC
	rc = writefile(FLATFSD_CONFIG, total, dowrite);
	if (rc < 0 && !ret)
		ret = rc;
#endif

	/* Scan directory */
	if ((dirp = opendir(".")) == NULL) {
		rc = ERROR_CODE();
		if (rc < 0 && !ret)
			ret = rc;
		/* Really nothing we can do at this point */
		return ret;
	}

	while ((dp = readdir(dirp)) != NULL) {

		if ((strcmp(dp->d_name, ".") == 0) ||
		    (strcmp(dp->d_name, "..") == 0) ||
		    (strcmp(dp->d_name, FLATFSD_CONFIG) == 0))
			continue;

		rc = writefile(dp->d_name, total, dowrite);
		if (rc < 0) {
			syslog(LOG_ERR, "Failed to write write file %s (%d): %m %d",
				dp->d_name, rc, errno);
			if (!ret)
				ret = rc;
		}
	}
	closedir(dirp);

	/* Write the terminating entry */
	if (dowrite) {
		ent.namelen = FLATFS_EOF;
		ent.filelen = FLATFS_EOF;
		rc = flat_write(*total, &ent, sizeof(ent));
		if (rc < 0 && !ret)
			ret = rc;
	}

	*total += sizeof(ent);

#ifdef USING_MTD_DEVICE
	/*
	 * We need to account for the fact that we checksum the entire device,
	 * not just the data we wrote. On MTD devices, this data is 0xFF.
	 */
	{
		int checksum_len = flat_dev_length() - (BUF_SIZE - (sizeof(struct flathdr1) * 2));

		flat_sum += 0xFFu * (checksum_len - *total);

#ifdef DEBUG
		syslog(LOG_DEBUG, "flat_savefs(): added %d 0xFF bytes to "
			"checksum -> flat_sum=%u",
			checksum_len - *total, flat_sum);
#endif
	}
#endif

	if (dowrite) {
		/* Construct header */
		hdr.magic = FLATFS_MAGIC_V2;
		hdr.chksum = flat_sum;

#ifdef DEBUG
		syslog(LOG_DEBUG, "flat_savefs(): final checksum=%u, total=%d",
			flat_sum, *total);
#endif

		rc = flat_write(0L, &hdr, sizeof(hdr));
		if (rc < 0 && !ret)
			ret = rc;
	}

#ifdef DEBUG
	syslog(LOG_DEBUG, "flat_savefs() returning ret=%d, total=%u", ret, *total);
#endif

	return ret;
}
Beispiel #3
0
static int writefile(char *name, unsigned int *ptotal, int dowrite)
{
	struct flatent ent;
	struct stat st;
	unsigned int size;
	int fdfile, zero = 0;
	mode_t mode;
	char buf[BUF_SIZE];
	int n, written;

	/*
	 * Write file entry into flat fs. Names and file
	 * contents are aligned on long word boundaries.
	 * They are padded to that length with zeros.
	 */
	if (stat(name, &st) < 0)
		return ERROR_CODE();

	size = strlen(name) + 1;
	if (size > 128) {
		numdropped++;
		return ERROR_CODE();
	}

	ent.namelen = size;
	ent.filelen = st.st_size;
	if (dowrite && flat_write(*ptotal, &ent, sizeof(ent)) < 0)
		return ERROR_CODE();
	*ptotal += sizeof(ent);

	/* Write file name out, with padding to align */
	if (dowrite && flat_write(*ptotal, name, size) < 0)
		return ERROR_CODE();
	*ptotal += size;
	size = ((size + 3) & ~0x3) - size;
	if (dowrite && flat_write(*ptotal, &zero, size) < 0)
		return ERROR_CODE();
	*ptotal += size;

	/* Write out the permissions */
	mode = (mode_t) st.st_mode;
	size = sizeof(mode);
	if (dowrite && flat_write(*ptotal, &mode, size) < 0)
		return ERROR_CODE();
	*ptotal += size;

	/* Write the contents of the file. */
	size = st.st_size;

	written = 0;

	if (size > 0) {
		if (dowrite) {
			if ((fdfile = open(name, O_RDONLY)) < 0)
				return ERROR_CODE();
			while (size>written) {
				int bytes_read;
				n = ((size-written) > sizeof(buf))?sizeof(buf):(size-written);
				if ((bytes_read = read(fdfile, buf, n)) != n) {
					/* Somebody must have trunced the file - Log it. */
					syslog(LOG_WARNING, "File %s was shorter than expected.",
						name);
					if (bytes_read <= 0)
						break;
				}
				if (dowrite && flat_write(*ptotal, buf, bytes_read) < 0) {
					close(fdfile);
					return (ERROR_CODE());
				}
				*ptotal += bytes_read;
				written += bytes_read;
			}
			if (lseek(fdfile, 0, SEEK_END) != written) {
				/* 
				 * Log the file being longer than expected.
				 * We can't write more than expected because
				 * the size is already written.
				 */
				syslog(LOG_WARNING, "File %s was longer than expected.", name);
			}
			close(fdfile);
		} else {
			*ptotal += st.st_size;
		}

		/* Pad to align */
		written = ((st.st_size + 3) & ~0x3) - st.st_size;
		if (dowrite && flat_write(*ptotal, &zero, written) < 0)
			return ERROR_CODE();
		*ptotal += written;
	}

	numfiles++;
	numbytes += ent.filelen;

	return 0;
}