⛏️ index : haiku.git

author Michael Lotz <mmlr@mlotz.ch> 2009-09-02 15:08:40.0 +00:00:00
committer Michael Lotz <mmlr@mlotz.ch> 2009-09-02 15:08:40.0 +00:00:00
commit
3dc3d508632af8a5658a4f283d9862e93daa334a [patch]
tree
7f48c62d9230c056d5d7b0b89522d386c69095cf
parent
36386cc59d5495990151c47f2002c3349c9e7e21
download
3dc3d508632af8a5658a4f283d9862e93daa334a.tar.gz

Merging r32900 after successful tests on different machines.

git-svn-id: file:///srv/svn/repos/haiku/haiku/branches/releases/r1alpha1@32907 a95241bf-73f2-0310-859d-f6bbb57e9c96

Diff

 src/add-ons/kernel/file_systems/layers/write_overlay/Jamfile           |   1 +
 src/add-ons/kernel/file_systems/layers/write_overlay/write_overlay.cpp | 102 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------
 2 files changed, 79 insertions(+), 24 deletions(-)

diff --git a/src/add-ons/kernel/file_systems/layers/write_overlay/Jamfile b/src/add-ons/kernel/file_systems/layers/write_overlay/Jamfile
index f1dd75f..c66139a 100644
--- a/src/add-ons/kernel/file_systems/layers/write_overlay/Jamfile
+++ b/src/add-ons/kernel/file_systems/layers/write_overlay/Jamfile
@@ -1,6 +1,7 @@
SubDir HAIKU_TOP src add-ons kernel file_systems layers write_overlay ;

UsePrivateKernelHeaders ;
SubDirHdrs $(HAIKU_TOP) src system kernel device_manager ;

KernelAddon write_overlay :
	write_overlay.cpp
diff --git a/src/add-ons/kernel/file_systems/layers/write_overlay/write_overlay.cpp b/src/add-ons/kernel/file_systems/layers/write_overlay/write_overlay.cpp
index 86c0530..3ddf4a7 100644
--- a/src/add-ons/kernel/file_systems/layers/write_overlay/write_overlay.cpp
+++ b/src/add-ons/kernel/file_systems/layers/write_overlay/write_overlay.cpp
@@ -23,7 +23,9 @@
#include <KernelExport.h>
#include <NodeMonitor.h>

#include "IORequest.h"


//#define TRACE_OVERLAY
#ifdef TRACE_OVERLAY
#define TRACE(x...)			dprintf("write_overlay: " x)
@@ -132,9 +134,14 @@
		status_t			Close(void *cookie);
		status_t			FreeCookie(void *cookie);
		status_t			Read(void *cookie, off_t position, void *buffer,
								size_t *length, bool readPages);
								size_t *length, bool readPages,
								IORequest *ioRequest);
		status_t			Write(void *cookie, off_t position,
								const void *buffer, size_t *length);
								const void *buffer, size_t length,
								IORequest *request);

		status_t			SynchronousIO(void *cookie, IORequest *request);

		status_t			SetFlags(void *cookie, int flags);

		status_t			CreateDir(const char *name, int perms);
@@ -519,7 +526,7 @@

