static int write_backward( off64_t offset, long long *count, long long *total) { off64_t end, off = offset; ssize_t bytes = 0, bytes_requested; long long cnt = *count; int ops = 0; if ((end = off - cnt) < 0) { cnt += end; /* subtraction, end is negative */ end = 0; } *total = 0; *count = cnt; /* Do initial unaligned write if needed */ if ((bytes_requested = (off % buffersize))) { bytes_requested = min(cnt, bytes_requested); off -= bytes_requested; bytes = do_pwrite(file->fd, off, bytes_requested, buffersize); if (bytes == 0) return ops; if (bytes < 0) { perror("pwrite64"); return -1; } ops++; *total += bytes; if (bytes < bytes_requested) return ops; cnt -= bytes; } /* Iterate backward through the rest of the range */ while (cnt > end) { bytes_requested = min(cnt, buffersize); off -= bytes_requested; bytes = do_pwrite(file->fd, off, cnt, buffersize); if (bytes == 0) break; if (bytes < 0) { perror("pwrite64"); return -1; } ops++; *total += bytes; if (bytes < bytes_requested) break; cnt -= bytes; } return ops; }
ssize_t __libc_pwrite (int fd, const void *buf, size_t count, off_t offset) { if (SINGLE_THREAD_P) return do_pwrite (fd, buf, count, offset); int oldtype = LIBC_CANCEL_ASYNC (); ssize_t result = do_pwrite (fd, buf, count, offset); LIBC_CANCEL_RESET (oldtype); return result; }
int do_bandwidth(const char *file, int bytes, int blocksize, int do_write) { int offset = 0; long fd; char *buffer = malloc(blocksize); int i; for(i = 0; i < blocksize; i++) buffer[i] = (char) i; fd = do_open(file, (do_write ? O_WRONLY : O_RDONLY) | O_CREAT | do_sync | O_TRUNC, 0777); if(fd < 0 || fd == 0) { printf("couldn't open %s: %s", file, strerror(errno)); return 0; } while(bytes > 0) { if(do_write) { do_pwrite(fd, buffer, blocksize, offset); } else { do_pread(fd, buffer, blocksize, offset); } offset += blocksize; bytes -= blocksize; } do_close(fd); free(buffer); return 1; }
err_t sys_pwritev(fd_t fd, const struct iovec* iov, int iovcnt, off_t seek_to_offset, ssize_t* num_written_out) { ssize_t got; ssize_t got_total; err_t err_out; int i; STARTING_SLOW_SYSCALL; err_out = 0; got_total = 0; for( i = 0; i < iovcnt; i++ ) { got = 0; err_out = do_pwrite(fd, iov[i].iov_base, iov[i].iov_len, seek_to_offset + got_total, &got); if( got >= 0 ) { got_total += got; } else { break; } if( (size_t) got != iov[i].iov_len ) { break; } } *num_written_out = got_total; DONE_SLOW_SYSCALL; return err_out; }
static void format_superblock(State *s, SystemFileDiskRecord *rec, SystemFileDiskRecord *root_rec, SystemFileDiskRecord *sys_rec) { struct cmfs_dinode *di; uint64_t super_off = rec->fe_off; di = do_malloc(s, s->blocksize); memset(di, 0, s->blocksize); strcpy((char *)di->i_signature, CMFS_SUPER_BLOCK_SIGNATURE); di->i_generation = s->vol_generation; di->i_fs_generation = s->vol_generation; di->i_atime = 0; di->i_ctime = s->format_time; di->i_mtime = s->format_time; di->i_blkno = super_off >> s->blocksize_bits; di->i_flags = CMFS_VALID_FL | CMFS_SYSTEM_FL | CMFS_SUPER_BLOCK_FL; di->i_clusters = s->volume_size_in_clusters; di->id2.i_super.s_major_rev_level = CMFS_MAJOR_REV_LEVEL; di->id2.i_super.s_minor_rev_level = CMFS_MINOR_REV_LEVEL; di->id2.i_super.s_root_blkno = root_rec->fe_off >> s->blocksize_bits; di->id2.i_super.s_system_dir_blkno = sys_rec->fe_off >> s->blocksize_bits; di->id2.i_super.s_mnt_count = 0; di->id2.i_super.s_max_mnt_count = CMFS_DFL_MAX_MNT_COUNT; di->id2.i_super.s_state = 0; di->id2.i_super.s_errors = 0; di->id2.i_super.s_lastcheck = s->format_time; di->id2.i_super.s_checkinterval = CMFS_DFL_CHECKINTERVAL; di->id2.i_super.s_creator_os = CMFS_OS_LINUX; di->id2.i_super.s_blocksize_bits = s->blocksize_bits; di->id2.i_super.s_clustersize_bits = s->cluster_size_bits; /* We clear the "backup_sb" here since it should be written by * format_backup_super(), not by us. And we have already set the * "s->no_backup_super" according to the features in get_state(), * so it's safe to clear the flag here. */ s->feature_flags.opt_compat &= ~CMFS_FEATURE_COMPAT_BACKUP_SB; di->id2.i_super.s_feature_incompat = s->feature_flags.opt_incompat; di->id2.i_super.s_feature_compat = s->feature_flags.opt_compat; di->id2.i_super.s_feature_ro_compat = s->feature_flags.opt_ro_compat; strcpy((char *)di->id2.i_super.s_label, s->vol_label); memcpy(di->id2.i_super.s_uuid, s->uuid, CMFS_VOL_UUID_LEN); mkfs_swap_inode_from_cpu(s, di); mkfs_compute_meta_ecc(s, di, &di->i_check); do_pwrite(s, di, s->blocksize, super_off); free(di); }
err_t sys_pwrite(int fd, const void* buf, size_t count, off_t offset, ssize_t* num_written_out) { ssize_t got; err_t err_out; STARTING_SLOW_SYSCALL; got = 0; err_out = do_pwrite(fd, buf, count, offset, &got); if( got != -1 ) { *num_written_out = got; err_out = 0; } else { *num_written_out = 0; } DONE_SLOW_SYSCALL; return err_out; }
/* If src is NULL, we write cleaned buf out. */ static void write_metadata(State *s, SystemFileDiskRecord *rec, void *src) { void *buf; buf = do_malloc(s, rec->extent_len); if (!buf) { fprintf(stderr, "%s:%d: do_malloc failed.", __func__, __LINE__); exit(1); } memset(buf, 0, rec->extent_len); if (src) memcpy(buf, src, rec->file_size); do_pwrite(s, buf, rec->extent_len, rec->extent_off); free(buf); }
static int write_random( off64_t offset, long long count, unsigned int seed, long long *total) { off64_t off, range; ssize_t bytes; int ops = 0; srandom(seed); if ((bytes = (offset % buffersize))) offset -= bytes; offset = max(0, offset); if ((bytes = (count % buffersize))) count += bytes; count = max(buffersize, count); range = count - buffersize; *total = 0; while (count > 0) { off = ((random() % range) / buffersize) * buffersize; bytes = do_pwrite(file->fd, off, buffersize, buffersize); if (bytes == 0) break; if (bytes < 0) { perror("pwrite64"); return -1; } ops++; *total += bytes; if (bytes < buffersize) break; count -= bytes; } return ops; }
static int write_buffer( off64_t offset, long long count, size_t bs, int fd, off64_t skip, long long *total) { ssize_t bytes; long long bar = min(bs, count); int ops = 0; *total = 0; while (count >= 0) { if (fd > 0) { /* input file given, read buffer first */ if (read_buffer(fd, skip + *total, bs, &bar, 0, 1) < 0) break; } bytes = do_pwrite(file->fd, offset, count, bar); if (bytes == 0) break; if (bytes < 0) { perror("pwrite64"); return -1; } ops++; *total += bytes; if (bytes < min(count, bar)) break; offset += bytes; count -= bytes; if (count == 0) break; } return ops; }
static void format_leading_space(State *s) { int num_blocks, size; struct cmfs_vol_disk_hdr *hdr; struct cmfs_vol_label *lbl; void *buf; char *p; num_blocks = 2; size = num_blocks << s->blocksize_bits; p = buf = do_malloc(s, size); memset(buf, 0, size); hdr = (struct cmfs_vol_disk_hdr *)buf; strcpy((char *)hdr->signature, "this is a cmfs volume"); strcpy((char *)hdr->mount_point, "this is a cmfs volume"); p += 512; lbl = (struct cmfs_vol_label *)p; strcpy((char *)lbl->label, "this is a cmfs volume"); do_pwrite(s, buf, size, 0); free(buf); }
static int write_f(int argc, char **argv) { struct timeval t1, t2; int Cflag = 0, pflag = 0, qflag = 0, bflag = 0, Pflag = 0, zflag = 0; int cflag = 0; int c, cnt; char *buf = NULL; int64_t offset; int count; /* Some compilers get confused and warn if this is not initialized. */ int total = 0; int pattern = 0xcd; while ((c = getopt(argc, argv, "bcCpP:qz")) != EOF) { switch (c) { case 'b': bflag = 1; break; case 'c': cflag = 1; break; case 'C': Cflag = 1; break; case 'p': pflag = 1; break; case 'P': Pflag = 1; pattern = parse_pattern(optarg); if (pattern < 0) { return 0; } break; case 'q': qflag = 1; break; case 'z': zflag = 1; break; default: return command_usage(&write_cmd); } } if (optind != argc - 2) { return command_usage(&write_cmd); } if (bflag + pflag + zflag > 1) { printf("-b, -p, or -z cannot be specified at the same time\n"); return 0; } if (zflag && Pflag) { printf("-z and -P cannot be specified at the same time\n"); return 0; } offset = cvtnum(argv[optind]); if (offset < 0) { printf("non-numeric length argument -- %s\n", argv[optind]); return 0; } optind++; count = cvtnum(argv[optind]); if (count < 0) { printf("non-numeric length argument -- %s\n", argv[optind]); return 0; } if (!pflag) { if (offset & 0x1ff) { printf("offset %" PRId64 " is not sector aligned\n", offset); return 0; } if (count & 0x1ff) { printf("count %d is not sector aligned\n", count); return 0; } } if (!zflag) { buf = qemu_io_alloc(count, pattern); } gettimeofday(&t1, NULL); if (pflag) { cnt = do_pwrite(buf, offset, count, &total); } else if (bflag) { cnt = do_save_vmstate(buf, offset, count, &total); } else if (zflag) { cnt = do_co_write_zeroes(offset, count, &total); } else if (cflag) { cnt = do_write_compressed(buf, offset, count, &total); } else { cnt = do_write(buf, offset, count, &total); } gettimeofday(&t2, NULL); if (cnt < 0) { printf("write failed: %s\n", strerror(-cnt)); goto out; } if (qflag) { goto out; } /* Finally, report back -- -C gives a parsable format */ t2 = tsub(t2, t1); print_report("wrote", &t2, offset, count, total, cnt, Cflag); out: if (!zflag) { qemu_io_free(buf); } return 0; }
int main(int argc, char *argv[]) { long fd; int i, j, k; int bwloops; char *fname; char data[8192]; int runtime; struct stat buf; struct timeval start, stop; stoptime = time(0) + 3600; int filesize = 16 * 1024 * 1024; if(argc != 6) { printf("use: %s <host> <file> <loops> <cycles> <bwloops>\n", argv[0]); return -1; } auth_register_all(); host = argv[1]; fname = argv[2]; loops = atoi(argv[3]); cycles = atoi(argv[4]); bwloops = atoi(argv[5]); if(!strcmp(host, "unix")) { do_chirp = 0; } else { do_chirp = 1; } #ifdef SYS_getpid RUN_LOOP("getpid", syscall(SYS_getpid)); #else RUN_LOOP("getpid", getpid()); #endif fd = do_open(fname, O_WRONLY | O_CREAT | O_TRUNC | do_sync, 0777); if(fd < 0 || fd == 0) { perror(fname); return -1; } RUN_LOOP("write1", do_pwrite(fd, data, 1, 0)); RUN_LOOP("write8", do_pwrite(fd, data, 8192, 0)); do_close(fd); fd = do_open(fname, O_RDONLY | do_sync, 0777); if(fd < 0) { perror(fname); return -1; } RUN_LOOP("read1", do_pread(fd, data, 1, 0)); RUN_LOOP("read8", do_pread(fd, data, 8192, 0)); do_close(fd); RUN_LOOP("stat", do_stat(fname, &buf)); RUN_LOOP("open", fd = do_open(fname, O_RDONLY | do_sync, 0777); do_close(fd); );
static int write_f(int argc, char **argv) { struct timeval t1, t2; int Cflag = 0, pflag = 0, qflag = 0, bflag = 0; int c, cnt; char *buf; int64_t offset; int count; int total = 0; int pattern = 0xcd; while ((c = getopt(argc, argv, "bCpP:q")) != EOF) { switch (c) { case 'b': bflag = 1; break; case 'C': Cflag = 1; break; case 'p': pflag = 1; break; case 'P': pattern = parse_pattern(optarg); if (pattern < 0) return 0; break; case 'q': qflag = 1; break; default: return command_usage(&write_cmd); } } if (optind != argc - 2) return command_usage(&write_cmd); if (bflag && pflag) { printf("-b and -p cannot be specified at the same time\n"); return 0; } offset = cvtnum(argv[optind]); if (offset < 0) { printf("non-numeric length argument -- %s\n", argv[optind]); return 0; } optind++; count = cvtnum(argv[optind]); if (count < 0) { printf("non-numeric length argument -- %s\n", argv[optind]); return 0; } if (!pflag) { if (offset & 0x1ff) { printf("offset %" PRId64 " is not sector aligned\n", offset); return 0; } if (count & 0x1ff) { printf("count %d is not sector aligned\n", count); return 0; } } buf = qemu_io_alloc(count, pattern); gettimeofday(&t1, NULL); if (pflag) cnt = do_pwrite(buf, offset, count, &total); else if (bflag) cnt = do_save_vmstate(buf, offset, count, &total); else cnt = do_write(buf, offset, count, &total); gettimeofday(&t2, NULL); if (cnt < 0) { printf("write failed: %s\n", strerror(-cnt)); goto out; } if (qflag) goto out; t2 = tsub(t2, t1); print_report("wrote", &t2, offset, count, total, cnt, Cflag); out: qemu_io_free(buf); return 0; }