Exemplo n.º 1
0
	status_t ReadData(off_t offset, void* buffer, size_t* bufferSize)
	{
		if (offset < 0 || (uint64)offset > fData->UncompressedSize())
			return B_BAD_VALUE;

		*bufferSize = std::min((uint64)*bufferSize,
			fData->UncompressedSize() - offset);

		return file_cache_read(fFileCache, NULL, offset, buffer, bufferSize);
	}
Exemplo n.º 2
0
status_t
Inode::ReadAt(off_t pos, uint8* buffer, size_t* _length)
{
    size_t length = *_length;

    // set/check boundaries for pos/length
    if (pos < 0) {
        ERROR("inode %" B_PRIdINO ": ReadAt failed(pos %lld, length %lu)\n",
              ID(), pos, length);
        return B_BAD_VALUE;
    }

    if (pos >= Size() || length == 0) {
        TRACE("inode %" B_PRIdINO ": ReadAt 0 (pos %lld, length %lu)\n",
              ID(), pos, length);
        *_length = 0;
        return B_NO_ERROR;
    }

    // the file cache doesn't seem to like non block aligned file offset
    // so we avoid the file cache for inline extents
    struct btrfs_key search_key;
    search_key.SetType(BTRFS_KEY_TYPE_EXTENT_DATA);
    search_key.SetObjectID(fID);
    search_key.SetOffset(pos + 1);

    btrfs_extent_data *extent_data;
    status_t status = fVolume->FSTree()->FindPrevious(search_key,
                      (void**)&extent_data);
    if (status != B_OK) {
        ERROR("Inode::FindBlock(): Couldn't find extent_data 0x%lx\n", status);
        return status;
    }

    if (FileCache() != NULL
            && extent_data->Type() == BTRFS_EXTENT_DATA_REGULAR) {
        TRACE("inode %" B_PRIdINO ": ReadAt cache (pos %lld, length %lu)\n",
              ID(), pos, length);
        free(extent_data);
        return file_cache_read(FileCache(), NULL, pos, buffer, _length);
    }

    TRACE("Inode::ReadAt(%" B_PRIdINO ") key.Offset() %lld\n", ID(),
          search_key.Offset());

    off_t diff = pos - search_key.Offset();
    if (extent_data->Type() != BTRFS_EXTENT_DATA_INLINE)
        panic("unknown extent type; %d\n", extent_data->Type());

    *_length = min_c(extent_data->MemoryBytes() - diff, *_length);
    memcpy(buffer, extent_data->inline_data, *_length);
    free(extent_data);
    return B_OK;

}
Exemplo n.º 3
0
status_t
Inode::Read(OpenFileCookie* cookie, off_t pos, void* buffer, size_t* _length)
{
	ASSERT(cookie != NULL);
	ASSERT(buffer != NULL);
	ASSERT(_length != NULL);

	bool eof = false;
	if ((cookie->fMode & O_NOCACHE) != 0)
		return ReadDirect(cookie, pos, buffer, _length, &eof);
	return file_cache_read(fFileCache, cookie, pos, buffer, _length);
}
Exemplo n.º 4
0
static int uidlist_file_cache_read(struct squat_uidlist *uidlist,
				   size_t offset, size_t size)
{
	if (uidlist->file_cache == NULL)
		return 0;

	if (file_cache_read(uidlist->file_cache, offset, size) < 0) {
		i_error("read(%s) failed: %m", uidlist->path);
		return -1;
	}
	uidlist->data = file_cache_get_map(uidlist->file_cache,
					   &uidlist->data_size);
	squat_uidlist_map_blocks_set_pointers(uidlist);
	return 0;
}
Exemplo n.º 5
0
status_t
Inode::ReadAt(off_t pos, uint8* buffer, size_t* _length)
{
	size_t length = *_length;

	// set/check boundaries for pos/length
	if (pos < 0) {
		ERROR("inode %lld: ReadAt failed(pos %lld, length %lu)\n", ID(), pos,
			length);
		return B_BAD_VALUE;
	}

	if (pos >= Size() || length == 0) {
		TRACE("inode %lld: ReadAt 0 (pos %lld, length %lu)\n", ID(), pos, length);
		*_length = 0;
		return B_NO_ERROR;
	}

	return file_cache_read(FileCache(), NULL, pos, buffer, _length);
}
static status_t
fs_read(fs_volume* _volume, fs_vnode* _node, void* cookie, off_t pos,
	void* buffer, size_t* _length)
{
	iso9660_inode* node = (iso9660_inode*)_node->private_node;

	if ((node->flags & ISO_IS_DIR) != 0)
		return EISDIR;

	uint32 fileSize = node->dataLen[FS_DATA_FORMAT];

	// set/check boundaries for pos/length
	if (pos < 0)
		return B_BAD_VALUE;
	if (pos >= fileSize) {
		*_length = 0;
		return B_OK;
	}

	return file_cache_read(node->cache, NULL, pos, buffer, _length);
}
Exemplo n.º 7
0
status_t
Inode::ReadAt(off_t pos, uint8* buffer, size_t* _length)
{
	size_t length = *_length;

	// set/check boundaries for pos/length
	if (pos < 0) {
		ERROR("inode %" B_PRIdINO ": ReadAt failed(pos %" B_PRIdOFF
			", length %lu)\n", ID(), pos, length);
		return B_BAD_VALUE;
	}

	if (pos >= Size() || length == 0) {
		TRACE("inode %" B_PRIdINO ": ReadAt 0 (pos %" B_PRIdOFF
			", length %lu)\n", ID(), pos, length);
		*_length = 0;
		return B_NO_ERROR;
	}

	// the file cache doesn't seem to like non block aligned file offset
	// so we avoid the file cache for inline extents
	struct btrfs_key search_key;
	search_key.SetType(BTRFS_KEY_TYPE_EXTENT_DATA);
	search_key.SetObjectID(fID);
	search_key.SetOffset(pos + 1);

	size_t item_size;
	btrfs_extent_data *extent_data;
	status_t status = fVolume->FSTree()->FindPrevious(search_key,
		(void**)&extent_data, &item_size);
	if (status != B_OK) {
		ERROR("Inode::FindBlock(): Couldn't find extent_data 0x%" B_PRIx32
			"\n", status);
		return status;
	}

	uint8 compression = extent_data->Compression();
	if (FileCache() != NULL
		&& extent_data->Type() == BTRFS_EXTENT_DATA_REGULAR) {
		TRACE("inode %" B_PRIdINO ": ReadAt cache (pos %" B_PRIdOFF ", length %lu)\n",
			ID(), pos, length);
		free(extent_data);
		if (compression == BTRFS_EXTENT_COMPRESS_NONE)
			return file_cache_read(FileCache(), NULL, pos, buffer, _length);
		else if (compression == BTRFS_EXTENT_COMPRESS_ZLIB)
			panic("zlib isn't unsupported for regular extent\n");
		else
			panic("unknown extent compression; %d\n", compression);
	}

	TRACE("Inode::ReadAt(%" B_PRIdINO ") key.Offset() %" B_PRId64 "\n", ID(),
		search_key.Offset());

	off_t diff = pos - search_key.Offset();
	if (extent_data->Type() != BTRFS_EXTENT_DATA_INLINE)
		panic("unknown extent type; %d\n", extent_data->Type());

	*_length = min_c(extent_data->Size() - diff, *_length);
	if (compression == BTRFS_EXTENT_COMPRESS_NONE)
		memcpy(buffer, extent_data->inline_data, *_length);
	else if (compression == BTRFS_EXTENT_COMPRESS_ZLIB) {
		char in[2048];
		z_stream zStream = {
			(Bytef*)in,		// next in
			sizeof(in),		// avail in
			0,				// total in
			NULL,			// next out
			0,				// avail out
			0,				// total out
			0,				// msg
			0,				// state
			Z_NULL,			// zalloc
			Z_NULL,			// zfree
			Z_NULL,			// opaque
			0,				// data type
			0,				// adler
			0,				// reserved
		};

		int status;
		ssize_t offset = 0;
		size_t inline_size = item_size - 13;
		bool headerRead = false;

		TRACE("Inode::ReadAt(%" B_PRIdINO ") diff %" B_PRIdOFF " size %"
			B_PRIuSIZE "\n", ID(), diff, item_size);

		do {
			ssize_t bytesRead = min_c(sizeof(in), inline_size - offset);
			memcpy(in, extent_data->inline_data + offset, bytesRead);
			if (bytesRead != (ssize_t)sizeof(in)) {
				if (bytesRead <= 0) {
					status = Z_STREAM_ERROR;
					break;
				}
			}

			zStream.avail_in = bytesRead;
			zStream.next_in = (Bytef*)in;

			if (!headerRead) {
				headerRead = true;

				zStream.avail_out = length;
				zStream.next_out = (Bytef*)buffer;

				status = inflateInit2(&zStream, 15);
				if (status != Z_OK) {
					free(extent_data);
					return B_ERROR;
				}
			}

			status = inflate(&zStream, Z_SYNC_FLUSH);
			offset += bytesRead;
			if (diff > 0) {
				zStream.next_out -= max_c(bytesRead, diff);
				diff -= max_c(bytesRead, diff);
			}

			if (zStream.avail_in != 0 && status != Z_STREAM_END) {
				TRACE("Inode::ReadAt() didn't read whole block: %s\n",
					zStream.msg);
			}
		} while (status == Z_OK);

		inflateEnd(&zStream);

		if (status != Z_STREAM_END) {
			TRACE("Inode::ReadAt() inflating failed: %d!\n", status);
			free(extent_data);
			return B_BAD_DATA;
		}

		*_length = zStream.total_out;

	} else
		panic("unknown extent compression; %d\n", compression);
	free(extent_data);
	return B_OK;

}