status_t
OverlayInode::Read(void *_cookie, off_t position, void *buffer, size_t *length,
	bool readPages)
	bool readPages, IORequest *ioRequest)
{
	if (position >= fStat.st_size) {
		*length = 0;
@@ -555,6 +562,20 @@
				result = fSuperVnode.ops->read_pages(SuperVolume(),
					&fSuperVnode, superCookie, position, &vector, 1,
					&readLength);
			} else if (ioRequest != NULL) {
				IORequest *subRequest;
				result = ioRequest->CreateSubRequest(position, position,
					readLength, subRequest);
				if (result != B_OK)
					return result;

				result = fSuperVnode.ops->io(SuperVolume(), &fSuperVnode,
					superCookie, subRequest);
				if (result != B_OK)
					return result;

				result = subRequest->Wait(0, 0);
				readLength = subRequest->TransferredBytes();
			} else {
				result = fSuperVnode.ops->read(SuperVolume(), &fSuperVnode,
					superCookie, position, pointer, &readLength);
@@ -572,7 +593,11 @@
		if (gapSize > 0) {
			// there's a gap before our next position which we cannot
			// fill with original file content, zero it out
			memset(pointer, 0, gapSize);
			if (ioRequest != NULL)
				;// TODO: handle this case
			else
				memset(pointer, 0, gapSize);

			bytesLeft -= gapSize;
			position += gapSize;
			pointer += gapSize;
@@ -585,8 +610,14 @@
		off_t elementEnd = element->position + element->length;
		if (elementEnd > position) {
			size_t copyLength = MIN(elementEnd - position, bytesLeft);
			memcpy(pointer, element->buffer + (position - element->position),
				copyLength);

			const void *source = element->buffer + (position
				- element->position);
			if (ioRequest != NULL) {
				ioRequest->CopyData(source, (addr_t)pointer - (addr_t)buffer,
					copyLength);
			} else
				memcpy(pointer, source, copyLength);

			bytesLeft -= copyLength;
			position += copyLength;
@@ -602,7 +633,7 @@

status_t
OverlayInode::Write(void *_cookie, off_t position, const void *buffer,
	size_t *length)
	size_t length, IORequest *ioRequest)
{
	if (_cookie != NULL) {
		open_cookie *cookie = (open_cookie *)_cookie;
@@ -618,7 +649,7 @@
	write_buffer *other = fWriteBuffers;
	write_buffer *swallow = NULL;
	off_t newPosition = position;
	size_t newLength = *length;
	size_t newLength = length;
	uint32 swallowCount = 0;

	while (other) {
@@ -643,8 +674,11 @@
		if (other->position <= newPosition) {
			if (swallowCount == 1 && otherEnd >= newEnd) {
				// other chunk completely covers us, just copy
				memcpy(other->buffer + (newPosition - other->position),
					buffer, *length);
				void *target = other->buffer + (newPosition - other->position);
				if (ioRequest != NULL)
					ioRequest->CopyData(0, target, length);
				else
					memcpy(target, buffer, length);

				fStat.st_mtime = time(NULL);
				notify_stat_changed(SuperVolume()->id, fInodeNumber,
@@ -694,7 +728,11 @@
		}
	}

	memcpy(element->buffer + (position - newPosition), buffer, *length);
	void *target = element->buffer + (position - newPosition);
	if (ioRequest != NULL)
		ioRequest->CopyData(0, target, length);
	else
		memcpy(target, buffer, length);

	fStat.st_mtime = time(NULL);
	notify_stat_changed(SuperVolume()->id, fInodeNumber,
@@ -704,6 +742,25 @@


status_t
OverlayInode::SynchronousIO(void *cookie, IORequest *request)
{
	status_t result;
	size_t length = request->Length();
	if (request->IsWrite())
		result = Write(cookie, request->Offset(), NULL, length, request);
	else
		result = Read(cookie, request->Offset(), NULL, &length, false, request);

	if (result != B_OK)
		return result;

	request->SetTransferredBytes(false, length);
	request->SetStatusAndNotify(B_OK);
	return B_OK;
}


status_t
OverlayInode::SetFlags(void *_cookie, int flags)
{
	// we can only handle O_APPEND, O_NONBLOCK is ignored.
@@ -803,8 +860,7 @@
	if (result != B_OK)
		return result;

	size_t writeLength = strlen(path);
	return newNode->Write(NULL, 0, path, &writeLength);
	return newNode->Write(NULL, 0, path, strlen(path), NULL);
}


@@ -815,7 +871,7 @@
		if (!S_ISLNK(fStat.st_mode))
			return B_BAD_VALUE;

		return Read(NULL, 0, buffer, bufferSize, false);
		return Read(NULL, 0, buffer, bufferSize, false, NULL);
	}

	if (fSuperVnode.ops->read_symlink == NULL)
@@ -1239,7 +1295,7 @@
	for (size_t i = 0; i < count; i++) {
		size_t transferBytes = MIN(vecs[i].iov_len, bytesLeft);
		status_t result = node->Read(cookie, pos, vecs[i].iov_base,
			&transferBytes, true);
			&transferBytes, true, NULL);
		if (result != B_OK) {
			*numBytes -= bytesLeft;
			return result;
@@ -1272,7 +1328,7 @@
	for (size_t i = 0; i < count; i++) {
		size_t transferBytes = MIN(vecs[i].iov_len, bytesLeft);
		status_t result = node->Write(cookie, pos, vecs[i].iov_base,
			&transferBytes);
			transferBytes, NULL);
		if (result != B_OK) {
			*numBytes -= bytesLeft;
			return result;
@@ -1299,17 +1355,15 @@
overlay_io(fs_volume *volume, fs_vnode *vnode, void *cookie,
	io_request *request)
{
	if (io_request_is_write(request))
		return B_UNSUPPORTED;

	OverlayInode *node = (OverlayInode *)vnode->private_node;
	if (node->IsModified())
		return B_UNSUPPORTED;
	if (io_request_is_write(request) || node->IsModified())
		return node->SynchronousIO(cookie, (IORequest *)request);

	TRACE("relaying op: io\n");
	fs_vnode *superVnode = node->SuperVnode();
	if (superVnode->ops->io != NULL) {
		return superVnode->ops->io(volume->super_volume, superVnode, cookie,
		return superVnode->ops->io(volume->super_volume, superVnode,
			cookie != NULL ? ((open_cookie *)cookie)->super_cookie : NULL,
			request);
	}

@@ -1521,7 +1575,7 @@
{
	TRACE("read\n");
	return ((OverlayInode *)vnode->private_node)->Read(cookie, pos, buffer,
		length, false);
		length, false, NULL);
}


@@ -1531,7 +1585,7 @@
{
	TRACE("write\n");
	return ((OverlayInode *)vnode->private_node)->Write(cookie, pos, buffer,
		length);
		*length, NULL);
}