* Inode::Create() now has a "_created" parameter that will be set to true in case a

node has been created - this is now used in bfs_create() to suppress the new entry
  notification in case the file already existed.
* Implemented parameter parsing in bfs_initialize() - does not work in the new bfs_shell
  though, as it currently misses driver_settings functionality.
* Attribute::Create() and Attribute::Open() will now honour O_TRUNC correctly.
* Note: Inode::WriteAttribute() still follows R5 semantics for small_data attributes
  in this regard and must be fixed (I've opened ticket #1242 for this).
* Some cleanup.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@21204 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler 2007-05-22 13:19:44 +00:00
parent 261fd618fe
commit 065e318429
7 changed files with 204 additions and 165 deletions

View File

@ -1,9 +1,10 @@
/* Attribute - connection between pure inode and kernel_interface attributes
*
* Copyright 2004, Axel Dörfler, axeld@pinc-software.de.
/*
* Copyright 2004-2007, Axel Dörfler, axeld@pinc-software.de.
* This file may be used under the terms of the MIT License.
*/
//! connection between pure inode and kernel_interface attributes
#include "Attribute.h"
@ -128,6 +129,11 @@ Attribute::Create(const char *name, type_code type, int openMode, attr_cookie **
cookie->open_mode = openMode;
cookie->create = true;
if (Get(name) == B_OK) {
// attribute already exists
if ((openMode & O_TRUNC) != 0)
_Truncate();
}
*_cookie = cookie;
return B_OK;
}
@ -154,9 +160,8 @@ Attribute::Open(const char *name, int openMode, attr_cookie **_cookie)
cookie->create = false;
// Should we truncate the attribute?
if (openMode & O_TRUNC) {
// ToDo!
}
if ((openMode & O_TRUNC) != 0)
_Truncate();
*_cookie = cookie;
return B_OK;
@ -206,3 +211,30 @@ Attribute::Write(Transaction &transaction, attr_cookie *cookie,
pos, buffer, _length);
}
status_t
Attribute::_Truncate()
{
if (fSmall != NULL) {
// TODO: as long as Inode::_AddSmallData() works like it does,
// we've got nothing to do here
return B_OK;
}
if (fAttribute != NULL) {
WriteLocked locked(fAttribute->Lock());
Transaction transaction(fAttribute->GetVolume(), fAttribute->BlockNumber());
status_t status = fAttribute->SetFileSize(transaction, 0);
if (status >= B_OK)
status = fAttribute->WriteBack(transaction);
if (status < B_OK)
return status;
transaction.Done();
}
return B_OK;
}

View File

@ -30,7 +30,8 @@ class Attribute {
status_t Get(const char *name);
void Put();
status_t Create(const char *name, type_code type, int openMode, attr_cookie **_cookie);
status_t Create(const char *name, type_code type, int openMode,
attr_cookie **_cookie);
status_t Open(const char *name, int openMode, attr_cookie **_cookie);
status_t Stat(struct stat &stat);
@ -40,6 +41,8 @@ class Attribute {
off_t pos, const uint8 *buffer, size_t *_length);
private:
status_t _Truncate();
NodeGetter fNodeGetter;
Inode *fInode;
small_data *fSmall;

View File

@ -209,7 +209,7 @@ Index::Create(Transaction &transaction, const char *name, uint32 type)
// Inode::Create() will keep the inode locked for us
return Inode::Create(transaction, fVolume->IndicesNode(), name,
S_INDEX_DIR | S_DIRECTORY | mode, 0, type, NULL, &fNode);
S_INDEX_DIR | S_DIRECTORY | mode, 0, type, NULL, NULL, &fNode);
}

View File

