1/*! 2\file fs_interface.h 3\ingroup drivers 4*/ 5 6/*! 7\fn status_t new_vnode(mount_id mountID, vnode_id vnodeID, fs_vnode privateNode) 8\brief Creates the vnode with ID \a vnodeID and associates it with the private 9 data handle \a privateNode, but leaves is in an unpublished state. 10 11The effect of the function is similar to publish_vnode(), but the vnode 12remains in an unpublished state, with the effect that a subsequent 13remove_vnode() will just delete the vnode and not invoke the file system's 14\link file_system_module_info::remove_vnode remove_vnode() \endlink is not 15invoked. 16 17If the vnode shall be kept, publish_vnode() has to be invoked afterwards to 18mark the vnode published. The combined effect is the same as only invoking 19publish_vnode(). 20 21The function fails, if the vnode does already exist. 22 23\param mountID The ID of the volume. 24\param vnodeID The ID of the node. 25\param privateNode The private data handle to be associated with the node. 26\return \c B_OK if everything went fine, another error code otherwise. 27*/ 28 29/*! 30\fn status_t publish_vnode(mount_id mountID, vnode_id vnodeID, 31 fs_vnode privateNode) 32\brief Creates the vnode with ID \a vnodeID and associates it with the private 33 data handle \a privateNode or just marks it published. 34 35If the vnode does already exist and has been published, the function fails. 36If it has not been published yet (i.e. after a successful new_vnode()), the 37function just marks the vnode published. If the vnode did not exist at all 38before, it is created and published. 39 40If the function is successful, the caller owns a reference to the vnode. A 41sequence of new_vnode() and publish_vnode() results in just one reference as 42well. The reference can be surrendered by calling put_vnode(). 43 44\param mountID The ID of the volume. 45\param vnodeID The ID of the node. 46\param privateNode The private data handle to be associated with the node. 47\return \c B_OK if everything went fine, another error code otherwise. 48*/ 49 50/*! 51\fn status_t get_vnode(mount_id mountID, vnode_id vnodeID, 52 fs_vnode *_privateNode) 53\brief Retrieves the private data handle for the node with the given ID. 54 55If the function is successful, the caller owns a reference to the vnode. The 56reference can be surrendered by calling put_vnode(). 57 58\param mountID The ID of the volume. 59\param vnodeID The ID of the node. 60\param _privateNode Pointer to a pre-allocated variable the private data 61 handle shall be written to. 62\return \c B_OK if everything went fine, another error code otherwise. 63*/ 64 65/*! 66\fn status_t put_vnode(mount_id mountID, vnode_id vnodeID) 67\brief Surrenders a reference to the specified vnode. 68\param mountID The ID of the volume. 69\param vnodeID The ID of the node. 70\return \c B_OK if everything went fine, another error code otherwise. 71*/ 72 73/*! 74\fn status_t remove_vnode(mount_id mountID, vnode_id vnodeID) 75\brief Marks the specified vnode removed. 76 77The caller must own a reference to the vnode or at least ensure that a 78reference to the vnode exists. The function does not surrender a reference, 79though. 80 81As soon as the last reference to the vnode has been surrendered, the VFS 82invokes the file system's 83\link file_system_module_info::remove_vnode remove_vnode() \endlink 84hook. 85 86\param mountID The ID of the volume. 87\param vnodeID The ID of the node. 88\return \c B_OK if everything went fine, another error code otherwise. 89*/ 90 91/*! 92\fn status_t unremove_vnode(mount_id mountID, vnode_id vnodeID); 93\brief Clears the "removed" mark of the specified vnode. 94 95The caller must own a reference to the vnode or at least ensure that a 96reference to the vnode exists. 97 98The function is usually called when the caller, who has invoked remove_vnode() 99before realizes that it is not possible to remove the node (e.g. due to an 100error). 101 102\param mountID The ID of the volume. 103\param vnodeID The ID of the node. 104\return \c B_OK if everything went fine, another error code otherwise. 105*/ 106 107/*! 108\fn status_t get_vnode_removed(mount_id mountID, vnode_id vnodeID, 109 bool* removed); 110\brief Returns whether the specified vnode is marked removed. 111 112The caller must own a reference to the vnode or at least ensure that a 113reference to the vnode exists. 114 115\param mountID The ID of the volume. 116\param vnodeID The ID of the node. 117\param removed Pointer to a pre-allocated variable set to \c true, if the 118 node is marked removed, to \c false otherwise. 119\return \c B_OK if everything went fine, another error code otherwise. 120*/ 121 122 123/*! 124\class file_system_module_info 125\brief Kernel module interface for file systems. 126*/ 127 128/*! 129\fn status_t (*file_system_module_info::mount)(mount_id id, const char *device, 130 uint32 flags, const char *args, fs_volume *_fs, vnode_id *_rootVnodeID) 131\brief Mount a volume according to the specified parameters. 132 133Invoked by the VFS when it has been requested to mount the volume. The FS is 134supposed to perform whatever one-time initialization is necessary for the 135volume. It is required to create a volume handle for the volume and pass it 136back in \a _fs. Moreover it must invoke publish_vnode() for the root node 137of the volume and pass the ID of the volume back in \a _rootVnodeID. 138 139A disk-based FS will need to check whether \a device is not \c NULL, open 140it, and analyze whether the device or image file actually represents a volume 141of that FS type. 142 143If mounting the volume fails for whatever reason, the hook must return an 144error code other than \c B_OK. In this case all resources allocated by the 145hook must be freed before returning. If and only if \c B_OK is returned, the 146unmount() hook will be invoked at a later point when unmounting the volume. 147 148\param id The ID of the volume to be mounted. It should be saved in the FS's 149 volume private data (volume handle). 150\param device The path to the device (or image file) representing the volume 151 to be mounted. Can be \c NULL. 152\param flags Flags: 153 - \c B_MOUNT_READ_ONLY: Mount the volume read-only. 154\param args Null-terminated string in driver settings format, containing FS 155 specific parameters. 156\param _fs Pointer to a pre-allocated variable the volume handle shall be 157 written to. 158\param _rootVnodeID Pointer to a pre-allocated variable the ID of the volume's 159 root directory shall be written to. 160\return \c B_OK if everything went fine, another error code otherwise. 161*/ 162 163/*! 164\fn status_t (*file_system_module_info::unmount)(fs_volume fs) 165\brief Unmounts the given volume. 166 167Invoked by the VFS when it is asked to unmount the volume. The function must 168free all resources associated with the mounted volume, including the volume 169handle. Although the mount() hook called publish_vnode() for the root node 170of the volume, unmount() must not invoke put_vnode(). 171 172\param fs The volume handle. 173\return \c B_OK if everything went fine, another error code otherwise. The 174 error code will be ignored, though. 175*/ 176 177/*! 178\fn status_t (*file_system_module_info::read_fs_info)(fs_volume fs, 179 struct fs_info *info) 180\brief Retrieves general information about the volume. 181 182The following fields of the \c fs_info structure need to be filled in: 183- \c flags: Flags applying to the volume, e.g. \c B_FS_IS_READONLY, 184 \c B_FS_HAS_ATTR, etc. 185- \c block_size: The size of blocks the volume data are organized in. 186 Meaningful mainly for disk-based FSs, other FSs should use some reasonable 187 value for computing \c total_blocks and \c free_blocks. 188- \c io_size: Preferred size of the buffers passed to read() and write(). 189- \c total_blocks: Total number of blocks the volume contains. 190- \c free_blocks: Number of free blocks on the volume. 191- \c total_nodes: Maximal number of nodes the volume can contain. If there is 192 no such limitation use \c LONGLONG_MAX. 193- \c free_nodes: Number of additional nodes the volume could contain. If there 194 is no such limitation use \c LONGLONG_MAX. 195- \c device_name: The name of the device or image file containing the volume. 196 Non-disk-based FSs shall fill in an empty string. 197- \c volume_name: The name of the volume. 198 199The other values are filled in by the VFS. 200 201\param fs The volume handle. 202\param info Pointer to a pre-allocated variable the FS info shall be written 203 to. 204\return \c B_OK if everything went fine, another error code otherwise. The 205 error code will be ignored, though. 206*/ 207 208/*! 209\fn status_t (*file_system_module_info::lookup)(fs_volume fs, fs_vnode dir, 210 const char *name, vnode_id *_id, int *_type) 211\brief Looks up the node a directory entry refers to. 212 213The VFS uses this hook to resolve path names to vnodes. It is used quite often 214and should be implemented efficiently. 215 216If the parameter \a dir does not specify a directory, the function shall fail. 217It shall also fail, if it is a directory, but does not contain an entry with 218the given name \a name. Otherwise the function shall invoke get_vnode() for 219the node the entry refers to and pass back the ID and the type of the node 220in \a _id and \a _type respectively. 221 222Note that a directory must contain the special entries \c "." and \c "..", 223referring to the same directory and the parent directory respectively. 224lookup() must resolve the nodes accordingly. \c ".." for the root directory 225of the volume shall be resolved to the root directory itself. 226 227\param fs The volume handle. 228\param dir The node handle of the directory. 229\param name The name of the directory entry. 230\param _id Pointer to a pre-allocated variable the ID of the found node 231 shall be written to. 232\param _type Pointer to a pre-allocated variable the type of the found node 233 shall be written to. The type is encoded as in the \c st_mode field of a 234 <tt>struct stat</tt> (bitwise anded with \c S_IFMT). 235\retval B_OK Everything went fine. 236\retval B_ENTRY_NOT_FOUND The given directory does not contain an entry with 237 the given name. 238*/ 239 240/*! 241\fn status_t (*file_system_module_info::get_vnode)(fs_volume fs, vnode_id id, 242 fs_vnode *_vnode, bool reenter) 243\brief Creates the private data handle to be associated with the node referred 244 to by \a id. 245 246Invoked by the VFS when it creates the vnode for the respective node. 247 248\param fs The volume handle. 249\param id The ID of the node. 250\param _vnode Pointer to a pre-allocated variable the node handle shall be 251 written to. 252\param reenter \c true if the hook invocation has been caused by the FS itself, 253 e.g. by invoking ::get_vnode(). 254\return \c B_OK if everything went fine, another error code otherwise. 255*/ 256 257/*! 258\fn \fn status_t (*file_system_module_info::put_vnode)(fs_volume fs, 259 fs_vnode vnode, bool reenter) 260\brief Deletes the private data handle associated with the specified node. 261 262Invoked by the VFS when it deletes the vnode for the respective node and the 263node is not marked removed. 264 265\param fs The volume handle. 266\param vnode The node handle. 267\param reenter \c true if the hook invocation has been caused by the FS itself, 268 e.g. by invoking ::put_vnode(). 269\return \c B_OK if everything went fine, another error code otherwise. 270*/ 271 272/*! 273\fn status_t (*file_system_module_info::remove_vnode)(fs_volume fs, 274 fs_vnode vnode, bool reenter) 275\brief Deletes the private data handle associated with the specified node. 276 277Invoked by the VFS when it deletes the vnode for the respective node and the 278node is marked removed. 279 280\param fs The volume handle. 281\param vnode The node handle. 282\param reenter \c true if the hook invocation has been caused by the FS itself, 283 e.g. by invoking ::put_vnode(). 284\return \c B_OK if everything went fine, another error code otherwise. 285*/ 286 287/*! 288\fn status_t (*file_system_module_info::read_symlink)(fs_volume fs, 289 fs_vnode link, char *buffer, size_t *_bufferSize) 290\brief Reads the value of a symlink. 291 292If the function is successful, the string written to the buffer shall be 293null-terminated and the variable \a _bufferSize points to shall be set to 294the length of that string, including the terminating null character. 295 296\param fs The volume handle. 297\param link The node handle. 298\param buffer Pointer to a pre-allocated buffer the link value shall be written 299 to. 300\param buffer Pointer to a pre-allocated variable containing the size of the 301 buffer supplied to the function. Upon successful completion the hook shall 302 store the number of bytes actually written into the buffer in the variable. 303\retval B_OK Everything went fine. 304\retval B_BAD_VALUE \a link does not identify a symbolic link. 305\retval B_BUFFER_OVERFLOW The supplied buffer is not big enough to contain the 306 complete link value. 307*/ 308 309/*! 310\fn status_t (*file_system_module_info::access)(fs_volume fs, fs_vnode vnode, 311 int mode) 312\brief Checks whether the current user is allowed to access the node in the 313 specified way. 314 315\a mode is a bitwise combination of: 316- \c R_OK: Read access. 317- \c W_OK: Write access. 318- \c X_OK: Execution. 319 320If the current user does not have any of the access permissions represented 321by the set bits, the function shall return \c B_NOT_ALLOWED. As a special case, 322if the volume is read-only and write access is requested, 323\c B_READ_ONLY_DEVICE shall be returned. If the requested access mode complies 324with the user's access permissions, the function shall return \c B_OK. 325 326For most FSs the permissions a user has are defined by the \c st_mode, 327\c st_uid, and \c st_gid fields of the node's stat data. As a special 328exception, the root user (<tt>geteuid() == 0</tt>) does always have 329read and write permissions, execution permission only when at least one of the 330execution permission bits are set. 331 332\param fs The volume handle. 333\param vnode The node handle. 334\param mode The access mode mask. 335\retval B_OK The user has the permissions to access the node in the requested 336 way. 337\retval B_READ_ONLY_DEVICE The volume is read-only, but the write access has 338 been requested. 339\retval B_NOT_ALLOWED The user does not have all permissions to access the node 340 in the requested way. 341*/ 342 343/*! 344\fn status_t (*file_system_module_info::read_stat)(fs_volume fs, 345 fs_vnode vnode, struct stat *stat) 346\brief Retrieves the stat data for a given node. 347 348All values of the <tt>struct stat</tt> save \c st_dev, \c st_ino, \c st_rdev, 349and \c st_type need to be filled in. 350 351\param fs The volume handle. 352\param vnode The node handle. 353\param stat Pointer to a pre-allocated variable the stat data shall be written 354 to. 355\return \c B_OK if everything went fine, another error code otherwise. 356*/ 357 358/*! 359\fn status_t (*file_system_module_info::open)(fs_volume fs, fs_vnode vnode, 360 int openMode, fs_cookie *_cookie) 361\brief Opens the given node. 362 363The function shall check whether it is possible to open the node according to 364the mode specified by \c openMode (also considering the user's access 365permissions), create a node cookie, and store it in the variable 366\a _cookie points to. 367 368The open mode \a openMode is encoded in the same way as the parameter of the 369POSIX function \c open(), i.e. it is either \c O_RDONLY, \c O_WRONLY, or 370\c O_RDWR, bitwise or'ed with flags. The only relevant flags for this hook are 371\c O_TRUNC and \c O_NONBLOCK. 372 373\param fs The volume handle. 374\param vnode The node handle. 375\param openMode The open mode. 376\param _cookie Pointer to a pre-allocated variable the node cookie shall be 377 written to. 378\return \c B_OK if everything went fine, another error code otherwise. 379*/ 380 381/*! 382\fn status_t (*file_system_module_info::close)(fs_volume fs, fs_vnode vnode, 383 fs_cookie cookie) 384\brief Closes the given node cookie. 385 386The hook is invoked, when closing the node has been requested. At this point 387other threads might still use the cookie, i.e. still execute hooks to which 388the cookie has been passed. If the FS supports blocking I/O operations, this 389hook should make sure to unblock all currently blocking threads performing 390an operation using the cookie, and mark the cookie such that no further 391threads will block using it. 392 393For many FSs this hook is a no-op. 394 395\param fs The volume handle. 396\param vnode The node handle. 397\param cookie The node cookie as returned by open(). 398\return \c B_OK if everything went fine, another error code otherwise. 399*/ 400 401/*! 402\fn status_t (*file_system_module_info::free_cookie)(fs_volume fs, 403 fs_vnode vnode, fs_cookie cookie) 404\brief Frees the given node cookie. 405 406The hook is invoked after close(), when no other thread uses or is going to 407use the cookie. All resources associated with the cookie must be freed. 408 409\param fs The volume handle. 410\param vnode The node handle. 411\param cookie The node cookie as returned by open(). 412\return \c B_OK if everything went fine, another error code otherwise. 413*/ 414 415/*! 416\fn status_t (*file_system_module_info::read)(fs_volume fs, fs_vnode vnode, 417 fs_cookie cookie, off_t pos, void *buffer, size_t *length) 418\brief Reads data from a file. 419 420The function shall failed if 421- the node is not a file, 422- the cookie has not been opened for reading, 423- \a pos is negative, or 424- some other error occurs while trying to read the data, and no data have been 425 read at all. 426 427The number of bytes to be read is stored in the variable pointed to by 428\a length. If less data are available at file position \a pos, or if \a pos 429if greater than the size of the file, only as many data as available shall 430be read, the function shall store the number of bytes actually read into the 431variable pointed to by \a length, and return \c B_OK. 432 433\param fs The volume handle. 434\param vnode The node handle. 435\param cookie The node cookie as returned by open(). 436\param pos The file position where to start reading data. 437\param buffer Pointer to a pre-allocated buffer the read data shall be 438 written to. 439\param length Pointer to a pre-allocated variable containing the size of the 440 buffer when invoked, and into which the size of the data actually read 441 shall be written. 442\return \c B_OK if everything went fine, another error code otherwise. 443*/ 444 445/*! 446\fn status_t (*file_system_module_info::open_dir)(fs_volume fs, fs_vnode vnode, 447 fs_cookie *_cookie) 448\brief Opens the given directory node. 449 450If the specified node is not a directory, or if the current user does not have 451the permissions to read the directory, the function shall fail. Otherwise it 452shall allocate a directory cookie and store it in the variable \a _cookie 453points to. A subsequent read_dir() using the cookie shall start reading the 454first entry of the directory. 455 456\param fs The volume handle. 457\param vnode The node handle. 458\param _cookie Pointer to a pre-allocated variable the directory cookie shall 459 be written to. 460\return \c B_OK if everything went fine, another error code otherwise. 461*/ 462 463/*! 464\fn status_t (*file_system_module_info::close_dir)(fs_volume fs, 465 fs_vnode vnode, fs_cookie cookie) 466\brief Closes the given directory cookie. 467 468Generally the situation is similar to the one described for close(). In 469practice it is a bit, though, since directory cookies are exclusively used 470for directory iteration, and it normally doesn't make sense to have multiple 471threads read the same directory concurrently. Furthermore reading a directory 472should not block. Therefore for most FSs this hook is a no-op. 473 474\param fs The volume handle. 475\param vnode The node handle. 476\param cookie The directory cookie as returned by open_dir(). 477\return \c B_OK if everything went fine, another error code otherwise. 478*/ 479 480/*! 481\fn status_t (*file_system_module_info::free_dir_cookie)(fs_volume fs, 482 fs_vnode vnode, fs_cookie cookie) 483\brief Frees the given directory cookie. 484 485The hook is invoked after close_dir(), when no other thread uses or is going 486to use the cookie. All resources associated with the cookie must be freed. 487 488\param fs The volume handle. 489\param vnode The node handle. 490\param cookie The directory cookie as returned by open_dir(). 491\return \c B_OK if everything went fine, another error code otherwise. 492*/ 493 494/*! 495\fn status_t (*file_system_module_info::read_dir)(fs_volume fs, fs_vnode vnode, 496 fs_cookie cookie, struct dirent *buffer, size_t bufferSize, uint32 *_num) 497\brief Reads the next one or more directory entries. 498 499The number of entries to be read at maximum is stored in the variable \a _num 500points to. 501 502Per read \c dirent the following fields have to be filled in: 503- \c d_dev: The volume ID. 504- \c d_ino: The ID of the node the entry refers to. 505- \c d_name: The null-terminated name of the entry. 506- \c d_reclen: The size of the \c dirent structure in bytes, starting from 507 the beginning of the structure, counting all bytes up to and including 508 the null-termination char of the name stored in \c d_name. 509 510If more than one entry is read, the corresponding \c dirent structures are 511tightly packed, i.e. the second entry begins directly after the end of the 512first one (i.e. \c d_reclen bytes after the beginning of the first one). 513Most FSs read only one entry at a time though, even if more are requested. 514 515When the function is invoked after the end of the directory has been reached, 516it shall set the variable \a _num points to to \c 0 and return \c B_OK. If the 517provided buffer is too small to contain even the single next entry, 518\c B_BUFFER_OVERFLOW shall be returned. It shall not fail, if at least one 519entry has been read, and the buffer is just too small to hold as many entries 520as requested. 521 522Note that a directory is expected to contain the special entries \c "." and 523\c "..", referring to the same directory and the parent directory respectively. 524The \c dirent structure returned for the \c ".." entry of the volume's root 525directory shall refer to the root node itself. 526 527\param fs The volume handle. 528\param vnode The node handle. 529\param cookie The directory cookie as returned by open_dir(). 530\param buffer Pointer to a pre-allocated buffer the directory entries shall be 531 written to. 532\param bufferSize The size of \a buffer in bytes. 533\param _num Pointer to a pre-allocated variable, when invoked, containing the 534 number of directory entries to be read, and into which the number of 535 entries actually read shall be written. 536\return \c B_OK if everything went fine, another error code otherwise. 537*/ 538 539/*! 540\fn status_t (*file_system_module_info::rewind_dir)(fs_volume fs, 541 fs_vnode vnode, fs_cookie cookie) 542\brief Resets the directory cookie to the first entry of the directory. 543\param fs The volume handle. 544\param vnode The node handle. 545\param cookie The directory cookie as returned by open_dir(). 546\return \c B_OK if everything went fine, another error code otherwise. 547*/ 548 549 550/*! 551\fn status_t (*file_system_module_info::read_query)(fs_volume fs, 552 fs_cookie cookie, struct dirent *buffer, size_t bufferSize, uint32 *_num) 553\brief Reads the next one or more entries matching the query. 554 555This hook function works pretty much the same way as read_dir(), with the 556difference that it doesn't read the entries of a directory, but the entries 557matching the given query. 558 559\param fs The volume handle. 560\param cookie The query cookie as returned by open_query(). 561\param buffer Pointer to a pre-allocated buffer the directory entries shall be 562 written to. 563\param bufferSize The size of \a buffer in bytes. 564\param _num Pointer to a pre-allocated variable, when invoked, containing the 565 number of entries to be read, and into which the number of entries 566 actually read shall be written. 567\return \c B_OK if everything went fine, another error code otherwise. 568*/ 569