コード例 #1
0
void CacheFile::read(Uint8* buf,Uint32 size,Uint64 off)
{
    QMutexLocker lock(&mutex);
    bool close_again = false;

    // reopen the file if necessary
    if (fd == -1)
    {
        //	Out() << "Reopening " << path << endl;
        openFile(READ);
        close_again = true;
    }

    if (off >= file_size || off >= max_size)
    {
        throw Error(i18n("Error : Reading past the end of the file %1").arg(path));
    }

    // jump to right position
    SeekFile(fd,(Int64)off,SEEK_SET);
    if ((Uint32)::read(fd,buf,size) != size)
    {
        if (close_again)
            closeTemporary();

        throw Error(i18n("Error reading from %1").arg(path));
    }

    if (close_again)
        closeTemporary();
}
コード例 #2
0
ファイル: cachefile.cpp プロジェクト: KDE/libktorrent
	void CacheFile::read(Uint8* buf,Uint32 size,Uint64 off)
	{
		QMutexLocker lock(&mutex);
		bool close_again = false;
		
		// reopen the file if necessary
		if (!fptr)
		{
		//	Out(SYS_DIO|LOG_DEBUG) << "Reopening " << path << endl;
			openFile(READ);
			close_again = true;
		}
		
		if (off >= file_size || off >= max_size)
		{
			throw Error(i18n("Error: Reading past the end of the file %1",path));
		}
		
		// jump to right position
		if (!fptr->seek(off))
			throw Error(i18n("Failed to seek file %1: %2",path,fptr->errorString()));
		
		Uint32 sz = 0;
		if ((sz = fptr->read((char*)buf,size)) != size)
		{
			if (close_again)
				closeTemporary();
			
			throw Error(i18n("Error reading from %1",path));
		}
		
		if (close_again)
			closeTemporary();
	}
コード例 #3
0
void CacheFile::preallocate(PreallocationThread* prealloc)
{
    QMutexLocker lock(&mutex);

    if (FileSize(path) == max_size)
    {
        Out(SYS_GEN|LOG_NOTICE) << "File " << path << " already big enough" << endl;
        return;
    }

    Out(SYS_GEN|LOG_NOTICE) << "Preallocating file " << path << " (" << max_size << " bytes)" << endl;
    bool close_again = false;
    if (fd == -1)
    {
        openFile(RW);
        close_again = true;
    }

    if (read_only)
    {
        if (close_again)
            closeTemporary();

        throw Error(i18n("Cannot open %1 for writing : readonly filesystem").arg(path));
    }

    try
    {
        bool res = false;

#ifdef HAVE_XFS_XFS_H
        if( (! res) && Settings::fullDiskPrealloc() && (Settings::fullDiskPreallocMethod() == 1) )
        {
            res = XfsPreallocate(fd, max_size);
        }
#endif

        if(! res)
        {
            bt::TruncateFile(fd,max_size,!Settings::fullDiskPrealloc());
        }
    }
    catch (bt::Error & e)
    {
        // first attempt failed, must be fat so try that
        if (!FatPreallocate(fd,max_size))
        {
            if (close_again)
                closeTemporary();

            throw Error(i18n("Cannot preallocate diskspace : %1").arg(strerror(errno)));
        }
    }

    file_size = FileSize(fd);
    Out(SYS_GEN|LOG_DEBUG) << "file_size = " << file_size << endl;
    if (close_again)
        closeTemporary();
}
コード例 #4
0
ファイル: cachefile.cpp プロジェクト: KDE/libktorrent
	void CacheFile::preallocate(PreallocationThread* prealloc)
	{
		QMutexLocker lock(&mutex);
		
		if (FileSize(path) == max_size)
		{
			Out(SYS_GEN|LOG_NOTICE) << "File " << path << " already big enough" << endl;
			return;
		}

		Out(SYS_GEN|LOG_NOTICE) << "Preallocating file " << path << " (" << max_size << " bytes)" << endl;
		bool close_again = false;
		if (!fptr)
		{
			openFile(RW);
			close_again = true;
		}
		
		int fd = fptr->handle();
		
		if (read_only)
		{
			if (close_again)
				closeTemporary();
			
			throw Error(i18n("Cannot open %1 for writing: readonly filesystem",path));
		}

		try
		{
			bool res = false;
			
#ifdef HAVE_XFS_XFS_H
			if(Cache::preallocateFully())
			{
				res = XfsPreallocate(fd, max_size);
			}
#endif
			
			if(! res)
			{
				bt::TruncateFile(fd,max_size,!Cache::preallocateFully());
			}
		}
		catch (bt::Error & e)
		{
			throw Error(i18n("Cannot preallocate diskspace: %1",strerror(errno)));
		}

		file_size = FileSize(fd);
		prealloc->written(file_size);
		Out(SYS_GEN|LOG_DEBUG) << "file_size = " << file_size << endl;
		if (close_again)
			closeTemporary();
	}
