int keydiv_dtable::create(int dfd, const char * name, const params & config, dtype::ctype key_type) { int r, kdd_dfd, meta; divider_list dividers; const dtable_factory * base; params base_config; kddtable_header header; header.magic = KDDTABLE_MAGIC; header.version = KDDTABLE_VERSION; switch(key_type) { case dtype::UINT32: header.key_type = 1; r = load_dividers<int, uint32_t>(config, 0, ÷rs); break; case dtype::DOUBLE: header.key_type = 2; r = load_dividers<float, double>(config, 0, ÷rs); break; case dtype::STRING: header.key_type = 3; r = load_dividers<istr, istr>(config, 0, ÷rs); break; case dtype::BLOB: header.key_type = 4; r = load_dividers<blob, blob>(config, 0, ÷rs, true); break; default: return -EINVAL; } header.dt_count = dividers.size() + 1; /* make sure we don't overflow the header field */ if(header.dt_count != dividers.size() + 1) return -EINVAL; base = dtable_factory::lookup(config, "base"); if(!base) return -EINVAL; if(!config.get("base_config", &base_config, params())) return -EINVAL; r = mkdirat(dfd, name, 0755); if(r < 0) return r; kdd_dfd = openat(dfd, name, O_RDONLY); if(kdd_dfd < 0) { unlinkat(dfd, name, AT_REMOVEDIR); return kdd_dfd; } for(uint32_t i = 0; i < header.dt_count; i++) { char name[32]; sprintf(name, "kdd_data.%u", i); r = base->create(kdd_dfd, name, base_config, key_type); if(r < 0) goto fail; } meta = openat(kdd_dfd, "kdd_meta", O_WRONLY | O_CREAT, 0644); if(meta < 0) { r = meta; goto fail; } r = pwrite(meta, &header, sizeof(header), 0); close(meta); if(r != sizeof(header)) goto fail; close(kdd_dfd); return 0; fail: close(kdd_dfd); util::rm_r(dfd, name); return (r < 0) ? r : -1; }
void runtime·badsignal(void) { runtime·pwrite(2, badsignal, sizeof badsignal - 1, -1LL); runtime·exits(badsignal); }
int write_filemarks(uint32_t count, uint8_t *sam_stat) { uint32_t blk_number; uint64_t data_offset; ssize_t nwrite; if (!tape_loaded(sam_stat)) { return -1; } /* Applications assume that writing a filemark (even writing zero filemarks) will force-flush any data buffered in the drive to media so that after the write-filemarks call returns there is no possibility that any data previously written could be lost due to a power hit. Provide a similar guarantee here. */ if (count == 0) { MHVTL_DBG(2, "Flushing data - 0 filemarks written"); fsync(datafile); fsync(indxfile); fsync(metafile); return 0; } if (check_for_overwrite(sam_stat)) { return -1; } /* Preserve existing raw_pos data we need, then clear raw_pos and fill it in with new data. */ blk_number = raw_pos.hdr.blk_number; data_offset = raw_pos.data_offset; memset(&raw_pos, 0, sizeof(raw_pos)); raw_pos.data_offset = data_offset; raw_pos.hdr.blk_type = B_FILEMARK; /* Header type */ raw_pos.hdr.blk_flags = 0; raw_pos.hdr.blk_number = blk_number; raw_pos.hdr.blk_size = 0; raw_pos.hdr.disk_blk_size = 0; /* Now write out one header per filemark. */ for ( ; count > 0; count--, blk_number++) { raw_pos.hdr.blk_number = blk_number; MHVTL_DBG(3, "Writing filemark: block %d", blk_number); nwrite = pwrite(indxfile, &raw_pos, sizeof(raw_pos), blk_number * sizeof(raw_pos)); if (nwrite != sizeof(raw_pos)) { mkSenseBuf(MEDIUM_ERROR, E_WRITE_ERROR, sam_stat); MHVTL_ERR("Index file write failure," " pos: %" PRId64 ": %s", (uint64_t)blk_number * sizeof(raw_pos), strerror(errno)); return -1; } add_filemark(blk_number); } /* Provide the force-flush guarantee. */ fsync(datafile); fsync(indxfile); fsync(metafile); return mkEODHeader(blk_number, data_offset); }
int journal::init_crfd(const istr & commit_name) { int r; off_t filesize, nextcr = 0; struct timeval settime[2] = {{0, 0}, {0, 0}}; commit_record zero = {0, 0}, cr; /* Only append more empy records to the commit file if it is already open * otherwise create a new commit record file. */ if(crfd < 0) { istr cname = commit_name; if(!cname) { char commit_number[16]; snprintf(commit_number, sizeof(commit_number), "%d", commits); cname = path + J_COMMIT_EXT + commit_number; } crfd = openat(dfd, cname, O_CREAT | O_RDWR, 0644); if(crfd < 0) return -1; } filesize = lseek(crfd, 0, SEEK_END); util::memset(zero.checksum, 0, sizeof(zero.checksum)); /* find out where the last good commit record is */ while((r = pread(crfd, &cr, sizeof(cr), nextcr))) { if(r < (int) sizeof(cr)) break; if(!cr.offset && !cr.length && !memcmp(&cr.checksum, &zero.checksum, J_CHECKSUM_LEN)) break; nextcr += r; } /* We set the mtime for the commit record file in the future to prevent * the inode metadata being updated with every write - this uses a hack * in Featherstitch to optimize for patchgroups. */ /* atime */ settime[0].tv_sec = time(NULL); /* mtime is current time plus 10 years, or the end of 31-bit time, whichever is later */ settime[1].tv_sec = settime[0].tv_sec + 315360000; if(settime[1].tv_sec < 2147483647) settime[1].tv_sec = 2147483647; if((r = futimes(crfd, settime)) < 0) goto error; if(filesize < (nextcr + (int) sizeof(cr))) { /* zero out the rest of the file J_ADD_N_COMMITS records at a time */ uint8_t zbuffer[1000 * sizeof(zero)]; util::memset(zbuffer, 0, sizeof(zbuffer)); while((filesize - nextcr) < J_ADD_N_COMMITS * (int) sizeof(zbuffer)) { r = pwrite(crfd, zbuffer, sizeof(zbuffer), filesize); if(r <= 0) goto error; filesize += r; } /* necessary? */ fsync(crfd); } return nextcr; error: if(crfd > 0) { close(crfd); crfd = -1; } return r < 0 ? r : -1; }
int32 runtime·write(int32 fd, void *buf, int32 nbytes) { return runtime·pwrite(fd, buf, nbytes, -1LL); }
void masterconn_download_data(masterconn *eptr,const uint8_t *data,uint32_t length) { uint64_t offset; uint32_t leng; uint32_t crc; ssize_t ret; if (eptr->metafd<0) { syslog(LOG_NOTICE,"MATOML_DOWNLOAD_DATA - file not opened"); eptr->mode = KILL; return; } if (length<16) { syslog(LOG_NOTICE,"MATOML_DOWNLOAD_DATA - wrong size (%"PRIu32"/16+data)",length); eptr->mode = KILL; return; } passert(data); offset = get64bit(&data); leng = get32bit(&data); crc = get32bit(&data); if (leng+16!=length) { syslog(LOG_NOTICE,"MATOML_DOWNLOAD_DATA - wrong size (%"PRIu32"/16+%"PRIu32")",length,leng); eptr->mode = KILL; return; } if (offset!=eptr->dloffset) { syslog(LOG_NOTICE,"MATOML_DOWNLOAD_DATA - unexpected file offset (%"PRIu64"/%"PRIu64")",offset,eptr->dloffset); eptr->mode = KILL; return; } if (offset+leng>eptr->filesize) { syslog(LOG_NOTICE,"MATOML_DOWNLOAD_DATA - unexpected file size (%"PRIu64"/%"PRIu64")",offset+leng,eptr->filesize); eptr->mode = KILL; return; } #ifdef HAVE_PWRITE ret = pwrite(eptr->metafd,data,leng,offset); #else /* HAVE_PWRITE */ lseek(eptr->metafd,offset,SEEK_SET); ret = write(eptr->metafd,data,leng); #endif /* HAVE_PWRITE */ if (ret!=(ssize_t)leng) { mfs_errlog_silent(LOG_NOTICE,"error writing metafile"); if (eptr->downloadretrycnt>=5) { masterconn_download_end(eptr); } else { eptr->downloadretrycnt++; masterconn_download_next(eptr); } return; } if (crc!=mycrc32(0,data,leng)) { syslog(LOG_NOTICE,"metafile data crc error"); if (eptr->downloadretrycnt>=5) { masterconn_download_end(eptr); } else { eptr->downloadretrycnt++; masterconn_download_next(eptr); } return; } /*if (fsync(eptr->metafd)<0) { mfs_errlog_silent(LOG_NOTICE,"error syncing metafile"); if (eptr->downloadretrycnt>=5) { masterconn_download_end(eptr); } else { eptr->downloadretrycnt++; masterconn_download_next(eptr); } return; }*/ eptr->dloffset+=leng; eptr->downloadretrycnt=0; masterconn_download_next(eptr); }
int nandwrite_mlc(char *image_path, int dev, loff_t mtdoffset, struct mtd_info_user *meminfo) { int cnt = 0; int image = -1; int imglen = 0, pagesize, blocksize, badblocks = 0; unsigned int offs; int ret; bool read_next = true; unsigned char *writebuf = NULL; int retCode = 0; uint32_t nblock, npage, skip; int total_blocks, pagesperblock, blockskip; image = open(image_path, O_RDONLY); if (image == -1) { perror("open error"); return -1; } imglen = lseek(image, 0, SEEK_END); lseek (image, 0, SEEK_SET); pagesize = meminfo->writesize; blocksize = meminfo->erasesize; // Check, if length fits into device total_blocks = meminfo->size / blocksize; pagesperblock = blocksize / pagesize; blockskip = (MLC_MAX_IMG_SIZ / pagesize + 1) * CONFIG_PAGE_REPLICATION * CONFIG_BLOCK_REPLICATION / pagesperblock; if ((blockskip * 2) > total_blocks || imglen > MLC_MAX_IMG_SIZ) { show_nand_info(stderr, meminfo); perror("Assigned max image size does not fit into device"); retCode = -2; goto closeall; } // Allocate a buffer big enough to contain all the data for one page writebuf = (unsigned char*)MALLOC(pagesize); erase_buffer(writebuf, pagesize); while ((imglen > 0) && (mtdoffset < meminfo->size)) { int readlen = pagesize; int tinycnt = 0; skip = 0; badblocks = 0; if (read_next) { erase_buffer(writebuf, readlen); /* Read up to one page data */ while (tinycnt < readlen) { cnt = read(image, writebuf + tinycnt, readlen - tinycnt); if (cnt == 0) { /* EOF */ break; } else if (cnt < 0) { perror ("File I/O error on input"); retCode = -3; goto closeall; } tinycnt += cnt; } imglen -= tinycnt; read_next = false; } for (nblock = 0; nblock < CONFIG_BLOCK_REPLICATION; nblock++) { // offs = mtdoffset + nblock * blocksize + skip * blocksize; offs = mtdoffset + skip * blocksize; // skip bad blocks ret = nand_block_isbad(dev, offs); if (ret < 0) { retCode = -5; goto closeall; } else if (ret == 1) { #if 0 loff_t checkblock; char have_copy = 0; if (!quiet) { fprintf(stderr, "Skip bad block at address 0x%x, (block %u)\n", offs, offs / blocksize); } badblocks++; // make sure we have at least one copy for (checkblock = 0; checkblock < CONFIG_BLOCK_REPLICATION; checkblock++) { offs = mtdoffset + checkblock * blocksize + skip * blocksize; ret = nand_block_isbad(dev, offs); if (ret < 0) goto closeall; else if (ret == 0) { have_copy = 1; break; } } if (!have_copy) { printf("Too many bad blocks\n"); goto closeall; } skip += blockskip; continue; #else if (!quiet) { uint32_t block_mask = meminfo->erasesize - 1; printf("Bad block 0x%x\n", (offs & (~block_mask))); } if (++badblocks >= CONFIG_BLOCK_REPLICATION) { printf("Too many bad blocks\n"); retCode = -4; goto closeall; } skip += blockskip; continue; #endif } for (npage = 0; npage < CONFIG_PAGE_REPLICATION; npage++) { offs = mtdoffset + npage * pagesize + skip * blocksize; /* Write out the Page data */ if (pwrite(dev, writebuf, pagesize, offs) != pagesize) { fprintf(stderr, "Bad page for copy %u of block %x for address %x\n", npage, nblock, offs); } } skip += blockskip; read_next = true; } // for nblock mtdoffset += pagesize * CONFIG_PAGE_REPLICATION; } // while (imglen > 0) closeall: if (writebuf) { free(writebuf); } close(image); if (imglen > 0) { fprintf(stderr, "Data was only partially written due to error\n"); } return retCode; }
/* write data to a process memory space */ int write_process_memory( struct process *process, client_ptr_t ptr, data_size_t size, const char *src ) { struct thread *thread = get_ptrace_thread( process ); int ret = 0; long data = 0; data_size_t len; long *addr; unsigned long first_mask, first_offset, last_mask, last_offset; if (!thread) return 0; if ((unsigned long)ptr != ptr) { set_error( STATUS_ACCESS_DENIED ); return 0; } /* compute the mask for the first long */ first_mask = ~0; first_offset = ptr % sizeof(long); memset( &first_mask, 0, first_offset ); /* compute the mask for the last long */ last_offset = (size + first_offset) % sizeof(long); if (!last_offset) last_offset = sizeof(long); last_mask = 0; memset( &last_mask, 0xff, last_offset ); addr = (long *)(unsigned long)(ptr - first_offset); len = (size + first_offset + sizeof(long) - 1) / sizeof(long); if (suspend_for_ptrace( thread )) { if (!check_process_write_access( thread, addr, len )) { set_error( STATUS_ACCESS_DENIED ); goto done; } if (len > 3) { char procmem[24]; int fd; sprintf( procmem, "/proc/%u/mem", process->unix_pid ); if ((fd = open( procmem, O_WRONLY )) != -1) { ssize_t r = pwrite( fd, src, size, ptr ); close( fd ); if (r == size) { ret = 1; goto done; } } } /* first word is special */ if (len > 1) { memcpy( (char *)&data + first_offset, src, sizeof(long) - first_offset ); src += sizeof(long) - first_offset; if (write_thread_long( thread, addr++, data, first_mask ) == -1) goto done; first_offset = 0; len--; } else last_mask &= first_mask; while (len > 1) { memcpy( &data, src, sizeof(long) ); src += sizeof(long); if (write_thread_long( thread, addr++, data, ~0ul ) == -1) goto done; len--; } /* last word is special too */ memcpy( (char *)&data + first_offset, src, last_offset - first_offset ); if (write_thread_long( thread, addr, data, last_mask ) == -1) goto done; ret = 1; done: resume_after_ptrace( thread ); } return ret; }
static int xmp_write(const char *path, const char *buf, size_t size, off_t offset, struct fuse_file_info *fi) { (void) fi; (void) offset; int res=0; int action = COPY; ssize_t vsize = 0; char *tval = NULL; char fpath[PATH_MAX]; xmp_getfullpath(fpath, path); vsize = getxattr(fpath, XATRR_ENCRYPTED_FLAG, NULL, 0); tval = malloc(sizeof(*tval)*(vsize)); vsize = getxattr(fpath, XATRR_ENCRYPTED_FLAG, tval, vsize); if (vsize < 0 || memcmp(tval, "false", 5) == 0){ if(errno == ENODATA){ fprintf(stderr, "Encryption flag not set, file cannot be read.\n"); } fprintf(stderr, "File unencrypted, reading...\n"); } /* If the attribute exists and is true get size of decrypted file */ else if (memcmp(tval, "true", 4) == 0){ fprintf(stderr, "File encrypted, decrypting...\n"); action = DECRYPT; } /* If the file to be written to is encrypted */ if (action == DECRYPT){ FILE *fd = fopen(fpath, "rb+"); const char *tpath = ftemp(fpath, ".write"); FILE *dfd = fopen(tpath, "wb+"); fseek(fd, 0, SEEK_END); fseek(fd, 0, SEEK_SET); if(!do_crypt(fd, dfd, DECRYPT, ENCFS_DATA->passkey)){ fprintf(stderr, "Decryption failed, error code: %d\n", res); } fseek(fd, 0, SEEK_SET); res = fwrite(buf, 1, size, dfd); if (res == -1) res = -errno; fseek(dfd, 0, SEEK_SET); if(!do_crypt(dfd, fd, ENCRYPT, ENCFS_DATA->passkey)){ fprintf(stderr, "Encryption failed, error code: %d\n", res); } fclose(fd); fclose(dfd); remove(tpath); } /* If the file to be written to is unencrypted */ else if (action == COPY){ int fd1; fprintf(stderr, "File unencrypted, reading...\n"); fd1 = open(fpath, O_WRONLY); if (fd1 == -1) return -errno; res = pwrite(fd1, buf, size, offset); if (res == -1) res = -errno; close(fd1); } free(tval); return res; }
void ADIOI_XFS_WriteContig(ADIO_File fd, void *buf, int count, MPI_Datatype datatype, int file_ptr_type, ADIO_Offset offset, ADIO_Status *status, int *error_code) { int err=-1, datatype_size, len, diff, size, nbytes; void *newbuf; static char myname[] = "ADIOI_XFS_WRITECONTIG"; MPI_Type_size(datatype, &datatype_size); len = datatype_size * count; fd->fp_sys_posn = -1; /* set it to null, since we are using pwrite */ if (file_ptr_type == ADIO_INDIVIDUAL) offset = fd->fp_ind; if (!(fd->direct_write)) /* direct I/O not enabled */ err = pwrite(fd->fd_sys, buf, len, offset); else { /* direct I/O enabled */ /* (1) if mem_aligned && file_aligned use direct I/O to write up to correct io_size use buffered I/O for remaining */ if (!(((long) buf) % fd->d_mem) && !(offset % fd->d_miniosz)) ADIOI_XFS_Aligned_Mem_File_Write(fd, buf, len, offset, &err); /* (2) if !file_aligned use buffered I/O to write up to file_aligned At that point, if still mem_aligned, use (1) else copy into aligned buf and then use (1) */ else if (offset % fd->d_miniosz) { diff = fd->d_miniosz - (offset % fd->d_miniosz); diff = ADIOI_MIN(diff, len); nbytes = pwrite(fd->fd_sys, buf, diff, offset); buf = ((char *) buf) + diff; offset += diff; size = len - diff; if (!(((long) buf) % fd->d_mem)) { ADIOI_XFS_Aligned_Mem_File_Write(fd, buf, size, offset, &err); nbytes += err; } else { newbuf = (void *) memalign(XFS_MEMALIGN, size); if (newbuf) { memcpy(newbuf, buf, size); ADIOI_XFS_Aligned_Mem_File_Write(fd, newbuf, size, offset, &err); nbytes += err; free(newbuf); } else nbytes += pwrite(fd->fd_sys, buf, size, offset); } err = nbytes; } /* (3) if !mem_aligned && file_aligned copy into aligned buf, then use (1) */ else { newbuf = (void *) memalign(XFS_MEMALIGN, len); if (newbuf) { memcpy(newbuf, buf, len); ADIOI_XFS_Aligned_Mem_File_Write(fd, newbuf, len, offset, &err); free(newbuf); } else err = pwrite(fd->fd_sys, buf, len, offset); } } if (file_ptr_type == ADIO_INDIVIDUAL) fd->fp_ind += err; #ifdef HAVE_STATUS_SET_BYTES if (err != -1) MPIR_Status_set_bytes(status, datatype, err); #endif if (err == -1) { *error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_IO, "**io", "**io %s", strerror(errno)); } else *error_code = MPI_SUCCESS; }
int main(int argc, char **argv) { unsigned long startofs = 0, part_size = 0; unsigned long ezones = 0, ezone = 0, bad_zones = 0; unsigned char unit_factor = 0xFF; long MediaUnit1 = -1, MediaUnit2 = -1; unsigned char oobbuf[16]; struct mtd_oob_buf oob = {0, 16, oobbuf}; printf("$Id: nftl_format.c,v 1.1.1.1 2006-07-11 09:31:28 andy Exp $\n"); if (argc < 2) { fprintf(stderr, "Usage: %s <mtddevice> [<start offset> [<size>]]\n", argv[0]); return 1; } if (argc > 2) { startofs = strtoul(argv[2], NULL, 0); } if (argc > 3) { part_size = strtoul(argv[3], NULL, 0); } // Open and size the device if ((fd = open(argv[1], O_RDWR)) < 0) { perror("Open flash device"); return 1; } if (ioctl(fd, MEMGETINFO, &meminfo) != 0) { perror("ioctl(MEMGETINFO)"); close(fd); return 1; } switch (meminfo.erasesize) { case 0x1000: case 0x2000: case 0x4000: break; default: printf("Unrecognized Erase size, 0x%x - I'm confused\n", meminfo.erasesize); close(fd); return 1; } writebuf[0] = malloc(meminfo.erasesize * 5); if (!writebuf[0]) { printf("Malloc failed\n"); close(fd); return 1; } writebuf[1] = writebuf[0] + meminfo.erasesize; writebuf[2] = writebuf[1] + meminfo.erasesize; writebuf[3] = writebuf[2] + meminfo.erasesize; readbuf = writebuf[3] + meminfo.erasesize; memset(writebuf[0], 0xff, meminfo.erasesize); memset(writebuf[1], 0x00, meminfo.erasesize); memset(writebuf[2], 0x5a, meminfo.erasesize); memset(writebuf[3], 0xa5, meminfo.erasesize); memset(BadUnitTable, ZONE_GOOD, MAX_ERASE_ZONES); if (part_size == 0 || (part_size > meminfo.size - startofs)) /* the user doest not or incorrectly specify NFTL partition size */ part_size = meminfo.size - startofs; erase.length = meminfo.erasesize; ezones = part_size / meminfo.erasesize; if (ezones > MAX_ERASE_ZONES) { /* Ought to change the UnitSizeFactor. But later. */ part_size = meminfo.erasesize * MAX_ERASE_ZONES; ezones = MAX_ERASE_ZONES; unit_factor = 0xFF; } /* Phase 1. Erasing and checking each erase zones in the NFTL partition. N.B. Erase Zones not used by the NFTL partition are untouched and marked ZONE_GOOD */ printf("Phase 1. Checking and erasing Erase Zones from 0x%08lx to 0x%08lx\n", startofs, startofs + part_size); for (ezone = startofs / meminfo.erasesize; ezone < (ezones + startofs / meminfo.erasesize); ezone++) { if ((BadUnitTable[ezone] = erase_block(ezone)) == ZONE_GOOD) { if (MediaUnit1 == -1) { MediaUnit1 = ezone; } else if (MediaUnit2 == -1) { MediaUnit2 = ezone; } } else { bad_zones++; } } printf("\n"); /* N.B. from dump of M-System original chips, NumEraseUnits counts the 2 Erase Unit used by MediaHeader and the FirstPhysicalEUN starts from the MediaHeader */ NFTLhdr = (struct NFTLMediaHeader *) (writebuf[0]); strcpy(NFTLhdr->DataOrgID, "ANAND"); NFTLhdr->NumEraseUnits = cpu_to_le16(part_size / meminfo.erasesize); NFTLhdr->FirstPhysicalEUN = cpu_to_le16(MediaUnit1); /* N.B. we reserve 2 more Erase Units for "folding" of Virtual Unit Chain */ NFTLhdr->FormattedSize = cpu_to_le32(part_size - ( (5+bad_zones) * meminfo.erasesize)); NFTLhdr->UnitSizeFactor = unit_factor; /* Phase 2. Writing NFTL Media Headers and Bad Unit Table */ printf("Phase 2.a Writing NFTL Media Header and Bad Unit Table\n"); pwrite(fd, writebuf[0], 512, MediaUnit1 * meminfo.erasesize); for (ezone = 0; ezone < (meminfo.size / meminfo.erasesize); ezone += 512) { pwrite(fd, BadUnitTable + ezone, 512, (MediaUnit1 * meminfo.erasesize) + 512 * (1 + ezone / 512)); } #if 0 printf(" MediaHeader contents:\n"); printf(" NumEraseUnits: %d\n", le16_to_cpu(NFTLhdr->NumEraseUnits)); printf(" FirstPhysicalEUN: %d\n", le16_to_cpu(NFTLhdr->FirstPhysicalEUN)); printf(" FormattedSize: %d (%d sectors)\n", le32_to_cpu(NFTLhdr->FormattedSize), le32_to_cpu(NFTLhdr->FormattedSize)/512); #endif printf("Phase 2.b Writing Spare NFTL Media Header and Spare Bad Unit Table\n"); pwrite(fd, writebuf[0], 512, MediaUnit2 * meminfo.erasesize); for (ezone = 0; ezone < (meminfo.size / meminfo.erasesize); ezone += 512) { pwrite(fd, BadUnitTable + ezone, 512, (MediaUnit2 * meminfo.erasesize) + 512 * (1 + ezone / 512)); } /* UCI #1 for newly erased Erase Unit */ memset(oobbuf, 0xff, 16); oobbuf[11] = oobbuf[10] = oobbuf[9] = 0; oobbuf[8] = 0x03; oobbuf[12] = oobbuf[14] = 0x69; oobbuf[13] = oobbuf[15] = 0x3c; /* N.B. The Media Header and Bad Erase Unit Table are considered as Free Erase Unit by M-System i.e. their Virtual Unit Number == 0xFFFF in the Unit Control Information #0, but their Block Status is BLOCK_USED (0x5555) in their Block Control Information */ /* Phase 3. Writing Unit Control Information for each Erase Unit */ printf("Phase 3. Writing Unit Control Information to each Erase Unit\n"); for (ezone = cpu_to_le16(NFTLhdr->FirstPhysicalEUN); ezone < (ezones + startofs / meminfo.erasesize); ezone++) { /* write UCI #1 to each Erase Unit */ if (BadUnitTable[ezone] != ZONE_GOOD) continue; oob.start = (ezone * meminfo.erasesize) + 512; if (ioctl(fd, MEMWRITEOOB, &oob)) printf("MEMWRITEOOB at %lx: %s\n", (unsigned long)oob.start, strerror(errno)); } exit(0); }
static int xmp_read(const char *path, char *buf, size_t size, off_t offset, struct fuse_file_info *fi) { int fd; ino_t ino; int res = 0; static int cnt = 0; struct loop_file_info *info = (struct loop_file_info *) (unsigned long) fi->fh; fd = info->fd; ino = info->ino; if (fd == -1) return -errno; if (size > max_block_size) { return -ENOMEM; } if (fp_sync) { fprintf(fp_sync, "cnt %d read %s inode %llu size %lu off %ld\n", cnt, path, (unsigned long long) ino, size, offset); fflush(fp_sync); cnt++; } /* fill in the request */ sem_t sem; sem_init(&sem, 0, 0); struct cache_entry response; struct elm_read_req req = { .fd = fd, .ino = ino, .size = size, .offset = offset, .sem = &sem, .refcnt = 1, .p_response = &response }; /* check for already cached */ pthread_mutex_lock(&cache_lock); int get_rc; struct cache_entry *result; get_rc = cache->cache_lookup(cache, &req, &result); if (get_rc == 0 && result->rc > 0) { memcpy(buf, result->data, result->rc); fprintf(fp_sync, "Found record already cached " "ref = %d data = %p rc = %ld\n", *result->refcnt, result->data, result->rc); fflush(fp_sync); if (result->rc > 0) { cache_hit_bytes += result->rc; } cache_report(fp_sync, cache_hit_bytes, cache_miss_bytes); res = result->rc; pthread_mutex_unlock(&cache_lock); } else if (get_rc == -1) { pthread_mutex_unlock(&cache_lock); return -EIO; } else { pthread_mutex_unlock(&cache_lock); pthread_mutex_lock(&req_queue_lock); if (circ_enq(&req_queue, &req)) { return -EBUSY; } } int i; struct elm_read_req prefetch_req = req; for (i=0; i<prefetch_aggressiveness; i++) { prefetch_req.offset += prefetch_req.size; prefetch_req.sem = NULL; prefetch_req.refcnt = 0; prefetch_req.p_response = NULL; if (prefetch_req.offset + prefetch_req.size > info->st_buf.st_size) { /* XXX */ break; } /* Prefetch requests are advisory only. * If the queue is full, it may not be an error. */ if (circ_enq(&req_queue, &prefetch_req)) { break; } } int q_cnt = circ_cnt(&req_queue); fprintf(fp_sync, "req_queue_cnt = %d\n", q_cnt); fflush(fp_sync); pthread_cond_signal(&req_condition); pthread_mutex_unlock(&req_queue_lock); if (get_rc == 0) { /* If it was already in cache no need to wait. */ return res; } /* Wait for the response */ sem_wait(&sem); fprintf(fp_sync, "got response\n"); fflush(fp_sync); pthread_mutex_lock(&cache_lock); /* Check the response */ result = &response; if (result->rc >= 0) { memcpy(buf, result->data, result->rc); } res = result->rc; if (*result->refcnt > 0) { *result->refcnt -= 1; } cache_report(fp_sync, cache_hit_bytes, cache_miss_bytes); pthread_mutex_unlock(&cache_lock); sem_destroy(&sem); return res; } static int xmp_write(const char *path, const char *buf, size_t size, off_t offset, struct fuse_file_info *fi) { int fd; int res; (void) fi; fd = open(path, O_WRONLY); if (fd == -1) return -errno; res = pwrite(fd, buf, size, offset); if (res == -1) res = -errno; close(fd); return res; }
static int cfs_write(const char *path, const char *buf, size_t length, off_t offset, struct fuse_file_info *info) { update_dir_cache(path, offset + length, 0, 0); return pwrite(((openfile *)(uintptr_t)info->fh)->fd, buf, length, offset); }
int resize_gpt_partition(const char *devname, __u64 new_size) { unsigned char buf[SECTOR_SIZE*GPT_DATA_SIZE]; // LBA1 header, LBA2-34 partition entry int fd; int part, ret; struct GptHeader *pt; struct GptEntry *pe; __u32 pt_crc32, pe_crc32, orig_crc; off_t size; __u64 tmp; ret = has_partition(devname, &part); if (ret) return ret; if (!part) return 0; ret = ploop_get_size(devname, &size); if (ret) return ret; // Resize up to max available space if (new_size == 0) new_size = size; if (new_size > size) { ploop_err(0, "Unable to resize GPT partition:" " incorrect parameter new_size=%llu size=%lu", new_size, (long)size); return SYSEXIT_PARAM; } ploop_log(1, "Resizing GPT partition to %ld", (long)new_size); fd = open(devname, O_RDWR); if (fd == -1) { ploop_err(errno, "open %s", devname); return SYSEXIT_OPEN; } // skip LBA0 Protective MBR ret = pread(fd, buf, sizeof(buf), SECTOR_SIZE); if (ret == -1) { ploop_err(errno, "pread %s", devname); goto err; } pt = (struct GptHeader *)buf; pe = (struct GptEntry *)(&buf[SECTOR_SIZE * GPT_HEADER_SIZE]); // Validate crc orig_crc = pt->header_crc32; pt->header_crc32 = 0; pt_crc32 = ploop_crc32((unsigned char *)pt, pt->header_size); if (pt_crc32 != orig_crc) { ploop_err(0, "GPT validation failed orig crc %x != %x", orig_crc, pt_crc32); ret = -1; goto err; } // change GPT header pt->alternate_lba = new_size - 1; pt->last_usable_lba = new_size - GPT_DATA_SIZE - 1; pe->ending_lba = (pt->last_usable_lba >> 3 << 3) - 1; // Recalculate crc32 pe_crc32 = ploop_crc32((unsigned char *)pe, SECTOR_SIZE * GPT_PT_ENTRY_SIZE); pt->partition_entry_array_crc32 = pe_crc32; pt->header_crc32 = 0; pt_crc32 = ploop_crc32((unsigned char *)pt, pt->header_size); pt->header_crc32 = pt_crc32; ploop_log(0, "Storing GPT"); ret = pwrite(fd, pt, SECTOR_SIZE * GPT_DATA_SIZE, SECTOR_SIZE); if (ret == -1) { ploop_err(errno, "Failed to store primary GPT %s", devname); goto err; } ret = fsync(fd); if (ret) { ploop_err(errno, "Can't fsync %s", devname); ret = SYSEXIT_FSYNC; goto err; } // Store secondary GPT entries tmp = pt->my_lba; pt->my_lba = pt->alternate_lba; pt->alternate_lba = tmp; pt->partition_entry_lba = pt->last_usable_lba + 1; // Recalculate crc32 pt->header_crc32 = 0; pt_crc32 = ploop_crc32((unsigned char *)pt, pt->header_size); pt->header_crc32 = pt_crc32; ret = pwrite(fd, pe, SECTOR_SIZE * GPT_PT_ENTRY_SIZE, (new_size - GPT_DATA_SIZE)*SECTOR_SIZE); if (ret == -1) { ploop_err(errno, "Failed to store secondary GPT %s", devname); goto err; } // Store Secondary GPT header ret = pwrite(fd, pt, SECTOR_SIZE, (new_size - GPT_HEADER_SIZE)*SECTOR_SIZE); if (ret == -1) { ploop_err(errno, "Failed to store secondary GPT header %s", devname); goto err; } if (fsync(fd)) { ploop_err(errno, "Can't fsync %s", devname); ret = SYSEXIT_FSYNC; goto err; } blkpg_resize_partition(fd, pe); ret = 0; err: close(fd); if (ret < 0) ret = SYSEXIT_CHANGE_GPT; return ret; }
static int fifolog_write_output(struct fifolog_writer *f, int fl, time_t now) { long h, l = f->ff->zs->next_out - f->obuf; ssize_t i, w; int retval = 0; h = 4; /* seq */ be32enc(f->obuf, f->seq); f->obuf[h] = f->flag; h += 1; /* flag */ if (f->flag & FIFOLOG_FLG_SYNC) { be32enc(f->obuf + h, now); h += 4; /* timestamp */ } assert(l <= (long)f->ff->recsize); /* NB: l includes h */ assert(l >= h); /* We will never write an entirely empty buffer */ if (l == h) return (0); if (l < (long)f->ff->recsize && fl == Z_NO_FLUSH) return (0); w = f->ff->recsize - l; if (w > 255) { be32enc(f->obuf + f->ff->recsize - 4, w); f->obuf[4] |= FIFOLOG_FLG_4BYTE; } else if (w > 0) { f->obuf[f->ff->recsize - 1] = (uint8_t)w; f->obuf[4] |= FIFOLOG_FLG_1BYTE; } f->cnt[FIFOLOG_PT_BYTES_POST] += l - h; i = pwrite(f->ff->fd, f->obuf, f->ff->recsize, (f->recno + 1) * f->ff->recsize); if (i != f->ff->recsize) retval = -1; else retval = 1; f->cnt[FIFOLOG_PT_WRITES]++; f->cnt[FIFOLOG_PT_RUNTIME] = now - f->starttime; f->lastwrite = now; /* * We increment these even on error, so as to properly skip bad, * sectors or other light trouble. */ f->seq++; f->recno++; f->flag = 0; memset(f->obuf, 0, f->obufsize); f->ff->zs->next_out = f->obuf + 5; f->ff->zs->avail_out = f->obufsize - 5; return (retval); }
glio_arena_t * _glio_arena_create( glio_group_t *gg, /* group of processes to share access */ size_t asize) /* arena size (bytes per process) */ { char *fname, *fncpy; int fd; int groupsz; int namelen; int myrank; size_t arena_size; glio_arena_t *arp; shmem_group_t shg; void *aret; MPI_Comm comm; MPI_Status mpistatus; groupsz = gg->groupsz; myrank = gg->myrank; arp = malloc(sizeof(*arp)); if (arp == NULL) { fprintf(stderr,"%s:\n\ _glio_arena_create(a) could not allocate a memory object of size %lld bytes\n", GLOBERRMSG, (long long)sizeof(*arp)); abort(); } bzero(arp, sizeof(*arp)); arp->grp = *gg; /* copy it */ gg = &arp->grp; /* point to the new copy */ /* * Process with rank 0 finds a unique new file name to use as * a memory mapped file. */ if (myrank == 0) { fname = NULL; do { if (fname != NULL) free(fname); fname = tempnam(NULL, "glio_arena"); assert(fname != NULL); fd = open(fname, O_CREAT | O_EXCL | O_RDWR, 0700); } while (fd == -1 && errno == EEXIST); } /* * Trivial groups of size 1 can be handled trivially. */ if (groupsz == 1) goto past_file_name_send; _glio_barrier(arp); /* * Initialization */ switch (gg->grtype) { case GR_SHMEM: if ( _shmem_group_inquire != NULL) { _shmem_group_inquire(arp->grp.u.shmem.group, &shg); } else { /* Special case for pre-release versions of MPT 1.2 */ static int *world_plist; static int *world_racom; /* if pre-release version of MPT 1.2 is used, then all */ /* PEs are in the group */ assert (groupsz == _num_pes()); if (world_plist == NULL) { register short ipe; world_plist = malloc(_num_pes() * sizeof(int)); if (world_plist == NULL) { fprintf(stderr,"%s:\n\ _glio_arena_create(b) could not allocate a memory object of size %lld bytes\n", GLOBERRMSG, (long long)(_num_pes() * sizeof(int))); abort(); } world_racom = shmalloc(SHMEM_GROUP_COM_SIZE * sizeof(int)); assert(world_racom != NULL); bzero(world_racom, 10*sizeof(int)); for (ipe = 0; ipe < _num_pes(); ipe++) world_plist[ipe] = ipe; } shg.groupsz = _num_pes(); shg.myrank = _my_pe(); shg.plist = world_plist; shg.racom = world_racom; } break; case GR_MPI: comm = arp->grp.u.MPI.comm; break; default: break; } /* * Process 0 now must communicate the file name to all other * processes in the group. */ switch (gg->grtype) { case GR_SHMEM: if (myrank == 0) { void *vp; fncpy = _sma_global_heap_alloc(strlen(fname)+1); assert(fncpy != NULL); strcpy(fncpy, fname); vp = fncpy; /* racom[1] gets string length */ shg.racom[1] = strlen(fname); /* racom[2] and racom[3] get the pointer */ /* to the string. */ memcpy(&shg.racom[2], &vp, sizeof(vp)); } _glio_barrier(arp); /* * Other processes now get the file name. */ if (myrank != 0) { void *vp; namelen = _shmem_int_g( &shg.racom[1], shg.plist[0]); assert(namelen > 0); /* get pointer to the string */ _shmem_getmem(&vp, &shg.racom[2], sizeof(vp), shg.plist[0]); fname = malloc(namelen + 1); if (fname == NULL) { fprintf(stderr,"%s:\n\ _glio_arena_create(c) could not allocate a memory object of size %lld bytes\n", GLOBERRMSG, (long long)(namelen + 1)); abort(); } /* copy the string */ _shmem_getmem(fname, vp, namelen, shg.plist[0]); fname[namelen] = '\0'; } _glio_barrier(arp); if (myrank == 0) { _sma_global_heap_free(fncpy); } break; case GR_MPI: if (myrank == 0) { register int rank; namelen = strlen(fname); for (rank = 1; rank < groupsz; rank++) { ckMPIerr( MPI_Send(&namelen, 1, MPI_INT, rank, 1, comm) ); } for (rank = 1; rank < groupsz; rank++) { ckMPIerr( MPI_Send(fname, namelen, MPI_CHAR, rank, 2, comm) ); } } else { ckMPIerr( MPI_Recv(&namelen, 1, MPI_INT, 0, 1, comm, &mpistatus) ); fname = malloc(namelen + 1); if (fname == NULL) { fprintf(stderr,"%s:\n\ _glio_arena_create(d) could not allocate a memory object of size %lld bytes\n", GLOBERRMSG, (long long)(namelen + 1)); abort(); } ckMPIerr( MPI_Recv(fname, namelen, MPI_CHAR, 0, 2, comm, &mpistatus) ); fname[namelen] = '\0'; } break; default: assert(0); } _glio_barrier(arp); /* * Non-rank-0 processes now open the file. */ if (myrank != 0) { fd = open(fname, O_RDWR, 0700); if (fd == -1) { fprintf(stderr, "%s:\n\ Global I/O failed to open mapped file. Errno is %d\n", GLOBERRMSG, errno); abort(); } } _glio_barrier(arp); past_file_name_send: /* * All processes have opened the file, so rank 0 may now unlink it. */ if (myrank == 0) { unlink(fname); } _glio_barrier(arp); /* * After the barrier process 0 may initialize the mapped * file and unlink it because we know that all processes in the * group have now opened this file. */ arena_size = groupsz * CEILING(asize, 1024); if (myrank == 0) { ssize_t wret; wret = pwrite(fd, " ", 1, arena_size - 1); assert(wret != -1L); } _glio_barrier(arp); /* * A barrier assures us that the file has been initialized * to the right size. Now map the file into every process' * address space. */ aret = mmap64(NULL, arena_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); if (aret == MAP_FAILED) { fprintf(stderr,"%s:\n\ Cannot map internal file %s\n\ for shared memory arena. Error = %d\n", GLOBERRMSG, fname, errno); abort(); }
/** * write() equivalent * * @param path the path of the file to be written * @param buf buffer holding write() data * @param size how many bytes should be written (size of *buf) * @param offset starting of the write * @param fi struct fuse_file_info used for open() flags * @return(0 on success, -errno otherwise) */ int tagsistant_write(const char *path, const char *buf, size_t size, off_t offset, struct fuse_file_info *fi) { int res = 0, tagsistant_errno = 0, fh = 0; TAGSISTANT_START("WRITE on %s [size: %lu offset: %lu]", path, (unsigned long) size, (long unsigned int) offset); tagsistant_querytree *qtree = tagsistant_querytree_new(path, 0, 0, 1, 1); // -- malformed -- if (QTREE_IS_MALFORMED(qtree)) TAGSISTANT_ABORT_OPERATION(ENOENT); // -- alias -- if (QTREE_IS_ALIAS(qtree) && qtree->alias) { res = size; gchar *_buf = g_strndup(buf, size); // end the string at the first carriage return or line feed character gchar *path_ptr = rindex(_buf, '\n'); if (path_ptr) *path_ptr = '/'; path_ptr = rindex(_buf, '\r'); if (path_ptr) *path_ptr = '/'; // remove double slashes GRegex *rx = g_regex_new("//", 0, 0, NULL); gchar *_buf2 = g_regex_replace(rx, _buf, -1, 0, "/", 0, NULL); g_regex_unref(rx); g_free(_buf); _buf = _buf2; // get the size of the buffer size_t max_size = MIN(size, TAGSISTANT_ALIAS_MAX_LENGTH - 1); size_t real_size = MIN(max_size, strlen(_buf)); // copy the buffer to a temporary variable gchar *value = g_strndup(_buf, real_size); // save the buffer on disk tagsistant_sql_alias_set(qtree->dbi, qtree->alias, value); g_free(value); g_free(_buf); } else // -- object on disk -- if (QTREE_POINTS_TO_OBJECT(qtree)) { if (!qtree->full_archive_path) { dbg('F', LOG_ERR, "Null qtree->full_archive_path"); TAGSISTANT_ABORT_OPERATION(EFAULT); } #if TAGSISTANT_ENABLE_FILE_HANDLE_CACHING if (fi->fh) { tagsistant_get_file_handle(fi, fh); res = pwrite(fh, buf, size, offset); tagsistant_errno = errno; } if ((-1 == res) || (0 == fh)) { if (fh) close(fh); fh = open(qtree->full_archive_path, fi->flags|O_WRONLY); if (fh) res = pwrite(fh, buf, size, offset); else res = -1; tagsistant_errno = errno; } tagsistant_set_file_handle(fi, fh); #else fh = open(qtree->full_archive_path, fi->flags|O_WRONLY); if (fh) { res = pwrite(fh, buf, size, offset); tagsistant_errno = errno; close(fh); } else { TAGSISTANT_ABORT_OPERATION(errno); } #endif } // -- tags -- // -- stats -- // -- relations -- else TAGSISTANT_ABORT_OPERATION(EROFS); // dbg('F', LOG_ERR, "Yeah!"); TAGSISTANT_EXIT_OPERATION: if ( res == -1 ) { TAGSISTANT_STOP_ERROR("WRITE %s (%s) (%s): %d %d: %s", path, qtree->full_archive_path, tagsistant_querytree_type(qtree), res, tagsistant_errno, strerror(tagsistant_errno)); tagsistant_querytree_destroy(qtree, TAGSISTANT_ROLLBACK_TRANSACTION); return (-tagsistant_errno); } else { TAGSISTANT_STOP_OK("WRITE %s (%s): OK", path, tagsistant_querytree_type(qtree)); tagsistant_querytree_destroy(qtree, TAGSISTANT_COMMIT_TRANSACTION); return (res); } }
static void * rtems_aio_handle (void *arg) { rtems_aio_request_chain *r_chain = arg; rtems_aio_request *req; rtems_chain_control *chain; rtems_chain_node *node; int result, policy; struct sched_param param; AIO_printf ("Thread started\n"); while (1) { /* acquire the mutex of the current fd chain. we don't need to lock the queue mutex since we can add requests to idle fd chains or even active ones if the working request has been extracted from the chain */ result = pthread_mutex_lock (&r_chain->mutex); if (result != 0) return NULL; chain = &r_chain->perfd; /* If the locked chain is not empty, take the first request extract it, unlock the chain and process the request, in this way the user can supply more requests to this fd chain */ if (!rtems_chain_is_empty (chain)) { AIO_printf ("Get new request from not empty chain\n"); node = rtems_chain_first (chain); req = (rtems_aio_request *) node; /* See _POSIX_PRIORITIZE_IO and _POSIX_PRIORITY_SCHEDULING discussion in rtems_aio_enqueue () */ pthread_getschedparam (pthread_self(), &policy, ¶m); param.sched_priority = req->priority; pthread_setschedparam (pthread_self(), req->policy, ¶m); rtems_chain_extract (node); pthread_mutex_unlock (&r_chain->mutex); switch (req->aiocbp->aio_lio_opcode) { case LIO_READ: AIO_printf ("read\n"); result = pread (req->aiocbp->aio_fildes, (void *) req->aiocbp->aio_buf, req->aiocbp->aio_nbytes, req->aiocbp->aio_offset); break; case LIO_WRITE: AIO_printf ("write\n"); result = pwrite (req->aiocbp->aio_fildes, (void *) req->aiocbp->aio_buf, req->aiocbp->aio_nbytes, req->aiocbp->aio_offset); break; case LIO_SYNC: AIO_printf ("sync\n"); result = fsync (req->aiocbp->aio_fildes); break; default: result = -1; } if (result == -1) { req->aiocbp->return_value = -1; req->aiocbp->error_code = errno; } else { req->aiocbp->return_value = result; req->aiocbp->error_code = 0; } // notification needed for lio } else { /* If the fd chain is empty we unlock the fd chain and we lock the queue chain, this will ensure that we have at most one request comming to our fd chain when we check. If there was no request added sleep for 3 seconds and wait for a signal on chain, this will unlock the queue. The fd chain is already unlocked */ struct timespec timeout; AIO_printf ("Chain is empty [WQ], wait for work\n"); pthread_mutex_unlock (&r_chain->mutex); pthread_mutex_lock (&aio_request_queue.mutex); if (rtems_chain_is_empty (chain)) { clock_gettime (CLOCK_REALTIME, &timeout); timeout.tv_sec += 3; timeout.tv_nsec = 0; result = pthread_cond_timedwait (&r_chain->cond, &aio_request_queue.mutex, &timeout); /* If no requests were added to the chain we delete the fd chain from the queue and start working with idle fd chains */ if (result == ETIMEDOUT) { rtems_chain_extract (&r_chain->next_fd); pthread_mutex_destroy (&r_chain->mutex); pthread_cond_destroy (&r_chain->cond); free (r_chain); /* If the idle chain is empty sleep for 3 seconds and wait for a signal. The thread now becomes idle. */ if (rtems_chain_is_empty (&aio_request_queue.idle_req)) { AIO_printf ("Chain is empty [IQ], wait for work\n"); ++aio_request_queue.idle_threads; --aio_request_queue.active_threads; clock_gettime (CLOCK_REALTIME, &timeout); timeout.tv_sec += 3; timeout.tv_nsec = 0; result = pthread_cond_timedwait (&aio_request_queue.new_req, &aio_request_queue.mutex, &timeout); /* If no new fd chain was added in the idle requests then this thread is finished */ if (result == ETIMEDOUT) { AIO_printf ("Etimeout\n"); --aio_request_queue.idle_threads; pthread_mutex_unlock (&aio_request_queue.mutex); return NULL; } } /* Otherwise move this chain to the working chain and start the loop all over again */ AIO_printf ("Work on idle\n"); --aio_request_queue.idle_threads; ++aio_request_queue.active_threads; node = rtems_chain_first (&aio_request_queue.idle_req); rtems_chain_extract (node); r_chain = (rtems_aio_request_chain *) node; rtems_aio_move_to_work (r_chain); } } /* If there was a request added in the initial fd chain then release the mutex and process it */ pthread_mutex_unlock (&aio_request_queue.mutex); } } AIO_printf ("Thread finished\n"); return NULL; }
void main(int argc, char *argv[]) { int fd, i; int n = 1000, m; int s = 1; double *t, t0, t1; unsigned char *buf; double a, d, max, min; m = OREAD; ARGBEGIN{ case 'n': n = atoi(ARGF()); break; case 's': s = unittoull(ARGF()); if(s < 1 || s > 1024*1024) sysfatal("bad size"); break; case 'r': m = OREAD; break; case 'w': m = OWRITE; break; }ARGEND fd = 0; if(argc == 1){ fd = open(argv[0], m); if(fd < 0) sysfatal("could not open file: %s: %r", argv[0]); } buf = malloc(s); t = malloc(n*sizeof(double)); t0 = nsec(); for(i=0; i<n; i++){ if(m == OREAD){ if(pread(fd, buf, s, 0) < s) sysfatal("bad read: %r"); }else{ if(pwrite(fd, buf, s, 0) < s) sysfatal("bad write: %r"); } t1 = nsec(); t[i] = (t1 - t0)*1e-3; t0 = t1; } a = 0.; d = 0.; max = 0.; min = 1e12; for(i=0; i<n; i++){ a += t[i]; if(max < t[i]) max = t[i]; if(min > t[i]) min = t[i]; } a /= n; for(i=0; i<n; i++) d += (a - t[i]) * (a - t[i]); d /= n; d = sqrt(d); print("avg = %.0fµs min = %.0fµs max = %.0fµs dev = %.0fµs\n", a, min, max, d); exits(0); }
static int copy_one_extent(struct btrfs_root *root, int fd, struct extent_buffer *leaf, struct btrfs_file_extent_item *fi, u64 pos) { struct btrfs_multi_bio *multi = NULL; struct btrfs_device *device; char *inbuf, *outbuf = NULL; ssize_t done, total = 0; u64 bytenr; u64 ram_size; u64 disk_size; u64 num_bytes; u64 length; u64 size_left; u64 dev_bytenr; u64 offset; u64 count = 0; int compress; int ret; int dev_fd; int mirror_num = 1; int num_copies; compress = btrfs_file_extent_compression(leaf, fi); bytenr = btrfs_file_extent_disk_bytenr(leaf, fi); disk_size = btrfs_file_extent_disk_num_bytes(leaf, fi); ram_size = btrfs_file_extent_ram_bytes(leaf, fi); offset = btrfs_file_extent_offset(leaf, fi); num_bytes = btrfs_file_extent_num_bytes(leaf, fi); size_left = disk_size; if (compress == BTRFS_COMPRESS_NONE) bytenr += offset; if (verbose && offset) printf("offset is %Lu\n", offset); /* we found a hole */ if (disk_size == 0) return 0; inbuf = malloc(size_left); if (!inbuf) { error("not enough memory"); return -ENOMEM; } if (compress != BTRFS_COMPRESS_NONE) { outbuf = calloc(1, ram_size); if (!outbuf) { error("not enough memory"); free(inbuf); return -ENOMEM; } } again: length = size_left; ret = btrfs_map_block(root->fs_info, READ, bytenr, &length, &multi, mirror_num, NULL); if (ret) { error("cannot map block logical %llu length %llu: %d", (unsigned long long)bytenr, (unsigned long long)length, ret); goto out; } device = multi->stripes[0].dev; dev_fd = device->fd; device->total_ios++; dev_bytenr = multi->stripes[0].physical; free(multi); if (size_left < length) length = size_left; done = pread(dev_fd, inbuf+count, length, dev_bytenr); /* Need both checks, or we miss negative values due to u64 conversion */ if (done < 0 || done < length) { num_copies = btrfs_num_copies(root->fs_info, bytenr, length); mirror_num++; /* mirror_num is 1-indexed, so num_copies is a valid mirror. */ if (mirror_num > num_copies) { ret = -1; error("exhausted mirrors trying to read (%d > %d)", mirror_num, num_copies); goto out; } fprintf(stderr, "Trying another mirror\n"); goto again; } mirror_num = 1; size_left -= length; count += length; bytenr += length; if (size_left) goto again; if (compress == BTRFS_COMPRESS_NONE) { while (total < num_bytes) { done = pwrite(fd, inbuf+total, num_bytes-total, pos+total); if (done < 0) { ret = -1; error("cannot write data: %d %m", errno); goto out; } total += done; } ret = 0; goto out; } ret = decompress(root, inbuf, outbuf, disk_size, &ram_size, compress); if (ret) { num_copies = btrfs_num_copies(root->fs_info, bytenr, length); mirror_num++; if (mirror_num >= num_copies) { ret = -1; goto out; } fprintf(stderr, "Trying another mirror\n"); goto again; } while (total < num_bytes) { done = pwrite(fd, outbuf + offset + total, num_bytes - total, pos + total); if (done < 0) { ret = -1; goto out; } total += done; } out: free(inbuf); free(outbuf); return ret; }
int journal::commit() { commit_record cr; if(erasure) return -EINVAL; if(commits > playbacks) /* must play back previous commit first */ return -EINVAL; assert(playbacks == commits); if(!records) return 0; /* initialize crfd or if it is almost full add more empty records to it */ if(crfd < 0 || !(commits % (J_ADD_N_COMMITS * 1000))) if(init_crfd(istr::null) < 0) return -1; cr.offset = prev_cr.offset + prev_cr.length; cr.length = data_file.end() - cr.offset; if(checksum(cr.offset, cr.offset + cr.length, cr.checksum) < 0) return -1; #if HAVE_FSTITCH /* {{{ */ patchgroup_id_t commit; commit = patchgroup_create(0); if(commit <= 0) return -1; patchgroup_label(commit, "commit"); /* add the external dependency, if any */ assert(!ext_count); if(external > 0) { if(ext_success && patchgroup_add_depend(commit, external) < 0) goto fail; patchgroup_abandon(external); external = 0; } if(patchgroup_add_depend(commit, records) < 0) { fail: patchgroup_release(commit); patchgroup_abandon(commit); return -1; } if(last_commit > 0 && patchgroup_add_depend(commit, last_commit) < 0) goto fail; if(prev && prev->last_commit && !commits && patchgroup_add_depend(commit, prev->last_commit) < 0) goto fail; patchgroup_release(commit); if(patchgroup_engage(commit) < 0) { /* this basically can't happen */ patchgroup_abandon(commit); return -1; } #endif /* }}} */ data_file.flush(); if(pwrite(crfd, &cr, sizeof(cr), commits * sizeof(cr)) != sizeof(cr)) { #if HAVE_FSTITCH /* {{{ */ int save = errno; patchgroup_disengage(commit); /* the truncate() really should be part of records, but * since commit depends on records, we'll substitute it */ patchgroup_abandon(records); /* make sure the pointer is not past the end of the file */ errno = save; #endif /* }}} */ return -1; } #if HAVE_FSTITCH /* {{{ */ patchgroup_disengage(commit); patchgroup_abandon(records); if(last_commit) patchgroup_abandon(last_commit); last_commit = commit; #else /* }}} */ char commit_number[16]; istr old_commit, new_commit; last_commit = commits; snprintf(commit_number, sizeof(commit_number), "%d", last_commit); old_commit = path + J_COMMIT_EXT + commit_number; snprintf(commit_number, sizeof(commit_number), "%d", commits + 1); new_commit = path + J_COMMIT_EXT + commit_number; int r = renameat(dfd, old_commit, dfd, new_commit); if(r < 0) return r; #endif records = 0; ++commits; prev_cr = cr; return 0; }
int file_set_size(int fd, off_t size) { #ifdef HAVE_POSIX_FALLOCATE static bool posix_fallocate_supported = TRUE; #endif char block[IO_BLOCK_SIZE]; off_t offset; ssize_t ret; struct stat st; i_assert(size >= 0); if (fstat(fd, &st) < 0) { i_error("fstat() failed: %m"); return -1; } if (size < st.st_size) { if (ftruncate(fd, size) < 0) { i_error("ftruncate() failed: %m"); return -1; } return 0; } if (size == st.st_size) return 0; #ifdef HAVE_POSIX_FALLOCATE if (posix_fallocate_supported) { int err; err = posix_fallocate(fd, st.st_size, size - st.st_size); if (err == 0) return 0; if (err != EINVAL /* Solaris */ && err != EOPNOTSUPP /* AOX */) { if (!ENOSPACE(err)) i_error("posix_fallocate() failed: %m"); return -1; } /* Not supported by kernel, fallback to writing. */ posix_fallocate_supported = FALSE; } #endif /* start growing the file */ offset = st.st_size; memset(block, 0, I_MIN((ssize_t)sizeof(block), size - offset)); while (offset < size) { ret = pwrite(fd, block, I_MIN((ssize_t)sizeof(block), size - offset), offset); if (ret < 0) { if (!ENOSPACE(errno)) i_error("pwrite() failed: %m"); return -1; } offset += ret; } return 0; }
/** * FSAL_write: * Perform a write operation on an opened file. * * \param file_descriptor (input): * The file descriptor returned by FSAL_open. * \param p_context (input): * Authentication context for the operation (user,...). * \param seek_descriptor (optional input): * Specifies the position where data is to be written. * If not specified, data will be written at the current position. * \param buffer_size (input): * Amount (in bytes) of data to be written. * \param buffer (input): * Address in memory of the data to write to file. * \param write_amount (output): * Pointer to the amount of data (in bytes) that have been written * during this call. * * \return Major error codes: * - ERR_FSAL_NO_ERROR: no error. * - Another error code if an error occured during this call. */ fsal_status_t XFSFSAL_write(fsal_file_t * p_file_descriptor, /* IN */ fsal_op_context_t * p_context, /* IN */ fsal_seek_t * p_seek_descriptor, /* IN */ fsal_size_t buffer_size, /* IN */ caddr_t buffer, /* IN */ fsal_size_t * p_write_amount /* OUT */ ) { ssize_t nb_written; size_t i_size; int rc, errsv; int pcall = FALSE; /* sanity checks. */ if(!p_file_descriptor || !buffer || !p_write_amount) Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_write); if(((xfsfsal_file_t *)p_file_descriptor)->ro) Return(ERR_FSAL_PERM, 0, INDEX_FSAL_write); /** @todo: manage fsal_size_t to size_t convertion */ i_size = (size_t) buffer_size; *p_write_amount = 0; /* positioning */ if(p_seek_descriptor) { switch (p_seek_descriptor->whence) { case FSAL_SEEK_CUR: /* set position plus offset */ pcall = FALSE; TakeTokenFSCall(); rc = lseek(((xfsfsal_file_t *)p_file_descriptor)->fd, p_seek_descriptor->offset, SEEK_CUR); errsv = errno; ReleaseTokenFSCall(); break; case FSAL_SEEK_SET: /* set absolute position to offset */ pcall = TRUE; rc = 0; errsv = 0; break; case FSAL_SEEK_END: /* set end of file plus offset */ pcall = FALSE; TakeTokenFSCall(); rc = lseek(((xfsfsal_file_t *)p_file_descriptor)->fd, p_seek_descriptor->offset, SEEK_END); errsv = errno; ReleaseTokenFSCall(); break; default: rc = -1; errsv = EINVAL; break; } if(rc) { LogEvent(COMPONENT_FSAL, "Error in posix fseek operation (whence=%s, offset=%"PRId64")", (p_seek_descriptor->whence == FSAL_SEEK_CUR ? "SEEK_CUR" : (p_seek_descriptor->whence == FSAL_SEEK_SET ? "SEEK_SET" : (p_seek_descriptor->whence == FSAL_SEEK_END ? "SEEK_END" : "ERROR"))), p_seek_descriptor->offset); Return(posix2fsal_error(errsv), errsv, INDEX_FSAL_write); } LogFullDebug(COMPONENT_FSAL, "Write operation (whence=%s, offset=%"PRId64", size=%zu)", (p_seek_descriptor->whence == FSAL_SEEK_CUR ? "SEEK_CUR" : (p_seek_descriptor->whence == FSAL_SEEK_SET ? "SEEK_SET" : (p_seek_descriptor->whence == FSAL_SEEK_END ? "SEEK_END" : "ERROR"))), p_seek_descriptor->offset, buffer_size); } /* write operation */ TakeTokenFSCall(); if(pcall) nb_written = pwrite(((xfsfsal_file_t *)p_file_descriptor)->fd, buffer, i_size, p_seek_descriptor->offset); else nb_written = write(((xfsfsal_file_t *)p_file_descriptor)->fd, buffer, i_size); errsv = errno; ReleaseTokenFSCall(); /** @todo: manage ssize_t to fsal_size_t convertion */ if(nb_written <= 0) { LogDebug(COMPONENT_FSAL, "Write operation of size %zu at offset %"PRId64" failed. fd=%d, errno=%d.", i_size, p_seek_descriptor->offset, ((xfsfsal_file_t *)p_file_descriptor)->fd, errsv); Return(posix2fsal_error(errsv), errsv, INDEX_FSAL_write); } /* set output vars */ *p_write_amount = (fsal_size_t) nb_written; Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_write); }
static ssize_t uv__fs_write(uv_fs_t* req) { #if defined(__linux__) static int no_pwritev; #endif ssize_t r; /* Serialize writes on OS X, concurrent write() and pwrite() calls result in * data loss. We can't use a per-file descriptor lock, the descriptor may be * a dup(). */ #if defined(__APPLE__) static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER; pthread_mutex_lock(&lock); #endif if (req->off < 0) { if (req->nbufs == 1) r = write(req->file, req->bufs[0].base, req->bufs[0].len); else r = writev(req->file, (struct iovec*) req->bufs, req->nbufs); } else { if (req->nbufs == 1) { r = pwrite(req->file, req->bufs[0].base, req->bufs[0].len, req->off); goto done; } #if HAVE_PREADV r = pwritev(req->file, (struct iovec*) req->bufs, req->nbufs, req->off); #else # if defined(__linux__) if (no_pwritev) retry: # endif { off_t written; size_t index; written = 0; index = 0; r = 0; do { if (req->bufs[index].len > 0) { r = pwrite(req->file, req->bufs[index].base, req->bufs[index].len, req->off + written); if (r > 0) written += r; } index++; } while (index < req->nbufs && r >= 0); if (written > 0) r = written; } # if defined(__linux__) else { r = uv__pwritev(req->file, (struct iovec*) req->bufs, req->nbufs, req->off); if (r == -1 && errno == ENOSYS) { no_pwritev = 1; goto retry; } } # endif #endif } done: #if defined(__APPLE__) pthread_mutex_unlock(&lock); #endif if (req->bufs != req->bufsml) uv__free(req->bufs); return r; }
void runtime·badcallback(void) { runtime·pwrite(2, badcallback, sizeof badcallback - 1, -1LL); }
/* * Main program */ int main(int argc, char **argv) { int cnt, fd, ifd, imglen = 0, pagelen, baderaseblock, blockstart = -1; struct mtd_info_user meminfo; struct mtd_oob_buf oob; loff_mtd_t offs; int ret, readlen; int oobinfochanged = 0; struct nand_oobinfo old_oobinfo; printf("Warning: nandwrite_mlc instead of nandwrite is used for MLC NAND!\n"); process_options(argc, argv); memset(oobbuf, 0xff, sizeof(oobbuf)); if (pad && writeoob) { fprintf(stderr, "Can't pad when oob data is present.\n"); exit(1); } /* Open the device */ if ((fd = open(mtd_device, O_RDWR)) == -1) { perror("open flash"); exit(1); } /* Fill in MTD device capability structure */ if (ioctl(fd, MEMGETINFO, &meminfo) != 0) { perror("MEMGETINFO"); close(fd); exit(1); } /* Set erasesize to specified number of blocks - to match jffs2 * (virtual) block size */ meminfo.erasesize *= blockalign; /* Make sure device page sizes are valid */ if (!(meminfo.oobsize == 16 && meminfo.writesize == 512) && !(meminfo.oobsize == 8 && meminfo.writesize == 256) && !(meminfo.oobsize == 64 && meminfo.writesize == 2048) && !(meminfo.oobsize == 128 && meminfo.writesize == 4096)) { fprintf(stderr, "Unknown flash (not normal NAND)\n"); close(fd); exit(1); } if (autoplace) { /* Read the current oob info */ if (ioctl (fd, MEMGETOOBSEL, &old_oobinfo) != 0) { perror ("MEMGETOOBSEL"); close (fd); exit (1); } // autoplace ECC ? if (autoplace && (old_oobinfo.useecc != MTD_NANDECC_AUTOPLACE)) { if (ioctl (fd, MEMSETOOBSEL, &autoplace_oobinfo) != 0) { perror ("MEMSETOOBSEL"); close (fd); exit (1); } oobinfochanged = 1; } } if (noecc) { ret = ioctl(fd, MTDFILEMODE, (void *) MTD_MODE_RAW); if (ret == 0) { oobinfochanged = 2; } else { switch (errno) { case ENOTTY: if (ioctl (fd, MEMGETOOBSEL, &old_oobinfo) != 0) { perror ("MEMGETOOBSEL"); close (fd); exit (1); } if (ioctl (fd, MEMSETOOBSEL, &none_oobinfo) != 0) { perror ("MEMSETOOBSEL"); close (fd); exit (1); } oobinfochanged = 1; break; default: perror ("MTDFILEMODE"); close (fd); exit (1); } } } /* * force oob layout for jffs2 or yaffs ? * Legacy support */ if (forcejffs2 || forceyaffs) { struct nand_oobinfo *oobsel = forcejffs2 ? &jffs2_oobinfo : &yaffs_oobinfo; if (autoplace) { fprintf(stderr, "Autoplacement is not possible for legacy -j/-y options\n"); goto restoreoob; } if ((old_oobinfo.useecc == MTD_NANDECC_AUTOPLACE) && !forcelegacy) { fprintf(stderr, "Use -f option to enforce legacy placement on autoplacement enabled mtd device\n"); goto restoreoob; } if (meminfo.oobsize == 8) { if (forceyaffs) { fprintf (stderr, "YAFSS cannot operate on 256 Byte page size"); goto restoreoob; } /* Adjust number of ecc bytes */ jffs2_oobinfo.eccbytes = 3; } if (ioctl (fd, MEMSETOOBSEL, oobsel) != 0) { perror ("MEMSETOOBSEL"); goto restoreoob; } } oob.length = meminfo.oobsize; oob.ptr = noecc ? oobreadbuf : oobbuf; /* Open the input file */ if ((ifd = open(img, O_RDONLY)) == -1) { perror("open input file"); goto restoreoob; } // get image length imglen = lseek(ifd, 0, SEEK_END); lseek (ifd, 0, SEEK_SET); pagelen = meminfo.writesize + ((writeoob == 1) ? meminfo.oobsize : 0); // Check, if file is pagealigned if ((!pad) && ((imglen % pagelen) != 0)) { fprintf (stderr, "Input file is not page aligned\n"); goto closeall; } // Check, if length fits into device if ( ((imglen / pagelen) * meminfo.writesize) > (meminfo.size - mtdoffset)) { fprintf (stderr, "Image %d bytes, NAND page %d bytes, OOB area %u bytes, device size %llu bytes\n", imglen, pagelen, meminfo.writesize, meminfo.size); perror ("Input file does not fit into device"); goto closeall; } /* Get data from input and write to the device */ while (imglen && (mtdoffset < meminfo.size)) { // new eraseblock , check for bad block(s) // Stay in the loop to be sure if the mtdoffset changes because // of a bad block, that the next block that will be written to // is also checked. Thus avoiding errors if the block(s) after the // skipped block(s) is also bad (number of blocks depending on // the blockalign while (blockstart != (mtdoffset & (~meminfo.erasesize + 1))) { blockstart = mtdoffset & (~meminfo.erasesize + 1); offs = blockstart; baderaseblock = 0; if (!quiet) fprintf (stdout, "Writing data to block %x\n", blockstart); /* Check all the blocks in an erase block for bad blocks */ do { if ((ret = ioctl(fd, MEMGETBADBLOCK, &offs)) < 0) { perror("ioctl(MEMGETBADBLOCK)"); goto closeall; } if (ret == 1) { baderaseblock = 1; if (!quiet) fprintf (stderr, "Bad block at %x, %u block(s) " "from %x will be skipped\n", (int) offs, blockalign, blockstart); } if (baderaseblock) { mtdoffset = blockstart + meminfo.erasesize; } offs += meminfo.erasesize / blockalign ; } while ( offs < blockstart + meminfo.erasesize ); } readlen = meminfo.writesize; if (pad && (imglen < readlen)) { readlen = imglen; memset(writebuf + readlen, 0xff, meminfo.writesize - readlen); } /* Read Page Data from input file */ if ((cnt = read(ifd, writebuf, readlen)) != readlen) { if (cnt == 0) // EOF break; perror ("File I/O error on input file"); goto closeall; } if (writeoob) { /* Read OOB data from input file, exit on failure */ if ((cnt = read(ifd, oobreadbuf, meminfo.oobsize)) != meminfo.oobsize) { perror ("File I/O error on input file"); goto closeall; } if (!noecc) { int i, start, len; /* * We use autoplacement and have the oobinfo with the autoplacement * information from the kernel available * * Modified to support out of order oobfree segments, * such as the layout used by diskonchip.c */ if (!oobinfochanged && (old_oobinfo.useecc == MTD_NANDECC_AUTOPLACE)) { for (i = 0;old_oobinfo.oobfree[i][1]; i++) { /* Set the reserved bytes to 0xff */ start = old_oobinfo.oobfree[i][0]; len = old_oobinfo.oobfree[i][1]; memcpy(oobbuf + start, oobreadbuf + start, len); } } else { /* Set at least the ecc byte positions to 0xff */ start = old_oobinfo.eccbytes; len = meminfo.oobsize - start; memcpy(oobbuf + start, oobreadbuf + start, len); } } /* Write OOB data first, as ecc will be placed in there*/ oob.start = mtdoffset; if (ioctl(fd, MEMWRITEOOB, &oob) != 0) { perror ("ioctl(MEMWRITEOOB)"); goto closeall; } imglen -= meminfo.oobsize; } /* Write out the Page data */ if (pwrite(fd, writebuf, meminfo.writesize, mtdoffset) != meminfo.writesize) { int rewind_blocks; off_t rewind_bytes; erase_info_t erase; perror ("pwrite"); /* Must rewind to blockstart if we can */ rewind_blocks = (mtdoffset - blockstart) / meminfo.writesize; /* Not including the one we just attempted */ rewind_bytes = (rewind_blocks * meminfo.writesize) + readlen; if (writeoob) rewind_bytes += (rewind_blocks + 1) * meminfo.oobsize; if (lseek(ifd, -rewind_bytes, SEEK_CUR) == -1) { perror("lseek"); fprintf(stderr, "Failed to seek backwards to recover from write error\n"); goto closeall; } erase.start = blockstart; erase.length = meminfo.erasesize; fprintf(stderr, "Erasing failed write from 0x%09llx-0x%09llx\n", erase.start, erase.start+erase.length-1); if (ioctl(fd, MEMERASE, &erase) != 0) { perror("MEMERASE"); goto closeall; } if (markbad) { loff_mtd_t bad_addr = mtdoffset & (~(meminfo.erasesize / blockalign) + 1); fprintf(stderr, "Marking block at %09llx bad\n", (long long)bad_addr); if (ioctl(fd, MEMSETBADBLOCK, &bad_addr)) { perror("MEMSETBADBLOCK"); /* But continue anyway */ } } mtdoffset = blockstart + meminfo.erasesize; imglen += rewind_blocks * meminfo.writesize; continue; } imglen -= readlen; mtdoffset += meminfo.writesize; } closeall: close(ifd); restoreoob: if (oobinfochanged == 1) { if (ioctl (fd, MEMSETOOBSEL, &old_oobinfo) != 0) { perror ("MEMSETOOBSEL"); close (fd); exit (1); } } close(fd); if (imglen > 0) { perror ("Data was only partially written due to error\n"); exit (1); } /* Return happy */ return 0; }
liHandlerResult li_filter_buffer_on_disk(liVRequest *vr, liChunkQueue *out, liChunkQueue *in, bod_state *state) { UNUSED(vr); if (out->is_closed) { in->is_closed = TRUE; li_chunkqueue_skip_all(in); bod_close(state); return LI_HANDLER_GO_ON; } while (in->length > 0) { liChunk *c = li_chunkqueue_first_chunk(in); liChunkIter ci; off_t length, data_len; char *data = NULL; GError *err; switch (c->type) { case UNUSED_CHUNK: return LI_HANDLER_ERROR; case FILE_CHUNK: bod_flush(out, state); if (state->split_on_file_chunks) { bod_close(state); } li_chunkqueue_steal_chunk(out, in); break; case STRING_CHUNK: case MEM_CHUNK: case BUFFER_CHUNK: if (!bod_open(vr, state)) return LI_HANDLER_ERROR; length = li_chunk_length(c); ci = li_chunkqueue_iter(in); err = NULL; if (LI_HANDLER_GO_ON != li_chunkiter_read(ci, 0, length, &data, &data_len, &err)) { if (NULL != err) { VR_ERROR(vr, "%s", err->message); g_error_free(err); } return LI_HANDLER_ERROR; } while ( data_len > 0 ) { ssize_t r; r = pwrite(state->tempfile->fd, data, data_len, state->write_pos); if (r < 0) { switch (errno) { case EINTR: continue; default: break; } VR_ERROR(vr, "pwrite failed: %s", g_strerror(errno)); return LI_HANDLER_ERROR; } data += r; data_len -= r; state->write_pos += r; } li_chunkqueue_skip(in, length); break; } } bod_autoflush(out, state); if (in->is_closed) { bod_flush(out, state); out->is_closed = TRUE; bod_close(state); return LI_HANDLER_GO_ON; } return LI_HANDLER_GO_ON; }
void main(int argc, char *argv[]) { int fd, force; Header h; ulong bn; Entry e; char *label = "vfs"; char *host = nil; char *score = nil; u32int root; Dir *d; force = 0; ARGBEGIN{ default: usage(); case 'b': bsize = unittoull(EARGF(usage())); if(bsize == ~0) usage(); break; case 'h': host = EARGF(usage()); break; case 'i': iso9660file = EARGF(usage()); iso9660off = atoi(EARGF(usage())); break; case 'l': label = EARGF(usage()); break; case 'v': score = EARGF(usage()); break; /* * This is -y instead of -f because flchk has a * (frequently used) -f option. I type flfmt instead * of flchk all the time, and want to make it hard * to reformat my file system accidentally. */ case 'y': force = 1; break; }ARGEND if(argc != 1) usage(); if(iso9660file && score) vtFatal("cannot use -i with -v"); vtAttach(); fmtinstall('V', scoreFmt); fmtinstall('R', vtErrFmt); fmtinstall('L', labelFmt); fd = open(argv[0], ORDWR); if(fd < 0) vtFatal("could not open file: %s: %r", argv[0]); buf = vtMemAllocZ(bsize); if(pread(fd, buf, bsize, HeaderOffset) != bsize) vtFatal("could not read fs header block: %r"); if(headerUnpack(&h, buf) && !force && !confirm("fs header block already exists; are you sure?")) goto Out; if((d = dirfstat(fd)) == nil) vtFatal("dirfstat: %r"); if(d->type == 'M' && !force && !confirm("fs file is mounted via devmnt (is not a kernel device); are you sure?")) goto Out; partition(fd, bsize, &h); headerPack(&h, buf); if(pwrite(fd, buf, bsize, HeaderOffset) < bsize) vtFatal("could not write fs header: %r"); disk = diskAlloc(fd); if(disk == nil) vtFatal("could not open disk: %r"); if(iso9660file) iso9660init(fd, &h, iso9660file, iso9660off); /* zero labels */ memset(buf, 0, bsize); for(bn = 0; bn < diskSize(disk, PartLabel); bn++) blockWrite(PartLabel, bn); if(iso9660file) iso9660labels(disk, buf, blockWrite); if(score) root = ventiRoot(host, score); else{ rootMetaInit(&e); root = rootInit(&e); } superInit(label, root, vtZeroScore); diskFree(disk); if(score == nil) topLevel(argv[0]); Out: vtDetach(); exits(0); }
int write_tape_block(const uint8_t *buffer, uint32_t blk_size, uint32_t comp_size, const struct encryption *encryptp, uint8_t comp_type, uint8_t *sam_stat) { uint32_t blk_number, disk_blk_size; uint64_t data_offset; ssize_t nwrite; if (!tape_loaded(sam_stat)) { return -1; } if (check_for_overwrite(sam_stat)) { return -1; } /* Preserve existing raw_pos data we need, then clear out raw_pos and fill it in with new data. */ blk_number = raw_pos.hdr.blk_number; data_offset = raw_pos.data_offset; memset(&raw_pos, 0, sizeof(raw_pos)); raw_pos.data_offset = data_offset; raw_pos.hdr.blk_type = B_DATA; /* Header type */ raw_pos.hdr.blk_flags = 0; raw_pos.hdr.blk_number = blk_number; raw_pos.hdr.blk_size = blk_size; /* Size of uncompressed data */ if (comp_size) { if (comp_type == LZO) raw_pos.hdr.blk_flags |= BLKHDR_FLG_LZO_COMPRESSED; else raw_pos.hdr.blk_flags |= BLKHDR_FLG_ZLIB_COMPRESSED; raw_pos.hdr.disk_blk_size = disk_blk_size = comp_size; } else { raw_pos.hdr.disk_blk_size = disk_blk_size = blk_size; } if (encryptp != NULL) { unsigned int i; raw_pos.hdr.blk_flags |= BLKHDR_FLG_ENCRYPTED; raw_pos.hdr.encryption.ukad_length = encryptp->ukad_length; for (i = 0; i < encryptp->ukad_length; ++i) { raw_pos.hdr.encryption.ukad[i] = encryptp->ukad[i]; } raw_pos.hdr.encryption.akad_length = encryptp->akad_length; for (i = 0; i < encryptp->akad_length; ++i) { raw_pos.hdr.encryption.akad[i] = encryptp->akad[i]; } raw_pos.hdr.encryption.key_length = encryptp->key_length; for (i = 0; i < encryptp->key_length; ++i) { raw_pos.hdr.encryption.key[i] = encryptp->key[i]; } } /* Now write out both the header and the data. */ nwrite = pwrite(indxfile, &raw_pos, sizeof(raw_pos), blk_number * sizeof(raw_pos)); if (nwrite != sizeof(raw_pos)) { mkSenseBuf(MEDIUM_ERROR, E_WRITE_ERROR, sam_stat); MHVTL_ERR("Index file write failure, pos: %" PRId64 ": %s", (uint64_t)blk_number * sizeof(raw_pos), strerror(errno)); return -1; } nwrite = pwrite(datafile, buffer, disk_blk_size, data_offset); if (nwrite != disk_blk_size) { mkSenseBuf(MEDIUM_ERROR, E_WRITE_ERROR, sam_stat); MHVTL_ERR("Data file write failure, pos: %" PRId64 ": %s", data_offset, strerror(errno)); return -1; } MHVTL_DBG(3, "Successfully wrote block: %u", blk_number); return mkEODHeader(blk_number + 1, data_offset + disk_blk_size); }
/* * Perform data transfer on the selected device. */ static int vnd_transfer(devminor_t minor, int do_write, u64_t position, endpoint_t endpt, iovec_t *iovt, unsigned int nr_req, int flags) { struct device *dv; iovec_s_t *iov; size_t off, chunk, bytes, iov_off; ssize_t r; unsigned int i; iov = (iovec_s_t *) iovt; if (state.fd == -1 || (dv = vnd_part(minor)) == NULL) return ENXIO; /* Prevent write operations on devices opened as write-only. */ if (do_write && state.rdonly) return EACCES; /* Determine the total number of bytes to transfer. */ if (position >= dv->dv_size) return 0; bytes = 0; for (i = 0; i < nr_req; i++) { if (iov[i].iov_size == 0 || iov[i].iov_size > LONG_MAX) return EINVAL; bytes += iov[i].iov_size; if (bytes > LONG_MAX) return EINVAL; } if (bytes > dv->dv_size - position) bytes = dv->dv_size - position; position += dv->dv_base; /* Perform the actual transfer, in chunks if necessary. */ iov_off = 0; for (off = 0; off < bytes; off += chunk) { chunk = MIN(bytes - off, VND_BUF_SIZE); assert((unsigned int) (iov - (iovec_s_t *) iovt) < nr_req); /* For reads, read in the data for the chunk; possibly less. */ if (!do_write) { chunk = r = pread(state.fd, state.buf, chunk, position); if (r < 0) { printf("VND%u: pread failed (%d)\n", instance, -errno); return -errno; } if (r == 0) break; } /* Copy the data for this chunk from or to the caller. */ if ((r = vnd_copy(iov, iov_off, chunk, endpt, do_write)) < 0) { printf("VND%u: data copy failed (%d)\n", instance, r); return r; } /* For writes, write the data to the file; possibly less. */ if (do_write) { chunk = r = pwrite(state.fd, state.buf, chunk, position); if (r <= 0) { if (r < 0) r = -errno; printf("VND%u: pwrite failed (%d)\n", instance, r); return (r < 0) ? r : EIO; } } /* Move ahead on the I/O vector and the file position. */ iov = vnd_advance(iov, &iov_off, chunk); position += chunk; } /* If force-write is requested, flush the underlying file to disk. */ if (do_write && (flags & BDEV_FORCEWRITE)) fsync(state.fd); /* Return the number of bytes transferred. */ return off; }