Esempio n. 1
0
/* Optionally flush file to disk and discard page cache */
void discard_file_cache(xc_interface *xch, int fd, int flush)
{
    off_t cur = 0;
    int saved_errno = errno;

    if ( flush && (fsync(fd) < 0) )
    {
        /*PERROR("Failed to flush file: %s", strerror(errno));*/
        goto out;
    }

    /*
     * Calculate last page boundary of amount written so far
     * unless we are flushing in which case entire cache
     * is discarded.
     */
    if ( !flush )
    {
        if ( (cur = lseek(fd, 0, SEEK_CUR)) == (off_t)-1 )
            cur = 0;
        cur &= ~(XC_PAGE_SIZE-1);
    }

    /* Discard from the buffer cache. */
    if ( posix_fadvise64(fd, 0, cur, POSIX_FADV_DONTNEED) < 0 )
    {
        /*PERROR("Failed to discard cache: %s", strerror(errno));*/
        goto out;
    }

out:
    errno = saved_errno;
}
Esempio n. 2
0
File: copy.c Progetto: jyizheng/dtar
int DCOPY_open_input_fd(DCOPY_operation_t* op, \
                        off64_t offset, \
                        off64_t len)
{
    int in_fd = open64(op->operand, O_RDONLY | O_NOATIME);

    if(in_fd < 0) {
        LOG(DCOPY_LOG_DBG, "Failed to open input file `%s'. %s", \
            op->operand, strerror(errno));
        /* Handle operation requeue in parent function. */
    }

    posix_fadvise64(in_fd, offset, len, POSIX_FADV_SEQUENTIAL);
    return in_fd;
}
Esempio n. 3
0
int32_t SystemNative_PosixFAdvise(intptr_t fd, int64_t offset, int64_t length, int32_t advice)
{
#if HAVE_POSIX_ADVISE
    int32_t result;
    while ((
        result =
#if HAVE_POSIX_FADVISE64
            posix_fadvise64(
#else
            posix_fadvise(
#endif
                ToFileDescriptor(fd),
                (off_t)offset,
                (off_t)length,
                advice)) < 0 && errno == EINTR);
    return result;
#else
    // Not supported on this platform. Caller can ignore this failure since it's just a hint.
    (void)fd, (void)offset, (void)length, (void)advice;
    return ENOTSUP;
#endif
}
Esempio n. 4
0
CAMLprim value caml_extunix_fadvise64(value vfd, value voff, value vlen, value vadvise)
{
  int     errcode = 0;
  int     fd = -1;
  off64_t off = 0;
  off64_t len = 0;
  int     advise = 0;

  CAMLparam4(vfd, voff, vlen, vadvise);

  fd  = Int_val(vfd);
  off = Int64_val(voff);
  len = Int64_val(vlen);
  advise = caml_advises[Int_val(vadvise)]; 

  errcode = posix_fadvise64(fd, off, len, advise);

  if (errcode != 0)
  {
    unix_error(errcode, "fadvise64", Nothing);
  };

  CAMLreturn(Val_unit);
}
Esempio n. 5
0
int posix_fadvise(int fd, off_t offset, off_t len, int advice)
{
	return posix_fadvise64(fd, offset, len, advice);
}
Esempio n. 6
0
extern "C" Error SystemNative_Poll(PollEvent* pollEvents, uint32_t eventCount, int32_t milliseconds, uint32_t* triggered)
{
    if (pollEvents == nullptr || triggered == nullptr)
    {
        return PAL_EFAULT;
    }

    if (milliseconds < -1)
    {
        return PAL_EINVAL;
    }

    size_t bufferSize;
    if (!multiply_s(sizeof(pollfd), static_cast<size_t>(eventCount), &bufferSize))
    {
        return SystemNative_ConvertErrorPlatformToPal(EOVERFLOW);        
    }

    bool useStackBuffer = bufferSize <= 2048;
    pollfd* pollfds = reinterpret_cast<pollfd*>(useStackBuffer ? alloca(bufferSize) : malloc(bufferSize));
    if (pollfds == nullptr)
    {
        return PAL_ENOMEM;
    }

    for (uint32_t i = 0; i < eventCount; i++)
    {
        const PollEvent& event = pollEvents[i];
        pollfds[i] = { .fd = event.FileDescriptor, .events = event.Events, .revents = 0 };
    }

    int rv;
    while (CheckInterrupted(rv = poll(pollfds, static_cast<nfds_t>(eventCount), milliseconds)));

    if (rv < 0)
    {
        if (!useStackBuffer)
        {
            free(pollfds);
        }

        *triggered = 0;
        return SystemNative_ConvertErrorPlatformToPal(errno);
    }

    for (uint32_t i = 0; i < eventCount; i++)
    {
        const pollfd& pfd = pollfds[i];
        assert(pfd.fd == pollEvents[i].FileDescriptor);
        assert(pfd.events == pollEvents[i].Events);

        pollEvents[i].TriggeredEvents = static_cast<PollEvents>(pfd.revents);
    }

    *triggered = static_cast<uint32_t>(rv);

    if (!useStackBuffer)
    {
        free(pollfds);
    }

    return PAL_SUCCESS;
}

extern "C" int32_t SystemNative_PosixFAdvise(intptr_t fd, int64_t offset, int64_t length, FileAdvice advice)
{
#if HAVE_POSIX_ADVISE
    int32_t result;
    while (CheckInterrupted(
        result =
#if HAVE_POSIX_FADVISE64
            posix_fadvise64(
#else
            posix_fadvise(
#endif
                ToFileDescriptor(fd),
                offset,
                length,
                advice)));
    return result;
#else
    // Not supported on this platform. Caller can ignore this failure since it's just a hint.
    (void)fd, (void)offset, (void)length, (void)advice;
    return ENOTSUP;
#endif
}
    bool BlockData::WriteFile(const boost::filesystem::path& block_file_path)
    {
        if (bytes_ == 0)
        {
            LOG4CPLUS_WARN(Loggers::Service(), "An attempt to write an empty block into file "<<block_file_path<<" is rejected.");
            return false;
        }

        bool direct_io_applicable = ((bytes_ % MemoryChunk::GetPageSize()) == 0);
        int open_flags = O_CREAT | O_WRONLY;
        if (direct_io_applicable)
        {
            open_flags |= (O_DIRECT | O_SYNC);
        }
        
        LOG4CPLUS_TRACE(Loggers::Service(), "DIRECT IO:"<<direct_io_applicable<<", bytes_:"<<bytes_<<", page_size:"<<MemoryChunk::GetPageSize()<<", bytes%pagesize="<<(bytes_%MemoryChunk::GetPageSize()));
        
        int file_descriptor = open(block_file_path.string().c_str(), open_flags, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH);

        if (file_descriptor < 0)
        {
            LOG4CPLUS_ERROR(Loggers::Service(), "Failed to open file "<<block_file_path<<" to write.");
            return false;
        }

        size_t bytes_left = bytes_;
        size_t offset(0);
        int bytes_written(0);
        do
        {
            bytes_written = pwrite(file_descriptor, block_data_bytes_ + offset, bytes_left, offset);
            if (bytes_written > 0)
            {
                offset += bytes_written;
                bytes_left -= bytes_written;
            }
        }
        while(bytes_written > 0 && bytes_left > 0);

        if (bytes_written < 0)
        {
            LOG4CPLUS_ERROR(Loggers::Service(), "An error occurred while writing to file "<<block_file_path<<".(bytes_="<<bytes_<<", bytes_left="<<bytes_left<<")");
        }

        if (!direct_io_applicable)
        {
            //data would have to be flushed out before it can be wiped from page cache
            if (fdatasync(file_descriptor) == 0)
            {
                //to advise system NOT to keep the data in page cache
                //note that option POSIX_FADV_NOREUSE is no-op on linux, and should not be used
                if (0 != posix_fadvise64(file_descriptor, 0, 0, POSIX_FADV_DONTNEED))
                {
                    LOG4CPLUS_WARN(Loggers::Service(), "Failed to advise system to free file data from page cache.");
                }
            }
            else
            {
                LOG4CPLUS_WARN(Loggers::Service(), "Failed to flush data into memory");
            }
        }

        close(file_descriptor);
        return bytes_left == 0;
    }