Beispiel #1
0
static status_t
nfs4_remove_dir(fs_volume* volume, fs_vnode* parent, const char* name)
{
	VnodeToInode* vti = reinterpret_cast<VnodeToInode*>(parent->private_node);
	TRACE("volume = %p, parent = %" B_PRIi64 ", name = %s", volume, vti->ID(),
		name);

	VnodeToInodeLocker _(vti);
	Inode* inode = vti->Get();
	if (inode == NULL)
		return B_ENTRY_NOT_FOUND;

	ino_t id;
	status_t result = inode->Remove(name, NF4DIR, &id);
	if (result != B_OK)
		return result;

	result = acquire_vnode(volume, id);
	if (result == B_OK) {
		result = get_vnode(volume, id, reinterpret_cast<void**>(&vti));
		ASSERT(result == B_OK);

		if (vti->Unlink(inode->fInfo.fNames, name))
			remove_vnode(volume, id);

		put_vnode(volume, id);
		put_vnode(volume, id);
	}

	return B_OK;
}
Beispiel #2
0
Inode *InodeFactory::allocInode(FsMaker *fs, TARINO pino, int ftype)
{
	Inode *inode;
	TARINO ino = InodeFactory::inodeNum;
	TARBLK blkno;
	TARBLK oldblkno;
	SpaceManager *sp = fs->getDinodeManager();

	oldblkno = sp->getblkno();
	sp->allocBlock(fs, &blkno);
	if (oldblkno == TARBLK_NONE) {
		tarfs_dext de;
		de.de_off = ino;
		de.de_blkno = blkno;
		de.de_nblks = sp->getbulks();
		InodeFactory::freeInode->insBlock(fs, &de);
	}
	if (ftype == TARFS_IFDIR) {
		Dir *dir = new Dir(ino, pino, blkno);
		dir->dirInit(fs);
		inode = dir;
	} else {
		inode = new Inode(ino, pino, blkno, ftype);
	}
	if (inode) {
		inode->setDirty();
		InodeFactory::inodeNum++;
	} else {
		fs->rollback();
	}
	return inode;
}
Beispiel #3
0
static status_t
ext2_lookup(fs_volume* _volume, fs_vnode* _directory, const char* name,
	ino_t* _vnodeID)
{
	TRACE("ext2_lookup: name address: %p\n", name);
	TRACE("ext2_lookup: name: %s\n", name);
	Volume* volume = (Volume*)_volume->private_volume;
	Inode* directory = (Inode*)_directory->private_node;

	// check access permissions
	status_t status = directory->CheckPermissions(X_OK);
	if (status < B_OK)
		return status;

	HTree htree(volume, directory);
	DirectoryIterator* iterator;

	status = htree.Lookup(name, &iterator);
	if (status != B_OK)
		return status;

	ObjectDeleter<DirectoryIterator> iteratorDeleter(iterator);

	status = iterator->FindEntry(name, _vnodeID);
	if (status != B_OK)
		return status;

	return get_vnode(volume->FSVolume(), *_vnodeID, NULL);
}
Beispiel #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;
}
Beispiel #5
0
static status_t
ext2_get_vnode(fs_volume* _volume, ino_t id, fs_vnode* _node, int* _type,
	uint32* _flags, bool reenter)
{
	Volume* volume = (Volume*)_volume->private_volume;

	if (id < 2 || id > volume->NumInodes()) {
		ERROR("invalid inode id %" B_PRIdINO " requested!\n", id);
		return B_BAD_VALUE;
	}

	Inode* inode = new(std::nothrow) Inode(volume, id);
	if (inode == NULL)
		return B_NO_MEMORY;

	status_t status = inode->InitCheck();
	if (status != B_OK)
		delete inode;

	if (status == B_OK) {
		_node->private_node = inode;
		_node->ops = &gExt2VnodeOps;
		*_type = inode->Mode();
		*_flags = 0;
	} else
		ERROR("get_vnode: InitCheck() failed. Error: %s\n", strerror(status));

	return status;
}
Beispiel #6
0
static status_t
ext2_read_attr_dir(fs_volume* _volume, fs_vnode* _node,
				void* _cookie, struct dirent* dirent, size_t bufferSize,
				uint32* _num)
{
	Inode* inode = (Inode*)_node->private_node;
	int32 index = *(int32 *)_cookie;
	Attribute attribute(inode);
	TRACE("%s()\n", __FUNCTION__);

	size_t length = bufferSize;
	status_t status = attribute.Find(index);
	if (status == B_ENTRY_NOT_FOUND) {
		*_num = 0;
		return B_OK;
	} else if (status != B_OK)
		return status;

	status = attribute.GetName(dirent->d_name, &length);
	if (status != B_OK)
		return B_OK;

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

	dirent->d_dev = volume->ID();
	dirent->d_ino = inode->ID();
	dirent->d_reclen = sizeof(struct dirent) + length;

	*_num = 1;
	*(int32*)_cookie = index + 1;
	return B_OK;
}
Beispiel #7
0
static status_t
ext2_read_stat(fs_volume* _volume, fs_vnode* _node, struct stat* stat)
{
	Inode* inode = (Inode*)_node->private_node;
	const ext2_inode& node = inode->Node();

	stat->st_dev = inode->GetVolume()->ID();
	stat->st_ino = inode->ID();
	stat->st_nlink = node.NumLinks();
	stat->st_blksize = EXT2_IO_SIZE;

	stat->st_uid = node.UserID();
	stat->st_gid = node.GroupID();
	stat->st_mode = node.Mode();
	stat->st_type = 0;

	inode->GetAccessTime(&stat->st_atim);
	inode->GetModificationTime(&stat->st_mtim);
	inode->GetChangeTime(&stat->st_ctim);
	inode->GetCreationTime(&stat->st_crtim);

	stat->st_size = inode->Size();
	stat->st_blocks = (inode->Size() + 511) / 512;

	return B_OK;
}
Beispiel #8
0
static status_t
fifo_write(fs_volume* _volume, fs_vnode* _node, void* _cookie,
	off_t /*pos*/, const void* buffer, size_t* _length)
{
	file_cookie* cookie = (file_cookie*)_cookie;
	Inode* inode = (Inode*)_node->private_node;

	TRACE("fifo_write(vnode = %p, cookie = %p, length = %lu)\n",
		_node, cookie, *_length);

	MutexLocker locker(inode->RequestLock());

	if ((cookie->open_mode & O_RWMASK) != O_WRONLY)
		return B_NOT_ALLOWED;

	size_t length = *_length;
	if (length == 0)
		return B_OK;

	// copy data into ring buffer
	status_t status = inode->WriteDataToBuffer(buffer, &length,
		(cookie->open_mode & O_NONBLOCK) != 0, is_called_via_syscall());

	if (length > 0)
		status = B_OK;

	*_length = length;
	return status;
}
Beispiel #9
0
static status_t
nfs4_open_dir(fs_volume* volume, fs_vnode* vnode, void** _cookie)
{
	FileSystem* fs = reinterpret_cast<FileSystem*>(volume->private_volume);
	OpenDirCookie* cookie = new(std::nothrow) OpenDirCookie(fs);
	if (cookie == NULL)
		return B_NO_MEMORY;
	*_cookie = cookie;

	VnodeToInode* vti = reinterpret_cast<VnodeToInode*>(vnode->private_node);
	TRACE("volume = %p, vnode = %" B_PRIi64, volume, vti->ID());

	VnodeToInodeLocker _(vti);
	Inode* inode = vti->Get();
	if (inode == NULL)
		return B_ENTRY_NOT_FOUND;

	status_t result = inode->OpenDir(cookie);
	if (result != B_OK)
		delete cookie;

	TRACE("*cookie = %p", *_cookie);

	return result;
}
Beispiel #10
0
void
collectFiles(Disk &disk,Directory *directory)
{
	if (directory == NULL)
		return;

	directory->Rewind();
	char name[B_FILE_NAME_LENGTH];
	block_run run;
	while (directory->GetNextEntry(name,&run) >= B_OK)
	{
		if (!strcmp(name,".") || !strcmp(name,".."))
			continue;

		gHashtable.Put(run);

		if (++gCount % 50 == 0)
			printf("  %7Ld%s1A\n",gCount,gEscape);

		Inode *inode = Inode::Factory(&disk,run);
		if (inode != NULL)
		{
			if (inode->IsDirectory())
				collectFiles(disk,static_cast<Directory *>(inode));

			delete inode;
		}
		else
			printf("  Directory \"%s\" (%ld, %d) points to corrupt inode \"%s\" (%ld, %d)\n",
				directory->Name(),directory->BlockRun().allocation_group,directory->BlockRun().start,
				name,run.allocation_group,run.start);
	}
}
Beispiel #11
0
static status_t
btrfs_read_link(fs_volume *_volume, fs_vnode *_node, char *buffer,
	size_t *_bufferSize)
{
	Inode* inode = (Inode*)_node->private_node;
	return inode->ReadAt(0, (uint8*)buffer, _bufferSize);
}
Beispiel #12
0
static status_t
nfs4_open(fs_volume* volume, fs_vnode* vnode, int openMode, void** _cookie)
{
	VnodeToInode* vti = reinterpret_cast<VnodeToInode*>(vnode->private_node);
	TRACE("volume = %p, vnode = %" B_PRIi64 ", openMode = %d", volume,
		vti->ID(), openMode);

	VnodeToInodeLocker _(vti);
	Inode* inode = vti->Get();
	if (inode == NULL)
		return B_ENTRY_NOT_FOUND;

	if (inode->Type() == S_IFDIR || inode->Type() == S_IFLNK) {
		*_cookie = NULL;
		return B_OK;
	}

	FileSystem* fs = reinterpret_cast<FileSystem*>(volume->private_volume);
	OpenFileCookie* cookie = new OpenFileCookie(fs);
	if (cookie == NULL)
		return B_NO_MEMORY;
	*_cookie = cookie;

	status_t result = inode->Open(openMode, cookie);
	if (result != B_OK)
		delete cookie;

	TRACE("*cookie = %p", *_cookie);

	return result;
}
Beispiel #13
0
static status_t
btrfs_io(fs_volume* _volume, fs_vnode* _node, void* _cookie, io_request* request)
{
	Volume* volume = (Volume*)_volume->private_volume;
	Inode* inode = (Inode*)_node->private_node;

#ifndef BTRFS_SHELL
	if (io_request_is_write(request) && volume->IsReadOnly()) {
		notify_io_request(request, B_READ_ONLY_DEVICE);
		return B_READ_ONLY_DEVICE;
	}
#endif

	if (inode->FileCache() == NULL) {
#ifndef BTRFS_SHELL
		notify_io_request(request, B_BAD_VALUE);
#endif
		return B_BAD_VALUE;
	}

	// We lock the node here and will unlock it in the "finished" hook.
	rw_lock_read_lock(inode->Lock());

	return do_iterative_fd_io(volume->Device(), request,
		iterative_io_get_vecs_hook, iterative_io_finished_hook, inode);
}
Beispiel #14
0
static status_t
nfs4_get_vnode(fs_volume* volume, ino_t id, fs_vnode* vnode, int* _type,
	uint32* _flags, bool reenter)
{
	FileSystem* fs = reinterpret_cast<FileSystem*>(volume->private_volume);
	TRACE("volume = %p, id = %" B_PRIi64, volume, id);

	VnodeToInode* vnodeToInode = new VnodeToInode(id, fs);
	if (vnodeToInode == NULL)
		return B_NO_MEMORY;

	Inode* inode;	
	status_t result = fs->GetInode(id, &inode);
	if (result != B_OK) {
		delete vnodeToInode;
		return result;
	}

	vnodeToInode->Replace(inode);
	vnode->ops = &gNFSv4VnodeOps;
	vnode->private_node = vnodeToInode;

	*_type = inode->Type();
	*_flags = 0;

	return B_OK;
}
Beispiel #15
0
static status_t
nfs4_create_dir(fs_volume* volume, fs_vnode* parent, const char* name,
	int mode)
{
	VnodeToInode* vti = reinterpret_cast<VnodeToInode*>(parent->private_node);
	TRACE("volume = %p, parent = %" B_PRIi64 ", mode = %d", volume, vti->ID(),
		mode);

	VnodeToInodeLocker _(vti);
	Inode* inode = vti->Get();
	if (inode == NULL)
		return B_ENTRY_NOT_FOUND;

	ino_t id;
	status_t result = inode->CreateDir(name, mode, &id);
	if (result != B_OK)
		return result;

	result = get_vnode(volume, id, reinterpret_cast<void**>(&vti));
	if (result == B_OK) {
		unremove_vnode(volume, id);
		vti->Clear();
		put_vnode(volume, id);
	}

	return B_OK;
}
Beispiel #16
0
//!	btrfs_io() callback hook
static status_t
iterative_io_finished_hook(void* cookie, io_request* request, status_t status,
	bool partialTransfer, size_t bytesTransferred)
{
	Inode* inode = (Inode*)cookie;
	rw_lock_read_unlock(inode->Lock());
	return B_OK;
}
Beispiel #17
0
Inode::Inode(const Inode& orig) {
    this->address = orig.getAddress();
    this->type = orig.getType();
    for (int i = 0; i < MAX_ADDRESS_COUNT; i++) {
        this->dataaddress[i] = orig.getDataAddress(i);
    }
    this->filesize = orig.getFileSize();
}
Beispiel #18
0
//!	btrfs_io() callback hook
static status_t
iterative_io_get_vecs_hook(void* cookie, io_request* request, off_t offset,
	size_t size, struct file_io_vec* vecs, size_t* _count)
{
	Inode* inode = (Inode*)cookie;

	return file_map_translate(inode->Map(), offset, size, vecs, _count,
		inode->GetVolume()->BlockSize());
}
Beispiel #19
0
Inode *InodeFactory::allocInode(FsMaker *fs, TARINO pino, File *file)
{
	Inode *inode = InodeFactory::allocInode(fs, pino, file->getFtype());
	if (inode) {
		inode->setFile(file);
		if (file->getFtype() == TARFS_IFREG) {
			InodeFactory::totalDataSize += file->getBlocks();
		}
	}
	return inode;
}
Beispiel #20
0
static status_t
ext2_unlink(fs_volume* _volume, fs_vnode* _directory, const char* name)
{
	TRACE("ext2_unlink()\n");
	if (strcmp(name, ".") == 0 || strcmp(name, "..") == 0)
		return B_NOT_ALLOWED;

	Volume* volume = (Volume*)_volume->private_volume;
	Inode* directory = (Inode*)_directory->private_node;

	status_t status = directory->CheckPermissions(W_OK);
	if (status != B_OK)
		return status;

	TRACE("ext2_unlink(): Starting transaction\n");
	Transaction transaction(volume->GetJournal());

	directory->WriteLockInTransaction(transaction);

	TRACE("ext2_unlink(): Looking up for directory entry\n");
	HTree htree(volume, directory);
	DirectoryIterator* directoryIterator;

	status = htree.Lookup(name, &directoryIterator);
	if (status != B_OK)
		return status;

	ino_t id;
	status = directoryIterator->FindEntry(name, &id);
	if (status != B_OK)
		return status;

	Vnode vnode(volume, id);
	Inode* inode;
	status = vnode.Get(&inode);
	if (status != B_OK)
		return status;

	inode->WriteLockInTransaction(transaction);

	status = inode->Unlink(transaction);
	if (status != B_OK)
		return status;

	status = directoryIterator->RemoveEntry(transaction);
	if (status != B_OK)
		return status;

	entry_cache_remove(volume->ID(), directory->ID(), name);

	status = transaction.Done();
	if (status != B_OK)
		entry_cache_add(volume->ID(), directory->ID(), name, id);
	else
		notify_entry_removed(volume->ID(), directory->ID(), name, id);

	return status;
}
Beispiel #21
0
Inode *InodeFactory::getInode(FsIO *fsio, TARINO ino, TARINO pino)
{
	Inode *inode;
	TARBLK blkno;
	InodeFactory::freeInode->getBlock(fsio, ino, &blkno);
	inode = new Inode(ino, pino, blkno, fsio);
	if (inode && inode->isDir()) {
		delete inode;
		inode = new Dir(ino, pino, blkno, fsio);
	}
	return inode;
}
Beispiel #22
0
static status_t
nfs4_remove_attr(fs_volume* volume, fs_vnode* vnode, const char* name)
{
	VnodeToInode* vti = reinterpret_cast<VnodeToInode*>(vnode->private_node);

	VnodeToInodeLocker _(vti);
	Inode* inode = vti->Get();
	if (inode == NULL)
		return B_ENTRY_NOT_FOUND;

	return inode->Remove(name, NF4NAMEDATTR, NULL);
}
Beispiel #23
0
static status_t
btrfs_free_cookie(fs_volume* _volume, fs_vnode* _node, void* _cookie)
{
	file_cookie* cookie = (file_cookie*)_cookie;
	Volume* volume = (Volume*)_volume->private_volume;
	Inode* inode = (Inode*)_node->private_node;

	if (inode->Size() != cookie->last_size)
		notify_stat_changed(volume->ID(), inode->ID(), B_STAT_SIZE);

	delete cookie;
	return B_OK;
}
Beispiel #24
0
static status_t
fifo_set_flags(fs_volume* _volume, fs_vnode* _node, void* _cookie,
	int flags)
{
	Inode* inode = (Inode*)_node->private_node;
	file_cookie* cookie = (file_cookie*)_cookie;

	TRACE("fifo_set_flags(vnode = %p, flags = %x)\n", _vnode, flags);

	MutexLocker locker(inode->RequestLock());
	cookie->open_mode = (cookie->open_mode & ~(O_APPEND | O_NONBLOCK)) | flags;
	return B_OK;
}
Beispiel #25
0
static status_t
btrfs_read(fs_volume* _volume, fs_vnode* _node, void* _cookie, off_t pos,
	void* buffer, size_t* _length)
{
	Inode* inode = (Inode*)_node->private_node;

	if (!inode->IsFile()) {
		*_length = 0;
		return inode->IsDirectory() ? B_IS_A_DIRECTORY : B_BAD_VALUE;
	}

	return inode->ReadAt(pos, (uint8*)buffer, _length);
}
Beispiel #26
0
static status_t
nfs4_fsync(fs_volume* volume, fs_vnode* vnode)
{
	VnodeToInode* vti = reinterpret_cast<VnodeToInode*>(vnode->private_node);
	TRACE("volume = %p, vnode = %" B_PRIi64, volume, vti->ID());

	VnodeToInodeLocker _(vti);
	Inode* inode = vti->Get();
	if (inode == NULL)
		return B_ENTRY_NOT_FOUND;

	return inode->SyncAndCommit();
}
Beispiel #27
0
static status_t
nfs4_access(fs_volume* volume, fs_vnode* vnode, int mode)
{
	VnodeToInode* vti = reinterpret_cast<VnodeToInode*>(vnode->private_node);
	TRACE("volume = %p, vnode = %" B_PRIi64 ", mode = %d", volume, vti->ID(),
		mode);

	VnodeToInodeLocker _(vti);
	Inode* inode = vti->Get();
	if (inode == NULL)
		return B_ENTRY_NOT_FOUND;

	return inode->Access(mode);
}
Beispiel #28
0
static status_t
nfs4_read_symlink(fs_volume* volume, fs_vnode* link, char* buffer,
	size_t* _bufferSize)
{
	VnodeToInode* vti = reinterpret_cast<VnodeToInode*>(link->private_node);
	TRACE("volume = %p, link = %" B_PRIi64, volume, vti->ID());

	VnodeToInodeLocker _(vti);
	Inode* inode = vti->Get();
	if (inode == NULL)
		return B_ENTRY_NOT_FOUND;

	return inode->ReadLink(buffer, _bufferSize);
}
Beispiel #29
0
static status_t
nfs4_write_attr(fs_volume* volume, fs_vnode* vnode, void* _cookie, off_t pos,
	const void* buffer, size_t* length)
{
	VnodeToInode* vti = reinterpret_cast<VnodeToInode*>(vnode->private_node);
	OpenAttrCookie* cookie = reinterpret_cast<OpenAttrCookie*>(_cookie);

	VnodeToInodeLocker _(vti);
	Inode* inode = vti->Get();
	if (inode == NULL)
		return B_ENTRY_NOT_FOUND;

	return inode->WriteDirect(cookie, pos, buffer, length);
}
Beispiel #30
0
static status_t
nfs4_write_attr_stat(fs_volume* volume, fs_vnode* vnode, void* _cookie,
	const struct stat* stat, int statMask)
{
	VnodeToInode* vti = reinterpret_cast<VnodeToInode*>(vnode->private_node);
	OpenAttrCookie* cookie = reinterpret_cast<OpenAttrCookie*>(_cookie);

	VnodeToInodeLocker _(vti);
	Inode* inode = vti->Get();
	if (inode == NULL)
		return B_ENTRY_NOT_FOUND;

	return inode->WriteStat(stat, statMask, cookie);
}