Exemplo n.º 1
0
void
Inode::RemovedFromTransaction()
{
	TRACE("Inode::RemovedFromTransaction(): Unlocking\n");
	rw_lock_write_unlock(&fLock);

	put_vnode(fVolume->FSVolume(), ID());
}
Exemplo n.º 2
0
	bool TestDegrade(TestContext& context)
	{
		TEST_ASSERT(rw_lock_write_lock(&fLock) == B_OK);
		TEST_ASSERT(rw_lock_read_lock(&fLock) == B_OK);
		rw_lock_write_unlock(&fLock);
		rw_lock_read_unlock(&fLock);

		return true;
	}
Exemplo n.º 3
0
	bool TestNestedWrite(TestContext& context)
	{
		for (int32 i = 0; i < 10; i++)
			TEST_ASSERT(rw_lock_write_lock(&fLock) == B_OK);

		for (int32 i = 0; i < 10; i++)
			rw_lock_write_unlock(&fLock);

		return true;
	}
Exemplo n.º 4
0
	bool TestSimple(TestContext& context)
	{
		for (int32 i = 0; i < 3; i++) {
			TEST_ASSERT(rw_lock_read_lock(&fLock) == B_OK);
			rw_lock_read_unlock(&fLock);

			TEST_ASSERT(rw_lock_write_lock(&fLock) == B_OK);
			rw_lock_write_unlock(&fLock);
		}

		return true;
	}
/*static*/ void
VMAddressSpace::_DeleteIfUnreferenced(team_id id)
{
	rw_lock_write_lock(&sAddressSpaceTableLock);

	bool remove = false;
	VMAddressSpace* addressSpace = sAddressSpaceTable.Lookup(id);
	if (addressSpace != NULL && addressSpace->fRefCount == 0) {
		sAddressSpaceTable.RemoveUnchecked(addressSpace);
		remove = true;
	}

	rw_lock_write_unlock(&sAddressSpaceTableLock);

	if (remove)
		delete addressSpace;
}
/*static*/ status_t
VMAddressSpace::Create(team_id teamID, addr_t base, size_t size, bool kernel,
	VMAddressSpace** _addressSpace)
{
	VMAddressSpace* addressSpace = kernel
		? (VMAddressSpace*)new(std::nothrow) VMKernelAddressSpace(teamID, base,
			size)
		: (VMAddressSpace*)new(std::nothrow) VMUserAddressSpace(teamID, base,
			size);
	if (addressSpace == NULL)
		return B_NO_MEMORY;

	status_t status = addressSpace->InitObject();
	if (status != B_OK) {
		delete addressSpace;
		return status;
	}

	TRACE(("VMAddressSpace::Create(): team %ld (%skernel): %#lx bytes starting at "
		"%#lx => %p\n", teamID, kernel ? "" : "!", size, base, addressSpace));

	// create the corresponding translation map
	status = arch_vm_translation_map_create_map(kernel,
		&addressSpace->fTranslationMap);
	if (status != B_OK) {
		delete addressSpace;
		return status;
	}

	// add the aspace to the global hash table
	rw_lock_write_lock(&sAddressSpaceTableLock);
	sAddressSpaceTable.InsertUnchecked(addressSpace);
	rw_lock_write_unlock(&sAddressSpaceTableLock);

	*_addressSpace = addressSpace;
	return B_OK;
}
Exemplo n.º 7
0
status_t
ext2_write_stat(fs_volume* _volume, fs_vnode* _node, const struct stat* stat,
	uint32 mask)
{
	TRACE("ext2_write_stat\n");
	Volume* volume = (Volume*)_volume->private_volume;

	if (volume->IsReadOnly())
		return B_READ_ONLY_DEVICE;

	Inode* inode = (Inode*)_node->private_node;

	ext2_inode& node = inode->Node();
	bool updateTime = false;
	uid_t uid = geteuid();

	bool isOwnerOrRoot = uid == 0 || uid == (uid_t)node.UserID();
	bool hasWriteAccess = inode->CheckPermissions(W_OK) == B_OK;

	TRACE("ext2_write_stat: Starting transaction\n");
	Transaction transaction(volume->GetJournal());
	inode->WriteLockInTransaction(transaction);

	if ((mask & B_STAT_SIZE) != 0 && inode->Size() != stat->st_size) {
		if (inode->IsDirectory())
			return B_IS_A_DIRECTORY;
		if (!inode->IsFile())
			return B_BAD_VALUE;
		if (!hasWriteAccess)
			return B_NOT_ALLOWED;

		TRACE("ext2_write_stat: Old size: %ld, new size: %ld\n",
			(long)inode->Size(), (long)stat->st_size);

		off_t oldSize = inode->Size();

		status_t status = inode->Resize(transaction, stat->st_size);
		if(status != B_OK)
			return status;

		if ((mask & B_STAT_SIZE_INSECURE) == 0) {
			rw_lock_write_unlock(inode->Lock());
			inode->FillGapWithZeros(oldSize, inode->Size());
			rw_lock_write_lock(inode->Lock());
		}

		updateTime = true;
	}

	if ((mask & B_STAT_MODE) != 0) {
		// only the user or root can do that
		if (!isOwnerOrRoot)
			return B_NOT_ALLOWED;
		node.UpdateMode(stat->st_mode, S_IUMSK);
		updateTime = true;
	}

	if ((mask & B_STAT_UID) != 0) {
		// only root should be allowed
		if (uid != 0)
			return B_NOT_ALLOWED;
		node.SetUserID(stat->st_uid);
		updateTime = true;
	}

	if ((mask & B_STAT_GID) != 0) {
		// only the user or root can do that
		if (!isOwnerOrRoot)
			return B_NOT_ALLOWED;
		node.SetGroupID(stat->st_gid);
		updateTime = true;
	}

	if ((mask & B_STAT_MODIFICATION_TIME) != 0 || updateTime
		|| (mask & B_STAT_CHANGE_TIME) != 0) {
		// the user or root can do that or any user with write access
		if (!isOwnerOrRoot && !hasWriteAccess)
			return B_NOT_ALLOWED;
		struct timespec newTimespec = { 0, 0};

		if ((mask & B_STAT_MODIFICATION_TIME) != 0)
			newTimespec = stat->st_mtim;

		if ((mask & B_STAT_CHANGE_TIME) != 0
			&& stat->st_ctim.tv_sec > newTimespec.tv_sec)
			newTimespec = stat->st_ctim;

		if (newTimespec.tv_sec == 0)
			Inode::_BigtimeToTimespec(real_time_clock_usecs(), &newTimespec);

		inode->SetModificationTime(&newTimespec);
	}
	if ((mask & B_STAT_CREATION_TIME) != 0) {
		// the user or root can do that or any user with write access
		if (!isOwnerOrRoot && !hasWriteAccess)
			return B_NOT_ALLOWED;
		inode->SetCreationTime(&stat->st_crtim);
	}

	status_t status = inode->WriteBack(transaction);
	if (status == B_OK)
		status = transaction.Done();
	if (status == B_OK)
		notify_stat_changed(volume->ID(), -1, inode->ID(), mask);

	return status;
}