* 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

View File

@ -139,9 +139,9 @@ class InodeAllocator {
~InodeAllocator();
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 Keep();
status_t Keep(fs_vnode_ops *vnodeOps, uint32 publishFlags);
private:
static void _TransactionListener(int32 id, int32 event, void *_inode);
@ -180,7 +180,7 @@ InodeAllocator::~InodeAllocator()
status_t
InodeAllocator::New(block_run *parentRun, mode_t mode, block_run &run,
Inode **_inode)
fs_vnode_ops *vnodeOps, Inode **_inode)
{
Volume *volume = fTransaction->GetVolume();
@ -200,7 +200,7 @@ InodeAllocator::New(block_run *parentRun, mode_t mode, block_run &run,
if (volume->ID() >= 0) {
status = new_vnode(volume->FSVolume(), fInode->ID(), fInode,
&gBFSVnodeOps);
vnodeOps != NULL ? vnodeOps : &gBFSVnodeOps);
if (status < B_OK) {
delete fInode;
fInode = NULL;
@ -237,7 +237,7 @@ InodeAllocator::CreateTree()
status_t
InodeAllocator::Keep()
InodeAllocator::Keep(fs_vnode_ops *vnodeOps, uint32 publishFlags)
{
ASSERT(fInode != NULL && fTransaction != NULL);
Volume *volume = fTransaction->GetVolume();
@ -250,7 +250,8 @@ InodeAllocator::Keep()
if (!fInode->IsSymLink() && volume->ID() >= 0) {
status = publish_vnode(volume->FSVolume(), fInode->ID(), fInode,
&gBFSVnodeOps, fInode->Mode(), 0);
vnodeOps != NULL ? vnodeOps : &gBFSVnodeOps, fInode->Mode(),
publishFlags);
}
if (status == B_OK) {
@ -2302,7 +2303,7 @@ Inode::Remove(Transaction &transaction, const char *name, ino_t *_id,
status_t
Inode::Create(Transaction &transaction, Inode *parent, const char *name,
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));
@ -2388,7 +2389,7 @@ Inode::Create(Transaction &transaction, Inode *parent, const char *name,
InodeAllocator allocator(transaction);
block_run run;
Inode *inode;
status = allocator.New(&parentRun, mode, run, &inode);
status = allocator.New(&parentRun, mode, run, vnodeOps, &inode);
if (status < B_OK)
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
// initialized inode, and we want to keep it
allocator.Keep();
allocator.Keep(vnodeOps, publishFlags);
if (inode->IsFile() || inode->IsAttribute()) {
inode->SetFileCache(file_cache_create(volume->ID(), inode->ID(),

View File

@ -50,12 +50,9 @@ class Inode {
status_t WriteBack(Transaction &transaction);
bool IsContainer() const
{ return Mode() & (S_DIRECTORY | S_INDEX_DIR | S_ATTR_DIR); }
// note, that this test will also be true for S_IFBLK
// (not that it's used in the fs :)
{ return (Mode() & (S_INDEX_DIR | S_ATTR_DIR)) || S_ISDIR(Mode()); }
bool IsDirectory() const
{ return (Mode() & (S_DIRECTORY | S_INDEX_DIR | S_ATTR_DIR))
== S_DIRECTORY; }
{ return S_ISDIR(Mode()); }
bool IsIndex() const
{ return (Mode() & (S_INDEX_DIR | 0777)) == S_INDEX_DIR; }
// that's a stupid check, but AFAIK the only possible method...
@ -141,7 +138,8 @@ class Inode {
ino_t *_id = NULL, bool isDirectory = false);
static status_t Create(Transaction &transaction, Inode *parent,
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
void UpdateOldSize()

View File

@ -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 -
// Index functions
@ -2224,7 +2271,10 @@ fs_vnode_ops gBFSVnodeOps = {
&bfs_read_attr_stat,
&bfs_write_attr_stat,
&bfs_rename_attr,
&bfs_remove_attr
&bfs_remove_attr,
/* special nodes */
&bfs_create_special_node
};
static file_system_module_info sBeFileSystem = {