* Allow passing sub vnode ops and publish flags to Inode::Create().

* Implemented create_special_node() hook.
* Fixed Inode::IsContainer()/IsDirectory().


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@25140 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Ingo Weinhold
2008-04-25 01:04:48 +00:00
parent 0951fcb4a3
commit d11e733fee
3 changed files with 65 additions and 16 deletions
+10 -9
View File
@@ -139,9 +139,9 @@ class InodeAllocator {
~InodeAllocator(); ~InodeAllocator();
status_t New(block_run *parentRun, mode_t mode, block_run &run, status_t New(block_run *parentRun, mode_t mode, block_run &run,
Inode **_inode); fs_vnode_ops *vnodeOps, Inode **_inode);
status_t CreateTree(); status_t CreateTree();
status_t Keep(); status_t Keep(fs_vnode_ops *vnodeOps, uint32 publishFlags);
private: private:
static void _TransactionListener(int32 id, int32 event, void *_inode); static void _TransactionListener(int32 id, int32 event, void *_inode);
@@ -180,7 +180,7 @@ InodeAllocator::~InodeAllocator()
status_t status_t
InodeAllocator::New(block_run *parentRun, mode_t mode, block_run &run, InodeAllocator::New(block_run *parentRun, mode_t mode, block_run &run,
Inode **_inode) fs_vnode_ops *vnodeOps, Inode **_inode)
{ {
Volume *volume = fTransaction->GetVolume(); Volume *volume = fTransaction->GetVolume();
@@ -200,7 +200,7 @@ InodeAllocator::New(block_run *parentRun, mode_t mode, block_run &run,
if (volume->ID() >= 0) { if (volume->ID() >= 0) {
status = new_vnode(volume->FSVolume(), fInode->ID(), fInode, status = new_vnode(volume->FSVolume(), fInode->ID(), fInode,
&gBFSVnodeOps); vnodeOps != NULL ? vnodeOps : &gBFSVnodeOps);
if (status < B_OK) { if (status < B_OK) {
delete fInode; delete fInode;
fInode = NULL; fInode = NULL;
@@ -237,7 +237,7 @@ InodeAllocator::CreateTree()
status_t status_t
InodeAllocator::Keep() InodeAllocator::Keep(fs_vnode_ops *vnodeOps, uint32 publishFlags)
{ {
ASSERT(fInode != NULL && fTransaction != NULL); ASSERT(fInode != NULL && fTransaction != NULL);
Volume *volume = fTransaction->GetVolume(); Volume *volume = fTransaction->GetVolume();
@@ -250,7 +250,8 @@ InodeAllocator::Keep()
if (!fInode->IsSymLink() && volume->ID() >= 0) { if (!fInode->IsSymLink() && volume->ID() >= 0) {
status = publish_vnode(volume->FSVolume(), fInode->ID(), fInode, status = publish_vnode(volume->FSVolume(), fInode->ID(), fInode,
&gBFSVnodeOps, fInode->Mode(), 0); vnodeOps != NULL ? vnodeOps : &gBFSVnodeOps, fInode->Mode(),
publishFlags);
} }
if (status == B_OK) { if (status == B_OK) {
@@ -2302,7 +2303,7 @@ Inode::Remove(Transaction &transaction, const char *name, ino_t *_id,
status_t status_t
Inode::Create(Transaction &transaction, Inode *parent, const char *name, Inode::Create(Transaction &transaction, Inode *parent, const char *name,
int32 mode, int openMode, uint32 type, bool *_created, ino_t *_id, int32 mode, int openMode, uint32 type, bool *_created, ino_t *_id,
Inode **_inode) Inode **_inode, fs_vnode_ops *vnodeOps, uint32 publishFlags)
{ {
FUNCTION_START(("name = %s, mode = %ld\n", name, mode)); FUNCTION_START(("name = %s, mode = %ld\n", name, mode));
@@ -2388,7 +2389,7 @@ Inode::Create(Transaction &transaction, Inode *parent, const char *name,
InodeAllocator allocator(transaction); InodeAllocator allocator(transaction);
block_run run; block_run run;
Inode *inode; Inode *inode;
status = allocator.New(&parentRun, mode, run, &inode); status = allocator.New(&parentRun, mode, run, vnodeOps, &inode);
if (status < B_OK) if (status < B_OK)
return status; return status;
@@ -2481,7 +2482,7 @@ Inode::Create(Transaction &transaction, Inode *parent, const char *name,
// Everything worked well until this point, we have a fully // Everything worked well until this point, we have a fully
// initialized inode, and we want to keep it // initialized inode, and we want to keep it
allocator.Keep(); allocator.Keep(vnodeOps, publishFlags);
if (inode->IsFile() || inode->IsAttribute()) { if (inode->IsFile() || inode->IsAttribute()) {
inode->SetFileCache(file_cache_create(volume->ID(), inode->ID(), inode->SetFileCache(file_cache_create(volume->ID(), inode->ID(),
+4 -6
View File
@@ -50,12 +50,9 @@ class Inode {
status_t WriteBack(Transaction &transaction); status_t WriteBack(Transaction &transaction);
bool IsContainer() const bool IsContainer() const
{ return Mode() & (S_DIRECTORY | S_INDEX_DIR | S_ATTR_DIR); } { return (Mode() & (S_INDEX_DIR | S_ATTR_DIR)) || S_ISDIR(Mode()); }
// note, that this test will also be true for S_IFBLK
// (not that it's used in the fs :)
bool IsDirectory() const bool IsDirectory() const
{ return (Mode() & (S_DIRECTORY | S_INDEX_DIR | S_ATTR_DIR)) { return S_ISDIR(Mode()); }
== S_DIRECTORY; }
bool IsIndex() const bool IsIndex() const
{ return (Mode() & (S_INDEX_DIR | 0777)) == S_INDEX_DIR; } { return (Mode() & (S_INDEX_DIR | 0777)) == S_INDEX_DIR; }
// that's a stupid check, but AFAIK the only possible method... // that's a stupid check, but AFAIK the only possible method...
@@ -141,7 +138,8 @@ class Inode {
ino_t *_id = NULL, bool isDirectory = false); ino_t *_id = NULL, bool isDirectory = false);
static status_t Create(Transaction &transaction, Inode *parent, static status_t Create(Transaction &transaction, Inode *parent,
const char *name, int32 mode, int openMode, uint32 type, const char *name, int32 mode, int openMode, uint32 type,
bool *_created = NULL, ino_t *_id = NULL, Inode **_inode = NULL); bool *_created = NULL, ino_t *_id = NULL, Inode **_inode = NULL,
fs_vnode_ops *vnodeOps = NULL, uint32 publishFlags = 0);
// index maintaining helper // index maintaining helper
void UpdateOldSize() void UpdateOldSize()
@@ -1770,6 +1770,53 @@ bfs_remove_attr(fs_volume *_volume, fs_vnode *_node, const char *name)
} }
// #pragma mark - Special Nodes
status_t
bfs_create_special_node(fs_volume *_volume, fs_vnode *_directory,
const char *name, fs_vnode *subVnode, mode_t mode, uint32 flags,
fs_vnode *_superVnode, ino_t *_nodeID)
{
// no need to support entry-less nodes
if (name == NULL)
return B_UNSUPPORTED;
FUNCTION_START(("name = \"%s\", mode = %d, flags = 0x%lx, subVnode: %p\n",
name, mode, flags, subVnode));
Volume *volume = (Volume *)_volume->private_volume;
Inode *directory = (Inode *)_directory->private_node;
if (volume->IsReadOnly())
return B_READ_ONLY_DEVICE;
if (!directory->IsDirectory())
RETURN_ERROR(B_BAD_TYPE);
status_t status = directory->CheckPermissions(W_OK);
if (status < B_OK)
RETURN_ERROR(status);
Transaction transaction(volume, directory->BlockNumber());
off_t id;
Inode *inode;
status = Inode::Create(transaction, directory, name, mode, O_EXCL, 0, NULL,
&id, &inode, subVnode ? subVnode->ops : NULL, flags);
if (status == B_OK) {
_superVnode->private_node = inode;
_superVnode->ops = &gBFSVnodeOps;
*_nodeID = id;
transaction.Done();
notify_entry_created(volume->ID(), directory->ID(), name, id);
}
return status;
}
// #pragma mark - // #pragma mark -
// Index functions // Index functions
@@ -2224,7 +2271,10 @@ fs_vnode_ops gBFSVnodeOps = {
&bfs_read_attr_stat, &bfs_read_attr_stat,
&bfs_write_attr_stat, &bfs_write_attr_stat,
&bfs_rename_attr, &bfs_rename_attr,
&bfs_remove_attr &bfs_remove_attr,
/* special nodes */
&bfs_create_special_node
}; };
static file_system_module_info sBeFileSystem = { static file_system_module_info sBeFileSystem = {