static status_t
udf_get_vnode(fs_volume *_volume, ino_t id, fs_vnode *node, int *_type,
	uint32 *_flags, bool reenter)
{
	TRACE(("udf_get_vnode: _volume = %p, _node = %p, reenter = %s\n",
		_volume, _node, (reenter ? "true" : "false")));

	Volume *volume = (Volume *)_volume->private_volume;

	// Convert the given vnode id to an address, and create
	// and return a corresponding Icb object for it.
	TRACE(("udf_get_vnode: id = %Ld, blockSize = %lu\n", id,
		volume->BlockSize()));

	Icb *icb = new(std::nothrow) Icb(volume,
		to_long_address(id, volume->BlockSize()));
	if (icb == NULL)
		return B_NO_MEMORY;

	if (icb->InitCheck() == B_OK) {
		node->private_node = icb;
		node->ops = &gUDFVnodeOps;
		*_type = icb->Mode();
		*_flags = 0;
		return B_OK;
	}

	TRACE_ERROR(("udf_get_vnode: InitCheck failed\n"));
	delete icb;
	return B_ERROR;
}
Пример #2
0
Directory::Directory(Volume &volume, int32 block)
	:
	fVolume(volume)
{
	void *data = malloc(volume.BlockSize());
	if (data == NULL)
		return;

	if (read_pos(volume.Device(), block * volume.BlockSize(), data, volume.BlockSize()) == volume.BlockSize())
		fNode.SetTo(data, volume.BlockSize());
}
static status_t
udf_read_fs_stat(fs_volume *_volume, struct fs_info *info)
{
	TRACE(("udf_read_fs_stat: _volume = %p, info = %p\n", _volume, info));

	Volume *volume = (Volume *)_volume->private_volume;

	// File system flags.
	info->flags = B_FS_IS_PERSISTENT | B_FS_IS_READONLY;

	info->io_size = 65536;
		// whatever is appropriate here? Just use the same value as BFS (and iso9660) for now

	info->block_size = volume->BlockSize();
	info->total_blocks = volume->Length();
	info->free_blocks = 0;

	// Volume name
	sprintf(info->volume_name, "%s", volume->Name());

	// File system name
	strcpy(info->fsh_name, "udf");

	return B_OK;
}
Пример #4
0
static status_t
ext2_get_file_map(fs_volume* _volume, fs_vnode* _node, off_t offset,
	size_t size, struct file_io_vec* vecs, size_t* _count)
{
	TRACE("ext2_get_file_map()\n");
	Volume* volume = (Volume*)_volume->private_volume;
	Inode* inode = (Inode*)_node->private_node;
	size_t index = 0, max = *_count;

	while (true) {
		fsblock_t block;
		uint32 count = 1;
		status_t status = inode->FindBlock(offset, block, &count);
		if (status != B_OK)
			return status;

		if (block > volume->NumBlocks()) {
			panic("ext2_get_file_map() found block %" B_PRIu64 " for offset %"
				B_PRIdOFF "\n", block, offset);
		}

		off_t blockOffset = block << volume->BlockShift();
		uint32 blockLength = volume->BlockSize() * count;

		if (index > 0 && (vecs[index - 1].offset
				== blockOffset - vecs[index - 1].length
				|| (vecs[index - 1].offset == -1 && block == 0))) {
			vecs[index - 1].length += blockLength;
		} else {
			if (index >= max) {
				// we're out of file_io_vecs; let's bail out
				*_count = index;
				return B_BUFFER_OVERFLOW;
			}

			// 'block' is 0 for sparse blocks
			if (block != 0)
				vecs[index].offset = blockOffset;
			else
				vecs[index].offset = -1;

			vecs[index].length = blockLength;
			index++;
		}

		offset += blockLength;

		if (offset >= inode->Size() || size <= blockLength) {
			// We're done!
			*_count = index;
			TRACE("ext2_get_file_map for inode %" B_PRIdINO "\n", inode->ID());
			return B_OK;
		}

		size -= blockLength;
	}

	// can never get here
	return B_ERROR;
}
Пример #5
0
static status_t
ext2_ioctl(fs_volume* _volume, fs_vnode* _node, void* _cookie, uint32 cmd,
	void* buffer, size_t bufferLength)
{
	TRACE("ioctl: %" B_PRIu32 "\n", cmd);

	Volume* volume = (Volume*)_volume->private_volume;
	switch (cmd) {
		case 56742:
		{
			TRACE("ioctl: Test the block allocator\n");
			// Test the block allocator
			TRACE("ioctl: Creating transaction\n");
			Transaction transaction(volume->GetJournal());
			TRACE("ioctl: Creating cached block\n");
			CachedBlock cached(volume);
			uint32 blocksPerGroup = volume->BlocksPerGroup();
			uint32 blockSize  = volume->BlockSize();
			uint32 firstBlock = volume->FirstDataBlock();
			fsblock_t start = 0;
			uint32 group = 0;
			uint32 length;

			TRACE("ioctl: blocks per group: %" B_PRIu32 ", block size: %"
				B_PRIu32 ", first block: %" B_PRIu32 ", start: %" B_PRIu64
				", group: %" B_PRIu32 "\n", blocksPerGroup,
				blockSize, firstBlock, start, group);

			while (volume->AllocateBlocks(transaction, 1, 2048, group, start,
					length) == B_OK) {
				TRACE("ioctl: Allocated blocks in group %" B_PRIu32 ": %"
					B_PRIu64 "-%" B_PRIu64 "\n", group, start, start + length);
				off_t blockNum = start + group * blocksPerGroup - firstBlock;

				for (uint32 i = 0; i < length; ++i) {
					uint8* block = cached.SetToWritable(transaction, blockNum);
					memset(block, 0, blockSize);
					blockNum++;
				}

				TRACE("ioctl: Blocks cleared\n");

				transaction.Done();
				transaction.Start(volume->GetJournal());
			}

			TRACE("ioctl: Done\n");

			return B_OK;
		}
	}

	return B_DEV_INVALID_IOCTL;
}
Пример #6
0
static status_t
btrfs_read_fs_info(fs_volume* _volume, struct fs_info* info)
{
	Volume* volume = (Volume*)_volume->private_volume;

	// File system flags
	info->flags = B_FS_IS_PERSISTENT | B_FS_HAS_ATTR
		| (volume->IsReadOnly() ? B_FS_IS_READONLY : 0);
	info->io_size = BTRFS_IO_SIZE;
	info->block_size = volume->BlockSize();
	info->total_blocks = volume->SuperBlock().TotalSize() / volume->BlockSize();
	info->free_blocks = 0; //volume->NumFreeBlocks();

	// Volume name
	strlcpy(info->volume_name, volume->Name(), sizeof(info->volume_name));

	// File system name
	strlcpy(info->fsh_name, "btrfs", sizeof(info->fsh_name));

	return B_OK;
}
static status_t
udf_read_stat(fs_volume *_volume, fs_vnode *node, struct stat *stat)
{
	TRACE(("udf_read_stat: _volume = %p, node = %p\n", _volume, node));

	if (!_volume || !node || !stat)
		return B_BAD_VALUE;

	Volume *volume = (Volume *)_volume->private_volume;
	Icb *icb = (Icb *)node->private_node;

	stat->st_dev = volume->ID();
	stat->st_ino = icb->Id();
	stat->st_nlink = icb->FileLinkCount();
	stat->st_blksize = volume->BlockSize();

	TRACE(("udf_read_stat: st_dev = %ld, st_ino = %Ld, st_blksize = %d\n",
		stat->st_dev, stat->st_ino, stat->st_blksize));

	stat->st_uid = icb->Uid();
	stat->st_gid = icb->Gid();

	stat->st_mode = icb->Mode();
	stat->st_size = icb->Length();
	stat->st_blocks = (stat->st_size + 511) / 512;

	// File times. For now, treat the modification time as creation
	// time as well, since true creation time is an optional extended
	// attribute, and supporting EAs is going to be a PITA. ;-)
	stat->st_atime = icb->AccessTime();
	stat->st_mtime = stat->st_ctime = stat->st_crtime = icb->ModificationTime();

	TRACE(("udf_read_stat: mode = 0x%x, st_ino: %Ld\n", stat->st_mode,
		stat->st_ino));

	return B_OK;
}