1/*
2 * Copyright 2001-2009, Ingo Weinhold, ingo_weinhold@gmx.de.
3 * Distributed under the terms of the MIT License.
4 */
5
6#include "Volume.h"
7
8#include <dirent.h>
9#include <string.h>
10#include <sys/stat.h>
11
12#include "FileSystem.h"
13#include "kernel_emu.h"
14
15
16// constructor
17Volume::Volume(FileSystem* fileSystem, dev_t id)
18	: fFileSystem(fileSystem),
19	  fID(id)
20{
21	fFileSystem->RegisterVolume(this);
22}
23
24// destructor
25Volume::~Volume()
26{
27	fFileSystem->UnregisterVolume(this);
28}
29
30// GetFileSystem
31UserlandFS::FileSystem*
32Volume::GetFileSystem() const
33{
34	return fFileSystem;
35}
36
37// GetID
38dev_t
39Volume::GetID() const
40{
41	return fID;
42}
43
44
45// #pragma mark - FS
46
47
48// Mount
49status_t
50Volume::Mount(const char* device, uint32 flags, const char* parameters,
51	ino_t* rootID)
52{
53	return B_BAD_VALUE;
54}
55
56// Unmount
57status_t
58Volume::Unmount()
59{
60	return B_BAD_VALUE;
61}
62
63// Sync
64status_t
65Volume::Sync()
66{
67	return B_BAD_VALUE;
68}
69
70// ReadFSInfo
71status_t
72Volume::ReadFSInfo(fs_info* info)
73{
74	return B_BAD_VALUE;
75}
76
77// WriteFSInfo
78status_t
79Volume::WriteFSInfo(const struct fs_info* info, uint32 mask)
80{
81	return B_BAD_VALUE;
82}
83
84
85// #pragma mark - vnodes
86
87
88// Lookup
89status_t
90Volume::Lookup(void* dir, const char* entryName, ino_t* vnid)
91{
92	return B_BAD_VALUE;
93}
94
95
96// GetVNodeType
97status_t
98Volume::GetVNodeType(void* node, int* type)
99{
100	return B_UNSUPPORTED;
101}
102
103
104// GetVNodeName
105status_t
106Volume::GetVNodeName(void* node, char* buffer, size_t bufferSize)
107{
108	// stat the node to get its ID
109	struct stat st;
110	status_t error = ReadStat(node, &st);
111	if (error != B_OK)
112		return error;
113
114	// look up the parent directory
115	ino_t parentID;
116	error = Lookup(node, "..", &parentID);
117	if (error != B_OK)
118		return error;
119
120	// get the parent node handle
121	void* parentNode;
122	error = UserlandFS::KernelEmu::get_vnode(GetID(), parentID, &parentNode);
123	// Lookup() has already called get_vnode() for us, so we need to put it once
124	UserlandFS::KernelEmu::put_vnode(GetID(), parentID);
125	if (error != B_OK)
126		return error;
127
128	// open the parent dir
129	void* cookie;
130	error = OpenDir(parentNode, &cookie);
131	if (error == B_OK) {
132
133		while (true) {
134			// read an entry
135			char _entry[sizeof(struct dirent) + B_FILE_NAME_LENGTH];
136			struct dirent* entry = (struct dirent*)_entry;
137			uint32 num;
138
139			error = ReadDir(parentNode, cookie, entry, sizeof(_entry), 1, &num);
140
141			if (error != B_OK)
142				break;
143			if (num == 0) {
144				error = B_ENTRY_NOT_FOUND;
145				break;
146			}
147
148			// found an entry for our node?
149			if (st.st_ino == entry->d_ino) {
150				// yep, copy the entry name
151				size_t nameLen = strnlen(entry->d_name, B_FILE_NAME_LENGTH);
152				if (nameLen < bufferSize) {
153					memcpy(buffer, entry->d_name, nameLen);
154					buffer[nameLen] = '\0';
155				} else
156					error = B_BUFFER_OVERFLOW;
157				break;
158			}
159		}
160
161		// close the parent dir
162		CloseDir(parentNode, cookie);
163		FreeDirCookie(parentNode, cookie);
164	}
165
166	// put the parent node
167	UserlandFS::KernelEmu::put_vnode(GetID(), parentID);
168
169	return error;
170}
171
172// ReadVNode
173status_t
174Volume::ReadVNode(ino_t vnid, bool reenter, void** node, int* type,
175	uint32* flags, FSVNodeCapabilities* _capabilities)
176{
177	return B_BAD_VALUE;
178}
179
180// WriteVNode
181status_t
182Volume::WriteVNode(void* node, bool reenter)
183{
184	return B_BAD_VALUE;
185}
186
187// RemoveVNode
188status_t
189Volume::RemoveVNode(void* node, bool reenter)
190{
191	return B_BAD_VALUE;
192}
193
194
195// #pragma mark - asynchronous I/O
196
197
198status_t
199Volume::DoIO(void* node, void* cookie, const IORequestInfo& requestInfo)
200{
201	return B_BAD_VALUE;
202}
203
204
205status_t
206Volume::CancelIO(void* node, void* cookie, int32 ioRequestID)
207{
208	return B_BAD_VALUE;
209}
210
211
212status_t
213Volume::IterativeIOGetVecs(void* cookie, int32 requestID, off_t offset,
214	size_t size, struct file_io_vec* vecs, size_t* _count)
215{
216	return B_BAD_VALUE;
217}
218
219
220status_t
221Volume::IterativeIOFinished(void* cookie, int32 requestID, status_t status,
222	bool partialTransfer, size_t bytesTransferred)
223{
224	return B_BAD_VALUE;
225}
226
227
228// #pragma mark - nodes
229
230
231// IOCtl
232status_t
233Volume::IOCtl(void* node, void* cookie, uint32 command, void *buffer,
234	size_t size)
235{
236	return B_BAD_VALUE;
237}
238
239// SetFlags
240status_t
241Volume::SetFlags(void* node, void* cookie, int flags)
242{
243	return B_BAD_VALUE;
244}
245
246// Select
247status_t
248Volume::Select(void* node, void* cookie, uint8 event, selectsync* sync)
249{
250	return B_BAD_VALUE;
251}
252
253// Deselect
254status_t
255Volume::Deselect(void* node, void* cookie, uint8 event, selectsync* sync)
256{
257	return B_BAD_VALUE;
258}
259
260// FSync
261status_t
262Volume::FSync(void* node)
263{
264	return B_BAD_VALUE;
265}
266
267// ReadSymlink
268status_t
269Volume::ReadSymlink(void* node, char* buffer, size_t bufferSize,
270	size_t* bytesRead)
271{
272	return B_BAD_VALUE;
273}
274
275// CreateSymlink
276status_t
277Volume::CreateSymlink(void* dir, const char* name, const char* target,
278	int mode)
279{
280	return B_BAD_VALUE;
281}
282
283// Link
284status_t
285Volume::Link(void* dir, const char* name, void* node)
286{
287	return B_BAD_VALUE;
288}
289
290// Unlink
291status_t
292Volume::Unlink(void* dir, const char* name)
293{
294	return B_BAD_VALUE;
295}
296
297// Rename
298status_t
299Volume::Rename(void* oldDir, const char* oldName, void* newDir,
300	const char* newName)
301{
302	return B_BAD_VALUE;
303}
304
305// Access
306status_t
307Volume::Access(void* node, int mode)
308{
309	return B_BAD_VALUE;
310}
311
312// ReadStat
313status_t
314Volume::ReadStat(void* node, struct stat* st)
315{
316	return B_BAD_VALUE;
317}
318
319// WriteStat
320status_t
321Volume::WriteStat(void* node, const struct stat *st, uint32 mask)
322{
323	return B_BAD_VALUE;
324}
325
326
327// #pragma mark - files
328
329
330// Create
331status_t
332Volume::Create(void* dir, const char* name, int openMode, int mode,
333	void** cookie, ino_t* vnid)
334{
335	return B_BAD_VALUE;
336}
337
338// Open
339status_t
340Volume::Open(void* node, int openMode, void** cookie)
341{
342	return B_BAD_VALUE;
343}
344
345// Close
346status_t
347Volume::Close(void* node, void* cookie)
348{
349	return B_BAD_VALUE;
350}
351
352// FreeCookie
353status_t
354Volume::FreeCookie(void* node, void* cookie)
355{
356	return B_BAD_VALUE;
357}
358
359// Read
360status_t
361Volume::Read(void* node, void* cookie, off_t pos, void* buffer,
362	size_t bufferSize, size_t* bytesRead)
363{
364	return B_BAD_VALUE;
365}
366
367// Write
368status_t
369Volume::Write(void* node, void* cookie, off_t pos, const void* buffer,
370	size_t bufferSize, size_t* bytesWritten)
371{
372	return B_BAD_VALUE;
373}
374
375
376// #pragma mark - directories
377
378
379// CreateDir
380status_t
381Volume::CreateDir(void* dir, const char* name, int mode)
382{
383	return B_BAD_VALUE;
384}
385
386// RemoveDir
387status_t
388Volume::RemoveDir(void* dir, const char* name)
389{
390	return B_BAD_VALUE;
391}
392
393// OpenDir
394status_t
395Volume::OpenDir(void* node, void** cookie)
396{
397	return B_BAD_VALUE;
398}
399
400// CloseDir
401status_t
402Volume::CloseDir(void* node, void* cookie)
403{
404	return B_BAD_VALUE;
405}
406
407// FreeDirCookie
408status_t
409Volume::FreeDirCookie(void* node, void* cookie)
410{
411	return B_BAD_VALUE;
412}
413
414// ReadDir
415status_t
416Volume::ReadDir(void* node, void* cookie, void* buffer, size_t bufferSize,
417	uint32 count, uint32* countRead)
418{
419	return B_BAD_VALUE;
420}
421
422// RewindDir
423status_t
424Volume::RewindDir(void* node, void* cookie)
425{
426	return B_BAD_VALUE;
427}
428
429
430// #pragma mark - attribute directories
431
432
433// OpenAttrDir
434status_t
435Volume::OpenAttrDir(void* node, void** cookie)
436{
437	return B_BAD_VALUE;
438}
439
440// CloseAttrDir
441status_t
442Volume::CloseAttrDir(void* node, void* cookie)
443{
444	return B_BAD_VALUE;
445}
446
447// FreeAttrDirCookie
448status_t
449Volume::FreeAttrDirCookie(void* node, void* cookie)
450{
451	return B_BAD_VALUE;
452}
453
454// ReadAttrDir
455status_t
456Volume::ReadAttrDir(void* node, void* cookie, void* buffer,
457	size_t bufferSize, uint32 count, uint32* countRead)
458{
459	return B_BAD_VALUE;
460}
461
462// RewindAttrDir
463status_t
464Volume::RewindAttrDir(void* node, void* cookie)
465{
466	return B_BAD_VALUE;
467}
468
469
470// #pragma mark - attributes
471
472
473// CreateAttr
474status_t
475Volume::CreateAttr(void* node, const char* name, uint32 type, int openMode,
476	void** cookie)
477{
478	return B_BAD_VALUE;
479}
480
481// OpenAttr
482status_t
483Volume::OpenAttr(void* node, const char* name, int openMode,
484	void** cookie)
485{
486	return B_BAD_VALUE;
487}
488
489// CloseAttr
490status_t
491Volume::CloseAttr(void* node, void* cookie)
492{
493	return B_BAD_VALUE;
494}
495
496// FreeAttrCookie
497status_t
498Volume::FreeAttrCookie(void* node, void* cookie)
499{
500	return B_BAD_VALUE;
501}
502
503// ReadAttr
504status_t
505Volume::ReadAttr(void* node, void* cookie, off_t pos, void* buffer,
506	size_t bufferSize, size_t* bytesRead)
507{
508	return B_BAD_VALUE;
509}
510
511// WriteAttr
512status_t
513Volume::WriteAttr(void* node, void* cookie, off_t pos,
514	const void* buffer, size_t bufferSize, size_t* bytesWritten)
515{
516	return B_BAD_VALUE;
517}
518
519// ReadAttrStat
520status_t
521Volume::ReadAttrStat(void* node, void* cookie, struct stat *st)
522{
523	return B_BAD_VALUE;
524}
525
526// WriteAttrStat
527status_t
528Volume::WriteAttrStat(void* node, void* cookie, const struct stat* st,
529	int statMask)
530{
531	return B_BAD_VALUE;
532}
533
534// RenameAttr
535status_t
536Volume::RenameAttr(void* oldNode, const char* oldName, void* newNode,
537	const char* newName)
538{
539	return B_BAD_VALUE;
540}
541
542// RemoveAttr
543status_t
544Volume::RemoveAttr(void* node, const char* name)
545{
546	return B_BAD_VALUE;
547}
548
549
550// #pragma mark - indices
551
552
553// OpenIndexDir
554status_t
555Volume::OpenIndexDir(void** cookie)
556{
557	return B_BAD_VALUE;
558}
559
560// CloseIndexDir
561status_t
562Volume::CloseIndexDir(void* cookie)
563{
564	return B_BAD_VALUE;
565}
566
567// FreeIndexDirCookie
568status_t
569Volume::FreeIndexDirCookie(void* cookie)
570{
571	return B_BAD_VALUE;
572}
573
574// ReadIndexDir
575status_t
576Volume::ReadIndexDir(void* cookie, void* buffer, size_t bufferSize,
577	uint32 count, uint32* countRead)
578{
579	return B_BAD_VALUE;
580}
581
582// RewindIndexDir
583status_t
584Volume::RewindIndexDir(void* cookie)
585{
586	return B_BAD_VALUE;
587}
588
589// CreateIndex
590status_t
591Volume::CreateIndex(const char* name, uint32 type, uint32 flags)
592{
593	return B_BAD_VALUE;
594}
595
596// RemoveIndex
597status_t
598Volume::RemoveIndex(const char* name)
599{
600	return B_BAD_VALUE;
601}
602
603// ReadIndexStat
604status_t
605Volume::ReadIndexStat(const char *name, struct stat *st)
606{
607	return B_BAD_VALUE;
608}
609
610
611// #pragma mark - queries
612
613
614// OpenQuery
615status_t
616Volume::OpenQuery(const char* queryString, uint32 flags, port_id port,
617	uint32 token, void** cookie)
618{
619	return B_BAD_VALUE;
620}
621
622// CloseQuery
623status_t
624Volume::CloseQuery(void* cookie)
625{
626	return B_BAD_VALUE;
627}
628
629// FreeQueryCookie
630status_t
631Volume::FreeQueryCookie(void* cookie)
632{
633	return B_BAD_VALUE;
634}
635
636// ReadQuery
637status_t
638Volume::ReadQuery(void* cookie, void* buffer, size_t bufferSize,
639	uint32 count, uint32* countRead)
640{
641	return B_BAD_VALUE;
642}
643
644// RewindQuery
645status_t
646Volume::RewindQuery(void* cookie)
647{
648	return B_BAD_VALUE;
649}
650
651