From 4896a3735e1cf5209686f3c78c8ac5935206ce7f Mon Sep 17 00:00:00 2001 From: hyche Date: Tue, 29 Aug 2017 06:55:13 +0700 Subject: [PATCH] BTRFS: Implement btrfs_remove_dir that can remove directories in most case. We need to handle a case when node size is small reasonably it can be merged with another node or push data from other node to this node. Signed-off-by: Augustin Cavalier --- .../file_systems/btrfs/kernel_interface.cpp | 44 ++++++++++++++++++- 1 file changed, 43 insertions(+), 1 deletion(-) diff --git a/src/add-ons/kernel/file_systems/btrfs/kernel_interface.cpp b/src/add-ons/kernel/file_systems/btrfs/kernel_interface.cpp index c3f20cd787..ef56195a54 100644 --- a/src/add-ons/kernel/file_systems/btrfs/kernel_interface.cpp +++ b/src/add-ons/kernel/file_systems/btrfs/kernel_interface.cpp @@ -528,6 +528,48 @@ btrfs_create_dir(fs_volume* _volume, fs_vnode* _directory, const char* name, } +static status_t +btrfs_remove_dir(fs_volume* _volume, fs_vnode* _directory, const char* name) +{ + Volume* volume = (Volume*)_volume->private_volume; + Inode* directory = (Inode*)_directory->private_node; + + Transaction transaction(volume); + BTree::Path path(volume->FSTree()); + + ino_t id; + status_t status = DirectoryIterator(directory).Lookup(name, strlen(name), + &id); + if (status != B_OK) + return status; + + Inode inode(volume, id); + status = inode.InitCheck(); + if (status != B_OK) + return status; + + status = inode.Remove(transaction, &path); + if (status != B_OK) + return status; + status = inode.Dereference(transaction, &path, directory->ID(), name); + if (status != B_OK) + return status; + + entry_cache_remove(volume->ID(), directory->ID(), name); + entry_cache_remove(volume->ID(), id, ".."); + + status = transaction.Done(); + if (status == B_OK) + notify_entry_removed(volume->ID(), directory->ID(), name, id); + else { + entry_cache_add(volume->ID(), directory->ID(), name, id); + entry_cache_add(volume->ID(), id, "..", id); + } + + return status; +} + + static status_t btrfs_open_dir(fs_volume* /*_volume*/, fs_vnode* _node, void** _cookie) { @@ -861,7 +903,7 @@ fs_vnode_ops gBtrfsVnodeOps = { /* directory operations */ &btrfs_create_dir, - NULL, // fs_remove_dir, + &btrfs_remove_dir, &btrfs_open_dir, &btrfs_close_dir, &btrfs_free_dir_cookie,