コード例 #5
0
ファイル: cachefile.cpp プロジェクト: KDE/libktorrent
	void CacheFile::unmap(void* ptr,Uint32 size)
	{
		int ret = 0;
		QMutexLocker lock(&mutex);
#ifdef Q_OS_WIN
		if (!fptr)
			return;
			
		if (mappings.contains(ptr))
		{
			CacheFile::Entry & e = mappings[ptr];
			if (!fptr->unmap((uchar*)e.ptr))
				Out(SYS_DIO|LOG_IMPORTANT) << QString("Unmap failed : %1").arg(fptr->errorString()) << endl;
			
			mappings.remove(ptr);
			// no mappings, close temporary
			if (mappings.count() == 0)
				closeTemporary();
		}
#else
		// see if it wasn't an offsetted mapping
		if (mappings.contains(ptr))
		{
			CacheFile::Entry & e = mappings[ptr];
#ifdef HAVE_MUNMAP64
			ret = munmap64(e.ptr,e.size);
#else
			ret = munmap(e.ptr,e.size);
#endif
			if (ret < 0)
				Out(SYS_DIO|LOG_IMPORTANT) << QString("Munmap failed with error %1 : %2").arg(errno).arg(strerror(errno)) << endl;
			
			mappings.remove(ptr);
			// no mappings, close temporary
			if (mappings.count() == 0)
				closeTemporary();
		}
#endif
	}
コード例 #6
0
void CacheFile::write(const Uint8* buf,Uint32 size,Uint64 off)
{
    QMutexLocker lock(&mutex);
    bool close_again = false;

    // reopen the file if necessary
    if (fd == -1)
    {
        //	Out() << "Reopening " << path << endl;
        openFile(RW);
        close_again = true;
    }

    if (read_only)
        throw Error(i18n("Cannot open %1 for writing : readonly filesystem").arg(path));

    if (off + size > max_size)
    {
        Out() << "Warning : writing past the end of " << path << endl;
        Out() << (off + size) << " " << max_size << endl;
    }

    if (file_size < off)
    {
        //Out() << QString("Writing %1 bytes at %2").arg(size).arg(off) << endl;
        growFile(off - file_size);
    }

    // jump to right position
    SeekFile(fd,(Int64)off,SEEK_SET);
    int ret = ::write(fd,buf,size);
    if (close_again)
        closeTemporary();

    if (ret == -1)
        throw Error(i18n("Error writing to %1 : %2").arg(path).arg(strerror(errno)));
    else if ((Uint32)ret != size)
    {
        Out() << QString("Incomplete write of %1 bytes, should be %2").arg(ret).arg(size) << endl;
        throw Error(i18n("Error writing to %1").arg(path));
    }

    if (off + size > file_size)
        file_size = off + size;
}
コード例 #7
0
ファイル: cachefile.cpp プロジェクト: KDE/libktorrent
	void CacheFile::write(const Uint8* buf,Uint32 size,Uint64 off)
	{
		QMutexLocker lock(&mutex);
		bool close_again = false;
		
		// reopen the file if necessary
		if (!fptr)
		{
		//	Out(SYS_DIO|LOG_DEBUG) << "Reopening " << path << endl;
			openFile(RW);
			close_again = true;
		}
		
		if (read_only)
			throw Error(i18n("Cannot open %1 for writing: readonly filesystem",path));
		
		if (off + size > max_size)
		{
			Out(SYS_DIO|LOG_DEBUG) << "Warning : writing past the end of " << path << endl;
			Out(SYS_DIO|LOG_DEBUG) << (off + size) << " " << max_size << endl;
			throw Error(i18n("Attempting to write beyond the maximum size of %1",path));
		}
		
		if (file_size < off)
		{
			//Out(SYS_DIO|LOG_DEBUG) << QString("Writing %1 bytes at %2").arg(size).arg(off) << endl;
			growFile(off - file_size);
		}
		
		
		// jump to right position
		if (!fptr->seek(off))
			throw Error(i18n("Failed to seek file %1: %2",path,fptr->errorString()));
		
		if (fptr->write((const char*)buf,size) != size)
		{
			throw Error(i18n("Failed to write to file %1: %2",path,fptr->errorString()));
		}
		
		if (close_again)
			closeTemporary();
	
		if (off + size > file_size)
			file_size = off + size;
	}
コード例 #8
0
Uint64 CacheFile::diskUsage()
{
    Uint64 ret = 0;
    bool close_again = false;
    if (fd == -1)
    {
        openFile(READ);
        close_again = true;
    }

    struct stat sb;
    if (fstat(fd,&sb) == 0)
    {
        ret = (Uint64)sb.st_blocks * 512;
    }

    //	Out(SYS_GEN|LOG_NOTICE) << "CF: " << path << " is taking up " << ret << " bytes" << endl;
    if (close_again)
        closeTemporary();

    return ret;
}
コード例 #9
0
void CacheFile::unmap(void* ptr,Uint32 size)
{
    int ret = 0;
    QMutexLocker lock(&mutex);
    // see if it wasn't an offsetted mapping
    if (mappings.contains(ptr))
    {
        CacheFile::Entry & e = mappings[ptr];
#if HAVE_MUNMAP64
        if (e.diff > 0)
            ret = munmap64((char*)ptr - e.diff,e.size);
        else
            ret = munmap64(ptr,e.size);
#else
        if (e.diff > 0)
            ret = munmap((char*)ptr - e.diff,e.size);
        else
            ret = munmap(ptr,e.size);
#endif
        mappings.erase(ptr);
        // no mappings, close temporary
        if (mappings.count() == 0)
            closeTemporary();
    }
    else
    {
#if HAVE_MUNMAP64
        ret = munmap64(ptr,size);
#else
        ret = munmap(ptr,size);
#endif
    }

    if (ret < 0)
    {
        Out(SYS_DIO|LOG_IMPORTANT) << QString("Munmap failed with error %1 : %2").arg(errno).arg(strerror(errno)) << endl;
    }
}