* 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:
@@ -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(),
|
||||||
|
|||||||
@@ -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 = {
|
||||||
|
|||||||
Reference in New Issue
Block a user