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