Example #1
0
status_t
Inode::Write(OpenFileCookie* cookie, off_t pos, const void* _buffer,
	size_t* _length)
{
	ASSERT(cookie != NULL);
	ASSERT(_buffer != NULL);
	ASSERT(_length != NULL);

	struct stat st;
	status_t result = Stat(&st);
	if (result != B_OK)
		return result;

	if ((cookie->fMode & O_APPEND) != 0)
		pos = st.st_size;

	uint64 fileSize = max_c(st.st_size, pos + *_length);
	fMaxFileSize = max_c(fMaxFileSize, fileSize);

	if ((cookie->fMode & O_NOCACHE) != 0) {
		WriteDirect(cookie, pos, _buffer, _length);
		Commit();
	}

	result = file_cache_set_size(fFileCache, fileSize);
	if (result != B_OK)
		return result;

	return file_cache_write(fFileCache, cookie, pos, _buffer, _length);
}
Example #2
0
status_t
Inode::Write(OpenFileCookie* cookie, off_t pos, const void* _buffer,
	size_t* _length)
{
	ASSERT(cookie != NULL);
	ASSERT(_buffer != NULL);
	ASSERT(_length != NULL);

	if (pos < 0)
		pos = 0;

	if ((cookie->fMode & O_RWMASK) == O_RDONLY)
		return B_NOT_ALLOWED;

	if ((cookie->fMode & O_APPEND) != 0)
		pos = fMaxFileSize;

	uint64 fileSize = pos + *_length;
	if (fileSize > fMaxFileSize) {
		status_t result = file_cache_set_size(fFileCache, fileSize);
		if (result != B_OK)
			return result;
		fMaxFileSize = fileSize;
		fMetaCache.GrowFile(fMaxFileSize);
	}

	if ((cookie->fMode & O_NOCACHE) != 0) {
		WriteDirect(cookie, pos, _buffer, _length);
		Commit();
	}

	return file_cache_write(fFileCache, cookie, pos, _buffer, _length);
}
Example #3
0
status_t
Inode::Resize(Transaction& transaction, off_t size)
{
	TRACE("Inode::Resize() ID:%" B_PRIdINO " size: %" B_PRIdOFF "\n", ID(),
		size);
	if (size < 0)
		return B_BAD_VALUE;

	off_t oldSize = Size();

	if (size == oldSize)
		return B_OK;

	TRACE("Inode::Resize(): old size: %" B_PRIdOFF ", new size: %" B_PRIdOFF
		"\n", oldSize, size);

	status_t status;
	if (size > oldSize) {
		status = _EnlargeDataStream(transaction, size);
		if (status != B_OK) {
			// Restore original size
			_ShrinkDataStream(transaction, oldSize);
		}
	} else
		status = _ShrinkDataStream(transaction, size);

	TRACE("Inode::Resize(): Updating file map and cache\n");

	if (status != B_OK)
		return status;

	file_cache_set_size(FileCache(), size);
	file_map_set_size(Map(), size);

	TRACE("Inode::Resize(): Writing back inode changes. Size: %" B_PRIdOFF
		"\n", Size());

	return WriteBack(transaction);
}
Example #4
0
status_t
Inode::Open(int mode, OpenFileCookie* cookie)
{
	ASSERT(cookie != NULL);

	MutexLocker locker(fStateLock);

	OpenDelegationData data;
	data.fType = OPEN_DELEGATE_NONE;
	if (fOpenState == NULL) {
		RevalidateFileCache();

		OpenState* state = new(std::nothrow) OpenState;
		if (state == NULL)
			return B_NO_MEMORY;

		state->fInfo = fInfo;
		state->fFileSystem = fFileSystem;
		state->fMode = mode & O_RWMASK;
		status_t result = OpenFile(state, mode, &data);
		if (result != B_OK) {
			delete state;
			return result;
		}

		fFileSystem->AddOpenFile(state);
		fOpenState = state;
		cookie->fOpenState = state;
		locker.Unlock();
	} else {
		fOpenState->AcquireReference();
		cookie->fOpenState = fOpenState;
		locker.Unlock();

		int newMode = mode & O_RWMASK;
		int oldMode = fOpenState->fMode & O_RWMASK;
		if (oldMode != newMode && oldMode != O_RDWR) {
			if (oldMode == O_RDONLY)
				RecallReadDelegation();

			status_t result = OpenFile(fOpenState, O_RDWR, &data);
			if (result != B_OK) {
				locker.Lock();
				ReleaseOpenState();
				return result;
			}
			fOpenState->fMode = O_RDWR;
		} else {
			int newMode = mode & O_RWMASK;
			uint32 allowed = 0;
			if (newMode == O_RDWR || newMode == O_RDONLY)
				allowed |= R_OK;
			if (newMode == O_RDWR || newMode == O_WRONLY)
				allowed |= W_OK;

			status_t result = Access(allowed);
			if (result != B_OK) {
				locker.Lock();
				ReleaseOpenState();
				return result;
			}
		}
	}

	if ((mode & O_TRUNC) == O_TRUNC) {
		struct stat st;
		st.st_size = 0;
		WriteStat(&st, B_STAT_SIZE);
		file_cache_set_size(fFileCache, 0);
	}

	cookie->fFileSystem = fFileSystem;
	cookie->fMode = mode;
	cookie->fLocks = NULL;

	if (data.fType != OPEN_DELEGATE_NONE) {
		Delegation* delegation
			= new(std::nothrow) Delegation(data, this, fOpenState->fClientID);
		if (delegation != NULL) {
			delegation->fInfo = fOpenState->fInfo;
			delegation->fFileSystem = fFileSystem;
			SetDelegation(delegation);
		}
	}

	return B_OK;
}