1/*
2 * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
3 * Distributed under the terms of the MIT License.
4 */
5
6#include <fs_cache.h>
7
8#include <new>
9
10#include "AutoDeleter.h"
11#include "Debug.h"
12
13#include "../kernel_emu.h"
14
15
16struct FileCache {
17	dev_t	mountID;
18	ino_t	vnodeID;
19	bool	enabled;
20
21	FileCache(dev_t mountID, ino_t vnodeID)
22		:
23		mountID(mountID),
24		vnodeID(vnodeID),
25		enabled(true)
26	{
27	}
28};
29
30
31void*
32file_cache_create(dev_t mountID, ino_t vnodeID, off_t size)
33{
34	PRINT(("file_cache_create(%" B_PRIdDEV ", %" B_PRIdINO ", %"
35		B_PRIdOFF ")\n", mountID, vnodeID, size));
36
37	// create the client-side object
38	FileCache* fileCache = new(std::nothrow) FileCache(mountID, vnodeID);
39	if (fileCache == NULL)
40		return NULL;
41	ObjectDeleter<FileCache> cacheDeleter(fileCache);
42
43	// create the kernel-size file cache
44	status_t error = UserlandFS::KernelEmu::file_cache_create(mountID, vnodeID,
45		size);
46	if (error != B_OK) {
47		REPORT_ERROR(error);
48		return NULL;
49	}
50
51	cacheDeleter.Detach();
52
53	PRINT(("file_cache_create() -> %p\n", fileCache));
54	return fileCache;
55}
56
57
58void
59file_cache_delete(void *cacheRef)
60{
61	if (cacheRef == NULL)
62		return;
63
64	PRINT(("file_cache_delete(%p)\n", cacheRef));
65
66	FileCache* fileCache = (FileCache*)cacheRef;
67
68	UserlandFS::KernelEmu::file_cache_delete(fileCache->mountID,
69		fileCache->vnodeID);
70
71	delete fileCache;
72}
73
74
75void
76file_cache_enable(void *cacheRef)
77{
78	PRINT(("file_cache_enable(%p)\n", cacheRef));
79
80	FileCache* fileCache = (FileCache*)cacheRef;
81
82	if (fileCache->enabled)
83		return;
84
85	if (UserlandFS::KernelEmu::file_cache_set_enabled(fileCache->mountID,
86			fileCache->vnodeID, true) == B_OK) {
87		fileCache->enabled = true;
88	}
89}
90
91
92bool
93file_cache_is_enabled(void *cacheRef)
94{
95	FileCache* fileCache = (FileCache*)cacheRef;
96
97	return fileCache->enabled;
98}
99
100
101status_t
102file_cache_disable(void *cacheRef)
103{
104	PRINT(("file_cache_disable(%p)\n", cacheRef));
105
106	FileCache* fileCache = (FileCache*)cacheRef;
107
108	if (!fileCache->enabled)
109		return B_OK;
110
111	status_t error = UserlandFS::KernelEmu::file_cache_set_enabled(
112		fileCache->mountID, fileCache->vnodeID, false);
113	if (error == B_OK)
114		fileCache->enabled = false;
115
116	return error;
117}
118
119
120status_t
121file_cache_set_size(void *cacheRef, off_t size)
122{
123	if (cacheRef == NULL)
124		return B_BAD_VALUE;
125
126	PRINT(("file_cache_set_size(%p)\n", cacheRef));
127
128	FileCache* fileCache = (FileCache*)cacheRef;
129
130	return UserlandFS::KernelEmu::file_cache_set_size(fileCache->mountID,
131		fileCache->vnodeID, size);
132}
133
134
135status_t
136file_cache_sync(void *cacheRef)
137{
138	if (cacheRef == NULL)
139		return B_BAD_VALUE;
140
141	PRINT(("file_cache_sync(%p)\n", cacheRef));
142
143	FileCache* fileCache = (FileCache*)cacheRef;
144
145	return UserlandFS::KernelEmu::file_cache_sync(fileCache->mountID,
146		fileCache->vnodeID);
147}
148
149
150status_t
151file_cache_read(void *cacheRef, void *cookie, off_t offset, void *bufferBase,
152	size_t *_size)
153{
154	PRINT(("file_cache_read(%p, %p, %" B_PRIdOFF ", %p, %lu)\n",
155		cacheRef, cookie, offset, bufferBase, *_size));
156
157	FileCache* fileCache = (FileCache*)cacheRef;
158
159	return UserlandFS::KernelEmu::file_cache_read(fileCache->mountID,
160		fileCache->vnodeID, cookie, offset, bufferBase, _size);
161}
162
163
164status_t
165file_cache_write(void *cacheRef, void *cookie, off_t offset, const void *buffer,
166	size_t *_size)
167{
168	PRINT(("file_cache_write(%p, %p, %" B_PRIdOFF ", %p, %lu)\n",
169		cacheRef, cookie, offset, buffer, *_size));
170
171	FileCache* fileCache = (FileCache*)cacheRef;
172
173	return UserlandFS::KernelEmu::file_cache_write(fileCache->mountID,
174		fileCache->vnodeID, cookie, offset, buffer, _size);
175}
176