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; }
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; }
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; }
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; }
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; }