From 4e98292b8ee6eabfff9fd01a39e0aaf9da9a1fba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Wed, 15 Apr 2009 16:14:04 +0000 Subject: [PATCH] * Introduced new call get_next_removed_vnode() to be able to iterate over removed but not yet deleted vnodes. * Simplified get_vnode_removed(). * Header cleanup. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@30176 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- headers/os/drivers/fs_interface.h | 376 +++++++++++++++--------------- src/system/kernel/fs/vfs.cpp | 81 +++++-- 2 files changed, 254 insertions(+), 203 deletions(-) diff --git a/headers/os/drivers/fs_interface.h b/headers/os/drivers/fs_interface.h index cb6bb91c4c..4df0c2ca9c 100644 --- a/headers/os/drivers/fs_interface.h +++ b/headers/os/drivers/fs_interface.h @@ -1,5 +1,5 @@ /* - * Copyright 2004-2008, Haiku Inc. All Rights Reserved. + * Copyright 2004-2009, Haiku Inc. All Rights Reserved. * Distributed under the terms of the MIT License. */ #ifndef _FS_INTERFACE_H @@ -73,173 +73,173 @@ struct fs_vnode { }; struct fs_volume_ops { - status_t (*unmount)(fs_volume *volume); + status_t (*unmount)(fs_volume* volume); - status_t (*read_fs_info)(fs_volume *volume, struct fs_info *info); - status_t (*write_fs_info)(fs_volume *volume, const struct fs_info *info, + status_t (*read_fs_info)(fs_volume* volume, struct fs_info* info); + status_t (*write_fs_info)(fs_volume* volume, const struct fs_info* info, uint32 mask); - status_t (*sync)(fs_volume *volume); + status_t (*sync)(fs_volume* volume); - status_t (*get_vnode)(fs_volume *volume, ino_t id, fs_vnode *vnode, - int *_type, uint32 *_flags, bool reenter); + status_t (*get_vnode)(fs_volume* volume, ino_t id, fs_vnode* vnode, + int* _type, uint32* _flags, bool reenter); /* index directory & index operations */ - status_t (*open_index_dir)(fs_volume *volume, void **cookie); - status_t (*close_index_dir)(fs_volume *volume, void *cookie); - status_t (*free_index_dir_cookie)(fs_volume *volume, void *cookie); - status_t (*read_index_dir)(fs_volume *volume, void *cookie, - struct dirent *buffer, size_t bufferSize, uint32 *_num); - status_t (*rewind_index_dir)(fs_volume *volume, void *cookie); + status_t (*open_index_dir)(fs_volume* volume, void** _cookie); + status_t (*close_index_dir)(fs_volume* volume, void* cookie); + status_t (*free_index_dir_cookie)(fs_volume* volume, void* cookie); + status_t (*read_index_dir)(fs_volume* volume, void* cookie, + struct dirent* buffer, size_t bufferSize, uint32* _num); + status_t (*rewind_index_dir)(fs_volume* volume, void* cookie); - status_t (*create_index)(fs_volume *volume, const char *name, uint32 type, + status_t (*create_index)(fs_volume* volume, const char* name, uint32 type, uint32 flags); - status_t (*remove_index)(fs_volume *volume, const char *name); - status_t (*read_index_stat)(fs_volume *volume, const char *name, - struct stat *stat); + status_t (*remove_index)(fs_volume* volume, const char* name); + status_t (*read_index_stat)(fs_volume* volume, const char* name, + struct stat* stat); /* query operations */ - status_t (*open_query)(fs_volume *volume, const char *query, uint32 flags, - port_id port, uint32 token, void **_cookie); - status_t (*close_query)(fs_volume *volume, void *cookie); - status_t (*free_query_cookie)(fs_volume *volume, void *cookie); - status_t (*read_query)(fs_volume *volume, void *cookie, - struct dirent *buffer, size_t bufferSize, uint32 *_num); - status_t (*rewind_query)(fs_volume *volume, void *cookie); + status_t (*open_query)(fs_volume* volume, const char* query, uint32 flags, + port_id port, uint32 token, void** _cookie); + status_t (*close_query)(fs_volume* volume, void* cookie); + status_t (*free_query_cookie)(fs_volume* volume, void* cookie); + status_t (*read_query)(fs_volume* volume, void* cookie, + struct dirent* buffer, size_t bufferSize, uint32* _num); + status_t (*rewind_query)(fs_volume* volume, void* cookie); /* support for FS layers */ - status_t (*all_layers_mounted)(fs_volume *volume); - status_t (*create_sub_vnode)(fs_volume *volume, ino_t id, fs_vnode *vnode); - status_t (*delete_sub_vnode)(fs_volume *volume, fs_vnode *vnode); + status_t (*all_layers_mounted)(fs_volume* volume); + status_t (*create_sub_vnode)(fs_volume* volume, ino_t id, fs_vnode* vnode); + status_t (*delete_sub_vnode)(fs_volume* volume, fs_vnode* vnode); }; struct fs_vnode_ops { /* vnode operations */ - status_t (*lookup)(fs_volume *volume, fs_vnode *dir, const char *name, - ino_t *_id); - status_t (*get_vnode_name)(fs_volume *volume, fs_vnode *vnode, char *buffer, + status_t (*lookup)(fs_volume* volume, fs_vnode* dir, const char* name, + ino_t* _id); + status_t (*get_vnode_name)(fs_volume* volume, fs_vnode* vnode, char* buffer, size_t bufferSize); - status_t (*put_vnode)(fs_volume *volume, fs_vnode *vnode, bool reenter); - status_t (*remove_vnode)(fs_volume *volume, fs_vnode *vnode, bool reenter); + status_t (*put_vnode)(fs_volume* volume, fs_vnode* vnode, bool reenter); + status_t (*remove_vnode)(fs_volume* volume, fs_vnode* vnode, bool reenter); /* VM file access */ - bool (*can_page)(fs_volume *volume, fs_vnode *vnode, void *cookie); - status_t (*read_pages)(fs_volume *volume, fs_vnode *vnode, void *cookie, - off_t pos, const iovec *vecs, size_t count, size_t *_numBytes); - status_t (*write_pages)(fs_volume *volume, fs_vnode *vnode, - void *cookie, off_t pos, const iovec *vecs, size_t count, - size_t *_numBytes); + bool (*can_page)(fs_volume* volume, fs_vnode* vnode, void* cookie); + status_t (*read_pages)(fs_volume* volume, fs_vnode* vnode, void* cookie, + off_t pos, const iovec* vecs, size_t count, size_t* _numBytes); + status_t (*write_pages)(fs_volume* volume, fs_vnode* vnode, + void* cookie, off_t pos, const iovec* vecs, size_t count, + size_t* _numBytes); /* asynchronous I/O */ - status_t (*io)(fs_volume *volume, fs_vnode *vnode, void *cookie, - io_request *request); - status_t (*cancel_io)(fs_volume *volume, fs_vnode *vnode, void *cookie, - io_request *request); + status_t (*io)(fs_volume* volume, fs_vnode* vnode, void* cookie, + io_request* request); + status_t (*cancel_io)(fs_volume* volume, fs_vnode* vnode, void* cookie, + io_request* request); /* cache file access */ - status_t (*get_file_map)(fs_volume *volume, fs_vnode *vnode, off_t offset, - size_t size, struct file_io_vec *vecs, size_t *_count); + status_t (*get_file_map)(fs_volume* volume, fs_vnode* vnode, off_t offset, + size_t size, struct file_io_vec* vecs, size_t* _count); /* common operations */ - status_t (*ioctl)(fs_volume *volume, fs_vnode *vnode, void *cookie, - ulong op, void *buffer, size_t length); - status_t (*set_flags)(fs_volume *volume, fs_vnode *vnode, void *cookie, + status_t (*ioctl)(fs_volume* volume, fs_vnode* vnode, void* cookie, + ulong op, void* buffer, size_t length); + status_t (*set_flags)(fs_volume* volume, fs_vnode* vnode, void* cookie, int flags); - status_t (*select)(fs_volume *volume, fs_vnode *vnode, void *cookie, - uint8 event, selectsync *sync); - status_t (*deselect)(fs_volume *volume, fs_vnode *vnode, void *cookie, - uint8 event, selectsync *sync); - status_t (*fsync)(fs_volume *volume, fs_vnode *vnode); + status_t (*select)(fs_volume* volume, fs_vnode* vnode, void* cookie, + uint8 event, selectsync* sync); + status_t (*deselect)(fs_volume* volume, fs_vnode* vnode, void* cookie, + uint8 event, selectsync* sync); + status_t (*fsync)(fs_volume* volume, fs_vnode* vnode); - status_t (*read_symlink)(fs_volume *volume, fs_vnode *link, char *buffer, - size_t *_bufferSize); - status_t (*create_symlink)(fs_volume *volume, fs_vnode *dir, - const char *name, const char *path, int mode); + status_t (*read_symlink)(fs_volume* volume, fs_vnode* link, char* buffer, + size_t* _bufferSize); + status_t (*create_symlink)(fs_volume* volume, fs_vnode* dir, + const char* name, const char* path, int mode); - status_t (*link)(fs_volume *volume, fs_vnode *dir, const char *name, - fs_vnode *vnode); - status_t (*unlink)(fs_volume *volume, fs_vnode *dir, const char *name); - status_t (*rename)(fs_volume *volume, fs_vnode *fromDir, - const char *fromName, fs_vnode *toDir, const char *toName); + status_t (*link)(fs_volume* volume, fs_vnode* dir, const char* name, + fs_vnode* vnode); + status_t (*unlink)(fs_volume* volume, fs_vnode* dir, const char* name); + status_t (*rename)(fs_volume* volume, fs_vnode* fromDir, + const char* fromName, fs_vnode* toDir, const char* toName); - status_t (*access)(fs_volume *volume, fs_vnode *vnode, int mode); - status_t (*read_stat)(fs_volume *volume, fs_vnode *vnode, - struct stat *stat); - status_t (*write_stat)(fs_volume *volume, fs_vnode *vnode, - const struct stat *stat, uint32 statMask); + status_t (*access)(fs_volume* volume, fs_vnode* vnode, int mode); + status_t (*read_stat)(fs_volume* volume, fs_vnode* vnode, + struct stat* stat); + status_t (*write_stat)(fs_volume* volume, fs_vnode* vnode, + const struct stat* stat, uint32 statMask); /* file operations */ - status_t (*create)(fs_volume *volume, fs_vnode *dir, const char *name, - int openMode, int perms, void **_cookie, - ino_t *_newVnodeID); - status_t (*open)(fs_volume *volume, fs_vnode *vnode, int openMode, - void **_cookie); - status_t (*close)(fs_volume *volume, fs_vnode *vnode, void *cookie); - status_t (*free_cookie)(fs_volume *volume, fs_vnode *vnode, - void *cookie); - status_t (*read)(fs_volume *volume, fs_vnode *vnode, void *cookie, - off_t pos, void *buffer, size_t *length); - status_t (*write)(fs_volume *volume, fs_vnode *vnode, void *cookie, - off_t pos, const void *buffer, size_t *length); + status_t (*create)(fs_volume* volume, fs_vnode* dir, const char* name, + int openMode, int perms, void** _cookie, + ino_t* _newVnodeID); + status_t (*open)(fs_volume* volume, fs_vnode* vnode, int openMode, + void** _cookie); + status_t (*close)(fs_volume* volume, fs_vnode* vnode, void* cookie); + status_t (*free_cookie)(fs_volume* volume, fs_vnode* vnode, + void* cookie); + status_t (*read)(fs_volume* volume, fs_vnode* vnode, void* cookie, + off_t pos, void* buffer, size_t* length); + status_t (*write)(fs_volume* volume, fs_vnode* vnode, void* cookie, + off_t pos, const void* buffer, size_t* length); /* directory operations */ - status_t (*create_dir)(fs_volume *volume, fs_vnode *parent, - const char *name, int perms); - status_t (*remove_dir)(fs_volume *volume, fs_vnode *parent, - const char *name); - status_t (*open_dir)(fs_volume *volume, fs_vnode *vnode, - void **_cookie); - status_t (*close_dir)(fs_volume *volume, fs_vnode *vnode, void *cookie); - status_t (*free_dir_cookie)(fs_volume *volume, fs_vnode *vnode, - void *cookie); - status_t (*read_dir)(fs_volume *volume, fs_vnode *vnode, void *cookie, - struct dirent *buffer, size_t bufferSize, uint32 *_num); - status_t (*rewind_dir)(fs_volume *volume, fs_vnode *vnode, - void *cookie); + status_t (*create_dir)(fs_volume* volume, fs_vnode* parent, + const char* name, int perms); + status_t (*remove_dir)(fs_volume* volume, fs_vnode* parent, + const char* name); + status_t (*open_dir)(fs_volume* volume, fs_vnode* vnode, + void** _cookie); + status_t (*close_dir)(fs_volume* volume, fs_vnode* vnode, void* cookie); + status_t (*free_dir_cookie)(fs_volume* volume, fs_vnode* vnode, + void* cookie); + status_t (*read_dir)(fs_volume* volume, fs_vnode* vnode, void* cookie, + struct dirent* buffer, size_t bufferSize, uint32* _num); + status_t (*rewind_dir)(fs_volume* volume, fs_vnode* vnode, + void* cookie); /* attribute directory operations */ - status_t (*open_attr_dir)(fs_volume *volume, fs_vnode *vnode, - void **_cookie); - status_t (*close_attr_dir)(fs_volume *volume, fs_vnode *vnode, - void *cookie); - status_t (*free_attr_dir_cookie)(fs_volume *volume, fs_vnode *vnode, - void *cookie); - status_t (*read_attr_dir)(fs_volume *volume, fs_vnode *vnode, - void *cookie, struct dirent *buffer, size_t bufferSize, - uint32 *_num); - status_t (*rewind_attr_dir)(fs_volume *volume, fs_vnode *vnode, - void *cookie); + status_t (*open_attr_dir)(fs_volume* volume, fs_vnode* vnode, + void** _cookie); + status_t (*close_attr_dir)(fs_volume* volume, fs_vnode* vnode, + void* cookie); + status_t (*free_attr_dir_cookie)(fs_volume* volume, fs_vnode* vnode, + void* cookie); + status_t (*read_attr_dir)(fs_volume* volume, fs_vnode* vnode, + void* cookie, struct dirent* buffer, size_t bufferSize, + uint32* _num); + status_t (*rewind_attr_dir)(fs_volume* volume, fs_vnode* vnode, + void* cookie); /* attribute operations */ - status_t (*create_attr)(fs_volume *volume, fs_vnode *vnode, - const char *name, uint32 type, int openMode, - void **_cookie); - status_t (*open_attr)(fs_volume *volume, fs_vnode *vnode, const char *name, - int openMode, void **_cookie); - status_t (*close_attr)(fs_volume *volume, fs_vnode *vnode, - void *cookie); - status_t (*free_attr_cookie)(fs_volume *volume, fs_vnode *vnode, - void *cookie); - status_t (*read_attr)(fs_volume *volume, fs_vnode *vnode, void *cookie, - off_t pos, void *buffer, size_t *length); - status_t (*write_attr)(fs_volume *volume, fs_vnode *vnode, void *cookie, - off_t pos, const void *buffer, size_t *length); + status_t (*create_attr)(fs_volume* volume, fs_vnode* vnode, + const char* name, uint32 type, int openMode, + void** _cookie); + status_t (*open_attr)(fs_volume* volume, fs_vnode* vnode, const char* name, + int openMode, void** _cookie); + status_t (*close_attr)(fs_volume* volume, fs_vnode* vnode, + void* cookie); + status_t (*free_attr_cookie)(fs_volume* volume, fs_vnode* vnode, + void* cookie); + status_t (*read_attr)(fs_volume* volume, fs_vnode* vnode, void* cookie, + off_t pos, void* buffer, size_t* length); + status_t (*write_attr)(fs_volume* volume, fs_vnode* vnode, void* cookie, + off_t pos, const void* buffer, size_t* length); - status_t (*read_attr_stat)(fs_volume *volume, fs_vnode *vnode, - void *cookie, struct stat *stat); - status_t (*write_attr_stat)(fs_volume *volume, fs_vnode *vnode, - void *cookie, const struct stat *stat, int statMask); - status_t (*rename_attr)(fs_volume *volume, fs_vnode *fromVnode, - const char *fromName, fs_vnode *toVnode, const char *toName); - status_t (*remove_attr)(fs_volume *volume, fs_vnode *vnode, - const char *name); + status_t (*read_attr_stat)(fs_volume* volume, fs_vnode* vnode, + void* cookie, struct stat* stat); + status_t (*write_attr_stat)(fs_volume* volume, fs_vnode* vnode, + void* cookie, const struct stat* stat, int statMask); + status_t (*rename_attr)(fs_volume* volume, fs_vnode* fromVnode, + const char* fromName, fs_vnode* toVnode, const char* toName); + status_t (*remove_attr)(fs_volume* volume, fs_vnode* vnode, + const char* name); /* support for node and FS layers */ - status_t (*create_special_node)(fs_volume *volume, fs_vnode *dir, - const char *name, fs_vnode *subVnode, mode_t mode, uint32 flags, - fs_vnode *_superVnode, ino_t *_nodeID); - status_t (*get_super_vnode)(fs_volume *volume, fs_vnode *vnode, - fs_volume *superVolume, fs_vnode *superVnode); + status_t (*create_special_node)(fs_volume* volume, fs_vnode* dir, + const char* name, fs_vnode* subVnode, mode_t mode, uint32 flags, + fs_vnode* _superVnode, ino_t* _nodeID); + status_t (*get_super_vnode)(fs_volume* volume, fs_vnode* vnode, + fs_volume* superVolume, fs_vnode* superVnode); }; struct file_system_module_info { @@ -249,33 +249,33 @@ struct file_system_module_info { uint32 flags; // DDM flags /* scanning (the device is write locked) */ - float (*identify_partition)(int fd, partition_data *partition, - void **cookie); - status_t (*scan_partition)(int fd, partition_data *partition, - void *cookie); - void (*free_identify_partition_cookie)(partition_data *partition, - void *cookie); - void (*free_partition_content_cookie)(partition_data *partition); + float (*identify_partition)(int fd, partition_data* partition, + void** _cookie); + status_t (*scan_partition)(int fd, partition_data* partition, + void* cookie); + void (*free_identify_partition_cookie)(partition_data* partition, + void* cookie); + void (*free_partition_content_cookie)(partition_data* partition); /* general operations */ - status_t (*mount)(fs_volume *volume, const char *device, uint32 flags, - const char *args, ino_t *_rootVnodeID); + status_t (*mount)(fs_volume* volume, const char* device, uint32 flags, + const char* args, ino_t* _rootVnodeID); /* capability querying (the device is read locked) */ uint32 (*get_supported_operations)(partition_data* partition, uint32 mask); - bool (*validate_resize)(partition_data *partition, off_t *size); - bool (*validate_move)(partition_data *partition, off_t *start); - bool (*validate_set_content_name)(partition_data *partition, - char *name); - bool (*validate_set_content_parameters)(partition_data *partition, - const char *parameters); - bool (*validate_initialize)(partition_data *partition, char *name, - const char *parameters); + bool (*validate_resize)(partition_data* partition, off_t* size); + bool (*validate_move)(partition_data* partition, off_t* start); + bool (*validate_set_content_name)(partition_data* partition, + char* name); + bool (*validate_set_content_parameters)(partition_data* partition, + const char* parameters); + bool (*validate_initialize)(partition_data* partition, char* name, + const char* parameters); /* shadow partition modification (device is write locked) */ - status_t (*shadow_changed)(partition_data *partition, - partition_data *child, uint32 operation); + status_t (*shadow_changed)(partition_data* partition, + partition_data* child, uint32 operation); /* writing (the device is NOT locked) */ status_t (*defragment)(int fd, partition_id partition, @@ -287,72 +287,74 @@ struct file_system_module_info { status_t (*move)(int fd, partition_id partition, off_t offset, disk_job_id job); status_t (*set_content_name)(int fd, partition_id partition, - const char *name, disk_job_id job); + const char* name, disk_job_id job); status_t (*set_content_parameters)(int fd, partition_id partition, - const char *parameters, disk_job_id job); - status_t (*initialize)(int fd, partition_id partition, const char *name, - const char *parameters, off_t partitionSize, disk_job_id job); + const char* parameters, disk_job_id job); + status_t (*initialize)(int fd, partition_id partition, const char* name, + const char* parameters, off_t partitionSize, disk_job_id job); }; /* file system add-ons only prototypes */ // callbacks for do_iterative_fd_io() -typedef status_t (*iterative_io_get_vecs)(void *cookie, io_request* request, - off_t offset, size_t size, struct file_io_vec *vecs, - size_t *_count); +typedef status_t (*iterative_io_get_vecs)(void* cookie, io_request* request, + off_t offset, size_t size, struct file_io_vec* vecs, + size_t* _count); typedef status_t (*iterative_io_finished)(void* cookie, io_request* request, status_t status, bool partialTransfer, size_t bytesTransferred); -extern status_t new_vnode(fs_volume *volume, ino_t vnodeID, void *privateNode, - fs_vnode_ops *ops); -extern status_t publish_vnode(fs_volume *volume, ino_t vnodeID, - void *privateNode, fs_vnode_ops *ops, int type, +extern status_t new_vnode(fs_volume* volume, ino_t vnodeID, void* privateNode, + fs_vnode_ops* ops); +extern status_t publish_vnode(fs_volume* volume, ino_t vnodeID, + void* privateNode, fs_vnode_ops* ops, int type, uint32 flags); -extern status_t get_vnode(fs_volume *volume, ino_t vnodeID, - void **_privateNode); -extern status_t put_vnode(fs_volume *volume, ino_t vnodeID); -extern status_t acquire_vnode(fs_volume *volume, ino_t vnodeID); -extern status_t remove_vnode(fs_volume *volume, ino_t vnodeID); -extern status_t unremove_vnode(fs_volume *volume, ino_t vnodeID); -extern status_t get_vnode_removed(fs_volume *volume, ino_t vnodeID, - bool *removed); -extern fs_volume* volume_for_vnode(fs_vnode *vnode); +extern status_t get_vnode(fs_volume* volume, ino_t vnodeID, + void** _privateNode); +extern status_t put_vnode(fs_volume* volume, ino_t vnodeID); +extern status_t acquire_vnode(fs_volume* volume, ino_t vnodeID); +extern status_t remove_vnode(fs_volume* volume, ino_t vnodeID); +extern status_t unremove_vnode(fs_volume* volume, ino_t vnodeID); +extern status_t get_vnode_removed(fs_volume* volume, ino_t vnodeID, + bool* _removed); +extern status_t get_next_removed_vnode(fs_volume* volume, ino_t* _vnodeID, + void** _privateNode); +extern fs_volume* volume_for_vnode(fs_vnode* vnode); -extern status_t read_pages(int fd, off_t pos, const struct iovec *vecs, - size_t count, size_t *_numBytes); -extern status_t write_pages(int fd, off_t pos, const struct iovec *vecs, - size_t count, size_t *_numBytes); +extern status_t read_pages(int fd, off_t pos, const struct iovec* vecs, + size_t count, size_t* _numBytes); +extern status_t write_pages(int fd, off_t pos, const struct iovec* vecs, + size_t count, size_t* _numBytes); extern status_t read_file_io_vec_pages(int fd, - const struct file_io_vec *fileVecs, size_t fileVecCount, - const struct iovec *vecs, size_t vecCount, - uint32 *_vecIndex, size_t *_vecOffset, size_t *_bytes); + const struct file_io_vec* fileVecs, size_t fileVecCount, + const struct iovec* vecs, size_t vecCount, + uint32* _vecIndex, size_t* _vecOffset, size_t* _bytes); extern status_t write_file_io_vec_pages(int fd, - const struct file_io_vec *fileVecs, size_t fileVecCount, - const struct iovec *vecs, size_t vecCount, - uint32 *_vecIndex, size_t *_vecOffset, size_t *_bytes); -extern status_t do_fd_io(int fd, io_request *request); -extern status_t do_iterative_fd_io(int fd, io_request *request, + const struct file_io_vec* fileVecs, size_t fileVecCount, + const struct iovec* vecs, size_t vecCount, + uint32* _vecIndex, size_t* _vecOffset, size_t* _bytes); +extern status_t do_fd_io(int fd, io_request* request); +extern status_t do_iterative_fd_io(int fd, io_request* request, iterative_io_get_vecs getVecs, - iterative_io_finished finished, void *cookie); + iterative_io_finished finished, void* cookie); extern status_t notify_entry_created(dev_t device, ino_t directory, - const char *name, ino_t node); + const char* name, ino_t node); extern status_t notify_entry_removed(dev_t device, ino_t directory, - const char *name, ino_t node); + const char* name, ino_t node); extern status_t notify_entry_moved(dev_t device, ino_t fromDirectory, - const char *fromName, ino_t toDirectory, - const char *toName, ino_t node); + const char* fromName, ino_t toDirectory, + const char* toName, ino_t node); extern status_t notify_stat_changed(dev_t device, ino_t node, uint32 statFields); extern status_t notify_attribute_changed(dev_t device, ino_t node, - const char *attribute, int32 cause); + const char* attribute, int32 cause); extern status_t notify_query_entry_created(port_id port, int32 token, - dev_t device, ino_t directory, const char *name, + dev_t device, ino_t directory, const char* name, ino_t node); extern status_t notify_query_entry_removed(port_id port, int32 token, - dev_t device, ino_t directory, const char *name, + dev_t device, ino_t directory, const char* name, ino_t node); #ifdef __cplusplus diff --git a/src/system/kernel/fs/vfs.cpp b/src/system/kernel/fs/vfs.cpp index a88500aa6a..e1a65ac495 100644 --- a/src/system/kernel/fs/vfs.cpp +++ b/src/system/kernel/fs/vfs.cpp @@ -3539,10 +3539,6 @@ new_vnode(fs_volume* volume, ino_t vnodeID, void* privateNode, // file system integrity check: // test if the vnode already exists and bail out if this is the case! - - // ToDo: the R5 implementation obviously checks for a different cookie - // and doesn't panic if they are equal - struct vnode* vnode = lookup_vnode(volume->id, vnodeID); if (vnode != NULL) { panic("vnode %ld:%Ld already exists (node = %p, vnode->node = %p)!", @@ -3653,7 +3649,7 @@ get_vnode(fs_volume* volume, ino_t vnodeID, void** _privateNode) return B_BAD_VALUE; status_t status = get_vnode(volume->id, vnodeID, &vnode, true, true); - if (status < B_OK) + if (status != B_OK) return status; // If this is a layered FS, we need to get the node cookie for the requested @@ -3764,21 +3760,74 @@ unremove_vnode(fs_volume* volume, ino_t vnodeID) extern "C" status_t -get_vnode_removed(fs_volume* volume, ino_t vnodeID, bool* removed) +get_vnode_removed(fs_volume* volume, ino_t vnodeID, bool* _removed) { - mutex_lock(&sVnodeMutex); - - status_t result; + MutexLocker _(sVnodeMutex); if (struct vnode* vnode = lookup_vnode(volume->id, vnodeID)) { - if (removed) - *removed = vnode->remove; - result = B_OK; - } else - result = B_BAD_VALUE; + if (_removed != NULL) + *_removed = vnode->remove; + return B_OK; + } - mutex_unlock(&sVnodeMutex); - return result; + return B_BAD_VALUE; +} + + +/*! Iterates over all removed vnodes of the volume. You own a reference to the + vnode when this call returns; you must initialize *_parentNode with NULL when + calling this function the first time, subsequent calls will automatically + put the previous reference again. +*/ +extern "C" status_t +get_next_removed_vnode(fs_volume* volume, ino_t* _vnodeID, void** _privateNode) +{ + fs_mount* mount; + status_t status = get_mount(volume->id, &mount); + if (status != B_OK) + return status; + + // Retrieve the previous vnode + + struct vnode* vnode = NULL; + + if (*_privateNode != NULL) { + MutexLocker _(sVnodeMutex); + vnode = lookup_vnode(volume->id, *_vnodeID); + // we already have a reference, so this vnode won't get away + } + + // Determine the ID of the next one + + RecursiveLocker locker(mount->rlock); + + struct vnode* nextVnode; + if (vnode == NULL) + nextVnode = mount->vnodes.First(); + else { + nextVnode = mount->vnodes.GetNext(vnode); + dec_vnode_ref_count(vnode, false, true); + } + + while (nextVnode != NULL && !nextVnode->remove) { + nextVnode = mount->vnodes.GetNext(nextVnode); + } + + if (nextVnode == NULL) + return B_ENTRY_NOT_FOUND; + + *_vnodeID = nextVnode->id; + + locker.Unlock(); + + // Try to retrieve the vnode by ID, and return it's private node on success + + status = get_vnode(volume->id, *_vnodeID, &vnode, true, true); + if (status != B_OK) + return status; + + *_privateNode = vnode->private_node; + return B_OK; }