@ -498,6 +498,7 @@ status_t
Inode::_AddSmallData(Transaction &transaction, NodeGetter &nodeGetter,
const char *name, uint32 type, const uint8 *data, size_t length, bool force)
{
// TODO: support new write attr semantics and write offset!
bfs_inode *node = nodeGetter.WritableNode();
if (node == NULL || name == NULL || data == NULL)
@ -1047,7 +1048,7 @@ Inode::CreateAttribute(Transaction &transaction, const char *name, uint32 type,
// Inode::Create() locks the inode for us
return Inode::Create(transaction, attributes, name,
S_ATTR | S_FILE | 0666, 0, type, NULL, attribute);
S_ATTR | S_FILE | 0666, 0, type, NULL, NULL, attribute);
}
@ -2122,7 +2123,7 @@ Inode::Sync()
status_t
Inode::Remove(Transaction &transaction, const char *name, off_t *_id,
Inode::Remove(Transaction &transaction, const char *name, vnode_id *_id,
bool isDirectory)
{
BPlusTree *tree;
@ -2205,18 +2206,22 @@ Inode::Remove(Transaction &transaction, const char *name, off_t *_id,
/*!
Creates the inode with the specified parent directory, and automatically
adds the created inode to that parent directory. If an attribute directory
is created, it will also automatically added to the parent inode as such.
However, the indices root node, and the regular root node won't be added
to the super block.
is created, it will also automatically be added to the parent inode as
such. However, the indices root node, and the regular root node won't be
added to the super block.
It will also create the initial B+tree for the inode if it's a directory
of any kind.
If the "_id" or "_inode" variable is given and non-NULL to store the inode's
ID, the inode stays locked - you have to call put_vnode() if you don't use it
anymore.
If the "_id" or "_inode" variable is given and non-NULL to store the
inode's ID, the inode stays locked - you have to call put_vnode() if you
don't use it anymore.
If the node already exists, this method will fail if O_EXCL is set, or it's
a directory or a symlink. Otherwise, it will just be returned. If O_TRUNC
has been specified, the file will also be truncated.
*/
status_t
Inode::Create(Transaction &transaction, Inode *parent, const char *name,
int32 mode, int openMode, uint32 type, off_t *_id, Inode **_inode)
int32 mode, int openMode, uint32 type, bool *_created, vnode_id *_id,
Inode **_inode)
{
FUNCTION_START(("name = %s, mode = %ld\n", name, mode));
@ -2274,8 +2279,10 @@ Inode::Create(Transaction &transaction, Inode *parent, const char *name,
return status;
}
if (_created)
*_created = false;
if (_id)
*_id = offset;
*_id = inode->ID();
if (_inode)
*_inode = inode;
@ -2395,6 +2402,8 @@ Inode::Create(Transaction &transaction, Inode *parent, const char *name,
inode->Size(), volume->Device()));
}
if (_created)
*_created = true;
if (_id != NULL)
*_id = inode->ID();
if (_inode != NULL)

View File

@ -8,10 +8,6 @@
#include "system_dependencies.h"
#ifndef _IMPEXP_KERNEL
# define _IMPEXP_KERNEL
#endif
#include "Volume.h"
#include "Journal.h"
#include "Lock.h"
@ -40,7 +36,8 @@ enum inode_type {
class Inode {
public:
Inode(Volume *volume, vnode_id id);
Inode(Volume *volume, Transaction &transaction, vnode_id id, mode_t mode, block_run &run);
Inode(Volume *volume, Transaction &transaction, vnode_id id,
mode_t mode, block_run &run);
//Inode(CachedBlock *cached);
~Inode();
@ -52,17 +49,27 @@ class Inode {
SimpleLock &SmallDataLock() { return fSmallDataLock; }
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 :)
bool IsDirectory() const { return (Mode() & (S_DIRECTORY | S_INDEX_DIR | S_ATTR_DIR)) == S_DIRECTORY; }
bool IsIndex() const { return (Mode() & (S_INDEX_DIR | 0777)) == S_INDEX_DIR; }
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 :)
bool IsDirectory() const
{ return (Mode() & (S_DIRECTORY | S_INDEX_DIR | S_ATTR_DIR))
== S_DIRECTORY; }
bool IsIndex() const
{ return (Mode() & (S_INDEX_DIR | 0777)) == S_INDEX_DIR; }
// that's a stupid check, but AFAIK the only possible method...
bool IsAttributeDirectory() const { return (Mode() & S_ATTR_DIR) != 0; }
bool IsAttribute() const { return (Mode() & S_ATTR) != 0; }
bool IsFile() const { return (Mode() & (S_IFMT | S_ATTR)) == S_FILE; }
bool IsRegularNode() const { return (Mode() & (S_ATTR_DIR | S_INDEX_DIR | S_ATTR)) == 0; }
// a regular node in the standard namespace (i.e. not an index or attribute)
bool IsAttributeDirectory() const
{ return (Mode() & S_ATTR_DIR) != 0; }
bool IsAttribute() const
{ return (Mode() & S_ATTR) != 0; }
bool IsFile() const
{ return (Mode() & (S_IFMT | S_ATTR)) == S_FILE; }
bool IsRegularNode() const
{ return (Mode() & (S_ATTR_DIR | S_INDEX_DIR | S_ATTR)) == 0; }
// a regular node in the standard namespace
// (i.e. not an index or attribute)
bool IsSymLink() const { return S_ISLNK(Mode()); }
bool HasUserAccessableStream() const { return IsFile(); }
// currently only files can be accessed with bfs_read()/bfs_write()
@ -87,30 +94,36 @@ class Inode {
status_t CheckPermissions(int accessMode) const;
// small_data access methods
small_data *FindSmallData(const bfs_inode *node, const char *name) const;
small_data *FindSmallData(const bfs_inode *node,
const char *name) const;
const char *Name(const bfs_inode *node) const;
status_t GetName(char *buffer, size_t bufferSize = B_FILE_NAME_LENGTH) const;
status_t GetName(char *buffer,
size_t bufferSize = B_FILE_NAME_LENGTH) const;
status_t SetName(Transaction &transaction, const char *name);
// high-level attribute methods
status_t ReadAttribute(const char *name, int32 type, off_t pos, uint8 *buffer, size_t *_length);
status_t WriteAttribute(Transaction &transaction, const char *name, int32 type, off_t pos, const uint8 *buffer, size_t *_length);
status_t ReadAttribute(const char *name, int32 type, off_t pos,
uint8 *buffer, size_t *_length);
status_t WriteAttribute(Transaction &transaction, const char *name,
int32 type, off_t pos, const uint8 *buffer, size_t *_length);
status_t RemoveAttribute(Transaction &transaction, const char *name);
// attribute methods
status_t GetAttribute(const char *name, Inode **attribute);
void ReleaseAttribute(Inode *attribute);
status_t CreateAttribute(Transaction &transaction, const char *name, uint32 type, Inode **attribute);
status_t CreateAttribute(Transaction &transaction, const char *name,
uint32 type, Inode **attribute);
// for directories only:
status_t GetTree(BPlusTree **);
status_t GetTree(BPlusTree **_tree);
bool IsEmpty();
// manipulating the data stream
status_t FindBlockRun(off_t pos, block_run &run, off_t &offset);
status_t ReadAt(off_t pos, uint8 *buffer, size_t *length);
status_t WriteAt(Transaction &transaction, off_t pos, const uint8 *buffer, size_t *length);
status_t WriteAt(Transaction &transaction, off_t pos,
const uint8 *buffer, size_t *length);
status_t FillGapWithZeros(off_t oldSize, off_t newSize);
status_t SetFileSize(Transaction &transaction, off_t size);
@ -124,16 +137,21 @@ class Inode {
bfs_inode &Node() { return fNode; }
// create/remove inodes
status_t Remove(Transaction &transaction, const char *name, off_t *_id = NULL,
bool isDirectory = false);
static status_t Create(Transaction &transaction, Inode *parent, const char *name,
int32 mode, int omode, uint32 type, off_t *_id = NULL, Inode **_inode = NULL);
status_t Remove(Transaction &transaction, const char *name,
vnode_id *_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, vnode_id *_id = NULL, Inode **_inode = NULL);
// index maintaining helper
void UpdateOldSize() { fOldSize = Size(); }
void UpdateOldLastModified() { fOldLastModified = Node().LastModifiedTime(); }
off_t OldSize() { return fOldSize; }
off_t OldLastModified() { return fOldLastModified; }
void UpdateOldSize()
{ fOldSize = Size(); }
void UpdateOldLastModified()
{ fOldLastModified = Node().LastModifiedTime(); }
off_t OldSize()
{ return fOldSize; }
off_t OldLastModified()
{ return fOldLastModified; }
// file cache
void *FileCache() const { return fCache; }
@ -148,15 +166,17 @@ class Inode {
friend class InodeAllocator;
// small_data access methods
status_t _MakeSpaceForSmallData(Transaction &transaction, bfs_inode *node,
const char *name, int32 length);
status_t _MakeSpaceForSmallData(Transaction &transaction,
bfs_inode *node, const char *name, int32 length);
status_t _RemoveSmallData(Transaction &transaction, NodeGetter &node,
const char *name);
status_t _AddSmallData(Transaction &transaction, NodeGetter &node,
const char *name, uint32 type, const uint8 *data, size_t length,
bool force = false);
status_t _GetNextSmallData(bfs_inode *node, small_data **_smallData) const;
status_t _RemoveSmallData(bfs_inode *node, small_data *item, int32 index);
status_t _GetNextSmallData(bfs_inode *node,
small_data **_smallData) const;
status_t _RemoveSmallData(bfs_inode *node, small_data *item,
int32 index);
status_t _RemoveAttribute(Transaction &transaction, const char *name,
bool hasIndex, Index *index);
@ -179,8 +199,11 @@ class Inode {
Inode *fAttributes;
void *fCache;
bfs_inode fNode;
off_t fOldSize; // we need those values to ensure we will remove
off_t fOldLastModified; // the correct keys from the indices
off_t fOldSize;
off_t fOldLastModified;
// we need those values to ensure we will remove
// the correct keys from the indices
mutable SimpleLock fSmallDataLock;
Chain<AttributeIterator> fIterators;
@ -200,7 +223,8 @@ class NodeGetter : public CachedBlock {
SetTo(volume->VnodeToBlock(inode->ID()));
}
NodeGetter(Volume *volume, Transaction &transaction, const Inode *inode, bool empty = false)
NodeGetter(Volume *volume, Transaction &transaction,
const Inode *inode, bool empty = false)
: CachedBlock(volume)
{
SetToWritable(transaction, volume->VnodeToBlock(inode->ID()), empty);
@ -293,11 +317,11 @@ class AttributeIterator {
};
/** Converts the open mode, the open flags given to bfs_open(), into
* access modes, e.g. since O_RDONLY requires read access to the
* file, it will be converted to R_OK.
/*!
Converts the open mode, the open flags given to bfs_open(), into
access modes, e.g. since O_RDONLY requires read access to the
file, it will be converted to R_OK.
*/
inline int
openModeToAccess(int openMode)
{

View File

@ -455,7 +455,8 @@ Volume::CreateIndicesRoot(Transaction &transaction)
{
off_t id;
status_t status = Inode::Create(transaction, NULL, NULL,
S_INDEX_DIR | S_STR_INDEX | S_DIRECTORY | 0700, 0, 0, &id, &fIndicesNode);
S_INDEX_DIR | S_STR_INDEX | S_DIRECTORY | 0700, 0, 0, NULL, &id,
&fIndicesNode);
if (status < B_OK)
RETURN_ERROR(status);
@ -496,12 +497,12 @@ Volume::UpdateLiveQueries(Inode *inode, const char *attribute, int32 type, const
}
/** Checks if there is a live query whose results depend on the presence
* or value of the specified attribute.
* Don't use it if you already have all the data together to evaluate
* the queries - it wouldn't safe you anything in this case.
/*!
Checks if there is a live query whose results depend on the presence
or value of the specified attribute.
Don't use it if you already have all the data together to evaluate
the queries - it wouldn't safe you anything in this case.
*/
bool
Volume::CheckForLiveQuery(const char *attribute)
{
@ -534,8 +535,7 @@ Volume::RemoveQuery(Query *query)
}
// #pragma mark -
// Disk scanning and initialization
// #pragma mark - Disk scanning and initialization
status_t
@ -572,7 +572,8 @@ Volume::Initialize(const char *device, const char *name, uint32 blockSize,
if (strchr(name, '/') != NULL)
return B_BAD_VALUE;
if (blockSize != 1024 && blockSize != 2048 && blockSize != 4096 && blockSize != 8192)
if (blockSize != 1024 && blockSize != 2048 && blockSize != 4096
&& blockSize != 8192)
return B_BAD_VALUE;
DeviceOpener opener(device, O_RDWR);
@ -603,7 +604,8 @@ Volume::Initialize(const char *device, const char *name, uint32 blockSize,
* fSuperBlock.BlocksPerAllocationGroup() + 1);
fSuperBlock.log_blocks.length = HOST_ENDIAN_TO_BFS_INT16(2048);
// ToDo: set the log size depending on the disk size
fSuperBlock.log_start = fSuperBlock.log_end = HOST_ENDIAN_TO_BFS_INT64(ToBlock(Log()));
fSuperBlock.log_start = fSuperBlock.log_end = HOST_ENDIAN_TO_BFS_INT64(
ToBlock(Log()));
// set the current log pointers, so that journaling will work correctly
fLogStart = fSuperBlock.LogStart();
@ -628,7 +630,7 @@ Volume::Initialize(const char *device, const char *name, uint32 blockSize,
off_t id;
status_t status = Inode::Create(transaction, NULL, NULL,
S_DIRECTORY | 0755, 0, 0, &id, &fRootNode);
S_DIRECTORY | 0755, 0, 0, NULL, &id, &fRootNode);
if (status < B_OK)
RETURN_ERROR(status);

View File

@ -1,9 +1,10 @@
/* kernel_interface - file system interface to Haiku's vnode layer
*
/*
* Copyright 2001-2007, Axel Dörfler, axeld@pinc-software.de.
* This file may be used under the terms of the MIT License.
*/
//! file system interface to Haiku's vnode layer
#include "Debug.h"
#include "Volume.h"
@ -14,6 +15,9 @@
#include "Attribute.h"
#include "bfs_control.h"
#ifndef BFS_SHELL
# include <driver_settings.h>
#endif
#define BFS_IO_SIZE 65536
@ -79,7 +83,8 @@ bfs_scan_partition(int fd, partition_data *partition, void *_cookie)
partition->status = B_PARTITION_VALID;
partition->flags |= B_PARTITION_FILE_SYSTEM;
partition->content_size = cookie->super_block.NumBlocks() * cookie->super_block.BlockSize();
partition->content_size = cookie->super_block.NumBlocks()
* cookie->super_block.BlockSize();
partition->block_size = cookie->super_block.BlockSize();
partition->content_name = strdup(cookie->super_block.name);
if (partition->content_name == NULL)
@ -441,11 +446,6 @@ bfs_get_file_map(fs_volume _fs, fs_vnode _node, off_t offset, size_t size,
// #pragma mark -
/** the walk function just "walks" through a directory looking for the
* specified file. It calls get_vnode() on its vnode-id to init it
* for the kernel.
*/
static status_t
bfs_lookup(void *_ns, void *_directory, const char *file, vnode_id *_vnodeID, int *_type)
{
@ -487,7 +487,8 @@ bfs_lookup(void *_ns, void *_directory, const char *file, vnode_id *_vnodeID, in
static status_t
bfs_get_vnode_name(fs_volume _fs, fs_vnode _node, char *buffer, size_t bufferSize)
bfs_get_vnode_name(fs_volume _fs, fs_vnode _node, char *buffer,
size_t bufferSize)
{
Inode *inode = (Inode *)_node;
@ -496,9 +497,11 @@ bfs_get_vnode_name(fs_volume _fs, fs_vnode _node, char *buffer, size_t bufferSiz
static status_t
bfs_ioctl(void *_fs, void *_node, void *_cookie, ulong cmd, void *buffer, size_t bufferLength)
bfs_ioctl(void *_fs, void *_node, void *_cookie, ulong cmd, void *buffer,
size_t bufferLength)
{
FUNCTION_START(("node = %p, cmd = %lu, buf = %p, len = %ld\n", _node, cmd, buffer, bufferLength));
FUNCTION_START(("node = %p, cmd = %lu, buf = %p, len = %ld\n", _node, cmd,
buffer, bufferLength));
Volume *volume = (Volume *)_fs;
Inode *inode = (Inode *)_node;
@ -552,7 +555,8 @@ bfs_ioctl(void *_fs, void *_node, void *_cookie, ulong cmd, void *buffer, size_t
CachedBlock cached(volume);
block_run run;
while (allocator.AllocateBlocks(transaction, 8, 0, 64, 1, run) == B_OK) {
PRINT(("write block_run(%ld, %d, %d)\n", run.allocation_group, run.start, run.length));
PRINT(("write block_run(%ld, %d, %d)\n", run.allocation_group,
run.start, run.length));
for (int32 i = 0;i < run.length;i++) {
uint8 *block = cached.SetToWritable(transaction, run);
if (block != NULL)
@ -739,7 +743,7 @@ bfs_write_stat(void *_ns, void *_node, const struct stat *stat, uint32 mask)
status_t
bfs_create(void *_ns, void *_directory, const char *name, int openMode, int mode,
void **_cookie, vnode_id *vnodeID)
void **_cookie, vnode_id *_vnodeID)
{
FUNCTION_START(("name = \"%s\", perms = %d, openMode = %d\n", name, mode, openMode));
@ -766,8 +770,9 @@ bfs_create(void *_ns, void *_directory, const char *name, int openMode, int mode
Transaction transaction(volume, directory->BlockNumber());
status_t status = Inode::Create(transaction, directory, name, S_FILE | (mode & S_IUMSK),
openMode, 0, vnodeID);
bool created;
status_t status = Inode::Create(transaction, directory, name,
S_FILE | (mode & S_IUMSK), openMode, 0, &created, _vnodeID);
if (status >= B_OK) {
transaction.Done();
@ -775,7 +780,8 @@ bfs_create(void *_ns, void *_directory, const char *name, int openMode, int mode
// register the cookie
*_cookie = cookie;
notify_entry_created(volume->ID(), directory->ID(), name, *vnodeID);
if (created)
notify_entry_created(volume->ID(), directory->ID(), name, *_vnodeID);
} else
free(cookie);
@ -784,7 +790,8 @@ bfs_create(void *_ns, void *_directory, const char *name, int openMode, int mode
static status_t
bfs_create_symlink(void *_ns, void *_directory, const char *name, const char *path, int mode)
bfs_create_symlink(void *_ns, void *_directory, const char *name,
const char *path, int mode)
{
FUNCTION_START(("name = \"%s\", path = \"%s\"\n", name, path));
@ -806,7 +813,8 @@ bfs_create_symlink(void *_ns, void *_directory, const char *name, const char *pa
Inode *link;
off_t id;
status = Inode::Create(transaction, directory, name, S_SYMLINK | 0777, 0, 0, &id, &link);
status = Inode::Create(transaction, directory, name, S_SYMLINK | 0777,
0, 0, NULL, &id, &link);
if (status < B_OK)
RETURN_ERROR(status);
@ -814,10 +822,12 @@ bfs_create_symlink(void *_ns, void *_directory, const char *name, const char *pa
if (length < SHORT_SYMLINK_NAME_LENGTH) {
strcpy(link->Node().short_symlink, path);
} else {
link->Node().flags |= HOST_ENDIAN_TO_BFS_INT32(INODE_LONG_SYMLINK | INODE_LOGGED);
link->Node().flags |= HOST_ENDIAN_TO_BFS_INT32(INODE_LONG_SYMLINK
| INODE_LOGGED);
// links usually don't have a file cache attached - but we now need one
link->SetFileCache(file_cache_create(volume->ID(), link->ID(), 0, volume->Device()));
link->SetFileCache(file_cache_create(volume->ID(), link->ID(), 0,
volume->Device()));
// The following call will have to write the inode back, so
// we don't have to do that here...
@ -827,7 +837,8 @@ bfs_create_symlink(void *_ns, void *_directory, const char *name, const char *pa
if (status == B_OK)
status = link->WriteBack(transaction);
// Inode::Create() left the inode locked in memory, and also doesn't publish links
// Inode::Create() left the inode locked in memory, and also doesn't
// publish links
publish_vnode(volume->ID(), id, link);
put_vnode(volume->ID(), id);
@ -1348,7 +1359,8 @@ bfs_read_link(void *_ns, void *_node, char *buffer, size_t *_bufferSize)
static status_t
bfs_create_dir(void *_ns, void *_directory, const char *name, int mode, vnode_id *_newVnodeID)
bfs_create_dir(void *_ns, void *_directory, const char *name, int mode,
vnode_id *_newVnodeID)
{
FUNCTION_START(("name = \"%s\", perms = %d\n", name, mode));
@ -1371,7 +1383,8 @@ bfs_create_dir(void *_ns, void *_directory, const char *name, int mode, vnode_id
// Inode::Create() locks the inode if we pass the "id" parameter, but we
// need it anyway
off_t id;
status = Inode::Create(transaction, directory, name, S_DIRECTORY | (mode & S_IUMSK), 0, 0, &id);
status = Inode::Create(transaction, directory, name,
S_DIRECTORY | (mode & S_IUMSK), 0, 0, NULL, &id);
if (status == B_OK) {
*_newVnodeID = id;
put_vnode(volume->ID(), id);
@ -1742,7 +1755,7 @@ bfs_remove_attr(fs_volume _fs, fs_vnode _node, const char *name)
notify_attribute_changed(volume->ID(), inode->ID(), name, B_ATTR_REMOVED);
}
RETURN_ERROR(status);
return status;
}
@ -2034,56 +2047,39 @@ bfs_initialize(const char *partition, const char *name, const char *parameters,
if (partition == NULL)
return B_BAD_VALUE;
// TODO: Handle parameters!
// char **argv = (char**)parms;
uint32 blockSize = 1024;
uint32 flags = 0;
bool verbose = false;
#if 0
while (argv && *++argv) {
char *arg = *argv;
if (*arg == '-') {
if (arg[1] == '-') {
if (!strcmp(arg, "--noindex"))
// TODO: driver_settings are not yet supported by the fsshell
#ifndef BFS_SHELL
void *handle = parse_driver_settings_string(parameters);
if (handle != NULL) {
if (get_driver_boolean_parameter(handle, "noindex", false, true))
flags |= VOLUME_NO_INDICES;
else
return B_BAD_VALUE;
}
while (*++arg && *arg >= 'a' && *arg <= 'z') {
switch (*arg) {
case 'v':
if (get_driver_boolean_parameter(handle, "verbose", false, true))
verbose = true;
break;
case 'b':
if (*++argv == NULL || !(**argv >= '0' && **argv <= '9'))
const char *string = get_driver_parameter(handle, "block_size",
NULL, NULL);
if (string != NULL)
blockSize = strtoul(string, NULL, 0);
delete_driver_settings(handle);
}
if (blockSize != 1024 && blockSize != 2048 && blockSize != 4096
&& blockSize != 8192) {
INFORM(("valid block sizes are: 1024, 2048, 4096, and 8192\n"));
return B_BAD_VALUE;
blockSize = atol(*argv);
break;
case 'n':
flags |= VOLUME_NO_INDICES;
break;
}
}
}
else
break;
}
#endif // 0
if (blockSize != 1024 && blockSize != 2048 && blockSize != 4096 && blockSize != 8192) {
FATAL(("valid block sizes are: 1024, 2048, 4096, and 8192\n"));
return -1;
}
#endif
Volume volume(-1);
status_t status = volume.Initialize(partition, name, blockSize, flags);
if (status < B_OK) {
FATAL(("Initializing volume failed: %s\n", strerror(status)));
return -1;
INFORM(("Initializing volume failed: %s\n", strerror(status)));
return status;
}
if (verbose) {
@ -2101,33 +2097,6 @@ bfs_initialize(const char *partition, const char *name, const char *parameters,
INFORM(("\tlog size: %u blocks\n", super.log_blocks.Length()));
}
// make the disk image bootable
// TODO: Check whether this is necessary. Actually makebootable should do the
// trick anyway.
#if 0
int device = open(partition, O_RDWR);
if (device < 0) {
FATAL(("Could not make image bootable: Failed to open \"%s\"\n",
partition));
return B_FILE_ERROR;
}
// change BIOS drive and partition offset
// TODO: for now, this will only work for images only
sBootBlockData1[kBIOSDriveOffset] = 0x80;
// for now, this should be replaced by the real thing
uint32 *offset = (uint32 *)&sBootBlockData1[kPartitionDataOffset];
*offset = 0;
write_pos(device, 0, sBootBlockData1, kBootBlockData1Size);
write_pos(device, kBootBlockData2Offset, sBootBlockData2,
kBootBlockData2Size);
close(device);
#endif // 0
return B_OK;
}