1/*
2 * Copyright 2004-2010, Haiku Inc. All Rights Reserved.
3 * Distributed under the terms of the MIT License.
4 */
5#ifndef _FS_INTERFACE_H
6#define _FS_INTERFACE_H
7
8/*! File System Interface Layer Definition */
9
10
11#include <OS.h>
12#include <Select.h>
13#include <module.h>
14#include <disk_device_manager.h>
15
16#include <sys/uio.h>
17
18
19struct dirent;
20struct stat;
21struct fs_info;
22struct select_sync;
23
24typedef struct IORequest io_request;
25
26
27/* additional flags passed to write_stat() (see NodeMonitor.h for the others) */
28// NOTE: Changing the constants here or in NodeMonitor.h will break
29// src/kits/storage/LibBeAdapter.cpp:_kern_write_stat().
30#define B_STAT_SIZE_INSECURE	0x2000
31	// TODO: this should be faded out once BFS supports sparse files
32
33/* passed to write_fs_info() */
34#define	FS_WRITE_FSINFO_NAME	0x0001
35
36struct file_io_vec {
37	off_t	offset;
38	off_t	length;
39};
40
41#define	B_CURRENT_FS_API_VERSION "/v1"
42
43// flags for publish_vnode() and fs_volume_ops::get_vnode()
44#define B_VNODE_PUBLISH_REMOVED					0x01
45#define B_VNODE_DONT_CREATE_SPECIAL_SUB_NODE	0x02
46
47
48#ifdef __cplusplus
49extern "C" {
50#endif
51
52typedef struct fs_volume fs_volume;
53typedef struct fs_volume_ops fs_volume_ops;
54typedef struct fs_vnode fs_vnode;
55typedef struct fs_vnode_ops fs_vnode_ops;
56typedef struct file_system_module_info file_system_module_info;
57
58struct fs_volume {
59	dev_t						id;
60	partition_id				partition;
61	int32						layer;
62	void*						private_volume;
63	fs_volume_ops*				ops;
64	fs_volume*					sub_volume;
65	fs_volume*					super_volume;
66	file_system_module_info*	file_system;
67	char*						file_system_name;
68};
69
70struct fs_vnode {
71	void*			private_node;
72	fs_vnode_ops*	ops;
73};
74
75struct fs_volume_ops {
76	status_t (*unmount)(fs_volume* volume);
77
78	status_t (*read_fs_info)(fs_volume* volume, struct fs_info* info);
79	status_t (*write_fs_info)(fs_volume* volume, const struct fs_info* info,
80				uint32 mask);
81	status_t (*sync)(fs_volume* volume);
82
83	status_t (*get_vnode)(fs_volume* volume, ino_t id, fs_vnode* vnode,
84				int* _type, uint32* _flags, bool reenter);
85
86	/* index directory & index operations */
87	status_t (*open_index_dir)(fs_volume* volume, void** _cookie);
88	status_t (*close_index_dir)(fs_volume* volume, void* cookie);
89	status_t (*free_index_dir_cookie)(fs_volume* volume, void* cookie);
90	status_t (*read_index_dir)(fs_volume* volume, void* cookie,
91				struct dirent* buffer, size_t bufferSize, uint32* _num);
92	status_t (*rewind_index_dir)(fs_volume* volume, void* cookie);
93
94	status_t (*create_index)(fs_volume* volume, const char* name, uint32 type,
95				uint32 flags);
96	status_t (*remove_index)(fs_volume* volume, const char* name);
97	status_t (*read_index_stat)(fs_volume* volume, const char* name,
98				struct stat* stat);
99
100	/* query operations */
101	status_t (*open_query)(fs_volume* volume, const char* query, uint32 flags,
102				port_id port, uint32 token, void** _cookie);
103	status_t (*close_query)(fs_volume* volume, void* cookie);
104	status_t (*free_query_cookie)(fs_volume* volume, void* cookie);
105	status_t (*read_query)(fs_volume* volume, void* cookie,
106				struct dirent* buffer, size_t bufferSize, uint32* _num);
107	status_t (*rewind_query)(fs_volume* volume, void* cookie);
108
109	/* support for FS layers */
110	status_t (*all_layers_mounted)(fs_volume* volume);
111	status_t (*create_sub_vnode)(fs_volume* volume, ino_t id, fs_vnode* vnode);
112	status_t (*delete_sub_vnode)(fs_volume* volume, fs_vnode* vnode);
113};
114
115struct fs_vnode_ops {
116	/* vnode operations */
117	status_t (*lookup)(fs_volume* volume, fs_vnode* dir, const char* name,
118				ino_t* _id);
119	status_t (*get_vnode_name)(fs_volume* volume, fs_vnode* vnode, char* buffer,
120				size_t bufferSize);
121
122	status_t (*put_vnode)(fs_volume* volume, fs_vnode* vnode, bool reenter);
123	status_t (*remove_vnode)(fs_volume* volume, fs_vnode* vnode, bool reenter);
124
125	/* VM file access */
126	bool (*can_page)(fs_volume* volume, fs_vnode* vnode, void* cookie);
127	status_t (*read_pages)(fs_volume* volume, fs_vnode* vnode, void* cookie,
128				off_t pos, const iovec* vecs, size_t count, size_t* _numBytes);
129	status_t (*write_pages)(fs_volume* volume, fs_vnode* vnode,
130				void* cookie, off_t pos, const iovec* vecs, size_t count,
131				size_t* _numBytes);
132
133	/* asynchronous I/O */
134	status_t (*io)(fs_volume* volume, fs_vnode* vnode, void* cookie,
135				io_request* request);
136	status_t (*cancel_io)(fs_volume* volume, fs_vnode* vnode, void* cookie,
137				io_request* request);
138
139	/* cache file access */
140	status_t (*get_file_map)(fs_volume* volume, fs_vnode* vnode, off_t offset,
141				size_t size, struct file_io_vec* vecs, size_t* _count);
142
143	/* common operations */
144	status_t (*ioctl)(fs_volume* volume, fs_vnode* vnode, void* cookie,
145				uint32 op, void* buffer, size_t length);
146	status_t (*set_flags)(fs_volume* volume, fs_vnode* vnode, void* cookie,
147				int flags);
148	status_t (*select)(fs_volume* volume, fs_vnode* vnode, void* cookie,
149				uint8 event, selectsync* sync);
150	status_t (*deselect)(fs_volume* volume, fs_vnode* vnode, void* cookie,
151				uint8 event, selectsync* sync);
152	status_t (*fsync)(fs_volume* volume, fs_vnode* vnode);
153
154	status_t (*read_symlink)(fs_volume* volume, fs_vnode* link, char* buffer,
155				size_t* _bufferSize);
156	status_t (*create_symlink)(fs_volume* volume, fs_vnode* dir,
157				const char* name, const char* path, int mode);
158
159	status_t (*link)(fs_volume* volume, fs_vnode* dir, const char* name,
160				fs_vnode* vnode);
161	status_t (*unlink)(fs_volume* volume, fs_vnode* dir, const char* name);
162	status_t (*rename)(fs_volume* volume, fs_vnode* fromDir,
163				const char* fromName, fs_vnode* toDir, const char* toName);
164
165	status_t (*access)(fs_volume* volume, fs_vnode* vnode, int mode);
166	status_t (*read_stat)(fs_volume* volume, fs_vnode* vnode,
167				struct stat* stat);
168	status_t (*write_stat)(fs_volume* volume, fs_vnode* vnode,
169				const struct stat* stat, uint32 statMask);
170	status_t (*preallocate)(fs_volume* volume, fs_vnode* vnode,
171				off_t pos, off_t length);
172
173	/* file operations */
174	status_t (*create)(fs_volume* volume, fs_vnode* dir, const char* name,
175				int openMode, int perms, void** _cookie,
176				ino_t* _newVnodeID);
177	status_t (*open)(fs_volume* volume, fs_vnode* vnode, int openMode,
178				void** _cookie);
179	status_t (*close)(fs_volume* volume, fs_vnode* vnode, void* cookie);
180	status_t (*free_cookie)(fs_volume* volume, fs_vnode* vnode,
181				void* cookie);
182	status_t (*read)(fs_volume* volume, fs_vnode* vnode, void* cookie,
183				off_t pos, void* buffer, size_t* length);
184	status_t (*write)(fs_volume* volume, fs_vnode* vnode, void* cookie,
185				off_t pos, const void* buffer, size_t* length);
186
187	/* directory operations */
188	status_t (*create_dir)(fs_volume* volume, fs_vnode* parent,
189				const char* name, int perms);
190	status_t (*remove_dir)(fs_volume* volume, fs_vnode* parent,
191				const char* name);
192	status_t (*open_dir)(fs_volume* volume, fs_vnode* vnode,
193				void** _cookie);
194	status_t (*close_dir)(fs_volume* volume, fs_vnode* vnode, void* cookie);
195	status_t (*free_dir_cookie)(fs_volume* volume, fs_vnode* vnode,
196				void* cookie);
197	status_t (*read_dir)(fs_volume* volume, fs_vnode* vnode, void* cookie,
198				struct dirent* buffer, size_t bufferSize, uint32* _num);
199	status_t (*rewind_dir)(fs_volume* volume, fs_vnode* vnode,
200				void* cookie);
201
202	/* attribute directory operations */
203	status_t (*open_attr_dir)(fs_volume* volume, fs_vnode* vnode,
204				void** _cookie);
205	status_t (*close_attr_dir)(fs_volume* volume, fs_vnode* vnode,
206				void* cookie);
207	status_t (*free_attr_dir_cookie)(fs_volume* volume, fs_vnode* vnode,
208				void* cookie);
209	status_t (*read_attr_dir)(fs_volume* volume, fs_vnode* vnode,
210				void* cookie, struct dirent* buffer, size_t bufferSize,
211				uint32* _num);
212	status_t (*rewind_attr_dir)(fs_volume* volume, fs_vnode* vnode,
213				void* cookie);
214
215	/* attribute operations */
216	status_t (*create_attr)(fs_volume* volume, fs_vnode* vnode,
217				const char* name, uint32 type, int openMode,
218				void** _cookie);
219	status_t (*open_attr)(fs_volume* volume, fs_vnode* vnode, const char* name,
220				int openMode, void** _cookie);
221	status_t (*close_attr)(fs_volume* volume, fs_vnode* vnode,
222				void* cookie);
223	status_t (*free_attr_cookie)(fs_volume* volume, fs_vnode* vnode,
224				void* cookie);
225	status_t (*read_attr)(fs_volume* volume, fs_vnode* vnode, void* cookie,
226				off_t pos, void* buffer, size_t* length);
227	status_t (*write_attr)(fs_volume* volume, fs_vnode* vnode, void* cookie,
228				off_t pos, const void* buffer, size_t* length);
229
230	status_t (*read_attr_stat)(fs_volume* volume, fs_vnode* vnode,
231				void* cookie, struct stat* stat);
232	status_t (*write_attr_stat)(fs_volume* volume, fs_vnode* vnode,
233				void* cookie, const struct stat* stat, int statMask);
234	status_t (*rename_attr)(fs_volume* volume, fs_vnode* fromVnode,
235				const char* fromName, fs_vnode* toVnode, const char* toName);
236	status_t (*remove_attr)(fs_volume* volume, fs_vnode* vnode,
237				const char* name);
238
239	/* support for node and FS layers */
240	status_t (*create_special_node)(fs_volume* volume, fs_vnode* dir,
241				const char* name, fs_vnode* subVnode, mode_t mode, uint32 flags,
242				fs_vnode* _superVnode, ino_t* _nodeID);
243	status_t (*get_super_vnode)(fs_volume* volume, fs_vnode* vnode,
244				fs_volume* superVolume, fs_vnode* superVnode);
245};
246
247struct file_system_module_info {
248	struct module_info	info;
249	const char*			short_name;
250	const char*			pretty_name;
251	uint32				flags;	// DDM flags
252
253	/* scanning (the device is write locked) */
254	float (*identify_partition)(int fd, partition_data* partition,
255				void** _cookie);
256	status_t (*scan_partition)(int fd, partition_data* partition,
257				void* cookie);
258	void (*free_identify_partition_cookie)(partition_data* partition,
259				void* cookie);
260	void (*free_partition_content_cookie)(partition_data* partition);
261
262	/* general operations */
263	status_t (*mount)(fs_volume* volume, const char* device, uint32 flags,
264				const char* args, ino_t* _rootVnodeID);
265
266	/* capability querying (the device is read locked) */
267	uint32 (*get_supported_operations)(partition_data* partition, uint32 mask);
268
269	bool (*validate_resize)(partition_data* partition, off_t* size);
270	bool (*validate_move)(partition_data* partition, off_t* start);
271	bool (*validate_set_content_name)(partition_data* partition,
272				char* name);
273	bool (*validate_set_content_parameters)(partition_data* partition,
274				const char* parameters);
275	bool (*validate_initialize)(partition_data* partition, char* name,
276				const char* parameters);
277
278	/* shadow partition modification (device is write locked) */
279	status_t (*shadow_changed)(partition_data* partition,
280				partition_data* child, uint32 operation);
281
282	/* writing (the device is NOT locked) */
283	status_t (*defragment)(int fd, partition_id partition,
284				disk_job_id job);
285	status_t (*repair)(int fd, partition_id partition, bool checkOnly,
286				disk_job_id job);
287	status_t (*resize)(int fd, partition_id partition, off_t size,
288				disk_job_id job);
289	status_t (*move)(int fd, partition_id partition, off_t offset,
290				disk_job_id job);
291	status_t (*set_content_name)(int fd, partition_id partition,
292				const char* name, disk_job_id job);
293	status_t (*set_content_parameters)(int fd, partition_id partition,
294				const char* parameters, disk_job_id job);
295	status_t (*initialize)(int fd, partition_id partition, const char* name,
296				const char* parameters, off_t partitionSize, disk_job_id job);
297	status_t (*uninitialize)(int fd, partition_id partition,
298				off_t partitionSize, uint32 blockSize, disk_job_id job);
299};
300
301
302/* file system add-ons only prototypes */
303
304// callbacks for do_iterative_fd_io()
305typedef status_t (*iterative_io_get_vecs)(void* cookie, io_request* request,
306				off_t offset, size_t size, struct file_io_vec* vecs,
307				size_t* _count);
308typedef status_t (*iterative_io_finished)(void* cookie, io_request* request,
309				status_t status, bool partialTransfer, size_t bytesTransferred);
310
311extern status_t new_vnode(fs_volume* volume, ino_t vnodeID, void* privateNode,
312					fs_vnode_ops* ops);
313extern status_t publish_vnode(fs_volume* volume, ino_t vnodeID,
314					void* privateNode, fs_vnode_ops* ops, int type,
315					uint32 flags);
316extern status_t get_vnode(fs_volume* volume, ino_t vnodeID,
317					void** _privateNode);
318extern status_t put_vnode(fs_volume* volume, ino_t vnodeID);
319extern status_t acquire_vnode(fs_volume* volume, ino_t vnodeID);
320extern status_t remove_vnode(fs_volume* volume, ino_t vnodeID);
321extern status_t unremove_vnode(fs_volume* volume, ino_t vnodeID);
322extern status_t get_vnode_removed(fs_volume* volume, ino_t vnodeID,
323					bool* _removed);
324extern fs_volume* volume_for_vnode(fs_vnode* vnode);
325
326extern status_t read_pages(int fd, off_t pos, const struct iovec* vecs,
327					size_t count, size_t* _numBytes);
328extern status_t write_pages(int fd, off_t pos, const struct iovec* vecs,
329					size_t count, size_t* _numBytes);
330extern status_t read_file_io_vec_pages(int fd,
331					const struct file_io_vec* fileVecs, size_t fileVecCount,
332					const struct iovec* vecs, size_t vecCount,
333					uint32* _vecIndex, size_t* _vecOffset, size_t* _bytes);
334extern status_t write_file_io_vec_pages(int fd,
335					const struct file_io_vec* fileVecs, size_t fileVecCount,
336					const struct iovec* vecs, size_t vecCount,
337					uint32* _vecIndex, size_t* _vecOffset, size_t* _bytes);
338extern status_t do_fd_io(int fd, io_request* request);
339extern status_t do_iterative_fd_io(int fd, io_request* request,
340					iterative_io_get_vecs getVecs,
341					iterative_io_finished finished, void* cookie);
342
343extern status_t notify_entry_created(dev_t device, ino_t directory,
344					const char* name, ino_t node);
345extern status_t notify_entry_removed(dev_t device, ino_t directory,
346					const char* name, ino_t node);
347extern status_t notify_entry_moved(dev_t device, ino_t fromDirectory,
348					const char* fromName, ino_t toDirectory,
349					const char* toName, ino_t node);
350extern status_t notify_stat_changed(dev_t device, ino_t node,
351					uint32 statFields);
352extern status_t notify_attribute_changed(dev_t device, ino_t node,
353					const char* attribute, int32 cause);
354
355extern status_t notify_query_entry_created(port_id port, int32 token,
356					dev_t device, ino_t directory, const char* name,
357					ino_t node);
358extern status_t notify_query_entry_removed(port_id port, int32 token,
359					dev_t device, ino_t directory, const char* name,
360					ino_t node);
361extern status_t notify_query_attr_changed(port_id port, int32 token,
362					dev_t device, ino_t directory, const char* name,
363					ino_t node);
364
365#ifdef __cplusplus
366}
367#endif
368
369#endif	/* _FS_INTERFACE_H */
370