1/*
2 * Copyright 2003-2011, Haiku, Inc. All Rights Reserved.
3 * Distributed under the terms of the MIT License.
4 *
5 * Authors:
6 *		Ingo Weinhold, ingo_weinhold@gmx.de
7 */
8
9#include "KFileSystem.h"
10
11#include <fcntl.h>
12#include <stdlib.h>
13#include <unistd.h>
14
15#include <fs_interface.h>
16
17#include "ddm_modules.h"
18#include "KDiskDeviceUtils.h"
19#include "KPartition.h"
20
21
22// constructor
23KFileSystem::KFileSystem(const char *name)
24	: KDiskSystem(name),
25	fModule(NULL)
26{
27}
28
29
30// destructor
31KFileSystem::~KFileSystem()
32{
33}
34
35
36// Init
37status_t
38KFileSystem::Init()
39{
40	status_t error = KDiskSystem::Init();
41	if (error != B_OK)
42		return error;
43	error = Load();
44	if (error != B_OK)
45		return error;
46	error = SetShortName(fModule->short_name);
47	if (error == B_OK)
48		error = SetPrettyName(fModule->pretty_name);
49
50	SetFlags(fModule->flags | B_DISK_SYSTEM_IS_FILE_SYSTEM);
51	Unload();
52	return error;
53}
54
55
56// Identify
57float
58KFileSystem::Identify(KPartition *partition, void **cookie)
59{
60	if (!partition || !cookie || !fModule || !fModule->identify_partition)
61		return -1;
62	int fd = -1;
63	if (partition->Open(O_RDONLY, &fd) != B_OK)
64		return -1;
65	float result = fModule->identify_partition(fd, partition->PartitionData(),
66		cookie);
67	close(fd);
68	return result;
69}
70
71
72// Scan
73status_t
74KFileSystem::Scan(KPartition *partition, void *cookie)
75{
76	if (!partition || !fModule || !fModule->scan_partition)
77		return B_ERROR;
78	int fd = -1;
79	status_t result = partition->Open(O_RDONLY, &fd);
80	if (result != B_OK)
81		return result;
82	result = fModule->scan_partition(fd, partition->PartitionData(), cookie);
83	close(fd);
84	return result;
85}
86
87
88// FreeIdentifyCookie
89void
90KFileSystem::FreeIdentifyCookie(KPartition *partition, void *cookie)
91{
92	if (!partition || !fModule || !fModule->free_identify_partition_cookie)
93		return;
94	fModule->free_identify_partition_cookie(partition->PartitionData(), cookie);
95}
96
97
98// FreeContentCookie
99void
100KFileSystem::FreeContentCookie(KPartition *partition)
101{
102	if (!partition || !fModule || !fModule->free_partition_content_cookie)
103		return;
104	fModule->free_partition_content_cookie(partition->PartitionData());
105}
106
107
108// Defragment
109status_t
110KFileSystem::Defragment(KPartition* partition, disk_job_id job)
111{
112	// to be implemented
113	return B_ERROR;
114}
115
116
117// Repair
118status_t
119KFileSystem::Repair(KPartition* partition, bool checkOnly, disk_job_id job)
120{
121	// to be implemented
122	return B_ERROR;
123}
124
125
126// Resize
127status_t
128KFileSystem::Resize(KPartition* partition, off_t size, disk_job_id job)
129{
130	if (partition == NULL || fModule == NULL)
131		return B_ERROR;
132	if (fModule->resize == NULL)
133		return B_NOT_SUPPORTED;
134
135	int fd = -1;
136	status_t result = partition->Open(O_RDWR, &fd);
137	if (result != B_OK)
138		return result;
139
140	result = fModule->resize(fd, partition->ID(), size, job);
141
142	close(fd);
143	return result;
144}
145
146
147// Move
148status_t
149KFileSystem::Move(KPartition* partition, off_t offset, disk_job_id job)
150{
151	// to be implemented
152	return B_ERROR;
153}
154
155
156// SetContentName
157status_t
158KFileSystem::SetContentName(KPartition* partition, const char* name,
159	disk_job_id job)
160{
161	// check parameters
162	if (!partition || !fModule)
163		return B_BAD_VALUE;
164	if (!fModule->set_content_name)
165		return B_NOT_SUPPORTED;
166
167	// open partition device
168	int fd = -1;
169	status_t result = partition->Open(O_RDWR, &fd);
170	if (result != B_OK)
171		return result;
172
173	// let the module do its job
174	result = fModule->set_content_name(fd, partition->ID(), name, job);
175
176	// cleanup and return
177	close(fd);
178	return result;
179}
180
181
182// SetContentParameters
183status_t
184KFileSystem::SetContentParameters(KPartition* partition,
185	const char* parameters, disk_job_id job)
186{
187	// check parameters
188	if (!partition || !fModule)
189		return B_BAD_VALUE;
190	if (!fModule->set_content_parameters)
191		return B_NOT_SUPPORTED;
192
193	// open partition device
194	int fd = -1;
195	status_t result = partition->Open(O_RDWR, &fd);
196	if (result != B_OK)
197		return result;
198
199	// let the module do its job
200	result = fModule->set_content_parameters(fd, partition->ID(), parameters,
201		job);
202
203	// cleanup and return
204	close(fd);
205	return result;
206}
207
208
209// Initialize
210status_t
211KFileSystem::Initialize(KPartition* partition, const char* name,
212	const char* parameters, disk_job_id job)
213{
214	// check parameters
215	if (!partition || !fModule)
216		return B_BAD_VALUE;
217	if (!fModule->initialize)
218		return B_NOT_SUPPORTED;
219
220	// open partition device
221	int fd = -1;
222	status_t result = partition->Open(O_RDWR, &fd);
223	if (result != B_OK)
224		return result;
225
226	// let the module do its job
227	result = fModule->initialize(fd, partition->ID(), name, parameters,
228		partition->Size(), job);
229
230	// cleanup and return
231	close(fd);
232	return result;
233}
234
235
236status_t
237KFileSystem::Uninitialize(KPartition* partition, disk_job_id job)
238{
239	// check parameters
240	if (partition == NULL || fModule == NULL)
241		return B_BAD_VALUE;
242	if (fModule->uninitialize == NULL)
243		return B_NOT_SUPPORTED;
244
245	// open partition device
246	int fd = -1;
247	status_t result = partition->Open(O_RDWR, &fd);
248	if (result != B_OK)
249		return result;
250
251	// let the module do its job
252	result = fModule->uninitialize(fd, partition->ID(), partition->Size(),
253		partition->BlockSize(), job);
254
255	// cleanup and return
256	close(fd);
257	return result;
258}
259
260
261// LoadModule
262status_t
263KFileSystem::LoadModule()
264{
265	if (fModule)		// shouldn't happen
266		return B_OK;
267
268	return get_module(Name(), (module_info **)&fModule);
269}
270
271
272// UnloadModule
273void
274KFileSystem::UnloadModule()
275{
276	if (fModule) {
277		put_module(fModule->info.name);
278		fModule = NULL;
279	}
280}
281
282