1/*
2 * Copyright 2003-2005, Axel Dörfler, axeld@pinc-software.de.
3 * Distributed under the terms of the MIT License.
4 */
5#ifndef KERNEL_BOOT_VFS_H
6#define KERNEL_BOOT_VFS_H
7
8
9#include <dirent.h>
10
11#include <SupportDefs.h>
12
13#include <util/DoublyLinkedList.h>
14#include <boot/stage2_args.h>
15
16
17#ifdef __cplusplus
18
19struct file_map_run;
20struct stat;
21class PackageVolumeInfo;
22class PackageVolumeState;
23
24/** This is the base class for all VFS nodes */
25
26class Node : public DoublyLinkedListLinkImpl<Node> {
27	public:
28		Node();
29		virtual ~Node();
30
31		virtual status_t Open(void **_cookie, int mode);
32		virtual status_t Close(void *cookie);
33
34		virtual ssize_t ReadAt(void *cookie, off_t pos, void *buffer,
35			size_t bufferSize) = 0;
36		virtual ssize_t WriteAt(void *cookie, off_t pos, const void *buffer,
37			size_t bufferSize) = 0;
38
39		virtual status_t ReadLink(char* buffer, size_t bufferSize);
40
41		virtual status_t GetName(char *nameBuffer, size_t bufferSize) const;
42		virtual status_t GetFileMap(struct file_map_run *runs, int32 *count);
43		virtual int32 Type() const;
44		virtual off_t Size() const;
45		virtual ino_t Inode() const;
46
47		void Stat(struct stat& stat);
48
49		status_t Acquire();
50		status_t Release();
51
52	protected:
53		int32		fRefCount;
54};
55
56typedef DoublyLinkedList<Node> NodeList;
57typedef NodeList::Iterator NodeIterator;
58
59
60class Directory : public Node {
61	public:
62		Directory();
63
64		virtual ssize_t ReadAt(void *cookie, off_t pos, void *buffer, size_t bufferSize);
65		virtual ssize_t WriteAt(void *cookie, off_t pos, const void *buffer, size_t bufferSize);
66
67		virtual int32 Type() const;
68
69		virtual Node* Lookup(const char* name, bool traverseLinks);
70		virtual Node* LookupDontTraverse(const char* name) = 0;
71
72		virtual status_t GetNextEntry(void *cookie, char *nameBuffer, size_t bufferSize) = 0;
73		virtual status_t GetNextNode(void *cookie, Node **_node) = 0;
74		virtual status_t Rewind(void *cookie) = 0;
75		virtual bool IsEmpty() = 0;
76
77		virtual status_t CreateFile(const char *name, mode_t permissions,
78			Node **_node);
79};
80
81/** The console based nodes don't need cookies for I/O, they
82 *	also don't support to change the stream position.
83 *	Live is simple in the boot loader :-)
84 */
85
86class ConsoleNode : public Node {
87	public:
88		ConsoleNode();
89
90		virtual ssize_t Read(void *buffer, size_t bufferSize);
91		virtual ssize_t Write(const void *buffer, size_t bufferSize);
92};
93
94
95class MemoryDisk : public Node {
96	public:
97		MemoryDisk(const uint8* data, size_t size, const char* name);
98
99		virtual ssize_t ReadAt(void* cookie, off_t pos, void* buffer,
100			size_t bufferSize);
101		virtual ssize_t WriteAt(void* cookie, off_t pos, const void* buffer,
102			size_t bufferSize);
103
104		virtual off_t Size() const;
105		virtual status_t GetName(char *nameBuffer, size_t bufferSize) const;
106
107	private:
108		const uint8*	fData;
109		size_t			fSize;
110		char			fName[64];
111};
112
113
114class BootVolume {
115public:
116								BootVolume();
117								~BootVolume();
118
119			status_t			SetTo(Directory* rootDirectory,
120									PackageVolumeInfo* packageVolumeInfo
121										= NULL,
122									PackageVolumeState* packageVolumeState
123										= NULL);
124			void				Unset();
125
126			bool				IsValid() const
127									{ return fRootDirectory != NULL; }
128
129			Directory*			RootDirectory() const
130									{ return fRootDirectory; }
131			Directory*			SystemDirectory() const
132									{ return fSystemDirectory; }
133			bool				IsPackaged() const
134									{ return fPackageVolumeInfo != NULL; }
135			PackageVolumeInfo*	GetPackageVolumeInfo() const
136									{ return fPackageVolumeInfo; }
137			PackageVolumeState*	GetPackageVolumeState() const
138									{ return fPackageVolumeState; }
139
140private:
141			status_t			_SetTo(Directory* rootDirectory,
142									PackageVolumeInfo* packageVolumeInfo,
143									PackageVolumeState* packageVolumeState);
144			int					_OpenSystemPackage();
145
146private:
147			Directory*			fRootDirectory;
148				// root directory of the volume
149			Directory*			fSystemDirectory;
150				// "system" directory of the volume; if packaged the root
151				// directory of the mounted packagefs
152			PackageVolumeInfo*	fPackageVolumeInfo;
153			PackageVolumeState*	fPackageVolumeState;
154};
155
156
157/* function prototypes */
158
159extern status_t vfs_init(stage2_args *args);
160extern status_t register_boot_file_system(BootVolume& bootVolume);
161extern status_t get_boot_file_system(stage2_args* args,
162			BootVolume& _bootVolume);
163extern status_t mount_file_systems(stage2_args *args);
164extern int open_node(Node *node, int mode);
165extern int open_from(Directory *directory, const char *path, int mode,
166			mode_t permissions = 0);
167extern DIR* open_directory(Directory* baseDirectory, const char* path);
168extern status_t get_stat(Directory* directory, const char* path,
169			struct stat& st);
170
171extern Node* get_node_from(int fd);
172	// returns a reference
173extern Directory* directory_from(DIR* dir);
174	// does not return a reference
175
176extern status_t add_partitions_for(int fd, bool mountFileSystems, bool isBootDevice = false);
177extern status_t add_partitions_for(Node *device, bool mountFileSystems, bool isBootDevice = false);
178
179#endif	/* __cplusplus */
180
181#endif	/* KERNEL_BOOT_VFS_H */
182