int main() { struct stat s; int f = open("/test", O_RDWR, 0777); assert(f); printf("posix_fadvise: %d\n", posix_fadvise(f, 3, 2, POSIX_FADV_DONTNEED)); printf("errno: %d\n", errno); printf("\n"); errno = 0; printf("posix_fallocate: %d\n", posix_fallocate(f, 3, 2)); printf("errno: %d\n", errno); stat("/test", &s); printf("st_size: %d\n", s.st_size); memset(&s, 0, sizeof s); printf("\n"); errno = 0; printf("posix_fallocate2: %d\n", posix_fallocate(f, 3, 7)); printf("errno: %d\n", errno); stat("/test", &s); printf("st_size: %d\n", s.st_size); memset(&s, 0, sizeof s); return 0; }
static void make_level( const char* target, uint32_t depth, uint32_t width, uint32_t files, uint32_t file_size ) { if (chdir(target) == -1) { perror(target); return; } if (depth) { mode_t mode = 0775; for (size_t i = 0; i < width; i++) { char filename[18]; snprintf(filename, sizeof(filename), "d%u", i); if (mkdir(filename, mode) == -1) { if (errno != EEXIST) { perror(filename); goto up; } } make_level(filename, depth - 1, width, files, file_size); } } FILE* rand = fopen("/dev/urandom", "r"); if (rand == NULL) { perror("/dev/urandom"); goto up; } for (size_t i = 0; i < files; i++) { char filename[17]; snprintf(filename, sizeof(filename), "%u", i); FILE* f = fopen(filename, "w"); if (f == NULL) { perror("fopen"); goto up; } int fd = fileno(f); // if fallocate fails nbd posix_fallocate(fd, 0, file_size); const size_t chunk_size = 1000; char* buffer = malloc(chunk_size); for (size_t i = 0; i < file_size; i++) { // don't care if fread fails fread(buffer, 1, chunk_size, rand); size_t written = fwrite(buffer, 1, chunk_size, f); if (written < chunk_size) { perror(filename); goto cleanup; } } cleanup: free(buffer); fclose(f); } fclose(rand); up: chdir(".."); }
static void xposix_fallocate(int fd, off_t offset, off_t length) { int error = posix_fallocate(fd, offset, length); if (error < 0) { err(EXIT_FAILURE, _("fallocate failed")); } }
int server_open_kernel_seqnum(Server *s) { _cleanup_close_ int fd; uint64_t *p; int r; assert(s); /* We store the seqnum we last read in an mmaped file. That * way we can just use it like a variable, but it is * persistent and automatically flushed at reboot. */ fd = open("/run/systemd/journal/kernel-seqnum", O_RDWR|O_CREAT|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW, 0644); if (fd < 0) { log_error_errno(errno, "Failed to open /run/systemd/journal/kernel-seqnum, ignoring: %m"); return 0; } r = posix_fallocate(fd, 0, sizeof(uint64_t)); if (r != 0) { log_error_errno(r, "Failed to allocate sequential number file, ignoring: %m"); return 0; } p = mmap(NULL, sizeof(uint64_t), PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); if (p == MAP_FAILED) { log_error_errno(errno, "Failed to map sequential number file, ignoring: %m"); return 0; } s->kernel_seqnum = p; return 0; }
bool SharedStoreFileStorage::addFile() { if ((int64)m_chunks.size() * m_chunkSize >= m_maxSize) { m_state = StateFull; return false; } char name[PATH_MAX]; snprintf(name, sizeof(name), "%s.XXXXXX", m_prefix.c_str()); int fd = mkstemp(name); if (fd < 0) { Logger::Error("Failed to open temp file"); return false; } if (posix_fallocate(fd, 0, m_chunkSize)) { Logger::Error("Failred to posix_fallocate of size %llu", m_chunkSize); close(fd); return false; } if (RuntimeOption::ApcFileStorageKeepFileLinked) { m_fileNames.push_back(std::string(name)); } else { unlink(name); } char *addr = (char *)mmap(NULL, m_chunkSize, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); if (addr == (char *)-1) { Logger::Error("Failed to mmap of size %llu", name, m_chunkSize); close(fd); return false; } m_current = addr; m_chunkRemain = m_chunkSize - PaddingSize; m_chunks.push_back(addr); close(fd); return true; }
int main(int argc, const char *argv[]) { if (argc != 4) { fprintf(stderr, "Usage: fallocator <file> <offset> <len>\n"); return 1; } int fd = open(argv[1], O_RDWR | O_CREAT, 0666); if (fd == -1) { perror("failed to open file"); return 1; } uint64_t offset; uint64_t length; sscanf(argv[2], "%"SCNu64, &offset); sscanf(argv[3], "%"SCNu64, &length); errno = posix_fallocate(fd, offset, length); if (errno != 0) { perror("failed to fallocate"); close(fd); return 1; } close(fd); return 0; }
int fallocate_main(int argc UNUSED_PARAM, char **argv) { const char *str_l; const char *str_o = "0"; off_t ofs, len; unsigned opts; int fd; /* exactly one non-option arg */ opt_complementary = "=1"; opts = getopt32(argv, "l:o:", &str_l, &str_o); if (!(opts & 1)) bb_show_usage(); ofs = xatoull_sfx(str_o, kmg_i_suffixes); len = xatoull_sfx(str_l, kmg_i_suffixes); argv += optind; fd = xopen3(*argv, O_RDWR | O_CREAT, 0666); /* posix_fallocate has unusual method of returning error */ /* maybe use Linux-specific fallocate(int fd, int mode, off_t offset, off_t len) instead? */ if ((errno = posix_fallocate(fd, ofs, len)) != 0) bb_perror_msg_and_die("fallocate '%s'", *argv); /* util-linux also performs fsync(fd); */ return EXIT_SUCCESS; }
static int increase_packet_size(struct ctf_stream_pos *pos) { int ret; assert(pos); ret = munmap_align(pos->base_mma); if (ret) { goto end; } pos->packet_size += PACKET_LEN_INCREMENT; ret = posix_fallocate(pos->fd, pos->mmap_offset, pos->packet_size / CHAR_BIT); if (ret) { goto end; } pos->base_mma = mmap_align(pos->packet_size / CHAR_BIT, pos->prot, pos->flags, pos->fd, pos->mmap_offset); if (pos->base_mma == MAP_FAILED) { ret = -1; } end: return ret; }
int os_create_anonymous_file(std::size_t size) { static const char tmplate[] = "/wlc-shared-XXXXXX"; std::string path = getenv("XDG_RUNTIME_DIR"); if (path.empty()) return -1; std::string name = path; if(path.back() != '/') name.append("/"); name.append(tmplate); int fd = create_tmpfile_cloexec(name.c_str()); if (fd < 0) return -1; int ret; #if HAVE_POSIX_FALLOCATE if ((ret = posix_fallocate(fd, 0, size)) != 0) { close(fd); errno = ret; return -1; } #else if ((ret = ftruncate(fd, size)) < 0) { close(fd); return -1; } #endif return fd; }
void TruncateFile(int fd,Uint64 size,bool quick) { if (FileSize(fd) == size) return; if (quick) { #ifdef HAVE_FTRUNCATE64 if (ftruncate64(fd,size) == -1) #else if (ftruncate(fd,size) == -1) #endif throw Error(i18n("Cannot expand file: %1",strerror(errno))); } else { #ifdef HAVE_POSIX_FALLOCATE64 if (posix_fallocate64(fd,0,size) != 0) throw Error(i18n("Cannot expand file: %1",strerror(errno))); #elif HAVE_POSIX_FALLOCATE if (posix_fallocate(fd,0,size) != 0) throw Error(i18n("Cannot expand file: %1",strerror(errno))); #elif HAVE_FTRUNCATE64 if (ftruncate64(fd,size) == -1) throw Error(i18n("Cannot expand file: %1",strerror(errno))); #else if (ftruncate(fd,size) == -1) throw Error(i18n("Cannot expand file: %1",strerror(errno))); #endif } }
int FileAllocSpace(int fd, off_t off, off_t len) { #if (LINUX_SYS_FALLOCATE) && defined(SYS_fallocate) int e; static int fallocate_ok = 1; static int posix_fallocate_ok = 1; if (fallocate_ok) { e = syscall(SYS_fallocate, fd, 0, (loff_t)off, (loff_t)len); if (e == 0) return 0; if (e < 0 && (errno == ENOSYS || errno == EOPNOTSUPP)) fallocate_ok = 0; } if (posix_fallocate_ok) { e = posix_fallocate(fd, off, len); if (e == 0) return 0; if (e < 0 && (errno == ENOSYS || errno == EOPNOTSUPP)) posix_fallocate_ok = 0; } #endif return ftruncate(fd, off + len); }
/* * util_file_create -- create a new memory pool file */ int util_file_create(const char *path, size_t size, size_t minsize) { LOG(3, "path %s size %zu minsize %zu", path, size, minsize); ASSERTne(size, 0); if (size < minsize) { ERR("size %zu smaller than %zu", size, minsize); errno = EINVAL; return -1; } if (((off_t)size) < 0) { ERR("invalid size (%zu) for off_t", size); errno = EFBIG; return -1; } int fd; int mode; int flags = O_RDWR | O_CREAT | O_EXCL; #ifndef _WIN32 mode = 0; #else mode = S_IWRITE | S_IREAD; flags |= O_BINARY; #endif /* * Create file without any permission. It will be granted once * initialization completes. */ if ((fd = open(path, flags, mode)) < 0) { ERR("!open %s", path); return -1; } if ((errno = posix_fallocate(fd, 0, (off_t)size)) != 0) { ERR("!posix_fallocate"); goto err; } /* for windows we can't flock until after we fallocate */ if (flock(fd, LOCK_EX | LOCK_NB) < 0) { ERR("!flock"); goto err; } return fd; err: LOG(4, "error clean up"); int oerrno = errno; if (fd != -1) (void) close(fd); unlink(path); errno = oerrno; return -1; }
static int xmp_fallocate(const char *path, int mode, off_t offset, off_t length, struct fuse_file_info *fi) { if(conf.syscall_fallocate) sql_write(path,"fallocate"); int fd; int res; (void) fi; if (mode) { if(conf.syscall_fallocate && conf.enable_error_messages) sql_write_err(); return -EOPNOTSUPP; } char *rpath; rpath=get_rel_path(path); fd = open(rpath, O_WRONLY); free(rpath); if (fd == -1) { if(conf.syscall_fallocate && conf.enable_error_messages) sql_write_err(); return -errno; } res = -posix_fallocate(fd, offset, length); close(fd); return res; }
CAMLprim value netsys_fallocate(value fd, value start, value len) { #ifdef HAVE_POSIX_FALLOCATE int r; int64 start_int, len_int; off_t start_off, len_off; /* Att: off_t might be 64 bit even on 32 bit systems! */ start_int = Int64_val(start); len_int = Int64_val(len); if ( ((int64) ((off_t) start_int)) != start_int ) failwith("Netsys.fadvise: large files not supported on this OS"); if ( ((int64) ((off_t) len_int)) != len_int ) failwith("Netsys.fadvise: large files not supported on this OS"); start_off = start_int; len_off = len_int; r = posix_fallocate(Int_val(fd), start_off, len_off); /* does not set errno! */ if (r != 0) unix_error(r, "posix_fallocate64", Nothing); return Val_unit; #else invalid_argument("Netsys.fallocate not available"); #endif }
static void open_file() { if (file) return; if (!file_name[0] && !guess_filename()) { die("could not determine the filename, consider using the -o option.\n"); } file = fopen(file_name, "wb+"); if (!file) die("failed to open '%s': %s\n", file_name, strerror(errno)); if (file_size) { int fd = fileno(file); int err; if ((err = posix_fallocate(fd, 0, file_size))) { warn("failed to preallocate '%s': %s\n", file_name, strerror(err)); } if ((err = posix_fadvise(fd, 0, file_size, POSIX_FADV_RANDOM))) { warn("failed to set '%s's access policy: %s\n", file_name, strerror(err)); } } }
TEST(externalSort, testCorrectSorting) { int input, output, error; if((input = open(inputfile.c_str(), O_RDONLY)) < 0) { std::cerr << "cannot open input file: " << strerror(errno) << std::endl; return; } uint64_t input_filesize = fsize(inputfile); if((output = open(outputfile.c_str(), O_CREAT|O_TRUNC|O_WRONLY, S_IRUSR|S_IWUSR)) < 0) { std::cerr << "cannot open output file: " << strerror(errno) << std::endl; return; } else if((error = posix_fallocate(output, 0, input_filesize))) { std::cout << "error: " << strerror(error) << std::endl; exit(1); } externalSort(input, input_filesize / sizeof(uint64_t) , output, memoryBuffer); close(input); close(output); std::cout << "starting to check output" << std::endl; if((output = open(outputfile.c_str(), O_RDONLY)) < 0) { std::cerr << "cannot open output file for checking: " << strerror(errno) << std::endl; return; } uint64_t number = 0, lastnumber = 0; while(read(output, &number, sizeof(uint64_t)) > 0) { EXPECT_GE(number, lastnumber); lastnumber = number; } close(output); }
/* * stress_sendfile * stress reading of a temp file and writing to /dev/null via sendfile */ int stress_sendfile( uint64_t *const counter, const uint32_t instance, const uint64_t max_ops, const char *name) { char filename[PATH_MAX]; int fdin, fdout, ret = EXIT_SUCCESS; size_t sz; const pid_t pid = getpid(); if (!set_sendfile_size) { if (opt_flags & OPT_FLAGS_MAXIMIZE) opt_sendfile_size = MAX_SENDFILE_SIZE; if (opt_flags & OPT_FLAGS_MINIMIZE) opt_sendfile_size = MIN_SENDFILE_SIZE; } sz = (size_t)opt_sendfile_size; if (stress_temp_dir_mk(name, pid, instance) < 0) return EXIT_FAILURE; (void)umask(0077); (void)stress_temp_filename(filename, sizeof(filename), name, pid, instance, mwc32()); if ((fdin = open(filename, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR)) < 0) { pr_fail_err(name, "open"); ret = EXIT_FAILURE; goto dir_out; } (void)posix_fallocate(fdin, (off_t)0, (off_t)sz); if ((fdout = open("/dev/null", O_WRONLY)) < 0) { pr_fail_err(name, "open"); ret = EXIT_FAILURE; goto close_in; } do { off_t offset = 0; if (sendfile(fdout, fdin, &offset, sz) < 0) { pr_fail_err(name, "sendfile"); ret = EXIT_FAILURE; goto close_out; } (*counter)++; } while (opt_do_run && (!max_ops || *counter < max_ops)); close_out: (void)close(fdout); close_in: (void)close(fdin); (void)unlink(filename); dir_out: (void)stress_temp_dir_rm(name, pid, instance); return ret; }
int main(int argc, char **argv) { struct boot_img_hdr *hdr; int inf, inp, rd_start; void *buf; int i, rd; if (argc != 2) { puts("Usage: injectrd boot.img < ramdisk.gz"); return 1; } inf = open(argv[1], O_RDWR); if (inf < 0) { puts("Unable to open boot.img!"); return 2; } buf = mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_POPULATE, inf, 0); if (buf == MAP_FAILED) { puts("mmap() failed!"); return 3; } for (i = 0; i < 512; i++) { hdr = (struct boot_img_hdr *)(buf + i); if (!memcmp(&hdr->magic, BOOT_MAGIC, BOOT_MAGIC_SIZE)) break; } if (i > 512) { puts("Invalid boot.img!"); return 4; } inp = hdr->page_size + hdr->kernel_size; if (inp & (hdr->page_size - 1)) inp = (inp & ~(hdr->page_size - 1)) + hdr->page_size; rd_start = inp; do { int wbase = inp & ~(PAGE_SIZE - 1); if (posix_fallocate(inf, wbase, CHUNK)) goto fail; buf = mmap(NULL, CHUNK, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_POPULATE, inf, wbase); if (buf == MAP_FAILED) goto fail; rd = read(0, buf + (inp - wbase), CHUNK - (inp - wbase)); if (rd < 0) goto fail; inp += rd; continue; fail: puts("Writing ramdisk failed!"); return 5; } while (rd > 0); ftruncate(inf, inp); hdr->ramdisk_size = inp - rd_start; return 0; }
gint32 Mono_Posix_Syscall_posix_fallocate (gint32 fd, mph_off_t offset, mph_size_t len) { mph_return_if_off_t_overflow (offset); mph_return_if_size_t_overflow (len); return posix_fallocate (fd, (off_t) offset, (size_t) len); }
int art_tree_map_init(struct datastore *ds, struct ds_context *ctx) { int errors = 0; char *error_string; /* calculate a required pool size */ if (ctx->psize < PMEMOBJ_MIN_POOL) ctx->psize = PMEMOBJ_MIN_POOL; if (!ctx->fileio) { if (access(ctx->filename, F_OK) != 0) { error_string = "pmemobj_create"; ctx->pop = pmemobj_create(ctx->filename, POBJ_LAYOUT_NAME(arttree_tx), ctx->psize, ctx->fmode); ctx->newpool = 1; } else { error_string = "pmemobj_open"; ctx->pop = pmemobj_open(ctx->filename, POBJ_LAYOUT_NAME(arttree_tx)); } if (ctx->pop == NULL) { perror(error_string); errors++; } } else { int flags = O_CREAT | O_RDWR | O_SYNC; /* Create a file if it does not exist. */ if ((ctx->fd = open(ctx->filename, flags, ctx->fmode)) < 0) { perror(ctx->filename); errors++; } /* allocate the pmem */ if ((errno = posix_fallocate(ctx->fd, 0, ctx->psize)) != 0) { perror("posix_fallocate"); errors++; } } if (!errors) { pmemobj_ds_set_priv(ds, ctx); } else { if (ctx->fileio) { if (ctx->fd >= 0) { close(ctx->fd); } } else { if (ctx->pop) { pmemobj_close(ctx->pop); } } } return errors; }
/********************************************************************* Function : nvme_create_storage_disk Description : Creates a NVME Storage Disk and the namespaces within Return Type : int (0:1 Success:Failure) Arguments : uint32_t : instance number of the nvme device uint32_t : namespace id DiskInfo * : NVME disk to create storage for *********************************************************************/ int nvme_create_storage_disk(uint32_t instance, uint32_t nsid, DiskInfo *disk, NVMEState *n) { uint32_t blksize, lba_idx; uint64_t size, blks; char str[64]; snprintf(str, sizeof(str), "nvme_disk%d_n%d.img", instance, nsid); disk->nsid = nsid; disk->fd = open(str, O_RDWR | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR); if (disk->fd < 0) { LOG_ERR("Error while creating the storage"); return FAIL; } lba_idx = disk->idtfy_ns.flbas & 0xf; blks = disk->idtfy_ns.ncap; blksize = NVME_BLOCK_SIZE(disk->idtfy_ns.lbafx[lba_idx].lbads); size = blks * blksize; if (disk->idtfy_ns.flbas & 0x10) { /* extended lba */ size += (blks * disk->idtfy_ns.lbafx[lba_idx].ms); } if (size == 0) { return SUCCESS; } if (posix_fallocate(disk->fd, 0, size) != 0) { LOG_ERR("Error while allocating space for namespace"); return FAIL; } disk->mapping_addr = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, disk->fd, 0); if (disk->mapping_addr == NULL) { LOG_ERR("Error while opening namespace: %d", disk->nsid); return FAIL; } disk->mapping_size = size; if (nvme_create_meta_disk(instance, nsid, disk) != SUCCESS) { return FAIL; } disk->ns_util = qemu_mallocz((disk->idtfy_ns.nsze + 7) / 8); if (disk->ns_util == NULL) { LOG_ERR("Error while reallocating the ns_util"); return FAIL; } disk->thresh_warn_issued = 0; LOG_NORM("created disk storage, mapping_addr:%p size:%lu", disk->mapping_addr, disk->mapping_size); return SUCCESS; }
void FileAllocator::ensureLength(int fd , long size) { #if !defined(_WIN32) if (useSparseFiles(fd)) { LOG(1) << "using ftruncate to create a sparse file" << endl; int ret = ftruncate(fd, size); uassert(16063, "ftruncate failed: " + errnoWithDescription(), ret == 0); return; } #endif #if defined(__linux__) int ret = posix_fallocate(fd,0,size); if ( ret == 0 ) return; log() << "FileAllocator: posix_fallocate failed: " << errnoWithDescription( ret ) << " falling back" << endl; #endif off_t filelen = lseek( fd, 0, SEEK_END ); if ( filelen < size ) { if (filelen != 0) { stringstream ss; ss << "failure creating new datafile; lseek failed for fd " << fd << " with errno: " << errnoWithDescription(); uassert( 10440 , ss.str(), filelen == 0 ); } // Check for end of disk. uassert( 10441 , str::stream() << "Unable to allocate new file of size " << size << ' ' << errnoWithDescription(), size - 1 == lseek(fd, size - 1, SEEK_SET) ); uassert( 10442 , str::stream() << "Unable to allocate new file of size " << size << ' ' << errnoWithDescription(), 1 == write(fd, "", 1) ); // File expansion is completed here. Do not do the zeroing out on OS-es where there // is no risk of triggering allocation-related bugs such as // http://support.microsoft.com/kb/2731284. // if (!ProcessInfo::isDataFileZeroingNeeded()) { return; } lseek(fd, 0, SEEK_SET); const long z = 256 * 1024; const boost::scoped_array<char> buf_holder (new char[z]); char* buf = buf_holder.get(); memset(buf, 0, z); long left = size; while ( left > 0 ) { long towrite = left; if ( towrite > z ) towrite = z; int written = write( fd , buf , towrite ); uassert( 10443 , errnoWithPrefix("FileAllocator: file write failed" ), written > 0 ); left -= written; } } }
int efile_allocate(efile_data_t *d, Sint64 offset, Sint64 length) { efile_unix_t *u = (efile_unix_t*)d; int ret = -1; /* We prefer OS-specific methods, but fall back to posix_fallocate on * failure. It's unclear whether this has any practical benefit on * modern systems, but the old driver did it. */ #if defined(HAVE_FALLOCATE) /* Linux-specific */ do { ret = fallocate(u->fd, FALLOC_FL_KEEP_SIZE, offset, length); } while(ret < 0 && errno == EINTR); #elif defined(F_PREALLOCATE) /* Mac-specific */ fstore_t fs = {}; fs.fst_flags = F_ALLOCATECONTIG; fs.fst_posmode = F_VOLPOSMODE; fs.fst_offset = offset; fs.fst_length = length; ret = fcntl(u->fd, F_PREALLOCATE, &fs); if(ret < 0) { fs.fst_flags = F_ALLOCATEALL; ret = fcntl(u->fd, F_PREALLOCATE, &fs); } #elif !defined(HAVE_POSIX_FALLOCATE) u->common.posix_errno = ENOTSUP; return 0; #endif #ifdef HAVE_POSIX_FALLOCATE if(ret < 0) { do { ret = posix_fallocate(u->fd, offset, length); /* On Linux and Solaris for example, posix_fallocate() returns a * positive error number on error and it does not set errno. On * FreeBSD however (9.0 at least), it returns -1 on error and it * sets errno. */ if (ret > 0) { errno = ret; ret = -1; } } while(ret < 0 && errno == EINTR); } #endif if(ret < 0) { u->common.posix_errno = errno; return 0; } return 1; }
static int xmp_fallocate(const char *path, int mode, off_t offset, off_t length, struct fuse_file_info *fi) { (void) path; if (mode) return -EOPNOTSUPP; return -posix_fallocate(fi->fh, offset, length); }
bool CacheFile::allocateBytes(Uint64 off, Uint64 size) { #ifdef HAVE_POSIX_FALLOCATE64 return posix_fallocate64(fptr->handle(),off,size) != ENOSPC; #elif HAVE_POSIX_FALLOCATE return posix_fallocate(fptr->handle(),off,size) != ENOSPC; #else return true; #endif }
void FileDescriptor::fallocate(uint64_t size) { int ret = posix_fallocate(fd_, 0, size); if (ret != 0) { throw FileDescriptorException(ret, FileDescriptorException::Exception::FallocateException); } }
static int pfile_fallocate(struct stasis_handle_t* h, lsn_t off, lsn_t len) { pfile_impl * impl = h->impl; #ifdef HAVE_POSIX_FALLOCATE return posix_fallocate(impl->fd, off, len); #else (void)impl; fprintf(stderr, "pfile.c: fallocate called, but not supported by this build.\n"); return -1; #endif }
store_t* create_mmap_store(uint32_t size, const char* base_dir, const char* name, int flags) { //TODO : Enforce a max size //TODO : Check flags //TODO : check thread sanity //TODO : check size is near a page int dir_fd = open(base_dir, O_DIRECTORY, (mode_t)0600); if (dir_fd == -1) return NULL; int real_fd = openat(dir_fd, name, O_RDWR | O_CREAT, (mode_t)0600); close(dir_fd); // TODO - Check for the race condition if two people attempt to create // the same segment if (real_fd == -1) return NULL; if (posix_fallocate(real_fd, 0, size) != 0) { close(real_fd); return NULL; } struct mmap_store *store = (struct mmap_store*) calloc(1, sizeof(struct mmap_store)); if (store == NULL) return NULL; void *mapping = mmap(NULL, (size_t) size, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_POPULATE | MAP_NONBLOCK , real_fd, 0); if (mapping == NULL) return NULL; madvise(mapping, size, MADV_SEQUENTIAL); uint32_t off = sizeof(uint32_t) * 2; ((uint32_t *)mapping)[0] = 0xDEADBEEF; ((uint32_t *)mapping)[1] = size; store->fd = real_fd; store->capacity = size; store->flags = flags; store->mapping = mapping; ck_pr_store_32(&store->write_cursor, off); ck_pr_store_32(&store->sync_cursor, off); ck_pr_fence_atomic(); ensure(msync(mapping, off, MS_SYNC) == 0, "Unable to sync"); ensure(store->write_cursor != 0, "Cursor incorrect"); ensure(store->sync_cursor != 0, "Cursor incorrect"); ((store_t *)store)->write = &_mmap_write; ((store_t *)store)->open_cursor = &_mmap_open_cursor; ((store_t *)store)->capacity = &_mmap_capacity; ((store_t *)store)->cursor = &_mmap_cursor; ((store_t *)store)->sync = &_mmap_sync; ((store_t *)store)->close = &_mmap_close; ((store_t *)store)->destroy = &_mmap_destroy; return (store_t *)store; }
static int preallocateFile( const char * filename, uint64_t length ) { int success = 0; #ifdef WIN32 HANDLE hFile = CreateFile( filename, GENERIC_WRITE, 0, 0, CREATE_NEW, 0, 0 ); if( hFile != INVALID_HANDLE_VALUE ) { LARGE_INTEGER li; li.QuadPart = length; success = SetFilePointerEx( hFile, li, NULL, FILE_BEGIN ) && SetEndOfFile( hFile ); CloseHandle( hFile ); } #else int flags = O_RDWR | O_CREAT | O_LARGEFILE; int fd = open( filename, flags, 0666 ); if( fd >= 0 ) { # ifdef HAVE_FALLOCATE success = !fallocate( fd, FALLOC_FL_KEEP_SIZE, 0, length ); # elif defined(HAVE_POSIX_FALLOCATE) success = !posix_fallocate( fd, 0, length ); # elif defined(SYS_DARWIN) fstore_t fst; fst.fst_flags = F_ALLOCATECONTIG; fst.fst_posmode = F_PEOFPOSMODE; fst.fst_offset = 0; fst.fst_length = length; fst.fst_bytesalloc = 0; success = !fcntl( fd, F_PREALLOCATE, &fst ); # else #warning no known method to preallocate files on this platform success = 0; # endif close( fd ); } #endif return success; }
int lc_fallocate(lua_State* L) { int ret; off_t offset, len; FILE* f = *(FILE**) luaL_checkudata(L, 1, LUA_FILEHANDLE); if(f == NULL) { return luaL_error(L, "attempt to use a closed file"); } offset = luaL_checkinteger(L, 2); len = luaL_checkinteger(L, 3); #if defined(__linux__) && defined(_GNU_SOURCE) errno = 0; ret = fallocate(fileno(f), FALLOC_FL_KEEP_SIZE, offset, len); if(ret == 0) { lua_pushboolean(L, 1); return 1; } /* Some old versions of Linux apparently use the return value instead of errno */ if(errno == 0) { errno = ret; } if(errno != ENOSYS && errno != EOPNOTSUPP) { lua_pushnil(L); lua_pushstring(L, strerror(errno)); return 2; } #else #warning Only using posix_fallocate() fallback. #warning Linux fallocate() is strongly recommended if available: recompile with -D_GNU_SOURCE #warning Note that posix_fallocate() will still be used on filesystems that dont support fallocate() #endif ret = posix_fallocate(fileno(f), offset, len); if(ret == 0) { lua_pushboolean(L, 1); return 1; } else { lua_pushnil(L); lua_pushstring(L, strerror(ret)); /* posix_fallocate() can leave a bunch of NULs at the end, so we cut that * this assumes that offset == length of the file */ if(ftruncate(fileno(f), offset) != 0) { lua_pushstring(L, strerror(errno)); return 3; } return 2; } }