xref: /haiku/src/system/kernel/disk_device_manager/KFileSystem.cpp (revision d9cebac2b77547b7064f22497514eecd2d047160)
1 // KFileSystem.cpp
2 
3 #include <fcntl.h>
4 #include <stdlib.h>
5 #include <unistd.h>
6 
7 #include <fs_interface.h>
8 
9 #include "ddm_modules.h"
10 #include "KDiskDeviceJob.h"
11 #include "KDiskDeviceUtils.h"
12 #include "KFileSystem.h"
13 #include "KPartition.h"
14 
15 
16 // constructor
17 KFileSystem::KFileSystem(const char *name)
18 	: KDiskSystem(name),
19 	fModule(NULL)
20 {
21 }
22 
23 
24 // destructor
25 KFileSystem::~KFileSystem()
26 {
27 }
28 
29 
30 // Init
31 status_t
32 KFileSystem::Init()
33 {
34 	status_t error = KDiskSystem::Init();
35 	if (error != B_OK)
36 		return error;
37 	error = Load();
38 	if (error != B_OK)
39 		return error;
40 	error = SetPrettyName(fModule->pretty_name);
41 	SetFlags(fModule->flags | B_DISK_SYSTEM_IS_FILE_SYSTEM);
42 	Unload();
43 	return error;
44 }
45 
46 
47 // Identify
48 float
49 KFileSystem::Identify(KPartition *partition, void **cookie)
50 {
51 	if (!partition || !cookie || !fModule || !fModule->identify_partition)
52 		return -1;
53 	int fd = -1;
54 	if (partition->Open(O_RDONLY, &fd) != B_OK)
55 		return -1;
56 	float result = fModule->identify_partition(fd, partition->PartitionData(),
57 											   cookie);
58 	close(fd);
59 	return result;
60 }
61 
62 
63 // Scan
64 status_t
65 KFileSystem::Scan(KPartition *partition, void *cookie)
66 {
67 	if (!partition || !fModule || !fModule->scan_partition)
68 		return B_ERROR;
69 	int fd = -1;
70 	status_t result = partition->Open(O_RDONLY, &fd);
71 	if (result != B_OK)
72 		return result;
73 	result = fModule->scan_partition(fd, partition->PartitionData(), cookie);
74 	close(fd);
75 	return result;
76 }
77 
78 
79 // FreeIdentifyCookie
80 void
81 KFileSystem::FreeIdentifyCookie(KPartition *partition, void *cookie)
82 {
83 	if (!partition || !fModule || !fModule->free_identify_partition_cookie)
84 		return;
85 	fModule->free_identify_partition_cookie(partition->PartitionData(),
86 											cookie);
87 }
88 
89 
90 // FreeContentCookie
91 void
92 KFileSystem::FreeContentCookie(KPartition *partition)
93 {
94 	if (!partition || !fModule || !fModule->free_partition_content_cookie)
95 		return;
96 	fModule->free_partition_content_cookie(partition->PartitionData());
97 }
98 
99 
100 // GetSupportedOperations
101 uint32
102 KFileSystem::GetSupportedOperations(KPartition* partition, uint32 mask)
103 {
104 	ASSERT(partition != NULL);
105 
106 	// Note, that for initialization, the partition's disk system does not
107 	// need to be this disk system.
108 
109 	if (!fModule)
110 		return 0;
111 
112 	if (!fModule->get_supported_operations)
113 		return (Flags() & mask);
114 
115 	return fModule->get_supported_operations(partition->PartitionData(), mask)
116 		& mask;
117 }
118 
119 
120 // ValidateResize
121 bool
122 KFileSystem::ValidateResize(KPartition *partition, off_t *size)
123 {
124 	return (partition && size && partition->DiskSystem() == this && fModule
125 			&& fModule->validate_resize
126 			&& fModule->validate_resize(partition->PartitionData(), size));
127 }
128 
129 
130 // ValidateMove
131 bool
132 KFileSystem::ValidateMove(KPartition *partition, off_t *start)
133 {
134 	return (partition && start && partition->DiskSystem() == this && fModule
135 			&& fModule->validate_move
136 			&& fModule->validate_move(partition->PartitionData(), start));
137 }
138 
139 
140 // ValidateSetContentName
141 bool
142 KFileSystem::ValidateSetContentName(KPartition *partition, char *name)
143 {
144 	return (partition && name && partition->DiskSystem() == this
145 			&& fModule && fModule->validate_set_content_name
146 			&& fModule->validate_set_content_name(partition->PartitionData(),
147 												  name));
148 }
149 
150 
151 // ValidateSetContentParameters
152 bool
153 KFileSystem::ValidateSetContentParameters(KPartition *partition,
154 										  const char *parameters)
155 {
156 	return (partition && partition->DiskSystem() == this && fModule
157 			&& fModule->validate_set_content_parameters
158 			&& fModule->validate_set_content_parameters(
159 					partition->PartitionData(), parameters));
160 }
161 
162 
163 // ValidateInitialize
164 bool
165 KFileSystem::ValidateInitialize(KPartition *partition, char *name,
166 								const char *parameters)
167 {
168 	return (partition && fModule && fModule->validate_initialize
169 		&& fModule->validate_initialize(partition->PartitionData(), name,
170 				parameters));
171 }
172 
173 
174 // ShadowPartitionChanged
175 status_t
176 KFileSystem::ShadowPartitionChanged(KPartition *partition, KPartition *child,
177 	uint32 operation)
178 {
179 	if (!partition)
180 		return B_BAD_VALUE;
181 	if (!fModule)
182 		return B_ERROR;
183 	// If not implemented, we assume, that the file system doesn't have to
184 	// make any additional changes.
185 	if (!fModule->shadow_changed)
186 		return B_OK;
187 	return fModule->shadow_changed(partition->PartitionData(),
188 		child ? child->PartitionData() : NULL, operation);
189 }
190 
191 
192 // Defragment
193 status_t
194 KFileSystem::Defragment(KPartition *partition, KDiskDeviceJob *job)
195 {
196 	// to be implemented
197 	return B_ERROR;
198 }
199 
200 
201 // Repair
202 status_t
203 KFileSystem::Repair(KPartition *partition, bool checkOnly, KDiskDeviceJob *job)
204 {
205 	// to be implemented
206 	return B_ERROR;
207 }
208 
209 
210 // Resize
211 status_t
212 KFileSystem::Resize(KPartition *partition, off_t size, KDiskDeviceJob *job)
213 {
214 	// to be implemented
215 	return B_ERROR;
216 }
217 
218 
219 // Move
220 status_t
221 KFileSystem::Move(KPartition *partition, off_t offset, KDiskDeviceJob *job)
222 {
223 	// to be implemented
224 	return B_ERROR;
225 }
226 
227 
228 // SetContentName
229 status_t
230 KFileSystem::SetContentName(KPartition *partition, char *name,
231 							KDiskDeviceJob *job)
232 {
233 	// to be implemented
234 	return B_ERROR;
235 }
236 
237 
238 status_t
239 KFileSystem::SetContentParameters(KPartition *partition,
240 	const char *parameters, KDiskDeviceJob *job)
241 {
242 	// to be implemented
243 	return B_ERROR;
244 }
245 
246 
247 status_t
248 KFileSystem::Initialize(KPartition *partition, const char *name,
249 	const char *parameters, KDiskDeviceJob *job)
250 {
251 	// check parameters
252 	if (!partition || !job || !fModule)
253 		return B_BAD_VALUE;
254 	if (!fModule->initialize)
255 		return B_NOT_SUPPORTED;
256 
257 	// open partition device (we need a temporary read-lock)
258 	KDiskDeviceManager *manager = KDiskDeviceManager::Default();
259 	if (!manager->ReadLockPartition(partition->ID()))
260 		return B_ERROR;
261 	DeviceReadLocker locker(partition->Device(), true);
262 
263 	int fd = -1;
264 	status_t result = partition->Open(O_RDWR, &fd);
265 	if (result != B_OK)
266 		return result;
267 
268 	off_t partitionSize = partition->Size();
269 
270 	locker.Unlock();
271 
272 	// call the module hook
273 	result = fModule->initialize(fd, partition->ID(), name, parameters,
274 		partitionSize, job->ID());
275 
276 	close(fd);
277 	return result;
278 }
279 
280 
281 // LoadModule
282 status_t
283 KFileSystem::LoadModule()
284 {
285 	if (fModule)		// shouldn't happen
286 		return B_OK;
287 
288 	return get_module(Name(), (module_info **)&fModule);
289 }
290 
291 
292 // UnloadModule
293 void
294 KFileSystem::UnloadModule()
295 {
296 	if (fModule) {
297 		put_module(fModule->info.name);
298 		fModule = NULL;
299 	}
300 }
301 
302