2005-01-18 18:59:18 +03:00
|
|
|
/*
|
2008-03-30 09:59:54 +04:00
|
|
|
* Copyright 2005-2008, Ingo Weinhold, ingo_weinhold@gmx.de.
|
2008-01-12 20:36:10 +03:00
|
|
|
* Copyright 2002-2008, Axel Dörfler, axeld@pinc-software.de.
|
2004-11-15 23:02:04 +03:00
|
|
|
* Distributed under the terms of the MIT License.
|
|
|
|
*
|
|
|
|
* Copyright 2001-2002, Travis Geiselbrecht. All rights reserved.
|
|
|
|
* Distributed under the terms of the NewOS License.
|
|
|
|
*/
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2007-06-21 23:50:57 +04:00
|
|
|
/*! Virtual File System and File System Interface Layer */
|
|
|
|
|
2004-10-20 04:19:38 +04:00
|
|
|
|
2007-09-08 20:17:59 +04:00
|
|
|
#include <ctype.h>
|
|
|
|
#include <fcntl.h>
|
|
|
|
#include <limits.h>
|
|
|
|
#include <stddef.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <string.h>
|
2008-02-03 18:37:31 +03:00
|
|
|
#include <sys/file.h>
|
2007-09-08 20:17:59 +04:00
|
|
|
#include <sys/resource.h>
|
|
|
|
#include <sys/stat.h>
|
|
|
|
#include <unistd.h>
|
|
|
|
|
2004-06-07 21:25:55 +04:00
|
|
|
#include <fs_info.h>
|
|
|
|
#include <fs_interface.h>
|
2004-11-08 21:35:47 +03:00
|
|
|
#include <fs_volume.h>
|
2007-09-08 20:17:59 +04:00
|
|
|
#include <OS.h>
|
|
|
|
#include <StorageDefs.h>
|
|
|
|
|
|
|
|
#include <util/AutoLock.h>
|
2004-06-07 21:25:55 +04:00
|
|
|
|
2005-12-16 19:11:36 +03:00
|
|
|
#include <block_cache.h>
|
|
|
|
#include <fd.h>
|
|
|
|
#include <file_cache.h>
|
|
|
|
#include <khash.h>
|
2004-10-29 02:31:43 +04:00
|
|
|
#include <KPath.h>
|
2005-12-16 19:11:36 +03:00
|
|
|
#include <lock.h>
|
2004-07-02 06:47:43 +04:00
|
|
|
#include <syscalls.h>
|
axeld + bonefish:
* Implemented automatic syscall restarts:
- A syscall can indicate that it has been interrupted and can be
restarted by setting a respective bit in thread::flags. It can
store parameters it wants to be preserved for the restart in
thread::syscall_restart::parameters. Another thread::flags bit
indicates whether it has been restarted.
- handle_signals() clears the restart flag, if the handled signal
has a handler function installed and SA_RESTART is not set. Another
thread flag (THREAD_FLAGS_DONT_RESTART_SYSCALL) can prevent syscalls
from being restarted, even if they could be (not used yet, but we
might want to use it in resume_thread(), so that we stay
behaviorally compatible with BeOS).
- The architecture specific syscall handler restarts the syscall, if
the restart flag is set. Implemented for x86 only.
- Added some support functions in the private <syscall_restart.h> to
simplify the syscall restart code in the syscalls.
- Adjusted all syscalls that can potentially be restarted accordingly.
- _user_ioctl() sets new thread flag THREAD_FLAGS_IOCTL_SYSCALL while
calling the underlying FS's/driver's hook, so that syscall restarts
can also be supported there.
* thread_at_kernel_exit() invokes handle_signals() in a loop now, as
long as the latter indicates that the thread shall be suspended, so
that after waking up signals received in the meantime will be handled
before the thread returns to userland. Adjusted handle_signals()
accordingly -- when encountering a suspending signal we don't check
for further signals.
* Fixed sigsuspend(): Suspending the thread and rescheduling doesn't
result in the correct behavior. Instead we employ a temporary
condition variable and interruptably wait on it. The POSIX test
suite test passes, now.
* Made the switch_sem[_etc]() behavior on interruption consistent.
Depending on when the signal arrived (before the call or when already
waiting) the first semaphore would or wouldn't be released. Now we
consistently release it.
* Refactored _user_{read,write}[v]() syscalls. Use a common function for
either pair. The iovec version doesn't fail anymore, if anything could
be read/written at all. It also checks whether a complete vector
could be read/written, so that we won't skip data, if the underlying
FS/driver couldn't read/write more ATM.
* Some refactoring in the x86 syscall handler: The int 99 and sysenter
handlers use a common subroutine to avoid code duplication.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@23983 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-02-17 18:48:30 +03:00
|
|
|
#include <syscall_restart.h>
|
2002-07-09 16:24:59 +04:00
|
|
|
#include <vfs.h>
|
|
|
|
#include <vm.h>
|
|
|
|
#include <vm_cache.h>
|
2005-12-16 19:11:36 +03:00
|
|
|
#include <vm_low_memory.h>
|
|
|
|
|
|
|
|
#include <boot/kernel_args.h>
|
|
|
|
#include <disk_device_manager/KDiskDevice.h>
|
|
|
|
#include <disk_device_manager/KDiskDeviceManager.h>
|
|
|
|
#include <disk_device_manager/KDiskDeviceUtils.h>
|
|
|
|
#include <disk_device_manager/KDiskSystem.h>
|
2003-01-18 17:13:44 +03:00
|
|
|
#include <fs/node_monitor.h>
|
2002-07-09 16:24:59 +04:00
|
|
|
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
#include "fifo.h"
|
|
|
|
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2004-06-08 10:43:46 +04:00
|
|
|
//#define TRACE_VFS
|
|
|
|
#ifdef TRACE_VFS
|
2005-12-16 20:35:03 +03:00
|
|
|
# define TRACE(x) dprintf x
|
2002-07-09 16:24:59 +04:00
|
|
|
# define FUNCTION(x) dprintf x
|
|
|
|
#else
|
2005-12-16 20:35:03 +03:00
|
|
|
# define TRACE(x) ;
|
2002-07-09 16:24:59 +04:00
|
|
|
# define FUNCTION(x) ;
|
|
|
|
#endif
|
|
|
|
|
2005-08-18 19:07:38 +04:00
|
|
|
#define ADD_DEBUGGER_COMMANDS
|
|
|
|
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
|
|
|
|
#define HAS_FS_CALL(vnode, op) (vnode->ops->op != NULL)
|
|
|
|
#define HAS_FS_MOUNT_CALL(mount, op) (mount->volume->ops->op != NULL)
|
|
|
|
|
|
|
|
#define FS_CALL(vnode, op, params...) \
|
|
|
|
vnode->ops->op(vnode->mount->volume, vnode, params)
|
|
|
|
#define FS_CALL_NO_PARAMS(vnode, op) \
|
|
|
|
vnode->ops->op(vnode->mount->volume, vnode)
|
|
|
|
#define FS_MOUNT_CALL(mount, op, params...) \
|
|
|
|
mount->volume->ops->op(mount->volume, params)
|
|
|
|
#define FS_MOUNT_CALL_NO_PARAMS(mount, op) \
|
|
|
|
mount->volume->ops->op(mount->volume)
|
|
|
|
|
|
|
|
|
2004-12-01 10:41:07 +03:00
|
|
|
const static uint32 kMaxUnusedVnodes = 8192;
|
2004-11-30 00:27:17 +03:00
|
|
|
// This is the maximum number of unused vnodes that the system
|
2006-06-02 18:16:13 +04:00
|
|
|
// will keep around (weak limit, if there is enough memory left,
|
|
|
|
// they won't get flushed even when hitting that limit).
|
2004-11-30 00:27:17 +03:00
|
|
|
// It may be chosen with respect to the available memory or enhanced
|
|
|
|
// by some timestamp/frequency heurism.
|
|
|
|
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
struct vnode : fs_vnode {
|
2002-09-25 18:10:50 +04:00
|
|
|
struct vnode *next;
|
2007-07-18 04:16:27 +04:00
|
|
|
vm_cache *cache;
|
2007-06-21 23:50:57 +04:00
|
|
|
dev_t device;
|
2003-01-18 17:13:44 +03:00
|
|
|
list_link mount_link;
|
2004-11-30 00:27:17 +03:00
|
|
|
list_link unused_link;
|
2007-06-21 23:50:57 +04:00
|
|
|
ino_t id;
|
2002-09-25 18:10:50 +04:00
|
|
|
struct fs_mount *mount;
|
|
|
|
struct vnode *covered_by;
|
|
|
|
int32 ref_count;
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
uint32 type : 29;
|
|
|
|
// TODO: S_INDEX_DIR actually needs another bit.
|
|
|
|
// Better combine this field with the following ones.
|
|
|
|
uint32 remove : 1;
|
|
|
|
uint32 busy : 1;
|
|
|
|
uint32 unpublished : 1;
|
2005-03-17 16:18:29 +03:00
|
|
|
struct advisory_locking *advisory_locking;
|
2006-06-02 18:16:13 +04:00
|
|
|
struct file_descriptor *mandatory_locked_by;
|
2002-07-09 16:24:59 +04:00
|
|
|
};
|
|
|
|
|
|
|
|
struct vnode_hash_key {
|
2007-06-21 23:50:57 +04:00
|
|
|
dev_t device;
|
|
|
|
ino_t vnode;
|
2002-07-09 16:24:59 +04:00
|
|
|
};
|
|
|
|
|
2007-10-06 19:33:12 +04:00
|
|
|
/*! \brief Structure to manage a mounted file system
|
2007-03-03 05:42:36 +03:00
|
|
|
|
|
|
|
Note: The root_vnode and covers_vnode fields (what others?) are
|
|
|
|
initialized in fs_mount() and not changed afterwards. That is as soon
|
|
|
|
as the mount is mounted and it is made sure it won't be unmounted
|
|
|
|
(e.g. by holding a reference to a vnode of that mount) (read) access
|
|
|
|
to those fields is always safe, even without additional locking. Morever
|
|
|
|
while mounted the mount holds a reference to the covers_vnode, and thus
|
|
|
|
making the access path vnode->mount->covers_vnode->mount->... safe if a
|
|
|
|
reference to vnode is held (note that for the root mount covers_vnode
|
|
|
|
is NULL, though).
|
2007-10-06 19:33:12 +04:00
|
|
|
*/
|
2002-07-09 16:24:59 +04:00
|
|
|
struct fs_mount {
|
2002-09-25 18:10:50 +04:00
|
|
|
struct fs_mount *next;
|
2005-05-23 21:15:56 +04:00
|
|
|
file_system_module_info *fs;
|
2007-06-21 23:50:57 +04:00
|
|
|
dev_t id;
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
fs_volume *volume;
|
2004-08-13 08:20:06 +04:00
|
|
|
char *device_name;
|
|
|
|
char *fs_name;
|
2004-09-13 18:53:09 +04:00
|
|
|
recursive_lock rlock; // guards the vnodes list
|
2002-09-25 18:10:50 +04:00
|
|
|
struct vnode *root_vnode;
|
|
|
|
struct vnode *covers_vnode;
|
2004-10-28 02:11:57 +04:00
|
|
|
KPartition *partition;
|
2003-01-18 17:13:44 +03:00
|
|
|
struct list vnodes;
|
2002-09-25 18:10:50 +04:00
|
|
|
bool unmounting;
|
2004-10-29 02:31:43 +04:00
|
|
|
bool owns_file_device;
|
2002-07-09 16:24:59 +04:00
|
|
|
};
|
|
|
|
|
2008-02-19 22:16:36 +03:00
|
|
|
struct advisory_lock : public DoublyLinkedListLinkImpl<advisory_lock> {
|
2005-03-17 16:18:29 +03:00
|
|
|
list_link link;
|
|
|
|
team_id team;
|
2008-02-03 18:37:31 +03:00
|
|
|
pid_t session;
|
2008-02-19 22:16:36 +03:00
|
|
|
off_t start;
|
|
|
|
off_t end;
|
2005-03-17 16:18:29 +03:00
|
|
|
bool shared;
|
|
|
|
};
|
2004-10-28 02:11:57 +04:00
|
|
|
|
2008-02-19 22:16:36 +03:00
|
|
|
typedef DoublyLinkedList<advisory_lock> LockList;
|
|
|
|
|
|
|
|
struct advisory_locking {
|
|
|
|
sem_id lock;
|
|
|
|
sem_id wait_sem;
|
|
|
|
LockList locks;
|
|
|
|
};
|
|
|
|
|
2003-10-17 18:47:15 +04:00
|
|
|
static mutex sFileSystemsMutex;
|
2002-09-25 18:10:50 +04:00
|
|
|
|
2007-09-08 20:17:59 +04:00
|
|
|
/*! \brief Guards sMountsTable.
|
|
|
|
|
|
|
|
The holder is allowed to read/write access the sMountsTable.
|
|
|
|
Manipulation of the fs_mount structures themselves
|
|
|
|
(and their destruction) requires different locks though.
|
|
|
|
*/
|
2003-10-17 18:47:15 +04:00
|
|
|
static mutex sMountMutex;
|
2004-09-13 18:53:09 +04:00
|
|
|
|
2007-09-08 20:17:59 +04:00
|
|
|
/*! \brief Guards mount/unmount operations.
|
|
|
|
|
|
|
|
The fs_mount() and fs_unmount() hold the lock during their whole operation.
|
|
|
|
That is locking the lock ensures that no FS is mounted/unmounted. In
|
|
|
|
particular this means that
|
|
|
|
- sMountsTable will not be modified,
|
|
|
|
- the fields immutable after initialization of the fs_mount structures in
|
|
|
|
sMountsTable will not be modified,
|
|
|
|
- vnode::covered_by of any vnode in sVnodeTable will not be modified.
|
2008-03-04 19:59:59 +03:00
|
|
|
|
2007-09-08 20:17:59 +04:00
|
|
|
The thread trying to lock the lock must not hold sVnodeMutex or
|
|
|
|
sMountMutex.
|
|
|
|
*/
|
2004-09-17 16:29:27 +04:00
|
|
|
static recursive_lock sMountOpLock;
|
2004-09-13 18:53:09 +04:00
|
|
|
|
2007-09-08 20:17:59 +04:00
|
|
|
/*! \brief Guards the vnode::covered_by field of any vnode
|
|
|
|
|
|
|
|
The holder is allowed to read access the vnode::covered_by field of any
|
|
|
|
vnode. Additionally holding sMountOpLock allows for write access.
|
|
|
|
|
|
|
|
The thread trying to lock the must not hold sVnodeMutex.
|
|
|
|
*/
|
2007-03-03 05:42:36 +03:00
|
|
|
static mutex sVnodeCoveredByMutex;
|
|
|
|
|
2007-09-08 20:17:59 +04:00
|
|
|
/*! \brief Guards sVnodeTable.
|
|
|
|
|
|
|
|
The holder is allowed to read/write access sVnodeTable and to
|
|
|
|
any unbusy vnode in that table, save to the immutable fields (device, id,
|
|
|
|
private_node, mount) to which
|
|
|
|
only read-only access is allowed, and to the field covered_by, which is
|
|
|
|
guarded by sMountOpLock and sVnodeCoveredByMutex.
|
|
|
|
|
|
|
|
The thread trying to lock the mutex must not hold sMountMutex.
|
|
|
|
You must not have this mutex held when calling create_sem(), as this
|
|
|
|
might call vfs_free_unused_vnodes().
|
|
|
|
*/
|
2003-10-17 18:47:15 +04:00
|
|
|
static mutex sVnodeMutex;
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2008-03-30 09:59:54 +04:00
|
|
|
/*! \brief Guards io_context::root.
|
|
|
|
|
|
|
|
Must be held when setting or getting the io_context::root field.
|
|
|
|
The only operation allowed while holding this lock besides getting or
|
|
|
|
setting the field is inc_vnode_ref_count() on io_context::root.
|
|
|
|
*/
|
|
|
|
static benaphore sIOContextRootLock;
|
|
|
|
|
2002-09-25 18:10:50 +04:00
|
|
|
#define VNODE_HASH_TABLE_SIZE 1024
|
2003-10-17 18:47:15 +04:00
|
|
|
static hash_table *sVnodeTable;
|
2004-11-30 00:27:17 +03:00
|
|
|
static list sUnusedVnodeList;
|
|
|
|
static uint32 sUnusedVnodes = 0;
|
2003-10-17 18:47:15 +04:00
|
|
|
static struct vnode *sRoot;
|
2002-09-25 18:10:50 +04:00
|
|
|
|
|
|
|
#define MOUNTS_HASH_TABLE_SIZE 16
|
2003-10-17 18:47:15 +04:00
|
|
|
static hash_table *sMountsTable;
|
2007-06-21 23:50:57 +04:00
|
|
|
static dev_t sNextMountID = 1;
|
2002-09-25 18:10:50 +04:00
|
|
|
|
* Extracted file_map API out of the file cache - it's now an optional service
that can be used by file systems.
* Changed the way the file cache works: instead of reading/writing to the
underlying device directly, it can now be used for any data source, ie.
also network file systems.
* As a result, the former pages_io() moved to the VFS layer, and can now be
called by a file system via {read|write}_file_io_vec_pages() (naming
suggestions are always welcomed :-)). It now gets an FD, and uses that to
communicate with the device (via its fs_{read|write}_pages() hooks).
* The file_cache_{read|write}() functions must now be called without holding
an I/O relevant file system lock. That allows the file cache to prepare the
pages without colliding with the page writer, IOW the "mayBlock" flag can
go into the attic again (yay!).
* This also results in a much better performance when the system does I/O and
is low on memory, as the page writer can now finally write back some pages,
and that even without maxing out the CPU :)
* The API changes put slightly more burden on the fs_{read|write}_pages()
hooks, but in combination with the file_map it's still pretty straight
forward. It just will have to dispatch the call to the underlying device
directly, usually it will just call its fs_{read|write}_pages() hooks
via the above mentioned calls.
* Ported BFS and FAT to the new API, the latter has not been tested, though.
* Also ported the API changes to the fs_shell. I also completely removed its
file cache level page handling - the downside is that device access is no
longer cached (ie. depends on the host OS now), the upside is that the code
is greatly simplified.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@22886 a95241bf-73f2-0310-859d-f6bbb57e9c96
2007-11-11 00:19:52 +03:00
|
|
|
#define MAX_TEMP_IO_VECS 8
|
|
|
|
|
2005-02-02 09:49:45 +03:00
|
|
|
mode_t __gUmask = 022;
|
|
|
|
|
2002-07-09 16:24:59 +04:00
|
|
|
/* function declarations */
|
2002-07-14 09:13:20 +04:00
|
|
|
|
2002-09-25 06:18:20 +04:00
|
|
|
// file descriptor operation prototypes
|
2004-06-16 14:32:26 +04:00
|
|
|
static status_t file_read(struct file_descriptor *, off_t pos, void *buffer, size_t *);
|
|
|
|
static status_t file_write(struct file_descriptor *, off_t pos, const void *buffer, size_t *);
|
2002-07-17 11:55:51 +04:00
|
|
|
static off_t file_seek(struct file_descriptor *, off_t pos, int seek_type);
|
2002-07-14 09:13:20 +04:00
|
|
|
static void file_free_fd(struct file_descriptor *);
|
2002-10-08 07:24:51 +04:00
|
|
|
static status_t file_close(struct file_descriptor *);
|
2007-10-02 23:47:31 +04:00
|
|
|
static status_t file_select(struct file_descriptor *, uint8 event,
|
2007-10-01 05:37:28 +04:00
|
|
|
struct selectsync *sync);
|
2005-03-18 00:04:25 +03:00
|
|
|
static status_t file_deselect(struct file_descriptor *, uint8 event,
|
2007-10-01 05:37:28 +04:00
|
|
|
struct selectsync *sync);
|
2008-03-30 09:59:54 +04:00
|
|
|
static status_t dir_read(struct io_context *, struct file_descriptor *,
|
|
|
|
struct dirent *buffer, size_t bufferSize, uint32 *_count);
|
|
|
|
static status_t dir_read(struct io_context* ioContext, struct vnode *vnode,
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
void *cookie, struct dirent *buffer, size_t bufferSize, uint32 *_count);
|
2002-09-25 06:18:20 +04:00
|
|
|
static status_t dir_rewind(struct file_descriptor *);
|
2002-07-14 09:13:20 +04:00
|
|
|
static void dir_free_fd(struct file_descriptor *);
|
2002-10-08 07:24:51 +04:00
|
|
|
static status_t dir_close(struct file_descriptor *);
|
2008-03-30 09:59:54 +04:00
|
|
|
static status_t attr_dir_read(struct io_context *, struct file_descriptor *,
|
|
|
|
struct dirent *buffer, size_t bufferSize, uint32 *_count);
|
2002-09-26 07:50:14 +04:00
|
|
|
static status_t attr_dir_rewind(struct file_descriptor *);
|
|
|
|
static void attr_dir_free_fd(struct file_descriptor *);
|
2002-10-08 07:24:51 +04:00
|
|
|
static status_t attr_dir_close(struct file_descriptor *);
|
2004-06-16 14:32:26 +04:00
|
|
|
static status_t attr_read(struct file_descriptor *, off_t pos, void *buffer, size_t *);
|
|
|
|
static status_t attr_write(struct file_descriptor *, off_t pos, const void *buffer, size_t *);
|
2002-09-25 06:18:20 +04:00
|
|
|
static off_t attr_seek(struct file_descriptor *, off_t pos, int seek_type);
|
|
|
|
static void attr_free_fd(struct file_descriptor *);
|
2002-10-08 07:24:51 +04:00
|
|
|
static status_t attr_close(struct file_descriptor *);
|
|
|
|
static status_t attr_read_stat(struct file_descriptor *, struct stat *);
|
2002-10-17 07:09:25 +04:00
|
|
|
static status_t attr_write_stat(struct file_descriptor *, const struct stat *, int statMask);
|
2008-03-30 09:59:54 +04:00
|
|
|
static status_t index_dir_read(struct io_context *, struct file_descriptor *,
|
|
|
|
struct dirent *buffer, size_t bufferSize, uint32 *_count);
|
2002-09-26 07:50:14 +04:00
|
|
|
static status_t index_dir_rewind(struct file_descriptor *);
|
|
|
|
static void index_dir_free_fd(struct file_descriptor *);
|
2002-10-08 07:24:51 +04:00
|
|
|
static status_t index_dir_close(struct file_descriptor *);
|
2008-03-30 09:59:54 +04:00
|
|
|
static status_t query_read(struct io_context *, struct file_descriptor *,
|
|
|
|
struct dirent *buffer, size_t bufferSize, uint32 *_count);
|
2004-12-12 23:39:45 +03:00
|
|
|
static status_t query_rewind(struct file_descriptor *);
|
|
|
|
static void query_free_fd(struct file_descriptor *);
|
|
|
|
static status_t query_close(struct file_descriptor *);
|
2002-09-25 06:18:20 +04:00
|
|
|
|
2002-10-08 07:24:51 +04:00
|
|
|
static status_t common_ioctl(struct file_descriptor *, ulong, void *buf, size_t len);
|
|
|
|
static status_t common_read_stat(struct file_descriptor *, struct stat *);
|
2002-10-17 07:09:25 +04:00
|
|
|
static status_t common_write_stat(struct file_descriptor *, const struct stat *, int statMask);
|
2002-07-14 09:13:20 +04:00
|
|
|
|
2008-03-30 03:57:34 +04:00
|
|
|
static status_t common_path_read_stat(int fd, char *path, bool traverseLeafLink,
|
|
|
|
struct stat *stat, bool kernel);
|
|
|
|
|
2004-09-12 14:58:29 +04:00
|
|
|
static status_t vnode_path_to_vnode(struct vnode *vnode, char *path,
|
2008-03-30 09:59:54 +04:00
|
|
|
bool traverseLeafLink, int count, bool kernel,
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
struct vnode **_vnode, ino_t *_parentID);
|
2008-03-30 09:59:54 +04:00
|
|
|
static status_t dir_vnode_to_path(struct vnode *vnode, char *buffer,
|
|
|
|
size_t bufferSize, bool kernel);
|
2004-08-29 00:38:39 +04:00
|
|
|
static status_t fd_and_path_to_vnode(int fd, char *path, bool traverseLeafLink,
|
2007-06-21 23:50:57 +04:00
|
|
|
struct vnode **_vnode, ino_t *_parentID, bool kernel);
|
2003-09-04 08:01:25 +04:00
|
|
|
static void inc_vnode_ref_count(struct vnode *vnode);
|
|
|
|
static status_t dec_vnode_ref_count(struct vnode *vnode, bool reenter);
|
|
|
|
static inline void put_vnode(struct vnode *vnode);
|
2007-11-12 23:54:17 +03:00
|
|
|
static status_t fs_unmount(char *path, dev_t mountID, uint32 flags,
|
|
|
|
bool kernel);
|
|
|
|
|
2002-07-19 01:06:02 +04:00
|
|
|
|
2003-10-17 18:47:15 +04:00
|
|
|
static struct fd_ops sFileOps = {
|
2002-07-14 09:13:20 +04:00
|
|
|
file_read,
|
|
|
|
file_write,
|
|
|
|
file_seek,
|
|
|
|
common_ioctl,
|
2008-04-11 23:21:14 +04:00
|
|
|
NULL, // set_flags
|
2005-03-18 00:04:25 +03:00
|
|
|
file_select,
|
|
|
|
file_deselect,
|
2002-10-29 06:54:07 +03:00
|
|
|
NULL, // read_dir()
|
|
|
|
NULL, // rewind_dir()
|
2002-07-14 09:13:20 +04:00
|
|
|
common_read_stat,
|
2002-10-17 07:09:25 +04:00
|
|
|
common_write_stat,
|
2002-07-17 11:55:51 +04:00
|
|
|
file_close,
|
2002-07-14 09:13:20 +04:00
|
|
|
file_free_fd
|
|
|
|
};
|
|
|
|
|
2003-10-17 18:47:15 +04:00
|
|
|
static struct fd_ops sDirectoryOps = {
|
2002-10-29 06:54:07 +03:00
|
|
|
NULL, // read()
|
|
|
|
NULL, // write()
|
|
|
|
NULL, // seek()
|
2002-07-14 09:13:20 +04:00
|
|
|
common_ioctl,
|
2008-04-11 23:21:14 +04:00
|
|
|
NULL, // set_flags
|
2002-10-29 06:54:07 +03:00
|
|
|
NULL, // select()
|
|
|
|
NULL, // deselect()
|
2002-07-14 09:13:20 +04:00
|
|
|
dir_read,
|
|
|
|
dir_rewind,
|
|
|
|
common_read_stat,
|
2002-10-17 07:09:25 +04:00
|
|
|
common_write_stat,
|
2002-07-17 11:55:51 +04:00
|
|
|
dir_close,
|
2002-07-14 09:13:20 +04:00
|
|
|
dir_free_fd
|
2002-07-09 16:24:59 +04:00
|
|
|
};
|
|
|
|
|
2003-10-17 18:47:15 +04:00
|
|
|
static struct fd_ops sAttributeDirectoryOps = {
|
2002-10-29 06:54:07 +03:00
|
|
|
NULL, // read()
|
|
|
|
NULL, // write()
|
|
|
|
NULL, // seek()
|
2002-09-26 07:50:14 +04:00
|
|
|
common_ioctl,
|
2008-04-11 23:21:14 +04:00
|
|
|
NULL, // set_flags
|
2002-10-29 06:54:07 +03:00
|
|
|
NULL, // select()
|
|
|
|
NULL, // deselect()
|
2002-09-26 07:50:14 +04:00
|
|
|
attr_dir_read,
|
|
|
|
attr_dir_rewind,
|
|
|
|
common_read_stat,
|
2002-10-17 07:09:25 +04:00
|
|
|
common_write_stat,
|
2002-09-26 07:50:14 +04:00
|
|
|
attr_dir_close,
|
|
|
|
attr_dir_free_fd
|
|
|
|
};
|
|
|
|
|
2003-10-17 18:47:15 +04:00
|
|
|
static struct fd_ops sAttributeOps = {
|
2002-09-25 06:18:20 +04:00
|
|
|
attr_read,
|
|
|
|
attr_write,
|
|
|
|
attr_seek,
|
|
|
|
common_ioctl,
|
2008-04-11 23:21:14 +04:00
|
|
|
NULL, // set_flags
|
2002-10-29 06:54:07 +03:00
|
|
|
NULL, // select()
|
|
|
|
NULL, // deselect()
|
|
|
|
NULL, // read_dir()
|
|
|
|
NULL, // rewind_dir()
|
2002-09-25 06:18:20 +04:00
|
|
|
attr_read_stat,
|
2002-10-17 07:09:25 +04:00
|
|
|
attr_write_stat,
|
2002-09-25 06:18:20 +04:00
|
|
|
attr_close,
|
|
|
|
attr_free_fd
|
|
|
|
};
|
|
|
|
|
2003-10-17 18:47:15 +04:00
|
|
|
static struct fd_ops sIndexDirectoryOps = {
|
2002-10-17 07:09:25 +04:00
|
|
|
NULL, // read()
|
|
|
|
NULL, // write()
|
|
|
|
NULL, // seek()
|
|
|
|
NULL, // ioctl()
|
2008-04-11 23:21:14 +04:00
|
|
|
NULL, // set_flags
|
2002-10-29 06:54:07 +03:00
|
|
|
NULL, // select()
|
|
|
|
NULL, // deselect()
|
2002-09-26 07:50:14 +04:00
|
|
|
index_dir_read,
|
|
|
|
index_dir_rewind,
|
2002-10-17 07:09:25 +04:00
|
|
|
NULL, // read_stat()
|
|
|
|
NULL, // write_stat()
|
2002-09-26 07:50:14 +04:00
|
|
|
index_dir_close,
|
|
|
|
index_dir_free_fd
|
|
|
|
};
|
|
|
|
|
2003-09-04 08:07:39 +04:00
|
|
|
#if 0
|
2003-10-17 18:47:15 +04:00
|
|
|
static struct fd_ops sIndexOps = {
|
2003-09-04 08:07:39 +04:00
|
|
|
NULL, // read()
|
|
|
|
NULL, // write()
|
|
|
|
NULL, // seek()
|
|
|
|
NULL, // ioctl()
|
2008-04-11 23:21:14 +04:00
|
|
|
NULL, // set_flags
|
2003-09-04 08:07:39 +04:00
|
|
|
NULL, // select()
|
|
|
|
NULL, // deselect()
|
|
|
|
NULL, // dir_read()
|
|
|
|
NULL, // dir_rewind()
|
|
|
|
index_read_stat, // read_stat()
|
|
|
|
NULL, // write_stat()
|
|
|
|
NULL, // dir_close()
|
|
|
|
NULL // free_fd()
|
|
|
|
};
|
|
|
|
#endif
|
|
|
|
|
2004-12-12 23:39:45 +03:00
|
|
|
static struct fd_ops sQueryOps = {
|
|
|
|
NULL, // read()
|
|
|
|
NULL, // write()
|
|
|
|
NULL, // seek()
|
|
|
|
NULL, // ioctl()
|
2008-04-11 23:21:14 +04:00
|
|
|
NULL, // set_flags
|
2004-12-12 23:39:45 +03:00
|
|
|
NULL, // select()
|
|
|
|
NULL, // deselect()
|
|
|
|
query_read,
|
|
|
|
query_rewind,
|
|
|
|
NULL, // read_stat()
|
|
|
|
NULL, // write_stat()
|
|
|
|
query_close,
|
|
|
|
query_free_fd
|
|
|
|
};
|
|
|
|
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2004-08-29 00:38:39 +04:00
|
|
|
// VNodePutter
|
|
|
|
class VNodePutter {
|
|
|
|
public:
|
|
|
|
VNodePutter(struct vnode *vnode = NULL) : fVNode(vnode) {}
|
|
|
|
|
|
|
|
~VNodePutter()
|
|
|
|
{
|
|
|
|
Put();
|
|
|
|
}
|
|
|
|
|
|
|
|
void SetTo(struct vnode *vnode)
|
|
|
|
{
|
|
|
|
Put();
|
|
|
|
fVNode = vnode;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Put()
|
|
|
|
{
|
|
|
|
if (fVNode) {
|
|
|
|
put_vnode(fVNode);
|
|
|
|
fVNode = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
struct vnode *Detach()
|
|
|
|
{
|
|
|
|
struct vnode *vnode = fVNode;
|
|
|
|
fVNode = NULL;
|
|
|
|
return vnode;
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
struct vnode *fVNode;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
class FDCloser {
|
|
|
|
public:
|
|
|
|
FDCloser() : fFD(-1), fKernel(true) {}
|
|
|
|
|
|
|
|
FDCloser(int fd, bool kernel) : fFD(fd), fKernel(kernel) {}
|
|
|
|
|
|
|
|
~FDCloser()
|
|
|
|
{
|
|
|
|
Close();
|
|
|
|
}
|
|
|
|
|
|
|
|
void SetTo(int fd, bool kernel)
|
|
|
|
{
|
|
|
|
Close();
|
|
|
|
fFD = fd;
|
|
|
|
fKernel = kernel;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Close()
|
|
|
|
{
|
|
|
|
if (fFD >= 0) {
|
|
|
|
if (fKernel)
|
|
|
|
_kern_close(fFD);
|
|
|
|
else
|
|
|
|
_user_close(fFD);
|
|
|
|
fFD = -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
int Detach()
|
|
|
|
{
|
|
|
|
int fd = fFD;
|
|
|
|
fFD = -1;
|
|
|
|
return fd;
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
int fFD;
|
|
|
|
bool fKernel;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2002-07-09 16:24:59 +04:00
|
|
|
static int
|
|
|
|
mount_compare(void *_m, const void *_key)
|
|
|
|
{
|
2003-10-17 18:47:15 +04:00
|
|
|
struct fs_mount *mount = (fs_mount *)_m;
|
2007-06-21 23:50:57 +04:00
|
|
|
const dev_t *id = (dev_t *)_key;
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2002-07-17 11:55:51 +04:00
|
|
|
if (mount->id == *id)
|
2002-07-09 16:24:59 +04:00
|
|
|
return 0;
|
2002-07-17 11:55:51 +04:00
|
|
|
|
|
|
|
return -1;
|
2002-07-09 16:24:59 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2002-11-29 11:36:05 +03:00
|
|
|
static uint32
|
|
|
|
mount_hash(void *_m, const void *_key, uint32 range)
|
2002-07-09 16:24:59 +04:00
|
|
|
{
|
2003-10-17 18:47:15 +04:00
|
|
|
struct fs_mount *mount = (fs_mount *)_m;
|
2007-06-21 23:50:57 +04:00
|
|
|
const dev_t *id = (dev_t *)_key;
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2002-07-17 11:55:51 +04:00
|
|
|
if (mount)
|
2002-07-09 16:24:59 +04:00
|
|
|
return mount->id % range;
|
2002-07-17 11:55:51 +04:00
|
|
|
|
2005-08-26 06:01:21 +04:00
|
|
|
return (uint32)*id % range;
|
2002-07-09 16:24:59 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-10-06 19:33:12 +04:00
|
|
|
/*! Finds the mounted device (the fs_mount structure) with the given ID.
|
|
|
|
Note, you must hold the gMountMutex lock when you call this function.
|
|
|
|
*/
|
2002-09-26 07:50:14 +04:00
|
|
|
static struct fs_mount *
|
2007-06-21 23:50:57 +04:00
|
|
|
find_mount(dev_t id)
|
2002-09-26 07:50:14 +04:00
|
|
|
{
|
2003-10-17 18:47:15 +04:00
|
|
|
ASSERT_LOCKED_MUTEX(&sMountMutex);
|
2002-09-26 07:50:14 +04:00
|
|
|
|
2003-10-17 18:47:15 +04:00
|
|
|
return (fs_mount *)hash_lookup(sMountsTable, (void *)&id);
|
2002-09-26 07:50:14 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2005-09-22 21:45:43 +04:00
|
|
|
static status_t
|
2007-06-21 23:50:57 +04:00
|
|
|
get_mount(dev_t id, struct fs_mount **_mount)
|
2003-09-04 08:01:25 +04:00
|
|
|
{
|
|
|
|
struct fs_mount *mount;
|
2005-09-22 21:45:43 +04:00
|
|
|
status_t status;
|
2003-09-04 08:01:25 +04:00
|
|
|
|
2007-09-08 21:03:19 +04:00
|
|
|
MutexLocker nodeLocker(sVnodeMutex);
|
|
|
|
MutexLocker mountLocker(sMountMutex);
|
2003-09-04 08:01:25 +04:00
|
|
|
|
|
|
|
mount = find_mount(id);
|
2005-09-22 21:45:43 +04:00
|
|
|
if (mount == NULL)
|
2007-09-08 21:03:19 +04:00
|
|
|
return B_BAD_VALUE;
|
|
|
|
|
|
|
|
struct vnode* rootNode = mount->root_vnode;
|
|
|
|
if (rootNode == NULL || rootNode->busy || rootNode->ref_count == 0) {
|
|
|
|
// might have been called during a mount/unmount operation
|
2005-09-22 21:45:43 +04:00
|
|
|
return B_BUSY;
|
2007-09-08 21:03:19 +04:00
|
|
|
}
|
2005-09-22 21:45:43 +04:00
|
|
|
|
2007-09-08 21:03:19 +04:00
|
|
|
inc_vnode_ref_count(mount->root_vnode);
|
2005-09-22 21:45:43 +04:00
|
|
|
*_mount = mount;
|
|
|
|
return B_OK;
|
2003-09-04 08:01:25 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
put_mount(struct fs_mount *mount)
|
|
|
|
{
|
|
|
|
if (mount)
|
|
|
|
put_vnode(mount->root_vnode);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2002-09-25 18:10:50 +04:00
|
|
|
static status_t
|
2005-05-23 21:15:56 +04:00
|
|
|
put_file_system(file_system_module_info *fs)
|
2002-09-25 18:10:50 +04:00
|
|
|
{
|
2005-05-23 21:15:56 +04:00
|
|
|
return put_module(fs->info.name);
|
2002-09-25 18:10:50 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-10-06 19:33:12 +04:00
|
|
|
/*! Tries to open the specified file system module.
|
|
|
|
Accepts a file system name of the form "bfs" or "file_systems/bfs/v1".
|
|
|
|
Returns a pointer to file system module interface, or NULL if it
|
|
|
|
could not open the module.
|
|
|
|
*/
|
2005-05-23 21:15:56 +04:00
|
|
|
static file_system_module_info *
|
2004-06-07 21:25:55 +04:00
|
|
|
get_file_system(const char *fsName)
|
2002-09-25 18:10:50 +04:00
|
|
|
{
|
2004-06-07 21:25:55 +04:00
|
|
|
char name[B_FILE_NAME_LENGTH];
|
2005-05-23 22:22:04 +04:00
|
|
|
if (strncmp(fsName, "file_systems/", strlen("file_systems/"))) {
|
|
|
|
// construct module name if we didn't get one
|
|
|
|
// (we currently support only one API)
|
|
|
|
snprintf(name, sizeof(name), "file_systems/%s/v1", fsName);
|
|
|
|
fsName = NULL;
|
|
|
|
}
|
2002-09-25 18:10:50 +04:00
|
|
|
|
2005-05-23 21:15:56 +04:00
|
|
|
file_system_module_info *info;
|
2005-05-23 22:22:04 +04:00
|
|
|
if (get_module(fsName ? fsName : name, (module_info **)&info) != B_OK)
|
2004-06-07 21:25:55 +04:00
|
|
|
return NULL;
|
2002-09-25 18:10:50 +04:00
|
|
|
|
2004-06-07 21:25:55 +04:00
|
|
|
return info;
|
2002-09-25 18:10:50 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-10-06 19:33:12 +04:00
|
|
|
/*! Accepts a file system name of the form "bfs" or "file_systems/bfs/v1"
|
|
|
|
and returns a compatible fs_info.fsh_name name ("bfs" in both cases).
|
|
|
|
The name is allocated for you, and you have to free() it when you're
|
|
|
|
done with it.
|
|
|
|
Returns NULL if the required memory is no available.
|
|
|
|
*/
|
2005-05-23 22:22:04 +04:00
|
|
|
static char *
|
|
|
|
get_file_system_name(const char *fsName)
|
|
|
|
{
|
|
|
|
const size_t length = strlen("file_systems/");
|
|
|
|
|
|
|
|
if (strncmp(fsName, "file_systems/", length)) {
|
|
|
|
// the name already seems to be the module's file name
|
|
|
|
return strdup(fsName);
|
|
|
|
}
|
|
|
|
|
|
|
|
fsName += length;
|
|
|
|
const char *end = strchr(fsName, '/');
|
|
|
|
if (end == NULL) {
|
|
|
|
// this doesn't seem to be a valid name, but well...
|
|
|
|
return strdup(fsName);
|
|
|
|
}
|
|
|
|
|
|
|
|
// cut off the trailing /v1
|
|
|
|
|
|
|
|
char *name = (char *)malloc(end + 1 - fsName);
|
|
|
|
if (name == NULL)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
strlcpy(name, fsName, end + 1 - fsName);
|
|
|
|
return name;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2002-07-09 16:24:59 +04:00
|
|
|
static int
|
2002-11-29 11:36:05 +03:00
|
|
|
vnode_compare(void *_vnode, const void *_key)
|
2002-07-09 16:24:59 +04:00
|
|
|
{
|
2003-10-17 18:47:15 +04:00
|
|
|
struct vnode *vnode = (struct vnode *)_vnode;
|
|
|
|
const struct vnode_hash_key *key = (vnode_hash_key *)_key;
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2003-10-17 18:47:15 +04:00
|
|
|
if (vnode->device == key->device && vnode->id == key->vnode)
|
2002-07-09 16:24:59 +04:00
|
|
|
return 0;
|
2002-07-20 04:16:12 +04:00
|
|
|
|
|
|
|
return -1;
|
2002-07-09 16:24:59 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2002-11-29 11:36:05 +03:00
|
|
|
static uint32
|
|
|
|
vnode_hash(void *_vnode, const void *_key, uint32 range)
|
2002-07-09 16:24:59 +04:00
|
|
|
{
|
2003-10-17 18:47:15 +04:00
|
|
|
struct vnode *vnode = (struct vnode *)_vnode;
|
|
|
|
const struct vnode_hash_key *key = (vnode_hash_key *)_key;
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2002-09-25 18:10:50 +04:00
|
|
|
#define VHASH(mountid, vnodeid) (((uint32)((vnodeid) >> 32) + (uint32)(vnodeid)) ^ (uint32)(mountid))
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2002-07-20 04:16:12 +04:00
|
|
|
if (vnode != NULL)
|
2005-08-26 06:01:21 +04:00
|
|
|
return VHASH(vnode->device, vnode->id) % range;
|
2003-10-17 18:47:15 +04:00
|
|
|
|
2005-08-26 06:01:21 +04:00
|
|
|
return VHASH(key->device, key->vnode) % range;
|
2002-07-09 16:24:59 +04:00
|
|
|
|
|
|
|
#undef VHASH
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
2002-09-26 07:50:14 +04:00
|
|
|
add_vnode_to_mount_list(struct vnode *vnode, struct fs_mount *mount)
|
2002-07-09 16:24:59 +04:00
|
|
|
{
|
|
|
|
recursive_lock_lock(&mount->rlock);
|
|
|
|
|
2003-01-18 17:13:44 +03:00
|
|
|
list_add_link_to_head(&mount->vnodes, &vnode->mount_link);
|
2002-07-09 16:24:59 +04:00
|
|
|
|
|
|
|
recursive_lock_unlock(&mount->rlock);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
2002-09-26 07:50:14 +04:00
|
|
|
remove_vnode_from_mount_list(struct vnode *vnode, struct fs_mount *mount)
|
2002-07-09 16:24:59 +04:00
|
|
|
{
|
|
|
|
recursive_lock_lock(&mount->rlock);
|
|
|
|
|
2003-01-18 17:13:44 +03:00
|
|
|
list_remove_link(&vnode->mount_link);
|
|
|
|
vnode->mount_link.next = vnode->mount_link.prev = NULL;
|
2002-07-09 16:24:59 +04:00
|
|
|
|
|
|
|
recursive_lock_unlock(&mount->rlock);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-02-02 18:09:21 +03:00
|
|
|
static status_t
|
2007-06-21 23:50:57 +04:00
|
|
|
create_new_vnode(struct vnode **_vnode, dev_t mountID, ino_t vnodeID)
|
2002-07-09 16:24:59 +04:00
|
|
|
{
|
2004-06-08 10:43:46 +04:00
|
|
|
FUNCTION(("create_new_vnode()\n"));
|
|
|
|
|
2004-02-02 18:09:21 +03:00
|
|
|
struct vnode *vnode = (struct vnode *)malloc(sizeof(struct vnode));
|
2002-09-26 07:50:14 +04:00
|
|
|
if (vnode == NULL)
|
2004-02-02 18:09:21 +03:00
|
|
|
return B_NO_MEMORY;
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2004-02-02 18:09:21 +03:00
|
|
|
// initialize basic values
|
2002-09-26 07:50:14 +04:00
|
|
|
memset(vnode, 0, sizeof(struct vnode));
|
2004-02-02 18:09:21 +03:00
|
|
|
vnode->device = mountID;
|
|
|
|
vnode->id = vnodeID;
|
|
|
|
|
|
|
|
// add the vnode to the mount structure
|
2008-03-04 19:59:59 +03:00
|
|
|
mutex_lock(&sMountMutex);
|
2004-02-02 18:09:21 +03:00
|
|
|
vnode->mount = find_mount(mountID);
|
2004-09-13 18:53:09 +04:00
|
|
|
if (!vnode->mount || vnode->mount->unmounting) {
|
2004-02-02 18:09:21 +03:00
|
|
|
mutex_unlock(&sMountMutex);
|
|
|
|
free(vnode);
|
|
|
|
return B_ENTRY_NOT_FOUND;
|
|
|
|
}
|
|
|
|
|
|
|
|
hash_insert(sVnodeTable, vnode);
|
|
|
|
add_vnode_to_mount_list(vnode, vnode->mount);
|
|
|
|
|
|
|
|
mutex_unlock(&sMountMutex);
|
|
|
|
|
|
|
|
vnode->ref_count = 1;
|
|
|
|
*_vnode = vnode;
|
|
|
|
|
|
|
|
return B_OK;
|
2002-07-09 16:24:59 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-10-06 19:33:12 +04:00
|
|
|
/*! Frees the vnode and all resources it has acquired, and removes
|
|
|
|
it from the vnode hash as well as from its mount structure.
|
|
|
|
Will also make sure that any cache modifications are written back.
|
|
|
|
*/
|
2004-11-30 00:27:17 +03:00
|
|
|
static void
|
|
|
|
free_vnode(struct vnode *vnode, bool reenter)
|
|
|
|
{
|
2007-09-09 18:38:58 +04:00
|
|
|
ASSERT_PRINT(vnode->ref_count == 0 && vnode->busy, "vnode: %p\n", vnode);
|
2004-11-30 00:27:17 +03:00
|
|
|
|
2005-01-15 03:38:16 +03:00
|
|
|
// write back any changes in this vnode's cache -- but only
|
|
|
|
// if the vnode won't be deleted, in which case the changes
|
|
|
|
// will be discarded
|
2004-11-30 00:27:17 +03:00
|
|
|
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
if (!vnode->remove && HAS_FS_CALL(vnode, fsync))
|
|
|
|
FS_CALL_NO_PARAMS(vnode, fsync);
|
2004-11-30 00:27:17 +03:00
|
|
|
|
2007-09-09 18:38:58 +04:00
|
|
|
// Note: If this vnode has a cache attached, there will still be two
|
|
|
|
// references to that cache at this point. The last one belongs to the vnode
|
|
|
|
// itself (cf. vfs_get_vnode_cache()) and one belongs to the node's file
|
|
|
|
// cache. Each but the last reference to a cache also includes a reference
|
|
|
|
// to the vnode. The file cache, however, released its reference (cf.
|
|
|
|
// file_cache_create()), so that this vnode's ref count has the chance to
|
|
|
|
// ever drop to 0. Deleting the file cache now, will cause the next to last
|
|
|
|
// cache reference to be released, which will also release a (no longer
|
|
|
|
// existing) vnode reference. To avoid problems, we set the vnode's ref
|
|
|
|
// count, so that it will neither become negative nor 0.
|
|
|
|
vnode->ref_count = 2;
|
|
|
|
|
|
|
|
// TODO: Usually, when the vnode is unreferenced, no one can get hold of the
|
|
|
|
// cache either (i.e. no one can get a cache reference while we're deleting
|
|
|
|
// the vnode).. This is, however, not the case for the page daemon. It gets
|
|
|
|
// its cache references via the pages it scans, so it can in fact get a
|
|
|
|
// vnode reference while we're deleting the vnode.
|
|
|
|
|
2005-03-14 04:15:31 +03:00
|
|
|
if (!vnode->unpublished) {
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
if (vnode->remove)
|
|
|
|
FS_CALL(vnode, remove_vnode, reenter);
|
|
|
|
else
|
|
|
|
FS_CALL(vnode, put_vnode, reenter);
|
2005-03-14 04:15:31 +03:00
|
|
|
}
|
2004-11-30 00:27:17 +03:00
|
|
|
|
2008-03-27 12:48:33 +03:00
|
|
|
// The file system has removed the resources of the vnode now, so we can
|
|
|
|
// make it available again (and remove the busy vnode from the hash)
|
|
|
|
mutex_lock(&sVnodeMutex);
|
|
|
|
hash_remove(sVnodeTable, vnode);
|
|
|
|
mutex_unlock(&sVnodeMutex);
|
|
|
|
|
2004-11-30 00:27:17 +03:00
|
|
|
// if we have a vm_cache attached, remove it
|
|
|
|
if (vnode->cache)
|
2005-01-15 03:38:16 +03:00
|
|
|
vm_cache_release_ref(vnode->cache);
|
2004-11-30 00:27:17 +03:00
|
|
|
|
|
|
|
vnode->cache = NULL;
|
|
|
|
|
|
|
|
remove_vnode_from_mount_list(vnode, vnode->mount);
|
|
|
|
|
|
|
|
free(vnode);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-10-06 19:33:12 +04:00
|
|
|
/*! \brief Decrements the reference counter of the given vnode and deletes it,
|
|
|
|
if the counter dropped to 0.
|
2004-09-13 18:53:09 +04:00
|
|
|
|
2007-10-06 19:33:12 +04:00
|
|
|
The caller must, of course, own a reference to the vnode to call this
|
|
|
|
function.
|
|
|
|
The caller must not hold the sVnodeMutex or the sMountMutex.
|
|
|
|
|
|
|
|
\param vnode the vnode.
|
|
|
|
\param reenter \c true, if this function is called (indirectly) from within
|
|
|
|
a file system.
|
|
|
|
\return \c B_OK, if everything went fine, an error code otherwise.
|
|
|
|
*/
|
2003-02-21 16:49:26 +03:00
|
|
|
static status_t
|
2002-07-20 04:16:12 +04:00
|
|
|
dec_vnode_ref_count(struct vnode *vnode, bool reenter)
|
2002-07-09 16:24:59 +04:00
|
|
|
{
|
2003-10-17 18:47:15 +04:00
|
|
|
mutex_lock(&sVnodeMutex);
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2006-03-05 23:54:17 +03:00
|
|
|
int32 oldRefCount = atomic_add(&vnode->ref_count, -1);
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2007-09-09 18:38:58 +04:00
|
|
|
ASSERT_PRINT(oldRefCount > 0, "vnode %p\n", vnode);
|
|
|
|
|
2005-12-16 20:35:03 +03:00
|
|
|
TRACE(("dec_vnode_ref_count: vnode %p, ref now %ld\n", vnode, vnode->ref_count));
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2004-11-30 00:27:17 +03:00
|
|
|
if (oldRefCount == 1) {
|
2006-03-05 23:54:17 +03:00
|
|
|
if (vnode->busy)
|
|
|
|
panic("dec_vnode_ref_count: called on busy vnode %p\n", vnode);
|
|
|
|
|
2004-11-30 00:27:17 +03:00
|
|
|
bool freeNode = false;
|
2004-11-23 06:20:20 +03:00
|
|
|
|
2004-11-30 00:27:17 +03:00
|
|
|
// Just insert the vnode into an unused list if we don't need
|
|
|
|
// to delete it
|
2005-03-14 04:15:31 +03:00
|
|
|
if (vnode->remove) {
|
2004-11-30 00:27:17 +03:00
|
|
|
vnode->busy = true;
|
|
|
|
freeNode = true;
|
|
|
|
} else {
|
|
|
|
list_add_item(&sUnusedVnodeList, vnode);
|
2005-12-16 19:11:36 +03:00
|
|
|
if (++sUnusedVnodes > kMaxUnusedVnodes
|
|
|
|
&& vm_low_memory_state() != B_NO_LOW_MEMORY) {
|
2004-11-30 00:27:17 +03:00
|
|
|
// there are too many unused vnodes so we free the oldest one
|
|
|
|
// ToDo: evaluate this mechanism
|
|
|
|
vnode = (struct vnode *)list_remove_head_item(&sUnusedVnodeList);
|
|
|
|
vnode->busy = true;
|
|
|
|
freeNode = true;
|
2004-12-01 10:41:07 +03:00
|
|
|
sUnusedVnodes--;
|
2004-11-30 00:27:17 +03:00
|
|
|
}
|
|
|
|
}
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2003-10-17 18:47:15 +04:00
|
|
|
mutex_unlock(&sVnodeMutex);
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2004-11-30 00:27:17 +03:00
|
|
|
if (freeNode)
|
|
|
|
free_vnode(vnode, reenter);
|
|
|
|
} else
|
2003-10-17 18:47:15 +04:00
|
|
|
mutex_unlock(&sVnodeMutex);
|
2004-11-30 00:27:17 +03:00
|
|
|
|
|
|
|
return B_OK;
|
2002-07-09 16:24:59 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-10-06 19:33:12 +04:00
|
|
|
/*! \brief Increments the reference counter of the given vnode.
|
|
|
|
|
|
|
|
The caller must either already have a reference to the vnode or hold
|
|
|
|
the sVnodeMutex.
|
2004-09-13 18:53:09 +04:00
|
|
|
|
2007-10-06 19:33:12 +04:00
|
|
|
\param vnode the vnode.
|
|
|
|
*/
|
2003-02-21 16:49:26 +03:00
|
|
|
static void
|
2002-07-20 04:16:12 +04:00
|
|
|
inc_vnode_ref_count(struct vnode *vnode)
|
2002-07-09 16:24:59 +04:00
|
|
|
{
|
2002-07-20 04:16:12 +04:00
|
|
|
atomic_add(&vnode->ref_count, 1);
|
2005-12-16 20:35:03 +03:00
|
|
|
TRACE(("inc_vnode_ref_count: vnode %p, ref now %ld\n", vnode, vnode->ref_count));
|
2002-07-09 16:24:59 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-10-06 19:33:12 +04:00
|
|
|
/*! \brief Looks up a vnode by mount and node ID in the sVnodeTable.
|
|
|
|
|
|
|
|
The caller must hold the sVnodeMutex.
|
|
|
|
|
|
|
|
\param mountID the mount ID.
|
|
|
|
\param vnodeID the node ID.
|
2004-09-13 18:53:09 +04:00
|
|
|
|
2007-10-06 19:33:12 +04:00
|
|
|
\return The vnode structure, if it was found in the hash table, \c NULL
|
|
|
|
otherwise.
|
|
|
|
*/
|
2002-07-09 16:24:59 +04:00
|
|
|
static struct vnode *
|
2007-06-21 23:50:57 +04:00
|
|
|
lookup_vnode(dev_t mountID, ino_t vnodeID)
|
2002-07-09 16:24:59 +04:00
|
|
|
{
|
|
|
|
struct vnode_hash_key key;
|
|
|
|
|
2003-10-17 18:47:15 +04:00
|
|
|
key.device = mountID;
|
|
|
|
key.vnode = vnodeID;
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2003-10-17 18:47:15 +04:00
|
|
|
return (vnode *)hash_lookup(sVnodeTable, &key);
|
2002-07-09 16:24:59 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
static bool
|
|
|
|
is_special_node_type(int type)
|
|
|
|
{
|
|
|
|
// at the moment only FIFOs are supported
|
|
|
|
return S_ISFIFO(type);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static status_t
|
|
|
|
create_special_sub_node(struct vnode* vnode, uint32 flags)
|
|
|
|
{
|
|
|
|
if (S_ISFIFO(vnode->type))
|
|
|
|
return create_fifo_vnode(vnode->mount->volume, vnode);
|
|
|
|
|
|
|
|
return B_BAD_VALUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-10-06 19:33:12 +04:00
|
|
|
/*! \brief Retrieves a vnode for a given mount ID, node ID pair.
|
|
|
|
|
|
|
|
If the node is not yet in memory, it will be loaded.
|
2004-09-13 18:53:09 +04:00
|
|
|
|
2007-10-06 19:33:12 +04:00
|
|
|
The caller must not hold the sVnodeMutex or the sMountMutex.
|
|
|
|
|
|
|
|
\param mountID the mount ID.
|
|
|
|
\param vnodeID the node ID.
|
|
|
|
\param _vnode Pointer to a vnode* variable into which the pointer to the
|
|
|
|
retrieved vnode structure shall be written.
|
|
|
|
\param reenter \c true, if this function is called (indirectly) from within
|
|
|
|
a file system.
|
|
|
|
\return \c B_OK, if everything when fine, an error code otherwise.
|
|
|
|
*/
|
2003-02-21 16:49:26 +03:00
|
|
|
static status_t
|
2007-10-08 20:06:32 +04:00
|
|
|
get_vnode(dev_t mountID, ino_t vnodeID, struct vnode **_vnode, bool canWait,
|
|
|
|
int reenter)
|
2002-07-09 16:24:59 +04:00
|
|
|
{
|
2002-09-25 18:10:50 +04:00
|
|
|
FUNCTION(("get_vnode: mountid %ld vnid 0x%Lx %p\n", mountID, vnodeID, _vnode));
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2003-10-17 18:47:15 +04:00
|
|
|
mutex_lock(&sVnodeMutex);
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2007-10-08 20:06:32 +04:00
|
|
|
int32 tries = 1000;
|
|
|
|
// try for 10 secs
|
2004-02-02 18:09:21 +03:00
|
|
|
restart:
|
|
|
|
struct vnode *vnode = lookup_vnode(mountID, vnodeID);
|
|
|
|
if (vnode && vnode->busy) {
|
|
|
|
mutex_unlock(&sVnodeMutex);
|
2007-10-08 20:06:32 +04:00
|
|
|
if (!canWait || --tries < 0) {
|
2006-04-18 17:55:47 +04:00
|
|
|
// vnode doesn't seem to become unbusy
|
2007-10-08 20:06:32 +04:00
|
|
|
dprintf("vnode %ld:%Ld is not becoming unbusy!\n", mountID, vnodeID);
|
2006-04-18 17:55:47 +04:00
|
|
|
return B_BUSY;
|
|
|
|
}
|
2004-02-02 18:09:21 +03:00
|
|
|
snooze(10000); // 10 ms
|
|
|
|
mutex_lock(&sVnodeMutex);
|
|
|
|
goto restart;
|
2002-10-07 19:31:40 +04:00
|
|
|
}
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2005-12-16 20:35:03 +03:00
|
|
|
TRACE(("get_vnode: tried to lookup vnode, got %p\n", vnode));
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2004-02-02 18:09:21 +03:00
|
|
|
status_t status;
|
|
|
|
|
2002-07-20 04:16:12 +04:00
|
|
|
if (vnode) {
|
2004-11-30 00:27:17 +03:00
|
|
|
if (vnode->ref_count == 0) {
|
|
|
|
// this vnode has been unused before
|
|
|
|
list_remove_item(&sUnusedVnodeList, vnode);
|
2006-03-06 19:18:52 +03:00
|
|
|
sUnusedVnodes--;
|
2004-11-30 00:27:17 +03:00
|
|
|
}
|
2002-07-20 04:16:12 +04:00
|
|
|
inc_vnode_ref_count(vnode);
|
2002-07-09 16:24:59 +04:00
|
|
|
} else {
|
|
|
|
// we need to create a new vnode and read it in
|
2004-02-02 18:09:21 +03:00
|
|
|
status = create_new_vnode(&vnode, mountID, vnodeID);
|
|
|
|
if (status < B_OK)
|
2002-07-09 16:24:59 +04:00
|
|
|
goto err;
|
2002-09-26 07:50:14 +04:00
|
|
|
|
2002-07-20 04:16:12 +04:00
|
|
|
vnode->busy = true;
|
2003-10-17 18:47:15 +04:00
|
|
|
mutex_unlock(&sVnodeMutex);
|
2002-07-09 16:24:59 +04:00
|
|
|
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
int type;
|
|
|
|
uint32 flags;
|
|
|
|
status = FS_MOUNT_CALL(vnode->mount, get_vnode, vnodeID, vnode, &type,
|
|
|
|
&flags, reenter);
|
2006-04-18 21:40:27 +04:00
|
|
|
if (status == B_OK && vnode->private_node == NULL)
|
|
|
|
status = B_BAD_VALUE;
|
|
|
|
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
bool gotNode = status == B_OK;
|
|
|
|
bool publishSpecialSubNode = false;
|
|
|
|
if (gotNode) {
|
|
|
|
vnode->type = type;
|
|
|
|
publishSpecialSubNode = is_special_node_type(type)
|
|
|
|
&& (flags & B_VNODE_DONT_CREATE_SPECIAL_SUB_NODE) == 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (gotNode && publishSpecialSubNode)
|
|
|
|
status = create_special_sub_node(vnode, flags);
|
|
|
|
|
2003-10-17 18:47:15 +04:00
|
|
|
mutex_lock(&sVnodeMutex);
|
2004-02-02 18:09:21 +03:00
|
|
|
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
if (status < B_OK) {
|
|
|
|
if (gotNode)
|
|
|
|
FS_CALL(vnode, put_vnode, reenter);
|
|
|
|
|
2002-07-09 16:24:59 +04:00
|
|
|
goto err1;
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
}
|
2002-07-09 16:24:59 +04:00
|
|
|
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
vnode->remove = (flags & B_VNODE_PUBLISH_REMOVED) != 0;
|
2002-07-20 04:16:12 +04:00
|
|
|
vnode->busy = false;
|
2002-07-09 16:24:59 +04:00
|
|
|
}
|
|
|
|
|
2003-10-17 18:47:15 +04:00
|
|
|
mutex_unlock(&sVnodeMutex);
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2005-12-16 20:35:03 +03:00
|
|
|
TRACE(("get_vnode: returning %p\n", vnode));
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2002-07-20 04:16:12 +04:00
|
|
|
*_vnode = vnode;
|
|
|
|
return B_OK;
|
2002-07-09 16:24:59 +04:00
|
|
|
|
|
|
|
err1:
|
2003-10-17 18:47:15 +04:00
|
|
|
hash_remove(sVnodeTable, vnode);
|
2004-02-02 18:09:21 +03:00
|
|
|
remove_vnode_from_mount_list(vnode, vnode->mount);
|
2002-07-09 16:24:59 +04:00
|
|
|
err:
|
2003-10-17 18:47:15 +04:00
|
|
|
mutex_unlock(&sVnodeMutex);
|
2002-07-20 04:16:12 +04:00
|
|
|
if (vnode)
|
2002-10-30 02:07:06 +03:00
|
|
|
free(vnode);
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2004-02-02 18:09:21 +03:00
|
|
|
return status;
|
2002-07-09 16:24:59 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-10-06 19:33:12 +04:00
|
|
|
/*! \brief Decrements the reference counter of the given vnode and deletes it,
|
|
|
|
if the counter dropped to 0.
|
|
|
|
|
|
|
|
The caller must, of course, own a reference to the vnode to call this
|
|
|
|
function.
|
|
|
|
The caller must not hold the sVnodeMutex or the sMountMutex.
|
2004-09-13 18:53:09 +04:00
|
|
|
|
2007-10-06 19:33:12 +04:00
|
|
|
\param vnode the vnode.
|
|
|
|
*/
|
2002-08-10 00:20:28 +04:00
|
|
|
static inline void
|
2002-07-20 04:16:12 +04:00
|
|
|
put_vnode(struct vnode *vnode)
|
2002-07-09 16:24:59 +04:00
|
|
|
{
|
2002-07-20 04:16:12 +04:00
|
|
|
dec_vnode_ref_count(vnode, false);
|
2002-07-09 16:24:59 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2005-12-16 19:11:36 +03:00
|
|
|
static void
|
|
|
|
vnode_low_memory_handler(void */*data*/, int32 level)
|
|
|
|
{
|
2005-12-16 20:35:03 +03:00
|
|
|
TRACE(("vnode_low_memory_handler(level = %ld)\n", level));
|
2005-12-16 19:11:36 +03:00
|
|
|
|
2007-10-23 20:05:38 +04:00
|
|
|
uint32 count = 1;
|
2005-12-16 19:11:36 +03:00
|
|
|
switch (level) {
|
|
|
|
case B_NO_LOW_MEMORY:
|
|
|
|
return;
|
|
|
|
case B_LOW_MEMORY_NOTE:
|
|
|
|
count = sUnusedVnodes / 100;
|
|
|
|
break;
|
|
|
|
case B_LOW_MEMORY_WARNING:
|
|
|
|
count = sUnusedVnodes / 10;
|
|
|
|
break;
|
|
|
|
case B_LOW_MEMORY_CRITICAL:
|
|
|
|
count = sUnusedVnodes;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2007-10-23 20:05:38 +04:00
|
|
|
if (count > sUnusedVnodes)
|
|
|
|
count = sUnusedVnodes;
|
|
|
|
|
|
|
|
// first, write back the modified pages of some unused vnodes
|
|
|
|
|
|
|
|
uint32 freeCount = count;
|
|
|
|
|
|
|
|
for (uint32 i = 0; i < count; i++) {
|
|
|
|
mutex_lock(&sVnodeMutex);
|
|
|
|
struct vnode *vnode = (struct vnode *)list_remove_head_item(
|
|
|
|
&sUnusedVnodeList);
|
|
|
|
if (vnode == NULL) {
|
|
|
|
mutex_unlock(&sVnodeMutex);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
inc_vnode_ref_count(vnode);
|
|
|
|
sUnusedVnodes--;
|
|
|
|
|
|
|
|
mutex_unlock(&sVnodeMutex);
|
|
|
|
|
|
|
|
if (vnode->cache != NULL)
|
|
|
|
vm_cache_write_modified(vnode->cache, false);
|
|
|
|
|
|
|
|
dec_vnode_ref_count(vnode, false);
|
|
|
|
}
|
|
|
|
|
|
|
|
// and then free them
|
|
|
|
|
|
|
|
for (uint32 i = 0; i < freeCount; i++) {
|
2005-12-16 19:11:36 +03:00
|
|
|
mutex_lock(&sVnodeMutex);
|
|
|
|
|
2007-10-23 20:05:38 +04:00
|
|
|
// We're removing vnodes from the tail of the list - hoping it's
|
|
|
|
// one of those we have just written back; otherwise we'll write
|
|
|
|
// back the vnode with the busy flag turned on, and that might
|
|
|
|
// take some time.
|
|
|
|
struct vnode *vnode = (struct vnode *)list_remove_tail_item(
|
|
|
|
&sUnusedVnodeList);
|
2005-12-16 19:11:36 +03:00
|
|
|
if (vnode == NULL) {
|
|
|
|
mutex_unlock(&sVnodeMutex);
|
|
|
|
break;
|
|
|
|
}
|
2005-12-16 20:35:03 +03:00
|
|
|
TRACE((" free vnode %ld:%Ld (%p)\n", vnode->device, vnode->id, vnode));
|
2005-12-16 19:11:36 +03:00
|
|
|
|
|
|
|
vnode->busy = true;
|
|
|
|
sUnusedVnodes--;
|
|
|
|
|
|
|
|
mutex_unlock(&sVnodeMutex);
|
|
|
|
|
|
|
|
free_vnode(vnode, false);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-03-07 23:40:38 +03:00
|
|
|
static inline void
|
|
|
|
put_advisory_locking(struct advisory_locking *locking)
|
|
|
|
{
|
|
|
|
release_sem(locking->lock);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-10-06 19:33:12 +04:00
|
|
|
/*! Returns the advisory_locking object of the \a vnode in case it
|
|
|
|
has one, and locks it.
|
|
|
|
You have to call put_advisory_locking() when you're done with
|
|
|
|
it.
|
|
|
|
Note, you must not have the vnode mutex locked when calling
|
|
|
|
this function.
|
|
|
|
*/
|
2006-03-07 23:40:38 +03:00
|
|
|
static struct advisory_locking *
|
|
|
|
get_advisory_locking(struct vnode *vnode)
|
|
|
|
{
|
|
|
|
mutex_lock(&sVnodeMutex);
|
|
|
|
|
|
|
|
struct advisory_locking *locking = vnode->advisory_locking;
|
|
|
|
sem_id lock = locking != NULL ? locking->lock : B_ERROR;
|
|
|
|
|
|
|
|
mutex_unlock(&sVnodeMutex);
|
|
|
|
|
|
|
|
if (lock >= B_OK)
|
|
|
|
lock = acquire_sem(lock);
|
|
|
|
if (lock < B_OK) {
|
|
|
|
// This means the locking has been deleted in the mean time
|
|
|
|
// or had never existed in the first place - otherwise, we
|
|
|
|
// would get the lock at some point.
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
return locking;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-10-06 19:33:12 +04:00
|
|
|
/*! Creates a locked advisory_locking object, and attaches it to the
|
|
|
|
given \a vnode.
|
|
|
|
Returns B_OK in case of success - also if the vnode got such an
|
|
|
|
object from someone else in the mean time, you'll still get this
|
|
|
|
one locked then.
|
|
|
|
*/
|
2005-03-17 16:18:29 +03:00
|
|
|
static status_t
|
|
|
|
create_advisory_locking(struct vnode *vnode)
|
|
|
|
{
|
2005-12-16 19:11:36 +03:00
|
|
|
if (vnode == NULL)
|
|
|
|
return B_FILE_ERROR;
|
2005-03-17 16:18:29 +03:00
|
|
|
|
2008-02-19 22:16:36 +03:00
|
|
|
struct advisory_locking *locking = new(std::nothrow) advisory_locking;
|
2005-03-17 16:18:29 +03:00
|
|
|
if (locking == NULL)
|
|
|
|
return B_NO_MEMORY;
|
|
|
|
|
2005-12-16 19:11:36 +03:00
|
|
|
status_t status;
|
|
|
|
|
2005-03-17 16:18:29 +03:00
|
|
|
locking->wait_sem = create_sem(0, "advisory lock");
|
|
|
|
if (locking->wait_sem < B_OK) {
|
|
|
|
status = locking->wait_sem;
|
|
|
|
goto err1;
|
|
|
|
}
|
|
|
|
|
2006-03-07 23:40:38 +03:00
|
|
|
locking->lock = create_sem(0, "advisory locking");
|
2005-03-18 01:55:20 +03:00
|
|
|
if (locking->lock < B_OK) {
|
|
|
|
status = locking->lock;
|
2005-03-17 16:18:29 +03:00
|
|
|
goto err2;
|
2005-03-18 01:55:20 +03:00
|
|
|
}
|
2005-03-17 16:18:29 +03:00
|
|
|
|
2006-03-07 23:40:38 +03:00
|
|
|
// We need to set the locking structure atomically - someone
|
|
|
|
// else might set one at the same time
|
|
|
|
do {
|
2008-02-19 22:16:36 +03:00
|
|
|
if (atomic_test_and_set((vint32 *)&vnode->advisory_locking,
|
2008-03-18 19:10:04 +03:00
|
|
|
(addr_t)locking, (addr_t)NULL) == (addr_t)NULL)
|
2006-03-07 23:40:38 +03:00
|
|
|
return B_OK;
|
|
|
|
} while (get_advisory_locking(vnode) == NULL);
|
|
|
|
|
|
|
|
status = B_OK;
|
|
|
|
// we delete the one we've just created, but nevertheless, the vnode
|
|
|
|
// does have a locking structure now
|
|
|
|
|
|
|
|
delete_sem(locking->lock);
|
2005-03-17 16:18:29 +03:00
|
|
|
err2:
|
|
|
|
delete_sem(locking->wait_sem);
|
|
|
|
err1:
|
2008-02-19 22:16:36 +03:00
|
|
|
delete locking;
|
2005-03-17 16:18:29 +03:00
|
|
|
return status;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-10-06 19:33:12 +04:00
|
|
|
/*! Retrieves the first lock that has been set by the current team.
|
|
|
|
*/
|
2006-03-07 23:40:38 +03:00
|
|
|
static status_t
|
|
|
|
get_advisory_lock(struct vnode *vnode, struct flock *flock)
|
2005-03-17 16:18:29 +03:00
|
|
|
{
|
2006-03-07 23:40:38 +03:00
|
|
|
struct advisory_locking *locking = get_advisory_locking(vnode);
|
|
|
|
if (locking == NULL)
|
|
|
|
return B_BAD_VALUE;
|
2005-03-17 16:18:29 +03:00
|
|
|
|
2006-03-07 23:40:38 +03:00
|
|
|
// TODO: this should probably get the flock by its file descriptor!
|
|
|
|
team_id team = team_get_current_team_id();
|
|
|
|
status_t status = B_BAD_VALUE;
|
2005-03-17 16:18:29 +03:00
|
|
|
|
2008-02-19 22:16:36 +03:00
|
|
|
LockList::Iterator iterator = locking->locks.GetIterator();
|
|
|
|
while (iterator.HasNext()) {
|
|
|
|
struct advisory_lock *lock = iterator.Next();
|
|
|
|
|
2006-03-07 23:40:38 +03:00
|
|
|
if (lock->team == team) {
|
2008-02-19 22:16:36 +03:00
|
|
|
flock->l_start = lock->start;
|
|
|
|
flock->l_len = lock->end - lock->start + 1;
|
2006-03-07 23:40:38 +03:00
|
|
|
status = B_OK;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2005-03-17 16:18:29 +03:00
|
|
|
|
2006-03-07 23:40:38 +03:00
|
|
|
put_advisory_locking(locking);
|
|
|
|
return status;
|
2005-03-17 16:18:29 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-02-19 22:16:36 +03:00
|
|
|
/*! Returns \c true when either \a flock is \c NULL or the \a flock intersects
|
|
|
|
with the advisory_lock \a lock.
|
|
|
|
*/
|
|
|
|
static bool
|
|
|
|
advisory_lock_intersects(struct advisory_lock *lock, struct flock *flock)
|
|
|
|
{
|
|
|
|
if (flock == NULL)
|
|
|
|
return true;
|
|
|
|
|
|
|
|
return lock->start <= flock->l_start - 1 + flock->l_len
|
|
|
|
&& lock->end >= flock->l_start;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-10-06 19:33:12 +04:00
|
|
|
/*! Removes the specified lock, or all locks of the calling team
|
|
|
|
if \a flock is NULL.
|
|
|
|
*/
|
2005-03-17 16:18:29 +03:00
|
|
|
static status_t
|
|
|
|
release_advisory_lock(struct vnode *vnode, struct flock *flock)
|
|
|
|
{
|
|
|
|
FUNCTION(("release_advisory_lock(vnode = %p, flock = %p)\n", vnode, flock));
|
|
|
|
|
|
|
|
struct advisory_locking *locking = get_advisory_locking(vnode);
|
|
|
|
if (locking == NULL)
|
2008-02-19 22:16:36 +03:00
|
|
|
return B_OK;
|
2005-03-17 16:18:29 +03:00
|
|
|
|
2008-02-19 22:16:36 +03:00
|
|
|
// TODO: use the thread ID instead??
|
2005-03-17 16:18:29 +03:00
|
|
|
team_id team = team_get_current_team_id();
|
2008-02-03 18:37:31 +03:00
|
|
|
pid_t session = thread_get_current_thread()->team->session_id;
|
2005-03-17 16:18:29 +03:00
|
|
|
|
2008-02-19 22:16:36 +03:00
|
|
|
// find matching lock entries
|
|
|
|
|
|
|
|
LockList::Iterator iterator = locking->locks.GetIterator();
|
|
|
|
while (iterator.HasNext()) {
|
|
|
|
struct advisory_lock *lock = iterator.Next();
|
|
|
|
bool removeLock = false;
|
|
|
|
|
|
|
|
if (lock->session == session)
|
|
|
|
removeLock = true;
|
|
|
|
else if (lock->team == team && advisory_lock_intersects(lock, flock)) {
|
|
|
|
bool endsBeyond = false;
|
|
|
|
bool startsBefore = false;
|
|
|
|
if (flock != NULL) {
|
|
|
|
startsBefore = lock->start < flock->l_start;
|
|
|
|
endsBeyond = lock->end > flock->l_start - 1 + flock->l_len;
|
|
|
|
}
|
2005-03-17 16:18:29 +03:00
|
|
|
|
2008-02-19 22:16:36 +03:00
|
|
|
if (!startsBefore && !endsBeyond) {
|
|
|
|
// lock is completely contained in flock
|
|
|
|
removeLock = true;
|
|
|
|
} else if (startsBefore && !endsBeyond) {
|
|
|
|
// cut the end of the lock
|
|
|
|
lock->end = flock->l_start - 1;
|
|
|
|
} else if (!startsBefore && endsBeyond) {
|
|
|
|
// cut the start of the lock
|
|
|
|
lock->start = flock->l_start + flock->l_len;
|
|
|
|
} else {
|
|
|
|
// divide the lock into two locks
|
|
|
|
struct advisory_lock *secondLock = new advisory_lock;
|
|
|
|
if (secondLock == NULL) {
|
|
|
|
// TODO: we should probably revert the locks we already
|
|
|
|
// changed... (ie. allocate upfront)
|
|
|
|
put_advisory_locking(locking);
|
|
|
|
return B_NO_MEMORY;
|
|
|
|
}
|
|
|
|
|
|
|
|
lock->end = flock->l_start - 1;
|
|
|
|
|
|
|
|
secondLock->team = lock->team;
|
|
|
|
secondLock->session = lock->session;
|
|
|
|
// values must already be normalized when getting here
|
|
|
|
secondLock->start = flock->l_start + flock->l_len;
|
|
|
|
secondLock->end = lock->end;
|
|
|
|
secondLock->shared = lock->shared;
|
|
|
|
|
|
|
|
locking->locks.Add(secondLock);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (removeLock) {
|
|
|
|
// this lock is no longer used
|
|
|
|
iterator.Remove();
|
2005-03-17 16:18:29 +03:00
|
|
|
free(lock);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-02-19 22:16:36 +03:00
|
|
|
bool removeLocking = locking->locks.IsEmpty();
|
2005-03-17 16:18:29 +03:00
|
|
|
release_sem_etc(locking->wait_sem, 1, B_RELEASE_ALL);
|
|
|
|
|
|
|
|
put_advisory_locking(locking);
|
|
|
|
|
|
|
|
if (removeLocking) {
|
2008-02-19 22:16:36 +03:00
|
|
|
// We can remove the whole advisory locking structure; it's no
|
|
|
|
// longer used
|
2006-03-07 23:40:38 +03:00
|
|
|
locking = get_advisory_locking(vnode);
|
|
|
|
if (locking != NULL) {
|
|
|
|
// the locking could have been changed in the mean time
|
2008-02-19 22:16:36 +03:00
|
|
|
if (locking->locks.IsEmpty()) {
|
2006-03-07 23:40:38 +03:00
|
|
|
vnode->advisory_locking = NULL;
|
|
|
|
|
2008-02-19 22:16:36 +03:00
|
|
|
// we've detached the locking from the vnode, so we can
|
|
|
|
// safely delete it
|
2006-03-07 23:40:38 +03:00
|
|
|
delete_sem(locking->lock);
|
|
|
|
delete_sem(locking->wait_sem);
|
2008-02-19 22:16:36 +03:00
|
|
|
delete locking;
|
2006-03-07 23:40:38 +03:00
|
|
|
} else {
|
|
|
|
// the locking is in use again
|
|
|
|
release_sem_etc(locking->lock, 1, B_DO_NOT_RESCHEDULE);
|
|
|
|
}
|
2005-03-17 16:18:29 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return B_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-02-03 18:37:31 +03:00
|
|
|
/*! Acquires an advisory lock for the \a vnode. If \a wait is \c true, it
|
|
|
|
will wait for the lock to become available, if there are any collisions
|
|
|
|
(it will return B_PERMISSION_DENIED in this case if \a wait is \c false).
|
|
|
|
|
|
|
|
If \a session is -1, POSIX semantics are used for this lock. Otherwise,
|
|
|
|
BSD flock() semantics are used, that is, all children can unlock the file
|
|
|
|
in question (we even allow parents to remove the lock, though, but that
|
|
|
|
seems to be in line to what the BSD's are doing).
|
|
|
|
*/
|
2005-03-17 16:18:29 +03:00
|
|
|
static status_t
|
2008-02-03 18:37:31 +03:00
|
|
|
acquire_advisory_lock(struct vnode *vnode, pid_t session, struct flock *flock,
|
|
|
|
bool wait)
|
2005-03-17 16:18:29 +03:00
|
|
|
{
|
|
|
|
FUNCTION(("acquire_advisory_lock(vnode = %p, flock = %p, wait = %s)\n",
|
|
|
|
vnode, flock, wait ? "yes" : "no"));
|
|
|
|
|
|
|
|
bool shared = flock->l_type == F_RDLCK;
|
|
|
|
status_t status = B_OK;
|
|
|
|
|
2008-02-03 18:37:31 +03:00
|
|
|
// TODO: do deadlock detection!
|
|
|
|
|
2005-03-17 16:18:29 +03:00
|
|
|
restart:
|
|
|
|
// if this vnode has an advisory_locking structure attached,
|
2006-03-07 23:40:38 +03:00
|
|
|
// lock that one and search for any colliding file lock
|
2005-03-17 16:18:29 +03:00
|
|
|
struct advisory_locking *locking = get_advisory_locking(vnode);
|
2008-02-19 22:16:36 +03:00
|
|
|
team_id team = team_get_current_team_id();
|
2005-03-17 16:18:29 +03:00
|
|
|
sem_id waitForLock = -1;
|
|
|
|
|
|
|
|
if (locking != NULL) {
|
|
|
|
// test for collisions
|
2008-02-19 22:16:36 +03:00
|
|
|
LockList::Iterator iterator = locking->locks.GetIterator();
|
|
|
|
while (iterator.HasNext()) {
|
|
|
|
struct advisory_lock *lock = iterator.Next();
|
|
|
|
|
|
|
|
// TODO: locks from the same team might be joinable!
|
|
|
|
if (lock->team != team && advisory_lock_intersects(lock, flock)) {
|
2005-03-17 16:18:29 +03:00
|
|
|
// locks do overlap
|
|
|
|
if (!shared || !lock->shared) {
|
|
|
|
// we need to wait
|
|
|
|
waitForLock = locking->wait_sem;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2005-03-18 01:55:20 +03:00
|
|
|
if (waitForLock < B_OK || !wait)
|
|
|
|
put_advisory_locking(locking);
|
2005-03-17 16:18:29 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
// wait for the lock if we have to, or else return immediately
|
|
|
|
|
|
|
|
if (waitForLock >= B_OK) {
|
|
|
|
if (!wait)
|
2008-02-03 18:37:31 +03:00
|
|
|
status = session != -1 ? B_WOULD_BLOCK : B_PERMISSION_DENIED;
|
2005-03-17 16:18:29 +03:00
|
|
|
else {
|
2008-02-03 18:37:31 +03:00
|
|
|
status = switch_sem_etc(locking->lock, waitForLock, 1,
|
|
|
|
B_CAN_INTERRUPT, 0);
|
2005-03-17 16:18:29 +03:00
|
|
|
if (status == B_OK) {
|
|
|
|
// see if we're still colliding
|
|
|
|
goto restart;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (status < B_OK)
|
|
|
|
return status;
|
|
|
|
|
|
|
|
// install new lock
|
|
|
|
|
2006-03-07 23:40:38 +03:00
|
|
|
locking = get_advisory_locking(vnode);
|
2005-03-17 16:18:29 +03:00
|
|
|
if (locking == NULL) {
|
2006-03-07 23:40:38 +03:00
|
|
|
// we need to create a new locking object
|
2005-03-17 16:18:29 +03:00
|
|
|
status = create_advisory_locking(vnode);
|
2006-03-07 23:40:38 +03:00
|
|
|
if (status < B_OK)
|
|
|
|
return status;
|
|
|
|
|
2005-03-17 16:18:29 +03:00
|
|
|
locking = vnode->advisory_locking;
|
2006-03-07 23:40:38 +03:00
|
|
|
// we own the locking object, so it can't go away
|
2005-03-17 16:18:29 +03:00
|
|
|
}
|
|
|
|
|
2008-02-03 18:37:31 +03:00
|
|
|
struct advisory_lock *lock = (struct advisory_lock *)malloc(
|
|
|
|
sizeof(struct advisory_lock));
|
2005-03-17 16:18:29 +03:00
|
|
|
if (lock == NULL) {
|
|
|
|
if (waitForLock >= B_OK)
|
|
|
|
release_sem_etc(waitForLock, 1, B_RELEASE_ALL);
|
2005-03-18 01:55:20 +03:00
|
|
|
release_sem(locking->lock);
|
2005-03-17 16:18:29 +03:00
|
|
|
return B_NO_MEMORY;
|
|
|
|
}
|
|
|
|
|
|
|
|
lock->team = team_get_current_team_id();
|
2008-02-03 18:37:31 +03:00
|
|
|
lock->session = session;
|
2005-03-17 16:18:29 +03:00
|
|
|
// values must already be normalized when getting here
|
2008-02-19 22:16:36 +03:00
|
|
|
lock->start = flock->l_start;
|
|
|
|
lock->end = flock->l_start - 1 + flock->l_len;
|
2005-03-17 16:18:29 +03:00
|
|
|
lock->shared = shared;
|
|
|
|
|
2008-02-19 22:16:36 +03:00
|
|
|
locking->locks.Add(lock);
|
2006-03-07 23:40:38 +03:00
|
|
|
put_advisory_locking(locking);
|
2005-03-17 16:18:29 +03:00
|
|
|
|
|
|
|
return status;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-02-03 18:37:31 +03:00
|
|
|
/*! Normalizes the \a flock structure to make it easier to compare the
|
|
|
|
structure with others. The l_start and l_len fields are set to absolute
|
|
|
|
values according to the l_whence field.
|
|
|
|
*/
|
2005-03-17 16:18:29 +03:00
|
|
|
static status_t
|
|
|
|
normalize_flock(struct file_descriptor *descriptor, struct flock *flock)
|
|
|
|
{
|
|
|
|
switch (flock->l_whence) {
|
|
|
|
case SEEK_SET:
|
|
|
|
break;
|
|
|
|
case SEEK_CUR:
|
|
|
|
flock->l_start += descriptor->pos;
|
|
|
|
break;
|
|
|
|
case SEEK_END:
|
|
|
|
{
|
|
|
|
struct vnode *vnode = descriptor->u.vnode;
|
|
|
|
struct stat stat;
|
|
|
|
status_t status;
|
|
|
|
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
if (!HAS_FS_CALL(vnode, read_stat))
|
2005-03-17 16:18:29 +03:00
|
|
|
return EOPNOTSUPP;
|
|
|
|
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
status = FS_CALL(vnode, read_stat, &stat);
|
2005-03-17 16:18:29 +03:00
|
|
|
if (status < B_OK)
|
|
|
|
return status;
|
|
|
|
|
|
|
|
flock->l_start += stat.st_size;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
default:
|
|
|
|
return B_BAD_VALUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (flock->l_start < 0)
|
|
|
|
flock->l_start = 0;
|
|
|
|
if (flock->l_len == 0)
|
|
|
|
flock->l_len = OFF_MAX;
|
|
|
|
|
|
|
|
// don't let the offset and length overflow
|
|
|
|
if (flock->l_start > 0 && OFF_MAX - flock->l_start < flock->l_len)
|
|
|
|
flock->l_len = OFF_MAX - flock->l_start;
|
|
|
|
|
|
|
|
if (flock->l_len < 0) {
|
|
|
|
// a negative length reverses the region
|
|
|
|
flock->l_start += flock->l_len;
|
|
|
|
flock->l_len = -flock->l_len;
|
|
|
|
}
|
|
|
|
|
|
|
|
return B_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-03-30 09:59:54 +04:00
|
|
|
static void
|
|
|
|
replace_vnode_if_disconnected(struct fs_mount* mount,
|
|
|
|
struct vnode* vnodeToDisconnect, struct vnode*& vnode,
|
|
|
|
struct vnode* fallBack, bool lockRootLock)
|
|
|
|
{
|
|
|
|
if (lockRootLock)
|
|
|
|
benaphore_lock(&sIOContextRootLock);
|
|
|
|
|
|
|
|
struct vnode* obsoleteVnode = NULL;
|
|
|
|
|
|
|
|
if (vnode != NULL && vnode->mount == mount
|
|
|
|
&& (vnodeToDisconnect == NULL || vnodeToDisconnect == vnode)) {
|
|
|
|
obsoleteVnode = vnode;
|
|
|
|
|
|
|
|
if (vnode == mount->root_vnode) {
|
|
|
|
// redirect the vnode to the covered vnode
|
|
|
|
vnode = mount->covers_vnode;
|
|
|
|
} else
|
|
|
|
vnode = fallBack;
|
|
|
|
|
|
|
|
if (vnode != NULL)
|
|
|
|
inc_vnode_ref_count(vnode);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (lockRootLock)
|
|
|
|
benaphore_unlock(&sIOContextRootLock);
|
|
|
|
|
|
|
|
if (obsoleteVnode != NULL)
|
|
|
|
put_vnode(obsoleteVnode);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-03-04 19:59:59 +03:00
|
|
|
/*! Disconnects all file descriptors that are associated with the
|
2007-10-06 19:33:12 +04:00
|
|
|
\a vnodeToDisconnect, or if this is NULL, all vnodes of the specified
|
|
|
|
\a mount object.
|
2006-03-28 05:13:12 +04:00
|
|
|
|
2007-10-06 19:33:12 +04:00
|
|
|
Note, after you've called this function, there might still be ongoing
|
|
|
|
accesses - they won't be interrupted if they already happened before.
|
|
|
|
However, any subsequent access will fail.
|
|
|
|
|
|
|
|
This is not a cheap function and should be used with care and rarely.
|
|
|
|
TODO: there is currently no means to stop a blocking read/write!
|
|
|
|
*/
|
2006-03-28 05:13:12 +04:00
|
|
|
void
|
|
|
|
disconnect_mount_or_vnode_fds(struct fs_mount *mount,
|
|
|
|
struct vnode *vnodeToDisconnect)
|
|
|
|
{
|
|
|
|
// iterate over all teams and peek into their file descriptors
|
|
|
|
int32 nextTeamID = 0;
|
|
|
|
|
|
|
|
while (true) {
|
|
|
|
struct io_context *context = NULL;
|
|
|
|
sem_id contextMutex = -1;
|
|
|
|
struct team *team = NULL;
|
|
|
|
team_id lastTeamID;
|
|
|
|
|
|
|
|
cpu_status state = disable_interrupts();
|
|
|
|
GRAB_TEAM_LOCK();
|
|
|
|
|
|
|
|
lastTeamID = peek_next_thread_id();
|
|
|
|
if (nextTeamID < lastTeamID) {
|
|
|
|
// get next valid team
|
|
|
|
while (nextTeamID < lastTeamID
|
|
|
|
&& !(team = team_get_team_struct_locked(nextTeamID))) {
|
|
|
|
nextTeamID++;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (team) {
|
|
|
|
context = (io_context *)team->io_context;
|
|
|
|
contextMutex = context->io_mutex.sem;
|
|
|
|
nextTeamID++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
RELEASE_TEAM_LOCK();
|
|
|
|
restore_interrupts(state);
|
|
|
|
|
|
|
|
if (context == NULL)
|
|
|
|
break;
|
|
|
|
|
|
|
|
// we now have a context - since we couldn't lock it while having
|
|
|
|
// safe access to the team structure, we now need to lock the mutex
|
|
|
|
// manually
|
|
|
|
|
|
|
|
if (acquire_sem(contextMutex) != B_OK) {
|
|
|
|
// team seems to be gone, go over to the next team
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
// the team cannot be deleted completely while we're owning its
|
|
|
|
// io_context mutex, so we can safely play with it now
|
|
|
|
|
|
|
|
context->io_mutex.holder = thread_get_current_thread_id();
|
|
|
|
|
2008-03-30 09:59:54 +04:00
|
|
|
replace_vnode_if_disconnected(mount, vnodeToDisconnect, context->root,
|
|
|
|
sRoot, true);
|
|
|
|
replace_vnode_if_disconnected(mount, vnodeToDisconnect, context->cwd,
|
|
|
|
sRoot, false);
|
2006-03-28 05:13:12 +04:00
|
|
|
|
|
|
|
for (uint32 i = 0; i < context->table_size; i++) {
|
|
|
|
if (struct file_descriptor *descriptor = context->fds[i]) {
|
|
|
|
inc_fd_ref_count(descriptor);
|
|
|
|
|
|
|
|
// if this descriptor points at this mount, we
|
|
|
|
// need to disconnect it to be able to unmount
|
|
|
|
struct vnode *vnode = fd_vnode(descriptor);
|
|
|
|
if (vnodeToDisconnect != NULL) {
|
|
|
|
if (vnode == vnodeToDisconnect)
|
|
|
|
disconnect_fd(descriptor);
|
|
|
|
} else if (vnode != NULL && vnode->mount == mount
|
|
|
|
|| vnode == NULL && descriptor->u.mount == mount)
|
|
|
|
disconnect_fd(descriptor);
|
|
|
|
|
|
|
|
put_fd(descriptor);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
mutex_unlock(&context->io_mutex);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-03-30 09:59:54 +04:00
|
|
|
/*! \brief Gets the root node of the current IO context.
|
|
|
|
If \a kernel is \c true, the kernel IO context will be used.
|
|
|
|
The caller obtains a reference to the returned node.
|
|
|
|
*/
|
|
|
|
struct vnode*
|
|
|
|
get_root_vnode(bool kernel)
|
|
|
|
{
|
|
|
|
if (!kernel) {
|
|
|
|
// Get current working directory from io context
|
|
|
|
struct io_context* context = get_current_io_context(kernel);
|
|
|
|
|
|
|
|
benaphore_lock(&sIOContextRootLock);
|
|
|
|
|
|
|
|
struct vnode* root = context->root;
|
|
|
|
if (root != NULL)
|
|
|
|
inc_vnode_ref_count(root);
|
|
|
|
|
|
|
|
benaphore_unlock(&sIOContextRootLock);
|
|
|
|
|
|
|
|
if (root != NULL)
|
|
|
|
return root;
|
|
|
|
|
|
|
|
// That should never happen.
|
|
|
|
dprintf("get_root_vnode(): IO context for team %ld doesn't have a "
|
|
|
|
"root\n", team_get_current_team_id());
|
|
|
|
}
|
|
|
|
|
|
|
|
inc_vnode_ref_count(sRoot);
|
|
|
|
return sRoot;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-10-06 19:33:12 +04:00
|
|
|
/*! \brief Resolves a mount point vnode to the volume root vnode it is covered
|
|
|
|
by.
|
|
|
|
|
|
|
|
Given an arbitrary vnode, the function checks, whether the node is covered
|
|
|
|
by the root of a volume. If it is the function obtains a reference to the
|
|
|
|
volume root node and returns it.
|
2005-03-17 16:18:29 +03:00
|
|
|
|
2007-10-06 19:33:12 +04:00
|
|
|
\param vnode The vnode in question.
|
|
|
|
\return The volume root vnode the vnode cover is covered by, if it is
|
|
|
|
indeed a mount point, or \c NULL otherwise.
|
|
|
|
*/
|
2005-01-18 18:59:18 +03:00
|
|
|
static struct vnode *
|
2004-10-29 02:31:43 +04:00
|
|
|
resolve_mount_point_to_volume_root(struct vnode *vnode)
|
|
|
|
{
|
|
|
|
if (!vnode)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
struct vnode *volumeRoot = NULL;
|
|
|
|
|
2007-03-03 05:42:36 +03:00
|
|
|
mutex_lock(&sVnodeCoveredByMutex);
|
2004-10-29 02:31:43 +04:00
|
|
|
if (vnode->covered_by) {
|
|
|
|
volumeRoot = vnode->covered_by;
|
|
|
|
inc_vnode_ref_count(volumeRoot);
|
|
|
|
}
|
2007-03-03 05:42:36 +03:00
|
|
|
mutex_unlock(&sVnodeCoveredByMutex);
|
2004-10-29 02:31:43 +04:00
|
|
|
|
|
|
|
return volumeRoot;
|
|
|
|
}
|
|
|
|
|
2004-10-05 20:08:31 +04:00
|
|
|
|
2007-10-06 19:33:12 +04:00
|
|
|
/*! \brief Resolves a mount point vnode to the volume root vnode it is covered
|
|
|
|
by.
|
|
|
|
|
|
|
|
Given an arbitrary vnode (identified by mount and node ID), the function
|
|
|
|
checks, whether the node is covered by the root of a volume. If it is the
|
|
|
|
function returns the mount and node ID of the volume root node. Otherwise
|
|
|
|
it simply returns the supplied mount and node ID.
|
|
|
|
|
|
|
|
In case of error (e.g. the supplied node could not be found) the variables
|
|
|
|
for storing the resolved mount and node ID remain untouched and an error
|
|
|
|
code is returned.
|
2005-03-17 16:18:29 +03:00
|
|
|
|
2007-10-06 19:33:12 +04:00
|
|
|
\param mountID The mount ID of the vnode in question.
|
|
|
|
\param nodeID The node ID of the vnode in question.
|
|
|
|
\param resolvedMountID Pointer to storage for the resolved mount ID.
|
|
|
|
\param resolvedNodeID Pointer to storage for the resolved node ID.
|
|
|
|
\return
|
|
|
|
- \c B_OK, if everything went fine,
|
|
|
|
- another error code, if something went wrong.
|
|
|
|
*/
|
2005-01-30 19:11:46 +03:00
|
|
|
status_t
|
2007-06-21 23:50:57 +04:00
|
|
|
resolve_mount_point_to_volume_root(dev_t mountID, ino_t nodeID,
|
|
|
|
dev_t *resolvedMountID, ino_t *resolvedNodeID)
|
2005-01-30 19:11:46 +03:00
|
|
|
{
|
|
|
|
// get the node
|
|
|
|
struct vnode *node;
|
2007-10-08 20:06:32 +04:00
|
|
|
status_t error = get_vnode(mountID, nodeID, &node, true, false);
|
2005-01-30 19:11:46 +03:00
|
|
|
if (error != B_OK)
|
|
|
|
return error;
|
|
|
|
|
|
|
|
// resolve the node
|
|
|
|
struct vnode *resolvedNode = resolve_mount_point_to_volume_root(node);
|
|
|
|
if (resolvedNode) {
|
|
|
|
put_vnode(node);
|
|
|
|
node = resolvedNode;
|
|
|
|
}
|
|
|
|
|
|
|
|
// set the return values
|
|
|
|
*resolvedMountID = node->device;
|
|
|
|
*resolvedNodeID = node->id;
|
|
|
|
|
|
|
|
put_vnode(node);
|
|
|
|
|
|
|
|
return B_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-10-06 19:33:12 +04:00
|
|
|
/*! \brief Resolves a volume root vnode to the underlying mount point vnode.
|
|
|
|
|
|
|
|
Given an arbitrary vnode, the function checks, whether the node is the
|
|
|
|
root of a volume. If it is (and if it is not "/"), the function obtains
|
|
|
|
a reference to the underlying mount point node and returns it.
|
2004-10-05 20:08:31 +04:00
|
|
|
|
2007-10-06 19:33:12 +04:00
|
|
|
\param vnode The vnode in question (caller must have a reference).
|
|
|
|
\return The mount point vnode the vnode covers, if it is indeed a volume
|
|
|
|
root and not "/", or \c NULL otherwise.
|
|
|
|
*/
|
2005-01-18 18:59:18 +03:00
|
|
|
static struct vnode *
|
2004-10-05 20:08:31 +04:00
|
|
|
resolve_volume_root_to_mount_point(struct vnode *vnode)
|
|
|
|
{
|
|
|
|
if (!vnode)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
struct vnode *mountPoint = NULL;
|
|
|
|
|
2004-10-29 02:31:43 +04:00
|
|
|
struct fs_mount *mount = vnode->mount;
|
|
|
|
if (vnode == mount->root_vnode && mount->covers_vnode) {
|
|
|
|
mountPoint = mount->covers_vnode;
|
2004-10-05 20:08:31 +04:00
|
|
|
inc_vnode_ref_count(mountPoint);
|
|
|
|
}
|
|
|
|
|
|
|
|
return mountPoint;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-10-05 22:42:50 +04:00
|
|
|
/*! \brief Gets the directory path and leaf name for a given path.
|
|
|
|
|
|
|
|
The supplied \a path is transformed to refer to the directory part of
|
|
|
|
the entry identified by the original path, and into the buffer \a filename
|
|
|
|
the leaf name of the original entry is written.
|
|
|
|
Neither the returned path nor the leaf name can be expected to be
|
|
|
|
canonical.
|
|
|
|
|
|
|
|
\param path The path to be analyzed. Must be able to store at least one
|
|
|
|
additional character.
|
|
|
|
\param filename The buffer into which the leaf name will be written.
|
|
|
|
Must be of size B_FILE_NAME_LENGTH at least.
|
|
|
|
\return \c B_OK, if everything went fine, \c B_NAME_TOO_LONG, if the leaf
|
|
|
|
name is longer than \c B_FILE_NAME_LENGTH, or \c B_ENTRY_NOT_FOUND,
|
|
|
|
if the given path name is empty.
|
|
|
|
*/
|
2004-08-29 00:38:39 +04:00
|
|
|
static status_t
|
|
|
|
get_dir_path_and_leaf(char *path, char *filename)
|
|
|
|
{
|
2007-10-05 22:42:50 +04:00
|
|
|
if (*path == '\0')
|
|
|
|
return B_ENTRY_NOT_FOUND;
|
|
|
|
|
2004-08-29 00:38:39 +04:00
|
|
|
char *p = strrchr(path, '/');
|
|
|
|
// '/' are not allowed in file names!
|
|
|
|
|
|
|
|
FUNCTION(("get_dir_path_and_leaf(path = %s)\n", path));
|
|
|
|
|
|
|
|
if (!p) {
|
|
|
|
// this path is single segment with no '/' in it
|
|
|
|
// ex. "foo"
|
|
|
|
if (strlcpy(filename, path, B_FILE_NAME_LENGTH) >= B_FILE_NAME_LENGTH)
|
|
|
|
return B_NAME_TOO_LONG;
|
|
|
|
strcpy(path, ".");
|
|
|
|
} else {
|
2004-10-29 02:31:43 +04:00
|
|
|
p++;
|
2008-04-11 18:37:48 +04:00
|
|
|
if (p[0] == '\0') {
|
|
|
|
// special case: the path ends in one or more '/' - remove them
|
|
|
|
while (*--p == '/' && p != path);
|
|
|
|
p[1] = '\0';
|
|
|
|
|
|
|
|
if (p == path && p[0] == '/') {
|
|
|
|
// This path points to the root of the file system
|
|
|
|
strcpy(filename, ".");
|
|
|
|
return B_OK;
|
2004-10-29 02:31:43 +04:00
|
|
|
}
|
2008-04-11 18:37:48 +04:00
|
|
|
for (; p != path && *(p - 1) != '/'; p--);
|
|
|
|
// rewind to the start of the leaf before the '/'
|
|
|
|
}
|
|
|
|
|
|
|
|
// normal leaf: replace the leaf portion of the path with a '.'
|
|
|
|
if (strlcpy(filename, p, B_FILE_NAME_LENGTH)
|
|
|
|
>= B_FILE_NAME_LENGTH) {
|
|
|
|
return B_NAME_TOO_LONG;
|
2004-08-29 00:38:39 +04:00
|
|
|
}
|
2004-10-29 02:31:43 +04:00
|
|
|
p[0] = '.';
|
|
|
|
p[1] = '\0';
|
2004-08-29 00:38:39 +04:00
|
|
|
}
|
|
|
|
return B_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2002-07-20 04:16:12 +04:00
|
|
|
static status_t
|
2007-10-05 22:42:50 +04:00
|
|
|
entry_ref_to_vnode(dev_t mountID, ino_t directoryID, const char *name,
|
2008-03-30 09:59:54 +04:00
|
|
|
bool traverse, bool kernel, struct vnode **_vnode)
|
2002-07-20 04:16:12 +04:00
|
|
|
{
|
2004-09-12 14:58:29 +04:00
|
|
|
char clonedName[B_FILE_NAME_LENGTH + 1];
|
|
|
|
if (strlcpy(clonedName, name, B_FILE_NAME_LENGTH) >= B_FILE_NAME_LENGTH)
|
|
|
|
return B_NAME_TOO_LONG;
|
2004-09-12 04:05:51 +04:00
|
|
|
|
2004-09-12 14:58:29 +04:00
|
|
|
// get the directory vnode and let vnode_path_to_vnode() do the rest
|
|
|
|
struct vnode *directory;
|
2002-07-20 04:16:12 +04:00
|
|
|
|
2007-10-08 20:06:32 +04:00
|
|
|
status_t status = get_vnode(mountID, directoryID, &directory, true, false);
|
2002-07-20 04:16:12 +04:00
|
|
|
if (status < 0)
|
|
|
|
return status;
|
|
|
|
|
2008-03-30 09:59:54 +04:00
|
|
|
return vnode_path_to_vnode(directory, clonedName, traverse, 0, kernel,
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
_vnode, NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static status_t
|
|
|
|
lookup_dir_entry(struct vnode* dir, const char* name, struct vnode** _vnode)
|
|
|
|
{
|
|
|
|
ino_t id;
|
|
|
|
status_t status = FS_CALL(dir, lookup, name, &id);
|
|
|
|
if (status < B_OK)
|
|
|
|
return status;
|
|
|
|
|
|
|
|
mutex_lock(&sVnodeMutex);
|
|
|
|
*_vnode = lookup_vnode(dir->device, id);
|
|
|
|
mutex_unlock(&sVnodeMutex);
|
|
|
|
|
|
|
|
if (*_vnode == NULL) {
|
|
|
|
panic("lookup_dir_entry(): could not lookup vnode (mountid 0x%lx vnid "
|
|
|
|
"0x%Lx)\n", dir->device, id);
|
|
|
|
return B_ENTRY_NOT_FOUND;
|
|
|
|
}
|
|
|
|
|
|
|
|
return B_OK;
|
2002-07-20 04:16:12 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-10-05 22:42:50 +04:00
|
|
|
/*! Returns the vnode for the relative path starting at the specified \a vnode.
|
|
|
|
\a path must not be NULL.
|
|
|
|
If it returns successfully, \a path contains the name of the last path
|
2008-03-09 16:43:38 +03:00
|
|
|
component. This function clobbers the buffer pointed to by \a path only
|
|
|
|
if it does contain more than one component.
|
2007-10-05 22:42:50 +04:00
|
|
|
Note, this reduces the ref_count of the starting \a vnode, no matter if
|
|
|
|
it is successful or not!
|
|
|
|
*/
|
2002-10-05 23:45:31 +04:00
|
|
|
static status_t
|
2003-09-08 08:02:34 +04:00
|
|
|
vnode_path_to_vnode(struct vnode *vnode, char *path, bool traverseLeafLink,
|
2008-03-30 09:59:54 +04:00
|
|
|
int count, struct io_context *ioContext, struct vnode **_vnode,
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
ino_t *_parentID)
|
2002-07-09 16:24:59 +04:00
|
|
|
{
|
2008-04-01 21:59:51 +04:00
|
|
|
status_t status = B_OK;
|
2007-06-21 23:50:57 +04:00
|
|
|
ino_t lastParentID = vnode->id;
|
2002-10-05 23:45:31 +04:00
|
|
|
|
2004-06-08 15:34:49 +04:00
|
|
|
FUNCTION(("vnode_path_to_vnode(vnode = %p, path = %s)\n", vnode, path));
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2006-03-09 00:42:14 +03:00
|
|
|
if (path == NULL) {
|
|
|
|
put_vnode(vnode);
|
2004-06-08 15:34:49 +04:00
|
|
|
return B_BAD_VALUE;
|
2006-03-09 00:42:14 +03:00
|
|
|
}
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2007-10-05 22:42:50 +04:00
|
|
|
if (*path == '\0') {
|
|
|
|
put_vnode(vnode);
|
|
|
|
return B_ENTRY_NOT_FOUND;
|
|
|
|
}
|
|
|
|
|
2002-07-28 23:39:49 +04:00
|
|
|
while (true) {
|
2002-07-28 22:41:07 +04:00
|
|
|
struct vnode *nextVnode;
|
2007-06-21 23:50:57 +04:00
|
|
|
ino_t vnodeID;
|
2002-07-28 22:41:07 +04:00
|
|
|
char *nextPath;
|
|
|
|
|
2005-12-16 20:35:03 +03:00
|
|
|
TRACE(("vnode_path_to_vnode: top of loop. p = %p, p = '%s'\n", path, path));
|
2002-07-09 16:24:59 +04:00
|
|
|
|
|
|
|
// done?
|
2003-08-18 07:21:26 +04:00
|
|
|
if (path[0] == '\0')
|
2002-07-09 16:24:59 +04:00
|
|
|
break;
|
|
|
|
|
2002-07-28 22:41:07 +04:00
|
|
|
// walk to find the next path component ("path" will point to a single
|
|
|
|
// path component), and filter out multiple slashes
|
2008-04-01 21:59:51 +04:00
|
|
|
for (nextPath = path + 1; *nextPath != '\0' && *nextPath != '/';
|
|
|
|
nextPath++);
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2002-07-20 04:16:12 +04:00
|
|
|
if (*nextPath == '/') {
|
|
|
|
*nextPath = '\0';
|
2002-07-09 16:24:59 +04:00
|
|
|
do
|
2002-07-20 04:16:12 +04:00
|
|
|
nextPath++;
|
|
|
|
while (*nextPath == '/');
|
2002-07-09 16:24:59 +04:00
|
|
|
}
|
|
|
|
|
2004-06-08 15:34:49 +04:00
|
|
|
// See if the '..' is at the root of a mount and move to the covered
|
2008-03-30 09:59:54 +04:00
|
|
|
// vnode so we pass the '..' path to the underlying filesystem.
|
|
|
|
// Also prevent breaking the root of the IO context.
|
|
|
|
if (strcmp("..", path) == 0) {
|
|
|
|
if (vnode == ioContext->root) {
|
|
|
|
// Attempted prison break! Keep it contained.
|
|
|
|
path = nextPath;
|
|
|
|
continue;
|
|
|
|
} else if (vnode->mount->root_vnode == vnode
|
|
|
|
&& vnode->mount->covers_vnode) {
|
|
|
|
nextVnode = vnode->mount->covers_vnode;
|
|
|
|
inc_vnode_ref_count(nextVnode);
|
|
|
|
put_vnode(vnode);
|
|
|
|
vnode = nextVnode;
|
|
|
|
}
|
2008-04-02 05:55:37 +04:00
|
|
|
}
|
2008-04-01 21:59:51 +04:00
|
|
|
|
2008-04-02 05:55:37 +04:00
|
|
|
// check if vnode is really a directory
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
if (status == B_OK && !S_ISDIR(vnode->type))
|
2008-04-02 05:55:37 +04:00
|
|
|
status = B_NOT_A_DIRECTORY;
|
|
|
|
|
2002-11-11 15:14:19 +03:00
|
|
|
// Check if we have the right to search the current directory vnode.
|
|
|
|
// If a file system doesn't have the access() function, we assume that
|
|
|
|
// searching a directory is always allowed
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
if (status == B_OK && HAS_FS_CALL(vnode, access))
|
|
|
|
status = FS_CALL(vnode, access, X_OK);
|
2002-11-11 15:14:19 +03:00
|
|
|
|
|
|
|
// Tell the filesystem to get the vnode of this path component (if we got the
|
|
|
|
// permission from the call above)
|
|
|
|
if (status >= B_OK)
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
status = lookup_dir_entry(vnode, path, &nextVnode);
|
2002-11-11 15:14:19 +03:00
|
|
|
|
|
|
|
if (status < B_OK) {
|
2002-07-28 22:41:07 +04:00
|
|
|
put_vnode(vnode);
|
2002-07-28 23:39:49 +04:00
|
|
|
return status;
|
2002-07-09 16:24:59 +04:00
|
|
|
}
|
|
|
|
|
2008-04-01 21:39:52 +04:00
|
|
|
// If the new node is a symbolic link, resolve it (if we've been told
|
|
|
|
// to do it)
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
if (S_ISLNK(nextVnode->type)
|
|
|
|
&& !(!traverseLeafLink && nextPath[0] == '\0')) {
|
2005-04-06 20:07:10 +04:00
|
|
|
size_t bufferSize;
|
2002-07-28 23:39:49 +04:00
|
|
|
char *buffer;
|
|
|
|
|
2005-12-16 20:35:03 +03:00
|
|
|
TRACE(("traverse link\n"));
|
2004-06-08 10:43:46 +04:00
|
|
|
|
2002-08-03 06:03:27 +04:00
|
|
|
// it's not exactly nice style using goto in this way, but hey, it works :-/
|
2006-06-21 19:44:46 +04:00
|
|
|
if (count + 1 > B_MAX_SYMLINKS) {
|
2002-08-03 06:03:27 +04:00
|
|
|
status = B_LINK_LIMIT;
|
|
|
|
goto resolve_link_error;
|
2002-07-28 23:39:49 +04:00
|
|
|
}
|
|
|
|
|
2005-04-06 20:07:10 +04:00
|
|
|
buffer = (char *)malloc(bufferSize = B_PATH_NAME_LENGTH);
|
2002-07-28 23:39:49 +04:00
|
|
|
if (buffer == NULL) {
|
2002-08-03 06:03:27 +04:00
|
|
|
status = B_NO_MEMORY;
|
|
|
|
goto resolve_link_error;
|
2002-07-28 23:39:49 +04:00
|
|
|
}
|
2002-08-03 06:03:27 +04:00
|
|
|
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
if (HAS_FS_CALL(nextVnode, read_symlink)) {
|
2008-03-18 00:37:40 +03:00
|
|
|
bufferSize--;
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
status = FS_CALL(nextVnode, read_symlink, buffer, &bufferSize);
|
2008-03-18 00:37:40 +03:00
|
|
|
// null-terminate
|
|
|
|
if (status >= 0)
|
|
|
|
buffer[bufferSize] = '\0';
|
2007-03-05 06:52:57 +03:00
|
|
|
} else
|
|
|
|
status = B_BAD_VALUE;
|
|
|
|
|
2002-07-28 23:39:49 +04:00
|
|
|
if (status < B_OK) {
|
2002-10-30 02:07:06 +03:00
|
|
|
free(buffer);
|
2002-08-03 06:03:27 +04:00
|
|
|
|
2002-11-11 15:14:19 +03:00
|
|
|
resolve_link_error:
|
2002-08-03 06:03:27 +04:00
|
|
|
put_vnode(vnode);
|
|
|
|
put_vnode(nextVnode);
|
|
|
|
|
2002-07-28 23:39:49 +04:00
|
|
|
return status;
|
|
|
|
}
|
2002-08-03 06:03:27 +04:00
|
|
|
put_vnode(nextVnode);
|
|
|
|
|
|
|
|
// Check if we start from the root directory or the current
|
|
|
|
// directory ("vnode" still points to that one).
|
|
|
|
// Cut off all leading slashes if it's the root directory
|
|
|
|
path = buffer;
|
2007-10-05 22:42:50 +04:00
|
|
|
bool absoluteSymlink = false;
|
2002-08-03 06:03:27 +04:00
|
|
|
if (path[0] == '/') {
|
|
|
|
// we don't need the old directory anymore
|
|
|
|
put_vnode(vnode);
|
|
|
|
|
|
|
|
while (*++path == '/')
|
|
|
|
;
|
2008-03-30 09:59:54 +04:00
|
|
|
|
|
|
|
benaphore_lock(&sIOContextRootLock);
|
|
|
|
vnode = ioContext->root;
|
2002-08-03 06:03:27 +04:00
|
|
|
inc_vnode_ref_count(vnode);
|
2008-03-30 09:59:54 +04:00
|
|
|
benaphore_unlock(&sIOContextRootLock);
|
2007-10-05 22:42:50 +04:00
|
|
|
|
|
|
|
absoluteSymlink = true;
|
2002-08-03 06:03:27 +04:00
|
|
|
}
|
2007-10-05 22:42:50 +04:00
|
|
|
|
2004-06-08 15:34:49 +04:00
|
|
|
inc_vnode_ref_count(vnode);
|
2007-10-05 22:42:50 +04:00
|
|
|
// balance the next recursion - we will decrement the
|
|
|
|
// ref_count of the vnode, no matter if we succeeded or not
|
2002-08-03 06:03:27 +04:00
|
|
|
|
2007-10-05 22:42:50 +04:00
|
|
|
if (absoluteSymlink && *path == '\0') {
|
|
|
|
// symlink was just "/"
|
|
|
|
nextVnode = vnode;
|
|
|
|
} else {
|
|
|
|
status = vnode_path_to_vnode(vnode, path, traverseLeafLink,
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
count + 1, ioContext, &nextVnode, &lastParentID);
|
2007-10-05 22:42:50 +04:00
|
|
|
}
|
2002-07-28 23:39:49 +04:00
|
|
|
|
2002-10-30 02:07:06 +03:00
|
|
|
free(buffer);
|
2002-07-28 23:39:49 +04:00
|
|
|
|
2002-08-03 06:03:27 +04:00
|
|
|
if (status < B_OK) {
|
|
|
|
put_vnode(vnode);
|
|
|
|
return status;
|
|
|
|
}
|
2005-08-01 16:44:59 +04:00
|
|
|
} else
|
|
|
|
lastParentID = vnode->id;
|
2002-07-28 23:39:49 +04:00
|
|
|
|
2002-08-03 06:03:27 +04:00
|
|
|
// decrease the ref count on the old dir we just looked up into
|
|
|
|
put_vnode(vnode);
|
|
|
|
|
|
|
|
path = nextPath;
|
|
|
|
vnode = nextVnode;
|
|
|
|
|
2002-07-09 16:24:59 +04:00
|
|
|
// see if we hit a mount point
|
2004-10-29 02:31:43 +04:00
|
|
|
struct vnode *mountPoint = resolve_mount_point_to_volume_root(vnode);
|
2004-10-05 20:08:31 +04:00
|
|
|
if (mountPoint) {
|
2002-07-28 22:41:07 +04:00
|
|
|
put_vnode(vnode);
|
2004-10-05 20:08:31 +04:00
|
|
|
vnode = mountPoint;
|
2002-07-09 16:24:59 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2002-07-20 04:16:12 +04:00
|
|
|
*_vnode = vnode;
|
2005-08-01 16:44:59 +04:00
|
|
|
if (_parentID)
|
|
|
|
*_parentID = lastParentID;
|
2003-09-08 08:02:34 +04:00
|
|
|
|
2002-07-28 23:39:49 +04:00
|
|
|
return B_OK;
|
|
|
|
}
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2002-07-28 23:39:49 +04:00
|
|
|
|
2008-03-30 09:59:54 +04:00
|
|
|
static status_t
|
|
|
|
vnode_path_to_vnode(struct vnode *vnode, char *path, bool traverseLeafLink,
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
int count, bool kernel, struct vnode **_vnode, ino_t *_parentID)
|
2008-03-30 09:59:54 +04:00
|
|
|
{
|
|
|
|
return vnode_path_to_vnode(vnode, path, traverseLeafLink, count,
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
get_current_io_context(kernel), _vnode, _parentID);
|
2008-03-30 09:59:54 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2003-09-08 08:02:34 +04:00
|
|
|
static status_t
|
2005-08-01 16:44:59 +04:00
|
|
|
path_to_vnode(char *path, bool traverseLink, struct vnode **_vnode,
|
2007-06-21 23:50:57 +04:00
|
|
|
ino_t *_parentID, bool kernel)
|
2002-07-28 23:39:49 +04:00
|
|
|
{
|
2006-01-15 22:26:42 +03:00
|
|
|
struct vnode *start = NULL;
|
2002-10-05 23:45:31 +04:00
|
|
|
|
2003-08-18 07:21:26 +04:00
|
|
|
FUNCTION(("path_to_vnode(path = \"%s\")\n", path));
|
2002-07-28 23:39:49 +04:00
|
|
|
|
|
|
|
if (!path)
|
2004-06-08 15:34:49 +04:00
|
|
|
return B_BAD_VALUE;
|
2002-07-28 23:39:49 +04:00
|
|
|
|
2007-10-05 22:42:50 +04:00
|
|
|
if (*path == '\0')
|
|
|
|
return B_ENTRY_NOT_FOUND;
|
|
|
|
|
2002-07-28 23:39:49 +04:00
|
|
|
// figure out if we need to start at root or at cwd
|
|
|
|
if (*path == '/') {
|
2005-05-03 05:05:20 +04:00
|
|
|
if (sRoot == NULL) {
|
|
|
|
// we're a bit early, aren't we?
|
|
|
|
return B_ERROR;
|
|
|
|
}
|
|
|
|
|
2002-07-28 23:39:49 +04:00
|
|
|
while (*++path == '/')
|
|
|
|
;
|
2008-03-30 09:59:54 +04:00
|
|
|
start = get_root_vnode(kernel);
|
2007-10-05 22:42:50 +04:00
|
|
|
|
|
|
|
if (*path == '\0') {
|
|
|
|
*_vnode = start;
|
|
|
|
return B_OK;
|
|
|
|
}
|
|
|
|
|
2002-07-28 23:39:49 +04:00
|
|
|
} else {
|
|
|
|
struct io_context *context = get_current_io_context(kernel);
|
|
|
|
|
|
|
|
mutex_lock(&context->io_mutex);
|
|
|
|
start = context->cwd;
|
2006-01-15 22:26:42 +03:00
|
|
|
if (start != NULL)
|
|
|
|
inc_vnode_ref_count(start);
|
2002-07-28 23:39:49 +04:00
|
|
|
mutex_unlock(&context->io_mutex);
|
2006-01-15 22:26:42 +03:00
|
|
|
|
|
|
|
if (start == NULL)
|
|
|
|
return B_ERROR;
|
2002-07-28 23:39:49 +04:00
|
|
|
}
|
|
|
|
|
2008-03-30 09:59:54 +04:00
|
|
|
return vnode_path_to_vnode(start, path, traverseLink, 0, kernel, _vnode,
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
_parentID);
|
2002-07-09 16:24:59 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-10-05 22:42:50 +04:00
|
|
|
/*! Returns the vnode in the next to last segment of the path, and returns
|
|
|
|
the last portion in filename.
|
|
|
|
The path buffer must be able to store at least one additional character.
|
|
|
|
*/
|
2003-09-08 08:02:34 +04:00
|
|
|
static status_t
|
2002-07-20 04:16:12 +04:00
|
|
|
path_to_dir_vnode(char *path, struct vnode **_vnode, char *filename, bool kernel)
|
2002-07-09 16:24:59 +04:00
|
|
|
{
|
2004-08-29 00:38:39 +04:00
|
|
|
status_t status = get_dir_path_and_leaf(path, filename);
|
|
|
|
if (status != B_OK)
|
|
|
|
return status;
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2005-08-01 16:44:59 +04:00
|
|
|
return path_to_vnode(path, true, _vnode, NULL, kernel);
|
2004-08-29 00:38:39 +04:00
|
|
|
}
|
2002-10-05 23:45:31 +04:00
|
|
|
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2007-10-05 22:42:50 +04:00
|
|
|
/*! \brief Retrieves the directory vnode and the leaf name of an entry referred
|
|
|
|
to by a FD + path pair.
|
|
|
|
|
|
|
|
\a path must be given in either case. \a fd might be omitted, in which
|
|
|
|
case \a path is either an absolute path or one relative to the current
|
|
|
|
directory. If both a supplied and \a path is relative it is reckoned off
|
|
|
|
of the directory referred to by \a fd. If \a path is absolute \a fd is
|
|
|
|
ignored.
|
2004-08-29 00:38:39 +04:00
|
|
|
|
2007-10-05 22:42:50 +04:00
|
|
|
The caller has the responsibility to call put_vnode() on the returned
|
|
|
|
directory vnode.
|
|
|
|
|
|
|
|
\param fd The FD. May be < 0.
|
|
|
|
\param path The absolute or relative path. Must not be \c NULL. The buffer
|
|
|
|
is modified by this function. It must have at least room for a
|
|
|
|
string one character longer than the path it contains.
|
|
|
|
\param _vnode A pointer to a variable the directory vnode shall be written
|
|
|
|
into.
|
|
|
|
\param filename A buffer of size B_FILE_NAME_LENGTH or larger into which
|
|
|
|
the leaf name of the specified entry will be written.
|
|
|
|
\param kernel \c true, if invoked from inside the kernel, \c false if
|
|
|
|
invoked from userland.
|
|
|
|
\return \c B_OK, if everything went fine, another error code otherwise.
|
|
|
|
*/
|
2004-08-29 00:38:39 +04:00
|
|
|
static status_t
|
|
|
|
fd_and_path_to_dir_vnode(int fd, char *path, struct vnode **_vnode,
|
|
|
|
char *filename, bool kernel)
|
|
|
|
{
|
|
|
|
if (!path)
|
|
|
|
return B_BAD_VALUE;
|
2007-10-05 22:42:50 +04:00
|
|
|
if (*path == '\0')
|
|
|
|
return B_ENTRY_NOT_FOUND;
|
2004-08-29 00:38:39 +04:00
|
|
|
if (fd < 0)
|
|
|
|
return path_to_dir_vnode(path, _vnode, filename, kernel);
|
|
|
|
|
|
|
|
status_t status = get_dir_path_and_leaf(path, filename);
|
|
|
|
if (status != B_OK)
|
|
|
|
return status;
|
|
|
|
|
2005-08-01 16:44:59 +04:00
|
|
|
return fd_and_path_to_vnode(fd, path, true, _vnode, NULL, kernel);
|
2004-08-29 00:38:39 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-02-08 06:06:14 +03:00
|
|
|
/*! \brief Retrieves the directory vnode and the leaf name of an entry referred
|
|
|
|
to by a vnode + path pair.
|
|
|
|
|
|
|
|
\a path must be given in either case. \a vnode might be omitted, in which
|
|
|
|
case \a path is either an absolute path or one relative to the current
|
|
|
|
directory. If both a supplied and \a path is relative it is reckoned off
|
|
|
|
of the directory referred to by \a vnode. If \a path is absolute \a vnode is
|
|
|
|
ignored.
|
|
|
|
|
|
|
|
The caller has the responsibility to call put_vnode() on the returned
|
|
|
|
directory vnode.
|
|
|
|
|
|
|
|
\param vnode The vnode. May be \c NULL.
|
|
|
|
\param path The absolute or relative path. Must not be \c NULL. The buffer
|
|
|
|
is modified by this function. It must have at least room for a
|
|
|
|
string one character longer than the path it contains.
|
|
|
|
\param _vnode A pointer to a variable the directory vnode shall be written
|
|
|
|
into.
|
|
|
|
\param filename A buffer of size B_FILE_NAME_LENGTH or larger into which
|
|
|
|
the leaf name of the specified entry will be written.
|
|
|
|
\param kernel \c true, if invoked from inside the kernel, \c false if
|
|
|
|
invoked from userland.
|
|
|
|
\return \c B_OK, if everything went fine, another error code otherwise.
|
|
|
|
*/
|
|
|
|
static status_t
|
|
|
|
vnode_and_path_to_dir_vnode(struct vnode* vnode, char *path,
|
|
|
|
struct vnode **_vnode, char *filename, bool kernel)
|
|
|
|
{
|
|
|
|
if (!path)
|
|
|
|
return B_BAD_VALUE;
|
|
|
|
if (*path == '\0')
|
|
|
|
return B_ENTRY_NOT_FOUND;
|
2008-02-17 16:32:08 +03:00
|
|
|
if (vnode == NULL || path[0] == '/')
|
2008-02-08 06:06:14 +03:00
|
|
|
return path_to_dir_vnode(path, _vnode, filename, kernel);
|
|
|
|
|
|
|
|
status_t status = get_dir_path_and_leaf(path, filename);
|
|
|
|
if (status != B_OK)
|
|
|
|
return status;
|
|
|
|
|
|
|
|
inc_vnode_ref_count(vnode);
|
|
|
|
// vnode_path_to_vnode() always decrements the ref count
|
|
|
|
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
return vnode_path_to_vnode(vnode, path, true, 0, kernel, _vnode, NULL);
|
2008-02-08 06:06:14 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-10-05 22:42:50 +04:00
|
|
|
/*! Returns a vnode's name in the d_name field of a supplied dirent buffer.
|
|
|
|
*/
|
2004-08-29 00:38:39 +04:00
|
|
|
static status_t
|
2007-03-02 12:34:33 +03:00
|
|
|
get_vnode_name(struct vnode *vnode, struct vnode *parent, struct dirent *buffer,
|
2008-03-30 09:59:54 +04:00
|
|
|
size_t bufferSize, struct io_context* ioContext)
|
2004-08-29 00:38:39 +04:00
|
|
|
{
|
2007-03-02 12:34:33 +03:00
|
|
|
if (bufferSize < sizeof(struct dirent))
|
|
|
|
return B_BAD_VALUE;
|
2004-09-07 02:29:20 +04:00
|
|
|
|
|
|
|
// See if vnode is the root of a mount and move to the covered
|
|
|
|
// vnode so we get the underlying file system
|
2007-03-02 12:34:33 +03:00
|
|
|
VNodePutter vnodePutter;
|
2004-09-07 02:29:20 +04:00
|
|
|
if (vnode->mount->root_vnode == vnode && vnode->mount->covers_vnode != NULL) {
|
|
|
|
vnode = vnode->mount->covers_vnode;
|
|
|
|
inc_vnode_ref_count(vnode);
|
|
|
|
vnodePutter.SetTo(vnode);
|
|
|
|
}
|
|
|
|
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
if (HAS_FS_CALL(vnode, get_vnode_name)) {
|
2004-08-29 00:38:39 +04:00
|
|
|
// The FS supports getting the name of a vnode.
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
return FS_CALL(vnode, get_vnode_name, buffer->d_name,
|
2007-03-02 12:34:33 +03:00
|
|
|
(char*)buffer + bufferSize - buffer->d_name);
|
2004-08-29 00:38:39 +04:00
|
|
|
}
|
2005-01-18 18:59:18 +03:00
|
|
|
|
2004-08-29 00:38:39 +04:00
|
|
|
// The FS doesn't support getting the name of a vnode. So we search the
|
2005-01-18 18:59:18 +03:00
|
|
|
// parent directory for the vnode, if the caller let us.
|
|
|
|
|
|
|
|
if (parent == NULL)
|
|
|
|
return EOPNOTSUPP;
|
|
|
|
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
void *cookie;
|
2004-08-29 00:38:39 +04:00
|
|
|
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
status_t status = FS_CALL(parent, open_dir, &cookie);
|
2004-08-29 00:38:39 +04:00
|
|
|
if (status >= B_OK) {
|
|
|
|
while (true) {
|
|
|
|
uint32 num = 1;
|
2008-03-30 09:59:54 +04:00
|
|
|
status = dir_read(ioContext, parent, cookie, buffer, bufferSize,
|
|
|
|
&num);
|
2004-08-29 00:38:39 +04:00
|
|
|
if (status < B_OK)
|
|
|
|
break;
|
2007-04-03 08:29:24 +04:00
|
|
|
if (num == 0) {
|
|
|
|
status = B_ENTRY_NOT_FOUND;
|
|
|
|
break;
|
|
|
|
}
|
2004-09-07 02:29:20 +04:00
|
|
|
|
2007-03-02 12:34:33 +03:00
|
|
|
if (vnode->id == buffer->d_ino) {
|
2004-08-29 00:38:39 +04:00
|
|
|
// found correct entry!
|
|
|
|
break;
|
2004-12-13 02:12:08 +03:00
|
|
|
}
|
2002-07-09 16:24:59 +04:00
|
|
|
}
|
2007-04-03 08:29:24 +04:00
|
|
|
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
FS_CALL(vnode, close_dir, cookie);
|
|
|
|
FS_CALL(vnode, free_dir_cookie, cookie);
|
2002-07-09 16:24:59 +04:00
|
|
|
}
|
2004-08-29 00:38:39 +04:00
|
|
|
return status;
|
2002-07-09 16:24:59 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-03-02 12:34:33 +03:00
|
|
|
static status_t
|
|
|
|
get_vnode_name(struct vnode *vnode, struct vnode *parent, char *name,
|
2008-03-30 09:59:54 +04:00
|
|
|
size_t nameSize, bool kernel)
|
2007-03-02 12:34:33 +03:00
|
|
|
{
|
|
|
|
char buffer[sizeof(struct dirent) + B_FILE_NAME_LENGTH];
|
|
|
|
struct dirent *dirent = (struct dirent *)buffer;
|
|
|
|
|
2008-03-30 09:59:54 +04:00
|
|
|
status_t status = get_vnode_name(vnode, parent, buffer, sizeof(buffer),
|
|
|
|
get_current_io_context(kernel));
|
2007-03-02 12:34:33 +03:00
|
|
|
if (status != B_OK)
|
|
|
|
return status;
|
|
|
|
|
|
|
|
if (strlcpy(name, dirent->d_name, nameSize) >= nameSize)
|
|
|
|
return B_BUFFER_OVERFLOW;
|
|
|
|
|
|
|
|
return B_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-10-06 19:33:12 +04:00
|
|
|
/*! Gets the full path to a given directory vnode.
|
|
|
|
It uses the fs_get_vnode_name() call to get the name of a vnode; if a
|
|
|
|
file system doesn't support this call, it will fall back to iterating
|
|
|
|
through the parent directory to get the name of the child.
|
|
|
|
|
|
|
|
To protect against circular loops, it supports a maximum tree depth
|
|
|
|
of 256 levels.
|
2004-10-07 18:47:58 +04:00
|
|
|
|
2007-10-06 19:33:12 +04:00
|
|
|
Note that the path may not be correct the time this function returns!
|
|
|
|
It doesn't use any locking to prevent returning the correct path, as
|
|
|
|
paths aren't safe anyway: the path to a file can change at any time.
|
|
|
|
|
|
|
|
It might be a good idea, though, to check if the returned path exists
|
|
|
|
in the calling function (it's not done here because of efficiency)
|
|
|
|
*/
|
2002-07-20 04:16:12 +04:00
|
|
|
static status_t
|
2008-03-30 09:59:54 +04:00
|
|
|
dir_vnode_to_path(struct vnode *vnode, char *buffer, size_t bufferSize,
|
|
|
|
bool kernel)
|
2002-07-19 01:06:02 +04:00
|
|
|
{
|
2004-10-29 02:31:43 +04:00
|
|
|
FUNCTION(("dir_vnode_to_path(%p, %p, %lu)\n", vnode, buffer, bufferSize));
|
2004-10-05 20:08:31 +04:00
|
|
|
|
2006-03-05 21:11:59 +03:00
|
|
|
if (vnode == NULL || buffer == NULL)
|
|
|
|
return B_BAD_VALUE;
|
|
|
|
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
if (!S_ISDIR(vnode->type))
|
|
|
|
return B_NOT_A_DIRECTORY;
|
|
|
|
|
2004-11-01 03:35:27 +03:00
|
|
|
/* this implementation is currently bound to B_PATH_NAME_LENGTH */
|
2006-03-05 21:11:59 +03:00
|
|
|
KPath pathBuffer;
|
|
|
|
if (pathBuffer.InitCheck() != B_OK)
|
|
|
|
return B_NO_MEMORY;
|
|
|
|
|
|
|
|
char *path = pathBuffer.LockBuffer();
|
|
|
|
int32 insert = pathBuffer.BufferSize();
|
2002-07-19 01:06:02 +04:00
|
|
|
int32 maxLevel = 256;
|
|
|
|
int32 length;
|
|
|
|
status_t status;
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2002-07-19 08:20:07 +04:00
|
|
|
// we don't use get_vnode() here because this call is more
|
|
|
|
// efficient and does all we need from get_vnode()
|
2002-07-19 01:06:02 +04:00
|
|
|
inc_vnode_ref_count(vnode);
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2004-10-05 20:08:31 +04:00
|
|
|
// resolve a volume root to its mount point
|
|
|
|
struct vnode *mountPoint = resolve_volume_root_to_mount_point(vnode);
|
|
|
|
if (mountPoint) {
|
|
|
|
put_vnode(vnode);
|
|
|
|
vnode = mountPoint;
|
|
|
|
}
|
|
|
|
|
2002-07-19 01:06:02 +04:00
|
|
|
path[--insert] = '\0';
|
2005-01-18 18:59:18 +03:00
|
|
|
|
2008-03-30 09:59:54 +04:00
|
|
|
struct io_context* ioContext = get_current_io_context(kernel);
|
|
|
|
|
2002-07-19 01:06:02 +04:00
|
|
|
while (true) {
|
2002-07-19 08:20:07 +04:00
|
|
|
// the name buffer is also used for fs_read_dir()
|
|
|
|
char nameBuffer[sizeof(struct dirent) + B_FILE_NAME_LENGTH];
|
|
|
|
char *name = &((struct dirent *)nameBuffer)->d_name[0];
|
2002-07-28 22:41:07 +04:00
|
|
|
struct vnode *parentVnode;
|
2007-06-21 23:50:57 +04:00
|
|
|
ino_t parentID;
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2002-07-19 01:06:02 +04:00
|
|
|
// lookup the parent vnode
|
2008-03-30 09:59:54 +04:00
|
|
|
if (vnode == ioContext->root) {
|
|
|
|
// we hit the IO context root
|
|
|
|
parentVnode = vnode;
|
|
|
|
inc_vnode_ref_count(vnode);
|
|
|
|
} else {
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
status = lookup_dir_entry(vnode, "..", &parentVnode);
|
2008-03-30 09:59:54 +04:00
|
|
|
if (status < B_OK)
|
|
|
|
goto out;
|
2002-07-28 22:41:07 +04:00
|
|
|
}
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2007-03-02 12:34:33 +03:00
|
|
|
// get the node's name
|
|
|
|
status = get_vnode_name(vnode, parentVnode, (struct dirent*)nameBuffer,
|
2008-03-30 09:59:54 +04:00
|
|
|
sizeof(nameBuffer), ioContext);
|
2007-03-02 12:34:33 +03:00
|
|
|
|
2004-10-05 20:08:31 +04:00
|
|
|
// resolve a volume root to its mount point
|
|
|
|
mountPoint = resolve_volume_root_to_mount_point(parentVnode);
|
|
|
|
if (mountPoint) {
|
|
|
|
put_vnode(parentVnode);
|
|
|
|
parentVnode = mountPoint;
|
2004-10-29 02:31:43 +04:00
|
|
|
parentID = parentVnode->id;
|
2004-10-05 20:08:31 +04:00
|
|
|
}
|
|
|
|
|
2004-10-29 02:31:43 +04:00
|
|
|
bool hitRoot = (parentVnode == vnode);
|
|
|
|
|
2002-07-19 01:06:02 +04:00
|
|
|
// release the current vnode, we only need its parent from now on
|
|
|
|
put_vnode(vnode);
|
2002-07-28 22:41:07 +04:00
|
|
|
vnode = parentVnode;
|
2002-07-19 01:06:02 +04:00
|
|
|
|
|
|
|
if (status < B_OK)
|
2002-07-28 22:41:07 +04:00
|
|
|
goto out;
|
2002-07-19 01:06:02 +04:00
|
|
|
|
2004-10-29 02:31:43 +04:00
|
|
|
if (hitRoot) {
|
2004-10-05 20:08:31 +04:00
|
|
|
// we have reached "/", which means we have constructed the full
|
|
|
|
// path
|
2002-07-19 01:06:02 +04:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2007-03-02 12:34:33 +03:00
|
|
|
// ToDo: add an explicit check for loops in about 10 levels to do
|
|
|
|
// real loop detection
|
2002-07-19 01:06:02 +04:00
|
|
|
|
2007-03-02 12:34:33 +03:00
|
|
|
// don't go deeper as 'maxLevel' to prevent circular loops
|
|
|
|
if (maxLevel-- < 0) {
|
|
|
|
status = ELOOP;
|
|
|
|
goto out;
|
2002-07-09 16:24:59 +04:00
|
|
|
}
|
2002-07-19 01:06:02 +04:00
|
|
|
|
2007-03-02 12:34:33 +03:00
|
|
|
// add the name in front of the current path
|
2002-07-19 01:06:02 +04:00
|
|
|
name[B_FILE_NAME_LENGTH - 1] = '\0';
|
|
|
|
length = strlen(name);
|
|
|
|
insert -= length;
|
|
|
|
if (insert <= 0) {
|
2002-07-28 22:41:07 +04:00
|
|
|
status = ENOBUFS;
|
|
|
|
goto out;
|
2002-07-19 01:06:02 +04:00
|
|
|
}
|
|
|
|
memcpy(path + insert, name, length);
|
2002-07-19 08:20:07 +04:00
|
|
|
path[--insert] = '/';
|
2002-07-09 16:24:59 +04:00
|
|
|
}
|
|
|
|
|
2004-10-05 20:08:31 +04:00
|
|
|
// the root dir will result in an empty path: fix it
|
|
|
|
if (path[insert] == '\0')
|
|
|
|
path[--insert] = '/';
|
2002-07-19 01:06:02 +04:00
|
|
|
|
2005-12-16 20:35:03 +03:00
|
|
|
TRACE((" path is: %s\n", path + insert));
|
2004-10-05 20:08:31 +04:00
|
|
|
|
|
|
|
// copy the path to the output buffer
|
2006-03-05 21:11:59 +03:00
|
|
|
length = pathBuffer.BufferSize() - insert;
|
2004-10-05 20:08:31 +04:00
|
|
|
if (length <= (int)bufferSize)
|
|
|
|
memcpy(buffer, path + insert, length);
|
|
|
|
else
|
|
|
|
status = ENOBUFS;
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2002-07-28 22:41:07 +04:00
|
|
|
out:
|
|
|
|
put_vnode(vnode);
|
|
|
|
return status;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-10-05 22:42:50 +04:00
|
|
|
/*! Checks the length of every path component, and adds a '.'
|
|
|
|
if the path ends in a slash.
|
|
|
|
The given path buffer must be able to store at least one
|
|
|
|
additional character.
|
|
|
|
*/
|
2002-07-28 22:41:07 +04:00
|
|
|
static status_t
|
|
|
|
check_path(char *to)
|
|
|
|
{
|
|
|
|
int32 length = 0;
|
|
|
|
|
|
|
|
// check length of every path component
|
|
|
|
|
|
|
|
while (*to) {
|
|
|
|
char *begin;
|
|
|
|
if (*to == '/')
|
|
|
|
to++, length++;
|
2002-08-05 09:37:17 +04:00
|
|
|
|
2002-07-28 22:41:07 +04:00
|
|
|
begin = to;
|
|
|
|
while (*to != '/' && *to)
|
|
|
|
to++, length++;
|
|
|
|
|
|
|
|
if (to - begin > B_FILE_NAME_LENGTH)
|
|
|
|
return B_NAME_TOO_LONG;
|
|
|
|
}
|
2002-08-05 09:37:17 +04:00
|
|
|
|
2002-07-28 22:41:07 +04:00
|
|
|
if (length == 0)
|
|
|
|
return B_ENTRY_NOT_FOUND;
|
|
|
|
|
|
|
|
// complete path if there is a slash at the end
|
|
|
|
|
|
|
|
if (*(to - 1) == '/') {
|
2004-11-01 03:35:27 +03:00
|
|
|
if (length > B_PATH_NAME_LENGTH - 2)
|
2002-07-28 22:41:07 +04:00
|
|
|
return B_NAME_TOO_LONG;
|
|
|
|
|
|
|
|
to[0] = '.';
|
|
|
|
to[1] = '\0';
|
|
|
|
}
|
2002-08-05 09:37:17 +04:00
|
|
|
|
2002-07-19 01:06:02 +04:00
|
|
|
return B_OK;
|
|
|
|
}
|
2002-07-09 16:24:59 +04:00
|
|
|
|
|
|
|
|
2002-09-25 06:18:20 +04:00
|
|
|
static struct file_descriptor *
|
|
|
|
get_fd_and_vnode(int fd, struct vnode **_vnode, bool kernel)
|
|
|
|
{
|
|
|
|
struct file_descriptor *descriptor = get_fd(get_current_io_context(kernel), fd);
|
|
|
|
if (descriptor == NULL)
|
|
|
|
return NULL;
|
|
|
|
|
2008-04-11 23:21:14 +04:00
|
|
|
struct vnode* vnode = fd_vnode(descriptor);
|
|
|
|
if (vnode == NULL) {
|
2002-09-25 06:18:20 +04:00
|
|
|
put_fd(descriptor);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2004-05-16 15:55:42 +04:00
|
|
|
// ToDo: when we can close a file descriptor at any point, investigate
|
|
|
|
// if this is still valid to do (accessing the vnode without ref_count
|
|
|
|
// or locking)
|
2008-04-11 23:21:14 +04:00
|
|
|
*_vnode = vnode;
|
2002-09-25 06:18:20 +04:00
|
|
|
return descriptor;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static struct vnode *
|
2004-08-29 00:38:39 +04:00
|
|
|
get_vnode_from_fd(int fd, bool kernel)
|
2002-09-25 06:18:20 +04:00
|
|
|
{
|
|
|
|
struct file_descriptor *descriptor;
|
|
|
|
struct vnode *vnode;
|
|
|
|
|
2004-08-29 00:38:39 +04:00
|
|
|
descriptor = get_fd(get_current_io_context(kernel), fd);
|
2002-09-25 06:18:20 +04:00
|
|
|
if (descriptor == NULL)
|
|
|
|
return NULL;
|
|
|
|
|
2005-12-16 19:11:36 +03:00
|
|
|
vnode = fd_vnode(descriptor);
|
2002-09-25 06:18:20 +04:00
|
|
|
if (vnode != NULL)
|
|
|
|
inc_vnode_ref_count(vnode);
|
|
|
|
|
|
|
|
put_fd(descriptor);
|
|
|
|
return vnode;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-10-05 22:42:50 +04:00
|
|
|
/*! Gets the vnode from an FD + path combination. If \a fd is lower than zero,
|
|
|
|
only the path will be considered. In this case, the \a path must not be
|
|
|
|
NULL.
|
|
|
|
If \a fd is a valid file descriptor, \a path may be NULL for directories,
|
|
|
|
and should be NULL for files.
|
|
|
|
*/
|
2002-08-10 00:20:28 +04:00
|
|
|
static status_t
|
2005-08-01 16:44:59 +04:00
|
|
|
fd_and_path_to_vnode(int fd, char *path, bool traverseLeafLink,
|
2007-06-21 23:50:57 +04:00
|
|
|
struct vnode **_vnode, ino_t *_parentID, bool kernel)
|
2002-08-10 00:20:28 +04:00
|
|
|
{
|
2004-08-29 00:38:39 +04:00
|
|
|
if (fd < 0 && !path)
|
|
|
|
return B_BAD_VALUE;
|
2002-08-10 00:20:28 +04:00
|
|
|
|
2007-10-05 22:42:50 +04:00
|
|
|
if (path != NULL && *path == '\0')
|
|
|
|
return B_ENTRY_NOT_FOUND;
|
|
|
|
|
2004-12-07 19:15:57 +03:00
|
|
|
if (fd < 0 || (path != NULL && path[0] == '/')) {
|
2004-08-29 00:38:39 +04:00
|
|
|
// no FD or absolute path
|
2005-08-01 16:44:59 +04:00
|
|
|
return path_to_vnode(path, traverseLeafLink, _vnode, _parentID, kernel);
|
2002-08-10 00:20:28 +04:00
|
|
|
}
|
|
|
|
|
2005-08-01 16:44:59 +04:00
|
|
|
// FD only, or FD + relative path
|
|
|
|
struct vnode *vnode = get_vnode_from_fd(fd, kernel);
|
|
|
|
if (!vnode)
|
|
|
|
return B_FILE_ERROR;
|
|
|
|
|
|
|
|
if (path != NULL) {
|
2008-03-30 09:59:54 +04:00
|
|
|
return vnode_path_to_vnode(vnode, path, traverseLeafLink, 0, kernel,
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
_vnode, _parentID);
|
2005-08-01 16:44:59 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
// there is no relative path to take into account
|
|
|
|
|
|
|
|
*_vnode = vnode;
|
|
|
|
if (_parentID)
|
|
|
|
*_parentID = -1;
|
|
|
|
|
|
|
|
return B_OK;
|
2002-08-10 00:20:28 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2002-09-25 06:18:20 +04:00
|
|
|
static int
|
2004-12-14 01:17:00 +03:00
|
|
|
get_new_fd(int type, struct fs_mount *mount, struct vnode *vnode,
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
void *cookie, int openMode, bool kernel)
|
2002-09-25 06:18:20 +04:00
|
|
|
{
|
|
|
|
struct file_descriptor *descriptor;
|
|
|
|
int fd;
|
|
|
|
|
2006-06-02 18:16:13 +04:00
|
|
|
// if the vnode is locked, we don't allow creating a new file descriptor for it
|
|
|
|
if (vnode && vnode->mandatory_locked_by != NULL)
|
|
|
|
return B_BUSY;
|
|
|
|
|
2002-09-25 06:18:20 +04:00
|
|
|
descriptor = alloc_fd();
|
|
|
|
if (!descriptor)
|
|
|
|
return B_NO_MEMORY;
|
|
|
|
|
2004-12-14 01:17:00 +03:00
|
|
|
if (vnode)
|
|
|
|
descriptor->u.vnode = vnode;
|
|
|
|
else
|
|
|
|
descriptor->u.mount = mount;
|
2002-09-25 06:18:20 +04:00
|
|
|
descriptor->cookie = cookie;
|
2004-12-14 01:17:00 +03:00
|
|
|
|
2002-09-25 06:18:20 +04:00
|
|
|
switch (type) {
|
2005-12-16 19:11:36 +03:00
|
|
|
// vnode types
|
2002-09-25 06:18:20 +04:00
|
|
|
case FDTYPE_FILE:
|
2003-10-17 18:47:15 +04:00
|
|
|
descriptor->ops = &sFileOps;
|
2002-09-25 06:18:20 +04:00
|
|
|
break;
|
|
|
|
case FDTYPE_DIR:
|
2003-10-17 18:47:15 +04:00
|
|
|
descriptor->ops = &sDirectoryOps;
|
2002-09-25 06:18:20 +04:00
|
|
|
break;
|
|
|
|
case FDTYPE_ATTR:
|
2003-10-17 18:47:15 +04:00
|
|
|
descriptor->ops = &sAttributeOps;
|
2002-09-26 07:50:14 +04:00
|
|
|
break;
|
|
|
|
case FDTYPE_ATTR_DIR:
|
2003-10-17 18:47:15 +04:00
|
|
|
descriptor->ops = &sAttributeDirectoryOps;
|
2002-09-26 07:50:14 +04:00
|
|
|
break;
|
2005-12-16 19:11:36 +03:00
|
|
|
|
|
|
|
// mount types
|
2002-09-26 07:50:14 +04:00
|
|
|
case FDTYPE_INDEX_DIR:
|
2003-10-17 18:47:15 +04:00
|
|
|
descriptor->ops = &sIndexDirectoryOps;
|
2002-09-25 06:18:20 +04:00
|
|
|
break;
|
2004-12-12 23:39:45 +03:00
|
|
|
case FDTYPE_QUERY:
|
|
|
|
descriptor->ops = &sQueryOps;
|
|
|
|
break;
|
2005-12-16 19:11:36 +03:00
|
|
|
|
2002-09-25 06:18:20 +04:00
|
|
|
default:
|
2002-09-26 07:50:14 +04:00
|
|
|
panic("get_new_fd() called with unknown type %d\n", type);
|
2002-09-25 06:18:20 +04:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
descriptor->type = type;
|
|
|
|
descriptor->open_mode = openMode;
|
|
|
|
|
|
|
|
fd = new_fd(get_current_io_context(kernel), descriptor);
|
|
|
|
if (fd < 0) {
|
2002-10-30 02:07:06 +03:00
|
|
|
free(descriptor);
|
2002-09-25 06:18:20 +04:00
|
|
|
return B_NO_MORE_FDS;
|
|
|
|
}
|
|
|
|
|
|
|
|
return fd;
|
|
|
|
}
|
|
|
|
|
2005-08-18 19:07:38 +04:00
|
|
|
#ifdef ADD_DEBUGGER_COMMANDS
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
_dump_advisory_locking(advisory_locking *locking)
|
|
|
|
{
|
|
|
|
if (locking == NULL)
|
|
|
|
return;
|
|
|
|
|
|
|
|
kprintf(" lock: %ld", locking->lock);
|
|
|
|
kprintf(" wait_sem: %ld", locking->wait_sem);
|
|
|
|
|
|
|
|
int32 index = 0;
|
2008-02-19 22:16:36 +03:00
|
|
|
LockList::Iterator iterator = locking->locks.GetIterator();
|
|
|
|
while (iterator.HasNext()) {
|
|
|
|
struct advisory_lock *lock = iterator.Next();
|
|
|
|
|
|
|
|
kprintf(" [%2ld] team: %ld\n", index++, lock->team);
|
|
|
|
kprintf(" start: %Ld\n", lock->start);
|
|
|
|
kprintf(" end: %Ld\n", lock->end);
|
2005-08-18 19:07:38 +04:00
|
|
|
kprintf(" shared? %s\n", lock->shared ? "yes" : "no");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
_dump_mount(struct fs_mount *mount)
|
|
|
|
{
|
|
|
|
kprintf("MOUNT: %p\n", mount);
|
|
|
|
kprintf(" id: %ld\n", mount->id);
|
|
|
|
kprintf(" device_name: %s\n", mount->device_name);
|
|
|
|
kprintf(" fs_name: %s\n", mount->fs_name);
|
|
|
|
kprintf(" root_vnode: %p\n", mount->root_vnode);
|
|
|
|
kprintf(" covers_vnode: %p\n", mount->covers_vnode);
|
|
|
|
kprintf(" partition: %p\n", mount->partition);
|
|
|
|
kprintf(" lock: %ld\n", mount->rlock.sem);
|
|
|
|
kprintf(" flags: %s%s\n", mount->unmounting ? " unmounting" : "",
|
|
|
|
mount->owns_file_device ? " owns_file_device" : "");
|
2008-01-16 12:21:54 +03:00
|
|
|
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
fs_volume *volume = mount->volume;
|
|
|
|
while (volume != NULL) {
|
|
|
|
kprintf(" volume %p:\n", volume);
|
|
|
|
kprintf(" layer: %ld\n", volume->layer);
|
|
|
|
kprintf(" private_volume: %p\n", volume->private_volume);
|
|
|
|
kprintf(" ops: %p\n", volume->ops);
|
|
|
|
volume = volume->super_volume;
|
|
|
|
}
|
|
|
|
|
|
|
|
set_debug_variable("_cookie", (addr_t)mount->volume->private_volume);
|
2008-01-16 12:21:54 +03:00
|
|
|
set_debug_variable("_root", (addr_t)mount->root_vnode);
|
|
|
|
set_debug_variable("_covers", (addr_t)mount->covers_vnode);
|
|
|
|
set_debug_variable("_partition", (addr_t)mount->partition);
|
2005-08-18 19:07:38 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
_dump_vnode(struct vnode *vnode)
|
|
|
|
{
|
|
|
|
kprintf("VNODE: %p\n", vnode);
|
|
|
|
kprintf(" device: %ld\n", vnode->device);
|
|
|
|
kprintf(" id: %Ld\n", vnode->id);
|
|
|
|
kprintf(" ref_count: %ld\n", vnode->ref_count);
|
|
|
|
kprintf(" private_node: %p\n", vnode->private_node);
|
|
|
|
kprintf(" mount: %p\n", vnode->mount);
|
|
|
|
kprintf(" covered_by: %p\n", vnode->covered_by);
|
2007-09-29 19:48:11 +04:00
|
|
|
kprintf(" cache: %p\n", vnode->cache);
|
2005-08-18 19:07:38 +04:00
|
|
|
kprintf(" flags: %s%s%s\n", vnode->remove ? "r" : "-",
|
|
|
|
vnode->busy ? "b" : "-", vnode->unpublished ? "u" : "-");
|
|
|
|
kprintf(" advisory_lock: %p\n", vnode->advisory_locking);
|
|
|
|
|
|
|
|
_dump_advisory_locking(vnode->advisory_locking);
|
2008-01-16 12:21:54 +03:00
|
|
|
|
|
|
|
set_debug_variable("_node", (addr_t)vnode->private_node);
|
|
|
|
set_debug_variable("_mount", (addr_t)vnode->mount);
|
|
|
|
set_debug_variable("_covered_by", (addr_t)vnode->covered_by);
|
|
|
|
set_debug_variable("_adv_lock", (addr_t)vnode->advisory_locking);
|
2005-08-18 19:07:38 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
dump_mount(int argc, char **argv)
|
|
|
|
{
|
2008-01-16 12:21:54 +03:00
|
|
|
if (argc != 2 || !strcmp(argv[1], "--help")) {
|
|
|
|
kprintf("usage: %s [id|address]\n", argv[0]);
|
2005-08-18 19:07:38 +04:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2008-01-16 12:21:54 +03:00
|
|
|
uint32 id = parse_expression(argv[1]);
|
2005-08-18 19:07:38 +04:00
|
|
|
struct fs_mount *mount = NULL;
|
|
|
|
|
2008-01-16 12:21:54 +03:00
|
|
|
mount = (fs_mount *)hash_lookup(sMountsTable, (void *)&id);
|
|
|
|
if (mount == NULL) {
|
|
|
|
if (IS_USER_ADDRESS(id)) {
|
2005-08-18 19:07:38 +04:00
|
|
|
kprintf("fs_mount not found\n");
|
|
|
|
return 0;
|
|
|
|
}
|
2008-01-16 12:21:54 +03:00
|
|
|
mount = (fs_mount *)id;
|
2005-08-18 19:07:38 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
_dump_mount(mount);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
dump_mounts(int argc, char **argv)
|
|
|
|
{
|
2008-01-16 12:21:54 +03:00
|
|
|
if (argc != 1) {
|
|
|
|
kprintf("usage: %s\n", argv[0]);
|
|
|
|
return 0;
|
|
|
|
}
|
2005-08-18 19:07:38 +04:00
|
|
|
|
2008-01-13 02:45:11 +03:00
|
|
|
kprintf("address id root covers cookie fs_name\n");
|
2005-08-18 19:07:38 +04:00
|
|
|
|
2008-01-16 12:21:54 +03:00
|
|
|
struct hash_iterator iterator;
|
|
|
|
struct fs_mount *mount;
|
|
|
|
|
2005-08-18 19:07:38 +04:00
|
|
|
hash_open(sMountsTable, &iterator);
|
|
|
|
while ((mount = (struct fs_mount *)hash_next(sMountsTable, &iterator)) != NULL) {
|
2008-01-13 02:45:11 +03:00
|
|
|
kprintf("%p%4ld %p %p %p %s\n", mount, mount->id, mount->root_vnode,
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
mount->covers_vnode, mount->volume->private_volume, mount->fs_name);
|
2005-08-18 19:07:38 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
hash_close(sMountsTable, &iterator, false);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
dump_vnode(int argc, char **argv)
|
|
|
|
{
|
2008-01-16 12:21:54 +03:00
|
|
|
if (argc < 2 || argc > 3 || !strcmp(argv[1], "--help")) {
|
|
|
|
kprintf("usage: %s <device> <id>\n"
|
|
|
|
" or: %s <address>\n", argv[0], argv[0]);
|
2005-08-18 19:07:38 +04:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
struct vnode *vnode = NULL;
|
|
|
|
|
2008-01-16 12:21:54 +03:00
|
|
|
if (argc == 2) {
|
|
|
|
vnode = (struct vnode *)parse_expression(argv[1]);
|
2005-08-18 19:07:38 +04:00
|
|
|
if (IS_USER_ADDRESS(vnode)) {
|
|
|
|
kprintf("invalid vnode address\n");
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
_dump_vnode(vnode);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
struct hash_iterator iterator;
|
2008-01-16 12:21:54 +03:00
|
|
|
dev_t device = parse_expression(argv[1]);
|
|
|
|
ino_t id = atoll(argv[2]);
|
2005-08-18 19:07:38 +04:00
|
|
|
|
|
|
|
hash_open(sVnodeTable, &iterator);
|
|
|
|
while ((vnode = (struct vnode *)hash_next(sVnodeTable, &iterator)) != NULL) {
|
2008-01-16 12:21:54 +03:00
|
|
|
if (vnode->id != id || vnode->device != device)
|
2005-08-18 19:07:38 +04:00
|
|
|
continue;
|
|
|
|
|
|
|
|
_dump_vnode(vnode);
|
|
|
|
}
|
|
|
|
|
|
|
|
hash_close(sVnodeTable, &iterator, false);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
dump_vnodes(int argc, char **argv)
|
|
|
|
{
|
2008-01-16 23:36:27 +03:00
|
|
|
if (argc != 2 || !strcmp(argv[1], "--help")) {
|
2008-01-16 12:21:54 +03:00
|
|
|
kprintf("usage: %s [device]\n", argv[0]);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2005-08-18 19:07:38 +04:00
|
|
|
// restrict dumped nodes to a certain device if requested
|
2008-01-16 23:36:27 +03:00
|
|
|
dev_t device = parse_expression(argv[1]);
|
2005-08-18 19:07:38 +04:00
|
|
|
|
|
|
|
struct hash_iterator iterator;
|
|
|
|
struct vnode *vnode;
|
|
|
|
|
2008-01-13 02:45:11 +03:00
|
|
|
kprintf("address dev inode ref cache fs-node locking "
|
|
|
|
"flags\n");
|
2005-08-18 19:07:38 +04:00
|
|
|
|
|
|
|
hash_open(sVnodeTable, &iterator);
|
|
|
|
while ((vnode = (struct vnode *)hash_next(sVnodeTable, &iterator)) != NULL) {
|
2008-01-16 23:36:27 +03:00
|
|
|
if (vnode->device != device)
|
2005-08-18 19:07:38 +04:00
|
|
|
continue;
|
|
|
|
|
2008-01-13 02:45:11 +03:00
|
|
|
kprintf("%p%4ld%10Ld%5ld %p %p %p %s%s%s\n", vnode, vnode->device,
|
|
|
|
vnode->id, vnode->ref_count, vnode->cache, vnode->private_node,
|
|
|
|
vnode->advisory_locking, vnode->remove ? "r" : "-",
|
|
|
|
vnode->busy ? "b" : "-", vnode->unpublished ? "u" : "-");
|
2005-08-18 19:07:38 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
hash_close(sVnodeTable, &iterator, false);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
dump_vnode_caches(int argc, char **argv)
|
|
|
|
{
|
|
|
|
struct hash_iterator iterator;
|
|
|
|
struct vnode *vnode;
|
2008-03-04 19:59:59 +03:00
|
|
|
|
2008-01-16 12:21:54 +03:00
|
|
|
if (argc > 2 || !strcmp(argv[1], "--help")) {
|
|
|
|
kprintf("usage: %s [device]\n", argv[0]);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2006-08-25 00:54:24 +04:00
|
|
|
// restrict dumped nodes to a certain device if requested
|
2007-06-21 23:50:57 +04:00
|
|
|
dev_t device = -1;
|
2006-08-25 00:54:24 +04:00
|
|
|
if (argc > 1)
|
|
|
|
device = atoi(argv[1]);
|
2005-08-18 19:07:38 +04:00
|
|
|
|
|
|
|
kprintf("address dev inode cache size pages\n");
|
|
|
|
|
|
|
|
hash_open(sVnodeTable, &iterator);
|
|
|
|
while ((vnode = (struct vnode *)hash_next(sVnodeTable, &iterator)) != NULL) {
|
|
|
|
if (vnode->cache == NULL)
|
|
|
|
continue;
|
2006-08-25 00:54:24 +04:00
|
|
|
if (device != -1 && vnode->device != device)
|
|
|
|
continue;
|
2005-08-18 19:07:38 +04:00
|
|
|
|
|
|
|
// count pages in cache
|
|
|
|
size_t numPages = 0;
|
2007-07-18 04:16:27 +04:00
|
|
|
for (struct vm_page *page = vnode->cache->page_list;
|
2005-08-18 19:07:38 +04:00
|
|
|
page != NULL; page = page->cache_next) {
|
|
|
|
numPages++;
|
|
|
|
}
|
|
|
|
|
2007-07-18 04:16:27 +04:00
|
|
|
kprintf("%p%4ld%10Ld %p %8Ld%8ld\n", vnode, vnode->device, vnode->id,
|
|
|
|
vnode->cache, (vnode->cache->virtual_size + B_PAGE_SIZE - 1)
|
|
|
|
/ B_PAGE_SIZE, numPages);
|
2005-08-18 19:07:38 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
hash_close(sVnodeTable, &iterator, false);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2005-10-05 20:39:45 +04:00
|
|
|
|
|
|
|
int
|
2005-10-06 12:47:03 +04:00
|
|
|
dump_io_context(int argc, char **argv)
|
2005-10-05 20:39:45 +04:00
|
|
|
{
|
2008-01-16 12:21:54 +03:00
|
|
|
if (argc > 2 || !strcmp(argv[1], "--help")) {
|
|
|
|
kprintf("usage: %s [team-id|address]\n", argv[0]);
|
2005-10-06 12:47:03 +04:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2005-10-05 20:39:45 +04:00
|
|
|
struct io_context *context = NULL;
|
|
|
|
|
|
|
|
if (argc > 1) {
|
2008-01-16 12:21:54 +03:00
|
|
|
uint32 num = parse_expression(argv[1]);
|
2005-10-06 12:47:03 +04:00
|
|
|
if (IS_KERNEL_ADDRESS(num))
|
|
|
|
context = (struct io_context *)num;
|
|
|
|
else {
|
|
|
|
struct team *team = team_get_team_struct_locked(num);
|
|
|
|
if (team == NULL) {
|
|
|
|
kprintf("could not find team with ID %ld\n", num);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
context = (struct io_context *)team->io_context;
|
2005-10-05 20:39:45 +04:00
|
|
|
}
|
|
|
|
} else
|
|
|
|
context = get_current_io_context(true);
|
|
|
|
|
|
|
|
kprintf("I/O CONTEXT: %p\n", context);
|
2008-03-30 09:59:54 +04:00
|
|
|
kprintf(" root vnode:\t%p\n", context->root);
|
2005-10-05 20:39:45 +04:00
|
|
|
kprintf(" cwd vnode:\t%p\n", context->cwd);
|
2005-10-06 12:47:03 +04:00
|
|
|
kprintf(" used fds:\t%lu\n", context->num_used_fds);
|
|
|
|
kprintf(" max fds:\t%lu\n", context->table_size);
|
2008-03-04 19:59:59 +03:00
|
|
|
|
2005-10-05 20:39:45 +04:00
|
|
|
if (context->num_used_fds)
|
|
|
|
kprintf(" no. type ops ref open mode pos cookie\n");
|
|
|
|
|
|
|
|
for (uint32 i = 0; i < context->table_size; i++) {
|
|
|
|
struct file_descriptor *fd = context->fds[i];
|
|
|
|
if (fd == NULL)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
kprintf(" %3lu: %ld %p %3ld %4ld %4lx %10Ld %p %s %p\n", i, fd->type, fd->ops,
|
|
|
|
fd->ref_count, fd->open_count, fd->open_mode, fd->pos, fd->cookie,
|
|
|
|
fd->type >= FDTYPE_INDEX && fd->type <= FDTYPE_QUERY ? "mount" : "vnode",
|
|
|
|
fd->u.vnode);
|
|
|
|
}
|
|
|
|
|
|
|
|
kprintf(" used monitors:\t%lu\n", context->num_monitors);
|
|
|
|
kprintf(" max monitors:\t%lu\n", context->max_monitors);
|
|
|
|
|
2008-01-16 12:21:54 +03:00
|
|
|
set_debug_variable("_cwd", (addr_t)context->cwd);
|
|
|
|
|
2005-10-05 20:39:45 +04:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2006-03-06 16:39:04 +03:00
|
|
|
|
|
|
|
int
|
|
|
|
dump_vnode_usage(int argc, char **argv)
|
|
|
|
{
|
2008-01-16 12:21:54 +03:00
|
|
|
if (argc != 1) {
|
|
|
|
kprintf("usage: %s\n", argv[0]);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
kprintf("Unused vnodes: %ld (max unused %ld)\n", sUnusedVnodes,
|
|
|
|
kMaxUnusedVnodes);
|
2006-03-06 16:39:04 +03:00
|
|
|
|
|
|
|
struct hash_iterator iterator;
|
|
|
|
hash_open(sVnodeTable, &iterator);
|
|
|
|
|
|
|
|
uint32 count = 0;
|
|
|
|
struct vnode *vnode;
|
|
|
|
while ((vnode = (struct vnode *)hash_next(sVnodeTable, &iterator)) != NULL) {
|
|
|
|
count++;
|
|
|
|
}
|
|
|
|
|
|
|
|
hash_close(sVnodeTable, &iterator, false);
|
|
|
|
|
|
|
|
kprintf("%lu vnodes total (%ld in use).\n", count, count - sUnusedVnodes);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2005-08-18 19:07:38 +04:00
|
|
|
#endif // ADD_DEBUGGER_COMMANDS
|
|
|
|
|
* Extracted file_map API out of the file cache - it's now an optional service
that can be used by file systems.
* Changed the way the file cache works: instead of reading/writing to the
underlying device directly, it can now be used for any data source, ie.
also network file systems.
* As a result, the former pages_io() moved to the VFS layer, and can now be
called by a file system via {read|write}_file_io_vec_pages() (naming
suggestions are always welcomed :-)). It now gets an FD, and uses that to
communicate with the device (via its fs_{read|write}_pages() hooks).
* The file_cache_{read|write}() functions must now be called without holding
an I/O relevant file system lock. That allows the file cache to prepare the
pages without colliding with the page writer, IOW the "mayBlock" flag can
go into the attic again (yay!).
* This also results in a much better performance when the system does I/O and
is low on memory, as the page writer can now finally write back some pages,
and that even without maxing out the CPU :)
* The API changes put slightly more burden on the fs_{read|write}_pages()
hooks, but in combination with the file_map it's still pretty straight
forward. It just will have to dispatch the call to the underlying device
directly, usually it will just call its fs_{read|write}_pages() hooks
via the above mentioned calls.
* Ported BFS and FAT to the new API, the latter has not been tested, though.
* Also ported the API changes to the fs_shell. I also completely removed its
file cache level page handling - the downside is that device access is no
longer cached (ie. depends on the host OS now), the upside is that the code
is greatly simplified.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@22886 a95241bf-73f2-0310-859d-f6bbb57e9c96
2007-11-11 00:19:52 +03:00
|
|
|
/*! Does the dirty work of combining the file_io_vecs with the iovecs
|
|
|
|
and calls the file system hooks to read/write the request to disk.
|
|
|
|
*/
|
|
|
|
static status_t
|
|
|
|
common_file_io_vec_pages(struct vnode *vnode, void *cookie,
|
|
|
|
const file_io_vec *fileVecs, size_t fileVecCount, const iovec *vecs,
|
|
|
|
size_t vecCount, uint32 *_vecIndex, size_t *_vecOffset, size_t *_numBytes,
|
|
|
|
bool doWrite)
|
|
|
|
{
|
|
|
|
if (fileVecCount == 0) {
|
|
|
|
// There are no file vecs at this offset, so we're obviously trying
|
|
|
|
// to access the file outside of its bounds
|
|
|
|
return B_BAD_VALUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
size_t numBytes = *_numBytes;
|
|
|
|
uint32 fileVecIndex;
|
|
|
|
size_t vecOffset = *_vecOffset;
|
|
|
|
uint32 vecIndex = *_vecIndex;
|
|
|
|
status_t status;
|
|
|
|
size_t size;
|
|
|
|
|
2008-01-06 17:04:15 +03:00
|
|
|
if (!doWrite && vecOffset == 0) {
|
* Extracted file_map API out of the file cache - it's now an optional service
that can be used by file systems.
* Changed the way the file cache works: instead of reading/writing to the
underlying device directly, it can now be used for any data source, ie.
also network file systems.
* As a result, the former pages_io() moved to the VFS layer, and can now be
called by a file system via {read|write}_file_io_vec_pages() (naming
suggestions are always welcomed :-)). It now gets an FD, and uses that to
communicate with the device (via its fs_{read|write}_pages() hooks).
* The file_cache_{read|write}() functions must now be called without holding
an I/O relevant file system lock. That allows the file cache to prepare the
pages without colliding with the page writer, IOW the "mayBlock" flag can
go into the attic again (yay!).
* This also results in a much better performance when the system does I/O and
is low on memory, as the page writer can now finally write back some pages,
and that even without maxing out the CPU :)
* The API changes put slightly more burden on the fs_{read|write}_pages()
hooks, but in combination with the file_map it's still pretty straight
forward. It just will have to dispatch the call to the underlying device
directly, usually it will just call its fs_{read|write}_pages() hooks
via the above mentioned calls.
* Ported BFS and FAT to the new API, the latter has not been tested, though.
* Also ported the API changes to the fs_shell. I also completely removed its
file cache level page handling - the downside is that device access is no
longer cached (ie. depends on the host OS now), the upside is that the code
is greatly simplified.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@22886 a95241bf-73f2-0310-859d-f6bbb57e9c96
2007-11-11 00:19:52 +03:00
|
|
|
// now directly read the data from the device
|
|
|
|
// the first file_io_vec can be read directly
|
|
|
|
|
|
|
|
size = fileVecs[0].length;
|
|
|
|
if (size > numBytes)
|
|
|
|
size = numBytes;
|
|
|
|
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
status = FS_CALL(vnode, read_pages, cookie, fileVecs[0].offset,
|
|
|
|
&vecs[vecIndex], vecCount - vecIndex, &size, false);
|
* Extracted file_map API out of the file cache - it's now an optional service
that can be used by file systems.
* Changed the way the file cache works: instead of reading/writing to the
underlying device directly, it can now be used for any data source, ie.
also network file systems.
* As a result, the former pages_io() moved to the VFS layer, and can now be
called by a file system via {read|write}_file_io_vec_pages() (naming
suggestions are always welcomed :-)). It now gets an FD, and uses that to
communicate with the device (via its fs_{read|write}_pages() hooks).
* The file_cache_{read|write}() functions must now be called without holding
an I/O relevant file system lock. That allows the file cache to prepare the
pages without colliding with the page writer, IOW the "mayBlock" flag can
go into the attic again (yay!).
* This also results in a much better performance when the system does I/O and
is low on memory, as the page writer can now finally write back some pages,
and that even without maxing out the CPU :)
* The API changes put slightly more burden on the fs_{read|write}_pages()
hooks, but in combination with the file_map it's still pretty straight
forward. It just will have to dispatch the call to the underlying device
directly, usually it will just call its fs_{read|write}_pages() hooks
via the above mentioned calls.
* Ported BFS and FAT to the new API, the latter has not been tested, though.
* Also ported the API changes to the fs_shell. I also completely removed its
file cache level page handling - the downside is that device access is no
longer cached (ie. depends on the host OS now), the upside is that the code
is greatly simplified.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@22886 a95241bf-73f2-0310-859d-f6bbb57e9c96
2007-11-11 00:19:52 +03:00
|
|
|
if (status < B_OK)
|
|
|
|
return status;
|
|
|
|
|
|
|
|
// TODO: this is a work-around for buggy device drivers!
|
|
|
|
// When our own drivers honour the length, we can:
|
|
|
|
// a) also use this direct I/O for writes (otherwise, it would
|
|
|
|
// overwrite precious data)
|
|
|
|
// b) panic if the term below is true (at least for writes)
|
|
|
|
if (size > fileVecs[0].length) {
|
|
|
|
//dprintf("warning: device driver %p doesn't respect total length in read_pages() call!\n", ref->device);
|
|
|
|
size = fileVecs[0].length;
|
|
|
|
}
|
|
|
|
|
|
|
|
ASSERT(size <= fileVecs[0].length);
|
|
|
|
|
|
|
|
// If the file portion was contiguous, we're already done now
|
|
|
|
if (size == numBytes)
|
|
|
|
return B_OK;
|
|
|
|
|
|
|
|
// if we reached the end of the file, we can return as well
|
|
|
|
if (size != fileVecs[0].length) {
|
|
|
|
*_numBytes = size;
|
|
|
|
return B_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
fileVecIndex = 1;
|
|
|
|
|
|
|
|
// first, find out where we have to continue in our iovecs
|
|
|
|
for (; vecIndex < vecCount; vecIndex++) {
|
|
|
|
if (size < vecs[vecIndex].iov_len)
|
|
|
|
break;
|
2008-01-06 17:04:15 +03:00
|
|
|
|
* Extracted file_map API out of the file cache - it's now an optional service
that can be used by file systems.
* Changed the way the file cache works: instead of reading/writing to the
underlying device directly, it can now be used for any data source, ie.
also network file systems.
* As a result, the former pages_io() moved to the VFS layer, and can now be
called by a file system via {read|write}_file_io_vec_pages() (naming
suggestions are always welcomed :-)). It now gets an FD, and uses that to
communicate with the device (via its fs_{read|write}_pages() hooks).
* The file_cache_{read|write}() functions must now be called without holding
an I/O relevant file system lock. That allows the file cache to prepare the
pages without colliding with the page writer, IOW the "mayBlock" flag can
go into the attic again (yay!).
* This also results in a much better performance when the system does I/O and
is low on memory, as the page writer can now finally write back some pages,
and that even without maxing out the CPU :)
* The API changes put slightly more burden on the fs_{read|write}_pages()
hooks, but in combination with the file_map it's still pretty straight
forward. It just will have to dispatch the call to the underlying device
directly, usually it will just call its fs_{read|write}_pages() hooks
via the above mentioned calls.
* Ported BFS and FAT to the new API, the latter has not been tested, though.
* Also ported the API changes to the fs_shell. I also completely removed its
file cache level page handling - the downside is that device access is no
longer cached (ie. depends on the host OS now), the upside is that the code
is greatly simplified.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@22886 a95241bf-73f2-0310-859d-f6bbb57e9c96
2007-11-11 00:19:52 +03:00
|
|
|
size -= vecs[vecIndex].iov_len;
|
|
|
|
}
|
2008-01-06 17:04:15 +03:00
|
|
|
|
|
|
|
vecOffset = size;
|
* Extracted file_map API out of the file cache - it's now an optional service
that can be used by file systems.
* Changed the way the file cache works: instead of reading/writing to the
underlying device directly, it can now be used for any data source, ie.
also network file systems.
* As a result, the former pages_io() moved to the VFS layer, and can now be
called by a file system via {read|write}_file_io_vec_pages() (naming
suggestions are always welcomed :-)). It now gets an FD, and uses that to
communicate with the device (via its fs_{read|write}_pages() hooks).
* The file_cache_{read|write}() functions must now be called without holding
an I/O relevant file system lock. That allows the file cache to prepare the
pages without colliding with the page writer, IOW the "mayBlock" flag can
go into the attic again (yay!).
* This also results in a much better performance when the system does I/O and
is low on memory, as the page writer can now finally write back some pages,
and that even without maxing out the CPU :)
* The API changes put slightly more burden on the fs_{read|write}_pages()
hooks, but in combination with the file_map it's still pretty straight
forward. It just will have to dispatch the call to the underlying device
directly, usually it will just call its fs_{read|write}_pages() hooks
via the above mentioned calls.
* Ported BFS and FAT to the new API, the latter has not been tested, though.
* Also ported the API changes to the fs_shell. I also completely removed its
file cache level page handling - the downside is that device access is no
longer cached (ie. depends on the host OS now), the upside is that the code
is greatly simplified.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@22886 a95241bf-73f2-0310-859d-f6bbb57e9c96
2007-11-11 00:19:52 +03:00
|
|
|
} else {
|
|
|
|
fileVecIndex = 0;
|
|
|
|
size = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Too bad, let's process the rest of the file_io_vecs
|
|
|
|
|
|
|
|
size_t totalSize = size;
|
|
|
|
size_t bytesLeft = numBytes - size;
|
|
|
|
|
|
|
|
for (; fileVecIndex < fileVecCount; fileVecIndex++) {
|
|
|
|
const file_io_vec &fileVec = fileVecs[fileVecIndex];
|
|
|
|
off_t fileOffset = fileVec.offset;
|
|
|
|
off_t fileLeft = min_c(fileVec.length, bytesLeft);
|
|
|
|
|
|
|
|
TRACE(("FILE VEC [%lu] length %Ld\n", fileVecIndex, fileLeft));
|
|
|
|
|
|
|
|
// process the complete fileVec
|
|
|
|
while (fileLeft > 0) {
|
|
|
|
iovec tempVecs[MAX_TEMP_IO_VECS];
|
|
|
|
uint32 tempCount = 0;
|
|
|
|
|
|
|
|
// size tracks how much of what is left of the current fileVec
|
2008-03-04 19:59:59 +03:00
|
|
|
// (fileLeft) has been assigned to tempVecs
|
* Extracted file_map API out of the file cache - it's now an optional service
that can be used by file systems.
* Changed the way the file cache works: instead of reading/writing to the
underlying device directly, it can now be used for any data source, ie.
also network file systems.
* As a result, the former pages_io() moved to the VFS layer, and can now be
called by a file system via {read|write}_file_io_vec_pages() (naming
suggestions are always welcomed :-)). It now gets an FD, and uses that to
communicate with the device (via its fs_{read|write}_pages() hooks).
* The file_cache_{read|write}() functions must now be called without holding
an I/O relevant file system lock. That allows the file cache to prepare the
pages without colliding with the page writer, IOW the "mayBlock" flag can
go into the attic again (yay!).
* This also results in a much better performance when the system does I/O and
is low on memory, as the page writer can now finally write back some pages,
and that even without maxing out the CPU :)
* The API changes put slightly more burden on the fs_{read|write}_pages()
hooks, but in combination with the file_map it's still pretty straight
forward. It just will have to dispatch the call to the underlying device
directly, usually it will just call its fs_{read|write}_pages() hooks
via the above mentioned calls.
* Ported BFS and FAT to the new API, the latter has not been tested, though.
* Also ported the API changes to the fs_shell. I also completely removed its
file cache level page handling - the downside is that device access is no
longer cached (ie. depends on the host OS now), the upside is that the code
is greatly simplified.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@22886 a95241bf-73f2-0310-859d-f6bbb57e9c96
2007-11-11 00:19:52 +03:00
|
|
|
size = 0;
|
|
|
|
|
|
|
|
// assign what is left of the current fileVec to the tempVecs
|
|
|
|
for (size = 0; size < fileLeft && vecIndex < vecCount
|
|
|
|
&& tempCount < MAX_TEMP_IO_VECS;) {
|
|
|
|
// try to satisfy one iovec per iteration (or as much as
|
|
|
|
// possible)
|
|
|
|
|
|
|
|
// bytes left of the current iovec
|
|
|
|
size_t vecLeft = vecs[vecIndex].iov_len - vecOffset;
|
|
|
|
if (vecLeft == 0) {
|
|
|
|
vecOffset = 0;
|
|
|
|
vecIndex++;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
TRACE(("fill vec %ld, offset = %lu, size = %lu\n",
|
|
|
|
vecIndex, vecOffset, size));
|
|
|
|
|
|
|
|
// actually available bytes
|
|
|
|
size_t tempVecSize = min_c(vecLeft, fileLeft - size);
|
|
|
|
|
|
|
|
tempVecs[tempCount].iov_base
|
|
|
|
= (void *)((addr_t)vecs[vecIndex].iov_base + vecOffset);
|
|
|
|
tempVecs[tempCount].iov_len = tempVecSize;
|
|
|
|
tempCount++;
|
|
|
|
|
|
|
|
size += tempVecSize;
|
|
|
|
vecOffset += tempVecSize;
|
|
|
|
}
|
|
|
|
|
|
|
|
size_t bytes = size;
|
|
|
|
if (doWrite) {
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
status = FS_CALL(vnode, write_pages, cookie, fileOffset,
|
|
|
|
tempVecs, tempCount, &bytes, false);
|
* Extracted file_map API out of the file cache - it's now an optional service
that can be used by file systems.
* Changed the way the file cache works: instead of reading/writing to the
underlying device directly, it can now be used for any data source, ie.
also network file systems.
* As a result, the former pages_io() moved to the VFS layer, and can now be
called by a file system via {read|write}_file_io_vec_pages() (naming
suggestions are always welcomed :-)). It now gets an FD, and uses that to
communicate with the device (via its fs_{read|write}_pages() hooks).
* The file_cache_{read|write}() functions must now be called without holding
an I/O relevant file system lock. That allows the file cache to prepare the
pages without colliding with the page writer, IOW the "mayBlock" flag can
go into the attic again (yay!).
* This also results in a much better performance when the system does I/O and
is low on memory, as the page writer can now finally write back some pages,
and that even without maxing out the CPU :)
* The API changes put slightly more burden on the fs_{read|write}_pages()
hooks, but in combination with the file_map it's still pretty straight
forward. It just will have to dispatch the call to the underlying device
directly, usually it will just call its fs_{read|write}_pages() hooks
via the above mentioned calls.
* Ported BFS and FAT to the new API, the latter has not been tested, though.
* Also ported the API changes to the fs_shell. I also completely removed its
file cache level page handling - the downside is that device access is no
longer cached (ie. depends on the host OS now), the upside is that the code
is greatly simplified.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@22886 a95241bf-73f2-0310-859d-f6bbb57e9c96
2007-11-11 00:19:52 +03:00
|
|
|
} else {
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
status = FS_CALL(vnode, read_pages, cookie, fileOffset,
|
|
|
|
tempVecs, tempCount, &bytes, false);
|
* Extracted file_map API out of the file cache - it's now an optional service
that can be used by file systems.
* Changed the way the file cache works: instead of reading/writing to the
underlying device directly, it can now be used for any data source, ie.
also network file systems.
* As a result, the former pages_io() moved to the VFS layer, and can now be
called by a file system via {read|write}_file_io_vec_pages() (naming
suggestions are always welcomed :-)). It now gets an FD, and uses that to
communicate with the device (via its fs_{read|write}_pages() hooks).
* The file_cache_{read|write}() functions must now be called without holding
an I/O relevant file system lock. That allows the file cache to prepare the
pages without colliding with the page writer, IOW the "mayBlock" flag can
go into the attic again (yay!).
* This also results in a much better performance when the system does I/O and
is low on memory, as the page writer can now finally write back some pages,
and that even without maxing out the CPU :)
* The API changes put slightly more burden on the fs_{read|write}_pages()
hooks, but in combination with the file_map it's still pretty straight
forward. It just will have to dispatch the call to the underlying device
directly, usually it will just call its fs_{read|write}_pages() hooks
via the above mentioned calls.
* Ported BFS and FAT to the new API, the latter has not been tested, though.
* Also ported the API changes to the fs_shell. I also completely removed its
file cache level page handling - the downside is that device access is no
longer cached (ie. depends on the host OS now), the upside is that the code
is greatly simplified.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@22886 a95241bf-73f2-0310-859d-f6bbb57e9c96
2007-11-11 00:19:52 +03:00
|
|
|
}
|
|
|
|
if (status < B_OK)
|
|
|
|
return status;
|
|
|
|
|
|
|
|
totalSize += bytes;
|
|
|
|
bytesLeft -= size;
|
|
|
|
fileOffset += size;
|
|
|
|
fileLeft -= size;
|
|
|
|
//dprintf("-> file left = %Lu\n", fileLeft);
|
|
|
|
|
|
|
|
if (size != bytes || vecIndex >= vecCount) {
|
|
|
|
// there are no more bytes or iovecs, let's bail out
|
|
|
|
*_numBytes = totalSize;
|
|
|
|
return B_OK;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
*_vecIndex = vecIndex;
|
|
|
|
*_vecOffset = vecOffset;
|
|
|
|
*_numBytes = totalSize;
|
|
|
|
return B_OK;
|
|
|
|
}
|
|
|
|
|
2002-09-25 06:18:20 +04:00
|
|
|
|
2007-10-08 20:06:32 +04:00
|
|
|
// #pragma mark - public API for file systems
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2002-07-20 04:16:12 +04:00
|
|
|
|
2004-06-07 18:25:22 +04:00
|
|
|
extern "C" status_t
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
new_vnode(fs_volume *volume, ino_t vnodeID, void *privateNode,
|
|
|
|
fs_vnode_ops *ops)
|
2003-02-21 16:49:26 +03:00
|
|
|
{
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
FUNCTION(("new_vnode(volume = %p (%ld), vnodeID = %Ld, node = %p)\n",
|
|
|
|
volume, volume->id, vnodeID, privateNode));
|
2004-06-08 10:43:46 +04:00
|
|
|
|
2003-02-21 16:49:26 +03:00
|
|
|
if (privateNode == NULL)
|
|
|
|
return B_BAD_VALUE;
|
|
|
|
|
2003-10-17 18:47:15 +04:00
|
|
|
mutex_lock(&sVnodeMutex);
|
2003-02-21 16:49:26 +03:00
|
|
|
|
|
|
|
// file system integrity check:
|
|
|
|
// test if the vnode already exists and bail out if this is the case!
|
|
|
|
|
|
|
|
// ToDo: the R5 implementation obviously checks for a different cookie
|
|
|
|
// and doesn't panic if they are equal
|
|
|
|
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
struct vnode *vnode = lookup_vnode(volume->id, vnodeID);
|
|
|
|
if (vnode != NULL) {
|
|
|
|
panic("vnode %ld:%Ld already exists (node = %p, vnode->node = %p)!",
|
|
|
|
volume->id, vnodeID, privateNode, vnode->private_node);
|
|
|
|
}
|
2003-02-21 16:49:26 +03:00
|
|
|
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
status_t status = create_new_vnode(&vnode, volume->id, vnodeID);
|
2005-03-14 04:15:31 +03:00
|
|
|
if (status == B_OK) {
|
2004-02-02 18:09:21 +03:00
|
|
|
vnode->private_node = privateNode;
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
vnode->ops = ops;
|
2005-03-14 04:15:31 +03:00
|
|
|
vnode->busy = true;
|
|
|
|
vnode->unpublished = true;
|
|
|
|
}
|
|
|
|
|
2005-12-16 20:35:03 +03:00
|
|
|
TRACE(("returns: %s\n", strerror(status)));
|
2005-03-14 04:15:31 +03:00
|
|
|
|
|
|
|
mutex_unlock(&sVnodeMutex);
|
|
|
|
return status;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
extern "C" status_t
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
publish_vnode(fs_volume *volume, ino_t vnodeID, void *privateNode,
|
|
|
|
fs_vnode_ops *ops, int type, uint32 flags)
|
2005-03-14 04:15:31 +03:00
|
|
|
{
|
|
|
|
FUNCTION(("publish_vnode()\n"));
|
|
|
|
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
MutexLocker locker(sVnodeMutex);
|
2005-03-14 04:15:31 +03:00
|
|
|
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
struct vnode *vnode = lookup_vnode(volume->id, vnodeID);
|
2005-03-14 04:15:31 +03:00
|
|
|
status_t status = B_OK;
|
|
|
|
|
|
|
|
if (vnode != NULL && vnode->busy && vnode->unpublished
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
&& vnode->private_node == privateNode && vnode->ops == ops) {
|
|
|
|
// already known, but not published
|
2005-03-14 04:15:31 +03:00
|
|
|
} else if (vnode == NULL && privateNode != NULL) {
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
status = create_new_vnode(&vnode, volume->id, vnodeID);
|
|
|
|
if (status == B_OK) {
|
2005-03-14 04:15:31 +03:00
|
|
|
vnode->private_node = privateNode;
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
vnode->ops = ops;
|
|
|
|
vnode->busy = true;
|
|
|
|
vnode->unpublished = true;
|
|
|
|
}
|
2005-03-14 04:15:31 +03:00
|
|
|
} else
|
|
|
|
status = B_BAD_VALUE;
|
2003-02-21 16:49:26 +03:00
|
|
|
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
bool publishSpecialSubNode = false;
|
|
|
|
|
|
|
|
if (status == B_OK) {
|
|
|
|
vnode->type = type;
|
|
|
|
vnode->remove = (flags & B_VNODE_PUBLISH_REMOVED) != 0;
|
|
|
|
publishSpecialSubNode = is_special_node_type(type)
|
|
|
|
&& (flags & B_VNODE_DONT_CREATE_SPECIAL_SUB_NODE) == 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// create sub vnodes, if necessary
|
|
|
|
if (status == B_OK
|
|
|
|
&& (volume->sub_volume != NULL || publishSpecialSubNode)) {
|
|
|
|
locker.Unlock();
|
|
|
|
|
|
|
|
fs_volume *subVolume = volume;
|
|
|
|
if (volume->sub_volume != NULL) {
|
|
|
|
while (status == B_OK && subVolume->sub_volume != NULL) {
|
|
|
|
subVolume = subVolume->sub_volume;
|
|
|
|
status = subVolume->ops->create_sub_vnode(subVolume, vnodeID,
|
|
|
|
vnode);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (status == B_OK && publishSpecialSubNode)
|
|
|
|
status = create_special_sub_node(vnode, flags);
|
|
|
|
|
|
|
|
if (status != B_OK) {
|
|
|
|
// error -- clean up the created sub vnodes
|
|
|
|
while (subVolume->super_volume != volume) {
|
|
|
|
subVolume = subVolume->super_volume;
|
|
|
|
subVolume->ops->delete_sub_vnode(subVolume, vnode);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
locker.Lock();
|
|
|
|
|
|
|
|
if (status != B_OK) {
|
|
|
|
hash_remove(sVnodeTable, vnode);
|
|
|
|
remove_vnode_from_mount_list(vnode, vnode->mount);
|
|
|
|
free(vnode);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (status == B_OK) {
|
|
|
|
vnode->busy = false;
|
|
|
|
vnode->unpublished = false;
|
|
|
|
}
|
|
|
|
|
2005-12-16 20:35:03 +03:00
|
|
|
TRACE(("returns: %s\n", strerror(status)));
|
2004-06-08 10:43:46 +04:00
|
|
|
|
2003-02-21 16:49:26 +03:00
|
|
|
return status;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-06-07 18:25:22 +04:00
|
|
|
extern "C" status_t
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
get_vnode(fs_volume *volume, ino_t vnodeID, void **fsNode)
|
2002-07-09 16:24:59 +04:00
|
|
|
{
|
2002-07-20 04:16:12 +04:00
|
|
|
struct vnode *vnode;
|
2002-07-09 16:24:59 +04:00
|
|
|
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
if (volume == NULL)
|
|
|
|
return B_BAD_VALUE;
|
|
|
|
|
|
|
|
status_t status = get_vnode(volume->id, vnodeID, &vnode, true, true);
|
2004-12-14 01:17:00 +03:00
|
|
|
if (status < B_OK)
|
2002-07-28 22:41:07 +04:00
|
|
|
return status;
|
2002-07-09 16:24:59 +04:00
|
|
|
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
// If this is a layered FS, we need to get the node cookie for the requested
|
|
|
|
// layer.
|
|
|
|
if (HAS_FS_CALL(vnode, get_super_vnode)) {
|
|
|
|
fs_vnode resolvedNode;
|
|
|
|
status_t status = FS_CALL(vnode, get_super_vnode, volume,
|
|
|
|
&resolvedNode);
|
|
|
|
if (status != B_OK) {
|
|
|
|
panic("get_vnode(): Failed to get super node for vnode %p, "
|
|
|
|
"volume: %p", vnode, volume);
|
|
|
|
put_vnode(vnode);
|
|
|
|
return status;
|
|
|
|
}
|
|
|
|
|
|
|
|
*fsNode = resolvedNode.private_node;
|
|
|
|
} else
|
|
|
|
*fsNode = vnode->private_node;
|
|
|
|
|
2002-07-28 22:41:07 +04:00
|
|
|
return B_OK;
|
2002-07-20 04:16:12 +04:00
|
|
|
}
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2002-07-14 09:13:20 +04:00
|
|
|
|
2004-06-07 18:25:22 +04:00
|
|
|
extern "C" status_t
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
put_vnode(fs_volume *volume, ino_t vnodeID)
|
2002-07-20 04:16:12 +04:00
|
|
|
{
|
|
|
|
struct vnode *vnode;
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2003-10-17 18:47:15 +04:00
|
|
|
mutex_lock(&sVnodeMutex);
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
vnode = lookup_vnode(volume->id, vnodeID);
|
2003-10-17 18:47:15 +04:00
|
|
|
mutex_unlock(&sVnodeMutex);
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2002-07-20 04:16:12 +04:00
|
|
|
if (vnode)
|
|
|
|
dec_vnode_ref_count(vnode, true);
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2002-07-28 22:41:07 +04:00
|
|
|
return B_OK;
|
2002-07-20 04:16:12 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-06-07 18:25:22 +04:00
|
|
|
extern "C" status_t
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
remove_vnode(fs_volume *volume, ino_t vnodeID)
|
2004-06-07 18:25:22 +04:00
|
|
|
{
|
|
|
|
struct vnode *vnode;
|
2005-08-02 15:20:04 +04:00
|
|
|
bool remove = false;
|
2004-06-07 18:25:22 +04:00
|
|
|
|
2007-09-08 20:17:59 +04:00
|
|
|
MutexLocker locker(sVnodeMutex);
|
2004-06-07 18:25:22 +04:00
|
|
|
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
vnode = lookup_vnode(volume->id, vnodeID);
|
2007-09-08 20:17:59 +04:00
|
|
|
if (vnode == NULL)
|
|
|
|
return B_ENTRY_NOT_FOUND;
|
2005-10-20 20:34:18 +04:00
|
|
|
|
2007-09-08 20:17:59 +04:00
|
|
|
if (vnode->covered_by != NULL) {
|
|
|
|
// this vnode is in use
|
|
|
|
mutex_unlock(&sVnodeMutex);
|
|
|
|
return B_BUSY;
|
2005-03-14 04:15:31 +03:00
|
|
|
}
|
2004-06-07 18:25:22 +04:00
|
|
|
|
2007-09-08 20:17:59 +04:00
|
|
|
vnode->remove = true;
|
|
|
|
if (vnode->unpublished) {
|
|
|
|
// prepare the vnode for deletion
|
|
|
|
vnode->busy = true;
|
|
|
|
remove = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
locker.Unlock();
|
2008-03-04 19:59:59 +03:00
|
|
|
|
2005-08-02 15:20:04 +04:00
|
|
|
if (remove) {
|
|
|
|
// if the vnode hasn't been published yet, we delete it here
|
|
|
|
atomic_add(&vnode->ref_count, -1);
|
|
|
|
free_vnode(vnode, true);
|
|
|
|
}
|
|
|
|
|
2007-09-08 20:17:59 +04:00
|
|
|
return B_OK;
|
2004-06-07 21:25:55 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-07-15 16:38:13 +04:00
|
|
|
extern "C" status_t
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
unremove_vnode(fs_volume *volume, ino_t vnodeID)
|
2004-06-07 21:25:55 +04:00
|
|
|
{
|
|
|
|
struct vnode *vnode;
|
|
|
|
|
|
|
|
mutex_lock(&sVnodeMutex);
|
|
|
|
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
vnode = lookup_vnode(volume->id, vnodeID);
|
2004-06-07 21:25:55 +04:00
|
|
|
if (vnode)
|
2005-03-14 04:15:31 +03:00
|
|
|
vnode->remove = false;
|
2004-06-07 21:25:55 +04:00
|
|
|
|
|
|
|
mutex_unlock(&sVnodeMutex);
|
|
|
|
return B_OK;
|
2004-06-07 18:25:22 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-07-15 16:38:13 +04:00
|
|
|
extern "C" status_t
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
get_vnode_removed(fs_volume *volume, ino_t vnodeID, bool* removed)
|
2007-03-01 01:24:28 +03:00
|
|
|
{
|
|
|
|
mutex_lock(&sVnodeMutex);
|
|
|
|
|
|
|
|
status_t result;
|
|
|
|
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
if (struct vnode* vnode = lookup_vnode(volume->id, vnodeID)) {
|
2007-03-02 03:34:20 +03:00
|
|
|
if (removed)
|
|
|
|
*removed = vnode->remove;
|
|
|
|
result = B_OK;
|
|
|
|
} else
|
2007-03-01 01:24:28 +03:00
|
|
|
result = B_BAD_VALUE;
|
|
|
|
|
|
|
|
mutex_unlock(&sVnodeMutex);
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
* Extracted file_map API out of the file cache - it's now an optional service
that can be used by file systems.
* Changed the way the file cache works: instead of reading/writing to the
underlying device directly, it can now be used for any data source, ie.
also network file systems.
* As a result, the former pages_io() moved to the VFS layer, and can now be
called by a file system via {read|write}_file_io_vec_pages() (naming
suggestions are always welcomed :-)). It now gets an FD, and uses that to
communicate with the device (via its fs_{read|write}_pages() hooks).
* The file_cache_{read|write}() functions must now be called without holding
an I/O relevant file system lock. That allows the file cache to prepare the
pages without colliding with the page writer, IOW the "mayBlock" flag can
go into the attic again (yay!).
* This also results in a much better performance when the system does I/O and
is low on memory, as the page writer can now finally write back some pages,
and that even without maxing out the CPU :)
* The API changes put slightly more burden on the fs_{read|write}_pages()
hooks, but in combination with the file_map it's still pretty straight
forward. It just will have to dispatch the call to the underlying device
directly, usually it will just call its fs_{read|write}_pages() hooks
via the above mentioned calls.
* Ported BFS and FAT to the new API, the latter has not been tested, though.
* Also ported the API changes to the fs_shell. I also completely removed its
file cache level page handling - the downside is that device access is no
longer cached (ie. depends on the host OS now), the upside is that the code
is greatly simplified.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@22886 a95241bf-73f2-0310-859d-f6bbb57e9c96
2007-11-11 00:19:52 +03:00
|
|
|
extern "C" status_t
|
|
|
|
read_pages(int fd, off_t pos, const iovec *vecs, size_t count,
|
|
|
|
size_t *_numBytes, bool fsReenter)
|
|
|
|
{
|
|
|
|
struct file_descriptor *descriptor;
|
|
|
|
struct vnode *vnode;
|
|
|
|
|
|
|
|
descriptor = get_fd_and_vnode(fd, &vnode, true);
|
|
|
|
if (descriptor == NULL)
|
|
|
|
return B_FILE_ERROR;
|
|
|
|
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
status_t status = FS_CALL(vnode, read_pages, descriptor->cookie, pos, vecs,
|
|
|
|
count, _numBytes, fsReenter);
|
* Extracted file_map API out of the file cache - it's now an optional service
that can be used by file systems.
* Changed the way the file cache works: instead of reading/writing to the
underlying device directly, it can now be used for any data source, ie.
also network file systems.
* As a result, the former pages_io() moved to the VFS layer, and can now be
called by a file system via {read|write}_file_io_vec_pages() (naming
suggestions are always welcomed :-)). It now gets an FD, and uses that to
communicate with the device (via its fs_{read|write}_pages() hooks).
* The file_cache_{read|write}() functions must now be called without holding
an I/O relevant file system lock. That allows the file cache to prepare the
pages without colliding with the page writer, IOW the "mayBlock" flag can
go into the attic again (yay!).
* This also results in a much better performance when the system does I/O and
is low on memory, as the page writer can now finally write back some pages,
and that even without maxing out the CPU :)
* The API changes put slightly more burden on the fs_{read|write}_pages()
hooks, but in combination with the file_map it's still pretty straight
forward. It just will have to dispatch the call to the underlying device
directly, usually it will just call its fs_{read|write}_pages() hooks
via the above mentioned calls.
* Ported BFS and FAT to the new API, the latter has not been tested, though.
* Also ported the API changes to the fs_shell. I also completely removed its
file cache level page handling - the downside is that device access is no
longer cached (ie. depends on the host OS now), the upside is that the code
is greatly simplified.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@22886 a95241bf-73f2-0310-859d-f6bbb57e9c96
2007-11-11 00:19:52 +03:00
|
|
|
|
|
|
|
put_fd(descriptor);
|
|
|
|
return status;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
extern "C" status_t
|
|
|
|
write_pages(int fd, off_t pos, const iovec *vecs, size_t count,
|
|
|
|
size_t *_numBytes, bool fsReenter)
|
|
|
|
{
|
|
|
|
struct file_descriptor *descriptor;
|
|
|
|
struct vnode *vnode;
|
|
|
|
|
|
|
|
descriptor = get_fd_and_vnode(fd, &vnode, true);
|
|
|
|
if (descriptor == NULL)
|
|
|
|
return B_FILE_ERROR;
|
|
|
|
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
status_t status = FS_CALL(vnode, write_pages, descriptor->cookie, pos, vecs,
|
|
|
|
count, _numBytes, fsReenter);
|
* Extracted file_map API out of the file cache - it's now an optional service
that can be used by file systems.
* Changed the way the file cache works: instead of reading/writing to the
underlying device directly, it can now be used for any data source, ie.
also network file systems.
* As a result, the former pages_io() moved to the VFS layer, and can now be
called by a file system via {read|write}_file_io_vec_pages() (naming
suggestions are always welcomed :-)). It now gets an FD, and uses that to
communicate with the device (via its fs_{read|write}_pages() hooks).
* The file_cache_{read|write}() functions must now be called without holding
an I/O relevant file system lock. That allows the file cache to prepare the
pages without colliding with the page writer, IOW the "mayBlock" flag can
go into the attic again (yay!).
* This also results in a much better performance when the system does I/O and
is low on memory, as the page writer can now finally write back some pages,
and that even without maxing out the CPU :)
* The API changes put slightly more burden on the fs_{read|write}_pages()
hooks, but in combination with the file_map it's still pretty straight
forward. It just will have to dispatch the call to the underlying device
directly, usually it will just call its fs_{read|write}_pages() hooks
via the above mentioned calls.
* Ported BFS and FAT to the new API, the latter has not been tested, though.
* Also ported the API changes to the fs_shell. I also completely removed its
file cache level page handling - the downside is that device access is no
longer cached (ie. depends on the host OS now), the upside is that the code
is greatly simplified.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@22886 a95241bf-73f2-0310-859d-f6bbb57e9c96
2007-11-11 00:19:52 +03:00
|
|
|
|
|
|
|
put_fd(descriptor);
|
|
|
|
return status;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
extern "C" status_t
|
|
|
|
read_file_io_vec_pages(int fd, const file_io_vec *fileVecs, size_t fileVecCount,
|
|
|
|
const iovec *vecs, size_t vecCount, uint32 *_vecIndex, size_t *_vecOffset,
|
|
|
|
size_t *_bytes)
|
|
|
|
{
|
|
|
|
struct file_descriptor *descriptor;
|
|
|
|
struct vnode *vnode;
|
|
|
|
|
|
|
|
descriptor = get_fd_and_vnode(fd, &vnode, true);
|
|
|
|
if (descriptor == NULL)
|
|
|
|
return B_FILE_ERROR;
|
|
|
|
|
|
|
|
status_t status = common_file_io_vec_pages(vnode, descriptor->cookie,
|
|
|
|
fileVecs, fileVecCount, vecs, vecCount, _vecIndex, _vecOffset, _bytes,
|
|
|
|
false);
|
|
|
|
|
|
|
|
put_fd(descriptor);
|
|
|
|
return status;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
extern "C" status_t
|
|
|
|
write_file_io_vec_pages(int fd, const file_io_vec *fileVecs, size_t fileVecCount,
|
|
|
|
const iovec *vecs, size_t vecCount, uint32 *_vecIndex, size_t *_vecOffset,
|
|
|
|
size_t *_bytes)
|
|
|
|
{
|
|
|
|
struct file_descriptor *descriptor;
|
|
|
|
struct vnode *vnode;
|
|
|
|
|
|
|
|
descriptor = get_fd_and_vnode(fd, &vnode, true);
|
|
|
|
if (descriptor == NULL)
|
|
|
|
return B_FILE_ERROR;
|
|
|
|
|
|
|
|
status_t status = common_file_io_vec_pages(vnode, descriptor->cookie,
|
|
|
|
fileVecs, fileVecCount, vecs, vecCount, _vecIndex, _vecOffset, _bytes,
|
|
|
|
true);
|
|
|
|
|
|
|
|
put_fd(descriptor);
|
|
|
|
return status;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2005-12-16 19:11:36 +03:00
|
|
|
// #pragma mark - private VFS API
|
2004-06-07 18:25:22 +04:00
|
|
|
// Functions the VFS exports for other parts of the kernel
|
|
|
|
|
|
|
|
|
2007-10-06 19:33:12 +04:00
|
|
|
/*! Acquires another reference to the vnode that has to be released
|
|
|
|
by calling vfs_put_vnode().
|
|
|
|
*/
|
2002-07-20 04:16:12 +04:00
|
|
|
void
|
2007-10-06 19:33:12 +04:00
|
|
|
vfs_acquire_vnode(struct vnode *vnode)
|
2002-07-20 04:16:12 +04:00
|
|
|
{
|
2007-10-06 19:33:12 +04:00
|
|
|
inc_vnode_ref_count(vnode);
|
2002-07-20 04:16:12 +04:00
|
|
|
}
|
2002-07-09 16:24:59 +04:00
|
|
|
|
|
|
|
|
2007-10-06 19:33:12 +04:00
|
|
|
/*! This is currently called from file_cache_create() only.
|
|
|
|
It's probably a temporary solution as long as devfs requires that
|
|
|
|
fs_read_pages()/fs_write_pages() are called with the standard
|
|
|
|
open cookie and not with a device cookie.
|
|
|
|
If that's done differently, remove this call; it has no other
|
|
|
|
purpose.
|
|
|
|
*/
|
2004-09-03 18:11:04 +04:00
|
|
|
extern "C" status_t
|
2004-09-07 02:29:20 +04:00
|
|
|
vfs_get_cookie_from_fd(int fd, void **_cookie)
|
2002-07-20 04:16:12 +04:00
|
|
|
{
|
2004-09-07 02:29:20 +04:00
|
|
|
struct file_descriptor *descriptor;
|
2004-09-03 18:11:04 +04:00
|
|
|
|
2004-09-07 02:29:20 +04:00
|
|
|
descriptor = get_fd(get_current_io_context(true), fd);
|
|
|
|
if (descriptor == NULL)
|
|
|
|
return B_FILE_ERROR;
|
2004-09-03 18:11:04 +04:00
|
|
|
|
2004-09-07 02:29:20 +04:00
|
|
|
*_cookie = descriptor->cookie;
|
|
|
|
return B_OK;
|
2002-07-20 04:16:12 +04:00
|
|
|
}
|
2002-07-09 16:24:59 +04:00
|
|
|
|
|
|
|
|
2004-09-03 18:11:04 +04:00
|
|
|
extern "C" int
|
2007-10-06 19:33:12 +04:00
|
|
|
vfs_get_vnode_from_fd(int fd, bool kernel, struct vnode **vnode)
|
2002-07-20 04:16:12 +04:00
|
|
|
{
|
2004-08-29 00:38:39 +04:00
|
|
|
*vnode = get_vnode_from_fd(fd, kernel);
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2002-07-20 04:16:12 +04:00
|
|
|
if (*vnode == NULL)
|
2003-02-21 16:49:26 +03:00
|
|
|
return B_FILE_ERROR;
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2002-07-20 04:16:12 +04:00
|
|
|
return B_NO_ERROR;
|
2002-07-09 16:24:59 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-09-03 18:11:04 +04:00
|
|
|
extern "C" status_t
|
2007-10-06 19:33:12 +04:00
|
|
|
vfs_get_vnode_from_path(const char *path, bool kernel, struct vnode **_vnode)
|
2002-07-09 16:24:59 +04:00
|
|
|
{
|
2007-10-06 19:33:12 +04:00
|
|
|
TRACE(("vfs_get_vnode_from_path: entry. path = '%s', kernel %d\n",
|
|
|
|
path, kernel));
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2006-03-05 21:11:59 +03:00
|
|
|
KPath pathBuffer(B_PATH_NAME_LENGTH + 1);
|
|
|
|
if (pathBuffer.InitCheck() != B_OK)
|
|
|
|
return B_NO_MEMORY;
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2006-03-05 21:11:59 +03:00
|
|
|
char *buffer = pathBuffer.LockBuffer();
|
|
|
|
strlcpy(buffer, path, pathBuffer.BufferSize());
|
|
|
|
|
|
|
|
struct vnode *vnode;
|
|
|
|
status_t status = path_to_vnode(buffer, true, &vnode, NULL, kernel);
|
2004-02-23 07:31:51 +03:00
|
|
|
if (status < B_OK)
|
|
|
|
return status;
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2004-02-23 07:31:51 +03:00
|
|
|
*_vnode = vnode;
|
|
|
|
return B_OK;
|
2002-07-20 04:16:12 +04:00
|
|
|
}
|
2002-07-09 16:24:59 +04:00
|
|
|
|
|
|
|
|
2004-09-03 18:11:04 +04:00
|
|
|
extern "C" status_t
|
2007-10-08 20:06:32 +04:00
|
|
|
vfs_get_vnode(dev_t mountID, ino_t vnodeID, bool canWait, struct vnode **_vnode)
|
2004-12-14 01:17:00 +03:00
|
|
|
{
|
|
|
|
struct vnode *vnode;
|
|
|
|
|
2007-10-08 20:06:32 +04:00
|
|
|
status_t status = get_vnode(mountID, vnodeID, &vnode, canWait, false);
|
2004-12-14 01:17:00 +03:00
|
|
|
if (status < B_OK)
|
|
|
|
return status;
|
|
|
|
|
|
|
|
*_vnode = vnode;
|
|
|
|
return B_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2005-10-06 13:26:27 +04:00
|
|
|
extern "C" status_t
|
2007-06-21 23:50:57 +04:00
|
|
|
vfs_entry_ref_to_vnode(dev_t mountID, ino_t directoryID,
|
2007-10-06 19:33:12 +04:00
|
|
|
const char *name, struct vnode **_vnode)
|
2005-10-06 13:26:27 +04:00
|
|
|
{
|
2008-03-30 09:59:54 +04:00
|
|
|
return entry_ref_to_vnode(mountID, directoryID, name, false, true, _vnode);
|
2005-10-06 13:26:27 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
extern "C" void
|
2007-10-06 19:33:12 +04:00
|
|
|
vfs_vnode_to_node_ref(struct vnode *vnode, dev_t *_mountID, ino_t *_vnodeID)
|
2005-10-06 13:26:27 +04:00
|
|
|
{
|
|
|
|
*_mountID = vnode->device;
|
|
|
|
*_vnodeID = vnode->id;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-10-06 19:33:12 +04:00
|
|
|
/*! Looks up a vnode with the given mount and vnode ID.
|
|
|
|
Must only be used with "in-use" vnodes as it doesn't grab a reference
|
|
|
|
to the node.
|
|
|
|
It's currently only be used by file_cache_create().
|
|
|
|
*/
|
2004-12-14 01:17:00 +03:00
|
|
|
extern "C" status_t
|
2007-10-06 19:33:12 +04:00
|
|
|
vfs_lookup_vnode(dev_t mountID, ino_t vnodeID, struct vnode **_vnode)
|
2004-09-03 18:11:04 +04:00
|
|
|
{
|
2005-12-21 23:07:33 +03:00
|
|
|
mutex_lock(&sVnodeMutex);
|
2004-09-07 02:29:20 +04:00
|
|
|
struct vnode *vnode = lookup_vnode(mountID, vnodeID);
|
2005-12-21 23:07:33 +03:00
|
|
|
mutex_unlock(&sVnodeMutex);
|
|
|
|
|
2004-09-07 02:29:20 +04:00
|
|
|
if (vnode == NULL)
|
|
|
|
return B_ERROR;
|
|
|
|
|
|
|
|
*_vnode = vnode;
|
|
|
|
return B_OK;
|
2004-09-03 18:11:04 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-10-27 19:21:11 +04:00
|
|
|
extern "C" status_t
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
vfs_get_fs_node_from_path(fs_volume *volume, const char *path, bool kernel,
|
2007-10-06 19:33:12 +04:00
|
|
|
void **_node)
|
2004-10-27 19:21:11 +04:00
|
|
|
{
|
2006-03-05 21:11:59 +03:00
|
|
|
TRACE(("vfs_get_fs_node_from_path(mountID = %ld, path = \"%s\", kernel %d)\n",
|
|
|
|
mountID, path, kernel));
|
|
|
|
|
|
|
|
KPath pathBuffer(B_PATH_NAME_LENGTH + 1);
|
|
|
|
if (pathBuffer.InitCheck() != B_OK)
|
|
|
|
return B_NO_MEMORY;
|
2004-10-27 19:21:11 +04:00
|
|
|
|
2006-04-13 22:06:30 +04:00
|
|
|
fs_mount *mount;
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
status_t status = get_mount(volume->id, &mount);
|
2006-04-13 22:06:30 +04:00
|
|
|
if (status < B_OK)
|
|
|
|
return status;
|
|
|
|
|
2006-03-05 21:11:59 +03:00
|
|
|
char *buffer = pathBuffer.LockBuffer();
|
|
|
|
strlcpy(buffer, path, pathBuffer.BufferSize());
|
2004-10-27 19:21:11 +04:00
|
|
|
|
2006-04-13 22:06:30 +04:00
|
|
|
struct vnode *vnode = mount->root_vnode;
|
|
|
|
|
2006-04-16 15:44:54 +04:00
|
|
|
if (buffer[0] == '/')
|
|
|
|
status = path_to_vnode(buffer, true, &vnode, NULL, true);
|
|
|
|
else {
|
|
|
|
inc_vnode_ref_count(vnode);
|
|
|
|
// vnode_path_to_vnode() releases a reference to the starting vnode
|
2008-03-30 09:59:54 +04:00
|
|
|
status = vnode_path_to_vnode(vnode, buffer, true, 0, kernel, &vnode,
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
NULL);
|
2006-04-16 15:44:54 +04:00
|
|
|
}
|
2006-04-13 22:06:30 +04:00
|
|
|
|
|
|
|
put_mount(mount);
|
|
|
|
|
2004-10-27 19:21:11 +04:00
|
|
|
if (status < B_OK)
|
|
|
|
return status;
|
|
|
|
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
if (vnode->device != volume->id) {
|
2004-10-27 19:21:11 +04:00
|
|
|
// wrong mount ID - must not gain access on foreign file system nodes
|
|
|
|
put_vnode(vnode);
|
|
|
|
return B_BAD_VALUE;
|
|
|
|
}
|
|
|
|
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
// Use get_vnode() to resolve the cookie for the right layer.
|
|
|
|
status = get_vnode(volume, vnode->id, _node);
|
|
|
|
put_vnode(vnode);
|
|
|
|
|
|
|
|
return status;
|
2004-10-27 19:21:11 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-03-30 03:57:34 +04:00
|
|
|
status_t
|
|
|
|
vfs_read_stat(int fd, const char *path, bool traverseLeafLink,
|
|
|
|
struct stat *stat, bool kernel)
|
|
|
|
{
|
|
|
|
status_t status;
|
|
|
|
|
|
|
|
if (path) {
|
|
|
|
// path given: get the stat of the node referred to by (fd, path)
|
|
|
|
KPath pathBuffer(path, false, B_PATH_NAME_LENGTH + 1);
|
|
|
|
if (pathBuffer.InitCheck() != B_OK)
|
|
|
|
return B_NO_MEMORY;
|
|
|
|
|
|
|
|
status = common_path_read_stat(fd, pathBuffer.LockBuffer(),
|
|
|
|
traverseLeafLink, stat, kernel);
|
|
|
|
} else {
|
|
|
|
// no path given: get the FD and use the FD operation
|
|
|
|
struct file_descriptor *descriptor
|
|
|
|
= get_fd(get_current_io_context(kernel), fd);
|
|
|
|
if (descriptor == NULL)
|
|
|
|
return B_FILE_ERROR;
|
|
|
|
|
|
|
|
if (descriptor->ops->fd_read_stat)
|
|
|
|
status = descriptor->ops->fd_read_stat(descriptor, stat);
|
|
|
|
else
|
|
|
|
status = EOPNOTSUPP;
|
|
|
|
|
|
|
|
put_fd(descriptor);
|
|
|
|
}
|
|
|
|
|
|
|
|
return status;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-10-06 19:33:12 +04:00
|
|
|
/*! Finds the full path to the file that contains the module \a moduleName,
|
|
|
|
puts it into \a pathBuffer, and returns B_OK for success.
|
|
|
|
If \a pathBuffer was too small, it returns \c B_BUFFER_OVERFLOW,
|
|
|
|
\c B_ENTRY_NOT_FOUNT if no file could be found.
|
|
|
|
\a pathBuffer is clobbered in any case and must not be relied on if this
|
|
|
|
functions returns unsuccessfully.
|
2008-03-09 17:21:04 +03:00
|
|
|
\a basePath and \a pathBuffer must not point to the same space.
|
2007-10-06 19:33:12 +04:00
|
|
|
*/
|
2003-09-08 08:02:34 +04:00
|
|
|
status_t
|
2007-10-06 19:33:12 +04:00
|
|
|
vfs_get_module_path(const char *basePath, const char *moduleName,
|
|
|
|
char *pathBuffer, size_t bufferSize)
|
2003-09-08 08:02:34 +04:00
|
|
|
{
|
|
|
|
struct vnode *dir, *file;
|
|
|
|
status_t status;
|
|
|
|
size_t length;
|
|
|
|
char *path;
|
|
|
|
|
2008-03-09 17:21:04 +03:00
|
|
|
if (bufferSize == 0
|
|
|
|
|| strlcpy(pathBuffer, basePath, bufferSize) >= bufferSize)
|
2003-09-08 08:02:34 +04:00
|
|
|
return B_BUFFER_OVERFLOW;
|
|
|
|
|
2005-08-01 16:44:59 +04:00
|
|
|
status = path_to_vnode(pathBuffer, true, &dir, NULL, true);
|
2003-09-08 08:02:34 +04:00
|
|
|
if (status < B_OK)
|
|
|
|
return status;
|
|
|
|
|
2005-01-06 23:20:48 +03:00
|
|
|
// the path buffer had been clobbered by the above call
|
|
|
|
length = strlcpy(pathBuffer, basePath, bufferSize);
|
|
|
|
if (pathBuffer[length - 1] != '/')
|
|
|
|
pathBuffer[length++] = '/';
|
2003-09-08 08:02:34 +04:00
|
|
|
|
|
|
|
path = pathBuffer + length;
|
|
|
|
bufferSize -= length;
|
|
|
|
|
|
|
|
while (moduleName) {
|
|
|
|
char *nextPath = strchr(moduleName, '/');
|
|
|
|
if (nextPath == NULL)
|
|
|
|
length = strlen(moduleName);
|
2005-01-06 23:20:48 +03:00
|
|
|
else {
|
2003-09-08 08:02:34 +04:00
|
|
|
length = nextPath - moduleName;
|
2005-01-06 23:20:48 +03:00
|
|
|
nextPath++;
|
|
|
|
}
|
2003-09-08 08:02:34 +04:00
|
|
|
|
2004-04-28 15:20:19 +04:00
|
|
|
if (length + 1 >= bufferSize) {
|
2003-09-08 08:02:34 +04:00
|
|
|
status = B_BUFFER_OVERFLOW;
|
|
|
|
goto err;
|
|
|
|
}
|
|
|
|
|
|
|
|
memcpy(path, moduleName, length);
|
|
|
|
path[length] = '\0';
|
|
|
|
moduleName = nextPath;
|
|
|
|
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
status = vnode_path_to_vnode(dir, path, true, 0, true, &file, NULL);
|
2006-03-09 00:42:14 +03:00
|
|
|
if (status < B_OK) {
|
|
|
|
// vnode_path_to_vnode() has already released the reference to dir
|
|
|
|
return status;
|
|
|
|
}
|
2003-09-08 08:02:34 +04:00
|
|
|
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
if (S_ISDIR(file->type)) {
|
2003-09-08 08:02:34 +04:00
|
|
|
// goto the next directory
|
|
|
|
path[length] = '/';
|
|
|
|
path[length + 1] = '\0';
|
|
|
|
path += length + 1;
|
2005-01-06 23:20:48 +03:00
|
|
|
bufferSize -= length + 1;
|
2003-09-08 08:02:34 +04:00
|
|
|
|
|
|
|
dir = file;
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
} else if (S_ISREG(file->type)) {
|
2003-09-08 08:02:34 +04:00
|
|
|
// it's a file so it should be what we've searched for
|
|
|
|
put_vnode(file);
|
|
|
|
|
|
|
|
return B_OK;
|
|
|
|
} else {
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
TRACE(("vfs_get_module_path(): something is strange here: %d...\n",
|
|
|
|
file->type));
|
2003-09-08 08:02:34 +04:00
|
|
|
status = B_ERROR;
|
2006-03-09 00:42:14 +03:00
|
|
|
dir = file;
|
2003-09-08 08:02:34 +04:00
|
|
|
goto err;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// if we got here, the moduleName just pointed to a directory, not to
|
|
|
|
// a real module - what should we do in this case?
|
|
|
|
status = B_ENTRY_NOT_FOUND;
|
|
|
|
|
|
|
|
err:
|
|
|
|
put_vnode(dir);
|
|
|
|
return status;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-10-06 19:33:12 +04:00
|
|
|
/*! \brief Normalizes a given path.
|
2004-10-29 02:31:43 +04:00
|
|
|
|
2007-10-06 19:33:12 +04:00
|
|
|
The path must refer to an existing or non-existing entry in an existing
|
|
|
|
directory, that is chopping off the leaf component the remaining path must
|
|
|
|
refer to an existing directory.
|
|
|
|
|
|
|
|
The returned will be canonical in that it will be absolute, will not
|
|
|
|
contain any "." or ".." components or duplicate occurrences of '/'s,
|
|
|
|
and none of the directory components will by symbolic links.
|
|
|
|
|
|
|
|
Any two paths referring to the same entry, will result in the same
|
|
|
|
normalized path (well, that is pretty much the definition of `normalized',
|
|
|
|
isn't it :-).
|
|
|
|
|
|
|
|
\param path The path to be normalized.
|
|
|
|
\param buffer The buffer into which the normalized path will be written.
|
2008-02-08 06:06:14 +03:00
|
|
|
May be the same one as \a path.
|
2007-10-06 19:33:12 +04:00
|
|
|
\param bufferSize The size of \a buffer.
|
|
|
|
\param kernel \c true, if the IO context of the kernel shall be used,
|
|
|
|
otherwise that of the team this thread belongs to. Only relevant,
|
|
|
|
if the path is relative (to get the CWD).
|
|
|
|
\return \c B_OK if everything went fine, another error code otherwise.
|
|
|
|
*/
|
2004-10-29 02:31:43 +04:00
|
|
|
status_t
|
|
|
|
vfs_normalize_path(const char *path, char *buffer, size_t bufferSize,
|
|
|
|
bool kernel)
|
|
|
|
{
|
|
|
|
if (!path || !buffer || bufferSize < 1)
|
|
|
|
return B_BAD_VALUE;
|
2004-11-23 06:20:20 +03:00
|
|
|
|
2005-12-16 20:35:03 +03:00
|
|
|
TRACE(("vfs_normalize_path(`%s')\n", path));
|
2004-10-29 02:31:43 +04:00
|
|
|
|
|
|
|
// copy the supplied path to the stack, so it can be modified
|
2006-03-05 21:11:59 +03:00
|
|
|
KPath mutablePathBuffer(B_PATH_NAME_LENGTH + 1);
|
|
|
|
if (mutablePathBuffer.InitCheck() != B_OK)
|
|
|
|
return B_NO_MEMORY;
|
|
|
|
|
|
|
|
char *mutablePath = mutablePathBuffer.LockBuffer();
|
2004-10-29 02:31:43 +04:00
|
|
|
if (strlcpy(mutablePath, path, B_PATH_NAME_LENGTH) >= B_PATH_NAME_LENGTH)
|
|
|
|
return B_NAME_TOO_LONG;
|
|
|
|
|
|
|
|
// get the dir vnode and the leaf name
|
|
|
|
struct vnode *dirNode;
|
|
|
|
char leaf[B_FILE_NAME_LENGTH];
|
|
|
|
status_t error = path_to_dir_vnode(mutablePath, &dirNode, leaf, kernel);
|
2004-11-23 06:20:20 +03:00
|
|
|
if (error != B_OK) {
|
2005-12-16 20:35:03 +03:00
|
|
|
TRACE(("vfs_normalize_path(): failed to get dir vnode: %s\n", strerror(error)));
|
2004-10-29 02:31:43 +04:00
|
|
|
return error;
|
2004-11-23 06:20:20 +03:00
|
|
|
}
|
|
|
|
|
2004-10-29 02:31:43 +04:00
|
|
|
// if the leaf is "." or "..", we directly get the correct directory
|
|
|
|
// vnode and ignore the leaf later
|
|
|
|
bool isDir = (strcmp(leaf, ".") == 0 || strcmp(leaf, "..") == 0);
|
2008-03-30 09:59:54 +04:00
|
|
|
if (isDir) {
|
|
|
|
error = vnode_path_to_vnode(dirNode, leaf, false, 0, kernel, &dirNode,
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
NULL);
|
2008-03-30 09:59:54 +04:00
|
|
|
}
|
2004-11-23 06:20:20 +03:00
|
|
|
if (error != B_OK) {
|
2006-03-05 21:11:59 +03:00
|
|
|
TRACE(("vfs_normalize_path(): failed to get dir vnode for \".\" or \"..\": %s\n",
|
|
|
|
strerror(error)));
|
2004-10-29 02:31:43 +04:00
|
|
|
return error;
|
2004-11-23 06:20:20 +03:00
|
|
|
}
|
2004-10-29 02:31:43 +04:00
|
|
|
|
|
|
|
// get the directory path
|
2008-03-30 09:59:54 +04:00
|
|
|
error = dir_vnode_to_path(dirNode, buffer, bufferSize, kernel);
|
2004-10-29 02:31:43 +04:00
|
|
|
put_vnode(dirNode);
|
2004-11-23 06:20:20 +03:00
|
|
|
if (error < B_OK) {
|
2005-12-16 20:35:03 +03:00
|
|
|
TRACE(("vfs_normalize_path(): failed to get dir path: %s\n", strerror(error)));
|
2004-10-29 02:31:43 +04:00
|
|
|
return error;
|
2004-11-23 06:20:20 +03:00
|
|
|
}
|
2004-10-29 02:31:43 +04:00
|
|
|
|
|
|
|
// append the leaf name
|
|
|
|
if (!isDir) {
|
|
|
|
// insert a directory separator only if this is not the file system root
|
|
|
|
if ((strcmp(buffer, "/") != 0
|
|
|
|
&& strlcat(buffer, "/", bufferSize) >= bufferSize)
|
|
|
|
|| strlcat(buffer, leaf, bufferSize) >= bufferSize) {
|
|
|
|
return B_NAME_TOO_LONG;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2005-12-16 20:35:03 +03:00
|
|
|
TRACE(("vfs_normalize_path() -> `%s'\n", buffer));
|
2004-10-29 02:31:43 +04:00
|
|
|
return B_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-04-10 07:07:07 +04:00
|
|
|
/*! \brief Creates a special node in the file system.
|
|
|
|
|
|
|
|
The caller gets a reference to the newly created node (which is passed
|
|
|
|
back through \a _createdVnode) and is responsible for releasing it.
|
|
|
|
|
|
|
|
\param path The path where to create the entry for the node. Can be \c NULL,
|
|
|
|
in which case the node is created without an entry in the root FS -- it
|
|
|
|
will automatically be deleted when the last reference has been released.
|
|
|
|
\param subVnode The definition of the subnode. Can be \c NULL, in which case
|
|
|
|
the target file system will just create the node with its standard
|
|
|
|
operations. Depending on the type of the node a subnode might be created
|
|
|
|
automatically, though.
|
|
|
|
\param mode The type and permissions for the node to be created.
|
|
|
|
\param flags Flags to be passed to the creating FS.
|
|
|
|
\param kernel \c true, if called in the kernel context (relevant only if
|
|
|
|
\a path is not \c NULL and not absolute).
|
|
|
|
\param _superVnode Pointer to a pre-allocated structure to be filled by the
|
|
|
|
file system creating the node, with the private data pointer and
|
|
|
|
operations for the super node. Can be \c NULL.
|
|
|
|
\param _createVnode Pointer to pre-allocated storage where to store the
|
|
|
|
pointer to the newly created node.
|
|
|
|
\return \c B_OK, if everything went fine, another error code otherwise.
|
|
|
|
*/
|
|
|
|
status_t
|
|
|
|
vfs_create_special_node(const char *path, fs_vnode *subVnode, mode_t mode,
|
|
|
|
uint32 flags, bool kernel, fs_vnode *_superVnode,
|
|
|
|
struct vnode **_createdVnode)
|
|
|
|
{
|
|
|
|
struct vnode* dirNode;
|
|
|
|
char _leaf[B_FILE_NAME_LENGTH];
|
|
|
|
char* leaf = NULL;
|
|
|
|
|
|
|
|
if (path) {
|
|
|
|
// We've got a path. Get the dir vnode and the leaf name.
|
|
|
|
KPath tmpPathBuffer(B_PATH_NAME_LENGTH + 1);
|
|
|
|
if (tmpPathBuffer.InitCheck() != B_OK)
|
|
|
|
return B_NO_MEMORY;
|
|
|
|
|
|
|
|
char* tmpPath = tmpPathBuffer.LockBuffer();
|
|
|
|
if (strlcpy(tmpPath, path, B_PATH_NAME_LENGTH) >= B_PATH_NAME_LENGTH)
|
|
|
|
return B_NAME_TOO_LONG;
|
|
|
|
|
|
|
|
// get the dir vnode and the leaf name
|
|
|
|
leaf = _leaf;
|
|
|
|
status_t error = path_to_dir_vnode(tmpPath, &dirNode, leaf, kernel);
|
|
|
|
if (error != B_OK)
|
|
|
|
return error;
|
|
|
|
} else {
|
|
|
|
// No path. Create the node in the root FS.
|
|
|
|
dirNode = sRoot;
|
|
|
|
inc_vnode_ref_count(dirNode);
|
|
|
|
}
|
|
|
|
|
|
|
|
VNodePutter _(dirNode);
|
|
|
|
|
|
|
|
// check support for creating special nodes
|
|
|
|
if (!HAS_FS_CALL(dirNode, create_special_node))
|
|
|
|
return B_UNSUPPORTED;
|
|
|
|
|
|
|
|
// create the node
|
|
|
|
fs_vnode superVnode;
|
|
|
|
ino_t nodeID;
|
|
|
|
status_t status = FS_CALL(sRoot, create_special_node, leaf, subVnode,
|
|
|
|
mode, flags, _superVnode != NULL ? _superVnode : &superVnode, &nodeID);
|
|
|
|
if (status != B_OK)
|
|
|
|
return status;
|
|
|
|
|
|
|
|
// lookup the node
|
|
|
|
mutex_lock(&sVnodeMutex);
|
|
|
|
*_createdVnode = lookup_vnode(dirNode->mount->id, nodeID);
|
|
|
|
mutex_unlock(&sVnodeMutex);
|
|
|
|
|
|
|
|
if (*_createdVnode == NULL) {
|
|
|
|
panic("vfs_create_special_node(): lookup of node failed");
|
|
|
|
return B_ERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
return B_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2005-08-01 18:17:41 +04:00
|
|
|
extern "C" void
|
2007-10-06 19:33:12 +04:00
|
|
|
vfs_put_vnode(struct vnode *vnode)
|
2002-07-20 04:16:12 +04:00
|
|
|
{
|
2007-10-06 19:33:12 +04:00
|
|
|
put_vnode(vnode);
|
2002-07-20 04:16:12 +04:00
|
|
|
}
|
2002-07-09 16:24:59 +04:00
|
|
|
|
|
|
|
|
2005-08-09 20:25:01 +04:00
|
|
|
extern "C" status_t
|
2007-06-21 23:50:57 +04:00
|
|
|
vfs_get_cwd(dev_t *_mountID, ino_t *_vnodeID)
|
2005-08-09 20:25:01 +04:00
|
|
|
{
|
|
|
|
// Get current working directory from io context
|
|
|
|
struct io_context *context = get_current_io_context(false);
|
|
|
|
status_t status = B_OK;
|
|
|
|
|
|
|
|
mutex_lock(&context->io_mutex);
|
|
|
|
|
|
|
|
if (context->cwd != NULL) {
|
|
|
|
*_mountID = context->cwd->device;
|
|
|
|
*_vnodeID = context->cwd->id;
|
|
|
|
} else
|
|
|
|
status = B_ERROR;
|
|
|
|
|
|
|
|
mutex_unlock(&context->io_mutex);
|
|
|
|
return status;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-11-12 23:54:17 +03:00
|
|
|
status_t
|
|
|
|
vfs_unmount(dev_t mountID, uint32 flags)
|
|
|
|
{
|
|
|
|
return fs_unmount(NULL, mountID, flags, true);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-03-28 05:13:12 +04:00
|
|
|
extern "C" status_t
|
2007-06-21 23:50:57 +04:00
|
|
|
vfs_disconnect_vnode(dev_t mountID, ino_t vnodeID)
|
2006-03-28 05:13:12 +04:00
|
|
|
{
|
|
|
|
struct vnode *vnode;
|
|
|
|
|
2007-10-08 20:06:32 +04:00
|
|
|
status_t status = get_vnode(mountID, vnodeID, &vnode, true, true);
|
2006-03-28 05:13:12 +04:00
|
|
|
if (status < B_OK)
|
|
|
|
return status;
|
|
|
|
|
|
|
|
disconnect_mount_or_vnode_fds(vnode->mount, vnode);
|
2008-01-12 20:36:10 +03:00
|
|
|
put_vnode(vnode);
|
2006-03-28 05:13:12 +04:00
|
|
|
return B_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-03-06 19:18:52 +03:00
|
|
|
extern "C" void
|
|
|
|
vfs_free_unused_vnodes(int32 level)
|
|
|
|
{
|
|
|
|
vnode_low_memory_handler(NULL, level);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-09-07 02:29:20 +04:00
|
|
|
extern "C" bool
|
2007-10-06 19:33:12 +04:00
|
|
|
vfs_can_page(struct vnode *vnode, void *cookie)
|
2002-07-20 04:16:12 +04:00
|
|
|
{
|
|
|
|
FUNCTION(("vfs_canpage: vnode 0x%p\n", vnode));
|
2002-07-09 16:24:59 +04:00
|
|
|
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
if (HAS_FS_CALL(vnode, can_page))
|
|
|
|
return FS_CALL(vnode, can_page, cookie);
|
2004-09-04 21:48:11 +04:00
|
|
|
return false;
|
2002-07-20 04:16:12 +04:00
|
|
|
}
|
2002-07-09 16:24:59 +04:00
|
|
|
|
|
|
|
|
2004-09-07 02:29:20 +04:00
|
|
|
extern "C" status_t
|
2007-10-06 19:33:12 +04:00
|
|
|
vfs_read_pages(struct vnode *vnode, void *cookie, off_t pos, const iovec *vecs,
|
* Extracted file_map API out of the file cache - it's now an optional service
that can be used by file systems.
* Changed the way the file cache works: instead of reading/writing to the
underlying device directly, it can now be used for any data source, ie.
also network file systems.
* As a result, the former pages_io() moved to the VFS layer, and can now be
called by a file system via {read|write}_file_io_vec_pages() (naming
suggestions are always welcomed :-)). It now gets an FD, and uses that to
communicate with the device (via its fs_{read|write}_pages() hooks).
* The file_cache_{read|write}() functions must now be called without holding
an I/O relevant file system lock. That allows the file cache to prepare the
pages without colliding with the page writer, IOW the "mayBlock" flag can
go into the attic again (yay!).
* This also results in a much better performance when the system does I/O and
is low on memory, as the page writer can now finally write back some pages,
and that even without maxing out the CPU :)
* The API changes put slightly more burden on the fs_{read|write}_pages()
hooks, but in combination with the file_map it's still pretty straight
forward. It just will have to dispatch the call to the underlying device
directly, usually it will just call its fs_{read|write}_pages() hooks
via the above mentioned calls.
* Ported BFS and FAT to the new API, the latter has not been tested, though.
* Also ported the API changes to the fs_shell. I also completely removed its
file cache level page handling - the downside is that device access is no
longer cached (ie. depends on the host OS now), the upside is that the code
is greatly simplified.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@22886 a95241bf-73f2-0310-859d-f6bbb57e9c96
2007-11-11 00:19:52 +03:00
|
|
|
size_t count, size_t *_numBytes, bool fsReenter)
|
2004-09-07 02:29:20 +04:00
|
|
|
{
|
|
|
|
FUNCTION(("vfs_read_pages: vnode %p, vecs %p, pos %Ld\n", vnode, vecs, pos));
|
|
|
|
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
return FS_CALL(vnode, read_pages, cookie, pos, vecs, count, _numBytes,
|
|
|
|
fsReenter);
|
2004-09-07 02:29:20 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
extern "C" status_t
|
2007-10-06 19:33:12 +04:00
|
|
|
vfs_write_pages(struct vnode *vnode, void *cookie, off_t pos, const iovec *vecs,
|
* Extracted file_map API out of the file cache - it's now an optional service
that can be used by file systems.
* Changed the way the file cache works: instead of reading/writing to the
underlying device directly, it can now be used for any data source, ie.
also network file systems.
* As a result, the former pages_io() moved to the VFS layer, and can now be
called by a file system via {read|write}_file_io_vec_pages() (naming
suggestions are always welcomed :-)). It now gets an FD, and uses that to
communicate with the device (via its fs_{read|write}_pages() hooks).
* The file_cache_{read|write}() functions must now be called without holding
an I/O relevant file system lock. That allows the file cache to prepare the
pages without colliding with the page writer, IOW the "mayBlock" flag can
go into the attic again (yay!).
* This also results in a much better performance when the system does I/O and
is low on memory, as the page writer can now finally write back some pages,
and that even without maxing out the CPU :)
* The API changes put slightly more burden on the fs_{read|write}_pages()
hooks, but in combination with the file_map it's still pretty straight
forward. It just will have to dispatch the call to the underlying device
directly, usually it will just call its fs_{read|write}_pages() hooks
via the above mentioned calls.
* Ported BFS and FAT to the new API, the latter has not been tested, though.
* Also ported the API changes to the fs_shell. I also completely removed its
file cache level page handling - the downside is that device access is no
longer cached (ie. depends on the host OS now), the upside is that the code
is greatly simplified.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@22886 a95241bf-73f2-0310-859d-f6bbb57e9c96
2007-11-11 00:19:52 +03:00
|
|
|
size_t count, size_t *_numBytes, bool fsReenter)
|
2002-07-20 04:16:12 +04:00
|
|
|
{
|
2004-09-07 02:29:20 +04:00
|
|
|
FUNCTION(("vfs_write_pages: vnode %p, vecs %p, pos %Ld\n", vnode, vecs, pos));
|
|
|
|
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
return FS_CALL(vnode, write_pages, cookie, pos, vecs, count, _numBytes,
|
|
|
|
fsReenter);
|
2004-09-07 02:29:20 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-09-26 04:20:23 +04:00
|
|
|
/*! Gets the vnode's vm_cache object. If it didn't have one, it will be
|
|
|
|
created if \a allocate is \c true.
|
|
|
|
In case it's successful, it will also grab a reference to the cache
|
|
|
|
it returns.
|
|
|
|
*/
|
2004-09-07 02:29:20 +04:00
|
|
|
extern "C" status_t
|
2007-10-06 19:33:12 +04:00
|
|
|
vfs_get_vnode_cache(struct vnode *vnode, vm_cache **_cache, bool allocate)
|
2004-09-07 02:29:20 +04:00
|
|
|
{
|
|
|
|
if (vnode->cache != NULL) {
|
2005-12-21 20:00:03 +03:00
|
|
|
vm_cache_acquire_ref(vnode->cache);
|
2004-09-07 02:29:20 +04:00
|
|
|
*_cache = vnode->cache;
|
|
|
|
return B_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
mutex_lock(&sVnodeMutex);
|
|
|
|
|
|
|
|
status_t status = B_OK;
|
2005-08-05 15:52:22 +04:00
|
|
|
|
2004-09-07 02:29:20 +04:00
|
|
|
// The cache could have been created in the meantime
|
2005-08-05 15:52:22 +04:00
|
|
|
if (vnode->cache == NULL) {
|
2006-03-07 23:40:38 +03:00
|
|
|
if (allocate) {
|
2006-03-09 00:42:14 +03:00
|
|
|
// TODO: actually the vnode need to be busy already here, or
|
|
|
|
// else this won't work...
|
2006-03-07 23:40:38 +03:00
|
|
|
bool wasBusy = vnode->busy;
|
|
|
|
vnode->busy = true;
|
|
|
|
mutex_unlock(&sVnodeMutex);
|
|
|
|
|
2005-08-05 15:52:22 +04:00
|
|
|
status = vm_create_vnode_cache(vnode, &vnode->cache);
|
2006-03-07 23:40:38 +03:00
|
|
|
|
|
|
|
mutex_lock(&sVnodeMutex);
|
|
|
|
vnode->busy = wasBusy;
|
|
|
|
} else
|
2005-08-05 15:52:22 +04:00
|
|
|
status = B_BAD_VALUE;
|
2007-06-30 19:36:06 +04:00
|
|
|
}
|
2006-08-31 03:09:04 +04:00
|
|
|
|
2007-06-30 19:36:06 +04:00
|
|
|
if (status == B_OK) {
|
|
|
|
vm_cache_acquire_ref(vnode->cache);
|
2004-09-07 02:29:20 +04:00
|
|
|
*_cache = vnode->cache;
|
2007-06-30 19:36:06 +04:00
|
|
|
}
|
2004-09-07 02:29:20 +04:00
|
|
|
|
|
|
|
mutex_unlock(&sVnodeMutex);
|
|
|
|
return status;
|
2002-07-20 04:16:12 +04:00
|
|
|
}
|
2002-07-09 16:24:59 +04:00
|
|
|
|
|
|
|
|
2004-09-04 21:48:11 +04:00
|
|
|
status_t
|
2007-10-06 19:33:12 +04:00
|
|
|
vfs_get_file_map(struct vnode *vnode, off_t offset, size_t size,
|
|
|
|
file_io_vec *vecs, size_t *_count)
|
2002-07-20 04:16:12 +04:00
|
|
|
{
|
2004-09-10 03:21:09 +04:00
|
|
|
FUNCTION(("vfs_get_file_map: vnode %p, vecs %p, offset %Ld, size = %lu\n", vnode, vecs, offset, size));
|
2002-07-09 16:24:59 +04:00
|
|
|
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
return FS_CALL(vnode, get_file_map, offset, size, vecs, _count);
|
2002-07-09 16:24:59 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2005-02-02 09:21:31 +03:00
|
|
|
status_t
|
2007-10-06 19:33:12 +04:00
|
|
|
vfs_stat_vnode(struct vnode *vnode, struct stat *stat)
|
2005-02-02 09:21:31 +03:00
|
|
|
{
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
status_t status = FS_CALL(vnode, read_stat, stat);
|
2005-02-02 09:21:31 +03:00
|
|
|
|
|
|
|
// fill in the st_dev and st_ino fields
|
|
|
|
if (status == B_OK) {
|
|
|
|
stat->st_dev = vnode->device;
|
|
|
|
stat->st_ino = vnode->id;
|
|
|
|
}
|
|
|
|
|
|
|
|
return status;
|
2008-04-06 02:01:05 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
status_t
|
2008-04-06 13:18:27 +04:00
|
|
|
vfs_stat_node_ref(dev_t device, ino_t inode, struct stat *stat)
|
2008-04-06 02:01:05 +04:00
|
|
|
{
|
|
|
|
struct vnode *vnode;
|
|
|
|
status_t status = get_vnode(device, inode, &vnode, true, false);
|
|
|
|
if (status < B_OK)
|
|
|
|
return status;
|
|
|
|
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
status = FS_CALL(vnode, read_stat, stat);
|
2008-04-06 02:01:05 +04:00
|
|
|
put_vnode(vnode);
|
|
|
|
return status;
|
2005-02-02 09:21:31 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
status_t
|
2007-10-06 19:33:12 +04:00
|
|
|
vfs_get_vnode_name(struct vnode *vnode, char *name, size_t nameSize)
|
2005-02-02 09:21:31 +03:00
|
|
|
{
|
2008-03-30 09:59:54 +04:00
|
|
|
return get_vnode_name(vnode, NULL, name, nameSize, true);
|
2005-02-02 09:21:31 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-02-27 19:39:32 +03:00
|
|
|
status_t
|
|
|
|
vfs_entry_ref_to_path(dev_t device, ino_t inode, const char *leaf,
|
|
|
|
char *path, size_t pathLength)
|
|
|
|
{
|
|
|
|
struct vnode *vnode;
|
|
|
|
status_t status;
|
|
|
|
|
|
|
|
// filter invalid leaf names
|
2008-02-27 20:36:21 +03:00
|
|
|
if (leaf != NULL && (leaf[0] == '\0' || strchr(leaf, '/')))
|
2008-02-27 19:39:32 +03:00
|
|
|
return B_BAD_VALUE;
|
|
|
|
|
|
|
|
// get the vnode matching the dir's node_ref
|
|
|
|
if (leaf && (strcmp(leaf, ".") == 0 || strcmp(leaf, "..") == 0)) {
|
|
|
|
// special cases "." and "..": we can directly get the vnode of the
|
|
|
|
// referenced directory
|
2008-03-30 09:59:54 +04:00
|
|
|
status = entry_ref_to_vnode(device, inode, leaf, false, true, &vnode);
|
2008-02-27 19:39:32 +03:00
|
|
|
leaf = NULL;
|
|
|
|
} else
|
|
|
|
status = get_vnode(device, inode, &vnode, true, false);
|
|
|
|
if (status < B_OK)
|
|
|
|
return status;
|
|
|
|
|
|
|
|
// get the directory path
|
2008-03-30 09:59:54 +04:00
|
|
|
status = dir_vnode_to_path(vnode, path, pathLength, true);
|
2008-02-27 19:39:32 +03:00
|
|
|
put_vnode(vnode);
|
|
|
|
// we don't need the vnode anymore
|
|
|
|
if (status < B_OK)
|
|
|
|
return status;
|
|
|
|
|
|
|
|
// append the leaf name
|
|
|
|
if (leaf) {
|
|
|
|
// insert a directory separator if this is not the file system root
|
|
|
|
if ((strcmp(path, "/") && strlcat(path, "/", pathLength)
|
|
|
|
>= pathLength)
|
|
|
|
|| strlcat(path, leaf, pathLength) >= pathLength) {
|
|
|
|
return B_NAME_TOO_LONG;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return B_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-10-06 19:33:12 +04:00
|
|
|
/*! If the given descriptor locked its vnode, that lock will be released. */
|
2006-06-02 18:16:13 +04:00
|
|
|
void
|
|
|
|
vfs_unlock_vnode_if_locked(struct file_descriptor *descriptor)
|
|
|
|
{
|
|
|
|
struct vnode *vnode = fd_vnode(descriptor);
|
|
|
|
|
|
|
|
if (vnode != NULL && vnode->mandatory_locked_by == descriptor)
|
|
|
|
vnode->mandatory_locked_by = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-10-06 19:33:12 +04:00
|
|
|
/*! Closes all file descriptors of the specified I/O context that
|
2008-01-13 02:48:52 +03:00
|
|
|
have the O_CLOEXEC flag set.
|
2007-10-06 19:33:12 +04:00
|
|
|
*/
|
2004-10-07 18:47:58 +04:00
|
|
|
void
|
|
|
|
vfs_exec_io_context(void *_context)
|
|
|
|
{
|
|
|
|
struct io_context *context = (struct io_context *)_context;
|
|
|
|
uint32 i;
|
|
|
|
|
|
|
|
for (i = 0; i < context->table_size; i++) {
|
|
|
|
mutex_lock(&context->io_mutex);
|
|
|
|
|
|
|
|
struct file_descriptor *descriptor = context->fds[i];
|
|
|
|
bool remove = false;
|
|
|
|
|
2005-10-06 13:02:59 +04:00
|
|
|
if (descriptor != NULL && fd_close_on_exec(context, i)) {
|
2004-10-07 18:47:58 +04:00
|
|
|
context->fds[i] = NULL;
|
|
|
|
context->num_used_fds--;
|
|
|
|
|
|
|
|
remove = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
mutex_unlock(&context->io_mutex);
|
|
|
|
|
2005-03-31 21:22:33 +04:00
|
|
|
if (remove) {
|
|
|
|
close_fd(descriptor);
|
2004-10-07 18:47:58 +04:00
|
|
|
put_fd(descriptor);
|
2005-03-31 21:22:33 +04:00
|
|
|
}
|
2004-10-07 18:47:58 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-10-06 19:33:12 +04:00
|
|
|
/*! Sets up a new io_control structure, and inherits the properties
|
|
|
|
of the parent io_control if it is given.
|
|
|
|
*/
|
2002-07-20 04:16:12 +04:00
|
|
|
void *
|
|
|
|
vfs_new_io_context(void *_parentContext)
|
|
|
|
{
|
2004-10-07 18:47:58 +04:00
|
|
|
size_t tableSize;
|
2002-07-20 04:16:12 +04:00
|
|
|
struct io_context *context;
|
|
|
|
struct io_context *parentContext;
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2003-10-17 18:47:15 +04:00
|
|
|
context = (io_context *)malloc(sizeof(struct io_context));
|
2002-07-20 04:16:12 +04:00
|
|
|
if (context == NULL)
|
|
|
|
return NULL;
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2002-07-20 04:16:12 +04:00
|
|
|
memset(context, 0, sizeof(struct io_context));
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2002-07-20 04:16:12 +04:00
|
|
|
parentContext = (struct io_context *)_parentContext;
|
|
|
|
if (parentContext)
|
2004-10-07 18:47:58 +04:00
|
|
|
tableSize = parentContext->table_size;
|
2002-07-20 04:16:12 +04:00
|
|
|
else
|
2004-10-07 18:47:58 +04:00
|
|
|
tableSize = DEFAULT_FD_TABLE_SIZE;
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2005-10-06 13:02:59 +04:00
|
|
|
// allocate space for FDs and their close-on-exec flag
|
2007-10-01 05:37:28 +04:00
|
|
|
context->fds = (file_descriptor**)malloc(
|
|
|
|
sizeof(struct file_descriptor*) * tableSize
|
|
|
|
+ sizeof(struct select_sync*) * tableSize
|
2007-03-24 00:19:02 +03:00
|
|
|
+ (tableSize + 7) / 8);
|
2002-07-20 04:16:12 +04:00
|
|
|
if (context->fds == NULL) {
|
2002-10-30 02:07:06 +03:00
|
|
|
free(context);
|
2002-07-20 04:16:12 +04:00
|
|
|
return NULL;
|
2002-07-09 16:24:59 +04:00
|
|
|
}
|
|
|
|
|
2007-10-01 05:37:28 +04:00
|
|
|
context->select_infos = (select_info**)(context->fds + tableSize);
|
|
|
|
context->fds_close_on_exec = (uint8 *)(context->select_infos + tableSize);
|
|
|
|
|
|
|
|
memset(context->fds, 0, sizeof(struct file_descriptor*) * tableSize
|
|
|
|
+ sizeof(struct select_sync*) * tableSize
|
2007-03-24 00:19:02 +03:00
|
|
|
+ (tableSize + 7) / 8);
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2002-07-20 04:16:12 +04:00
|
|
|
if (mutex_init(&context->io_mutex, "I/O context") < 0) {
|
2002-10-30 02:07:06 +03:00
|
|
|
free(context->fds);
|
|
|
|
free(context);
|
2002-07-20 04:16:12 +04:00
|
|
|
return NULL;
|
2002-07-09 16:24:59 +04:00
|
|
|
}
|
|
|
|
|
2008-01-13 03:27:05 +03:00
|
|
|
// Copy all parent file descriptors
|
2002-10-07 19:31:40 +04:00
|
|
|
|
2002-07-20 04:16:12 +04:00
|
|
|
if (parentContext) {
|
|
|
|
size_t i;
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2002-07-20 04:16:12 +04:00
|
|
|
mutex_lock(&parentContext->io_mutex);
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2008-03-30 09:59:54 +04:00
|
|
|
benaphore_lock(&sIOContextRootLock);
|
|
|
|
context->root = parentContext->root;
|
|
|
|
if (context->root)
|
|
|
|
inc_vnode_ref_count(context->root);
|
|
|
|
benaphore_unlock(&sIOContextRootLock);
|
|
|
|
|
2002-07-20 04:16:12 +04:00
|
|
|
context->cwd = parentContext->cwd;
|
|
|
|
if (context->cwd)
|
|
|
|
inc_vnode_ref_count(context->cwd);
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2004-10-07 18:47:58 +04:00
|
|
|
for (i = 0; i < tableSize; i++) {
|
2005-03-18 04:24:11 +03:00
|
|
|
struct file_descriptor *descriptor = parentContext->fds[i];
|
|
|
|
|
2008-01-13 02:48:52 +03:00
|
|
|
if (descriptor != NULL) {
|
2005-03-18 04:24:11 +03:00
|
|
|
context->fds[i] = descriptor;
|
2005-10-06 12:53:17 +04:00
|
|
|
context->num_used_fds++;
|
2005-03-18 04:24:11 +03:00
|
|
|
atomic_add(&descriptor->ref_count, 1);
|
|
|
|
atomic_add(&descriptor->open_count, 1);
|
2008-03-09 21:00:17 +03:00
|
|
|
|
|
|
|
if (fd_close_on_exec(parentContext, i))
|
|
|
|
fd_set_close_on_exec(context, i, true);
|
2002-07-20 04:16:12 +04:00
|
|
|
}
|
|
|
|
}
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2002-07-20 04:16:12 +04:00
|
|
|
mutex_unlock(&parentContext->io_mutex);
|
|
|
|
} else {
|
2008-03-30 09:59:54 +04:00
|
|
|
context->root = sRoot;
|
2003-10-17 18:47:15 +04:00
|
|
|
context->cwd = sRoot;
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2008-03-30 09:59:54 +04:00
|
|
|
if (context->root)
|
|
|
|
inc_vnode_ref_count(context->root);
|
|
|
|
|
2002-07-20 04:16:12 +04:00
|
|
|
if (context->cwd)
|
|
|
|
inc_vnode_ref_count(context->cwd);
|
|
|
|
}
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2004-10-07 18:47:58 +04:00
|
|
|
context->table_size = tableSize;
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2003-01-18 17:13:44 +03:00
|
|
|
list_init(&context->node_monitors);
|
2007-02-19 18:48:02 +03:00
|
|
|
context->max_monitors = DEFAULT_NODE_MONITORS;
|
2003-01-18 17:13:44 +03:00
|
|
|
|
2002-07-20 04:16:12 +04:00
|
|
|
return context;
|
2002-07-09 16:24:59 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2005-03-18 04:24:11 +03:00
|
|
|
status_t
|
2002-07-20 04:16:12 +04:00
|
|
|
vfs_free_io_context(void *_ioContext)
|
2002-07-09 16:24:59 +04:00
|
|
|
{
|
2002-07-20 04:16:12 +04:00
|
|
|
struct io_context *context = (struct io_context *)_ioContext;
|
2003-09-04 08:01:25 +04:00
|
|
|
uint32 i;
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2008-03-30 09:59:54 +04:00
|
|
|
if (context->root)
|
|
|
|
dec_vnode_ref_count(context->root, false);
|
|
|
|
|
2002-07-20 04:16:12 +04:00
|
|
|
if (context->cwd)
|
|
|
|
dec_vnode_ref_count(context->cwd, false);
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2002-07-20 04:16:12 +04:00
|
|
|
mutex_lock(&context->io_mutex);
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2002-07-20 04:16:12 +04:00
|
|
|
for (i = 0; i < context->table_size; i++) {
|
2005-03-18 04:24:11 +03:00
|
|
|
if (struct file_descriptor *descriptor = context->fds[i]) {
|
|
|
|
close_fd(descriptor);
|
|
|
|
put_fd(descriptor);
|
|
|
|
}
|
2002-07-09 16:24:59 +04:00
|
|
|
}
|
|
|
|
|
2002-07-20 04:16:12 +04:00
|
|
|
mutex_destroy(&context->io_mutex);
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2003-01-18 17:13:44 +03:00
|
|
|
remove_node_monitors(context);
|
2002-10-30 02:07:06 +03:00
|
|
|
free(context->fds);
|
|
|
|
free(context);
|
2003-01-18 17:13:44 +03:00
|
|
|
|
2005-03-18 04:24:11 +03:00
|
|
|
return B_OK;
|
2002-07-09 16:24:59 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2005-03-18 04:24:11 +03:00
|
|
|
static status_t
|
2002-07-20 04:16:12 +04:00
|
|
|
vfs_resize_fd_table(struct io_context *context, const int newSize)
|
2002-07-09 16:24:59 +04:00
|
|
|
{
|
2007-03-24 00:19:02 +03:00
|
|
|
struct file_descriptor **fds;
|
2002-07-14 09:13:20 +04:00
|
|
|
|
2002-07-20 04:16:12 +04:00
|
|
|
if (newSize <= 0 || newSize > MAX_FD_TABLE_SIZE)
|
|
|
|
return EINVAL;
|
2002-07-14 09:13:20 +04:00
|
|
|
|
2007-10-01 05:37:28 +04:00
|
|
|
MutexLocker(context->io_mutex);
|
2002-07-14 09:13:20 +04:00
|
|
|
|
2007-03-24 00:19:02 +03:00
|
|
|
int oldSize = context->table_size;
|
|
|
|
int oldCloseOnExitBitmapSize = (oldSize + 7) / 8;
|
|
|
|
int newCloseOnExitBitmapSize = (newSize + 7) / 8;
|
|
|
|
|
2007-10-01 05:37:28 +04:00
|
|
|
// If the tables shrink, make sure none of the fds being dropped are in use.
|
2007-03-24 00:19:02 +03:00
|
|
|
if (newSize < oldSize) {
|
|
|
|
for (int i = oldSize; i-- > newSize;) {
|
2007-10-01 05:37:28 +04:00
|
|
|
if (context->fds[i])
|
|
|
|
return EBUSY;
|
2002-07-20 04:16:12 +04:00
|
|
|
}
|
2007-10-01 05:37:28 +04:00
|
|
|
}
|
2002-07-14 09:13:20 +04:00
|
|
|
|
2007-10-01 05:37:28 +04:00
|
|
|
// store pointers to the old tables
|
|
|
|
file_descriptor** oldFDs = context->fds;
|
|
|
|
select_info** oldSelectInfos = context->select_infos;
|
|
|
|
uint8* oldCloseOnExecTable = context->fds_close_on_exec;
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2007-10-01 05:37:28 +04:00
|
|
|
// allocate new tables
|
|
|
|
file_descriptor** newFDs = (file_descriptor**)malloc(
|
|
|
|
sizeof(struct file_descriptor*) * newSize
|
|
|
|
+ sizeof(struct select_sync*) * newSize
|
|
|
|
+ newCloseOnExitBitmapSize);
|
|
|
|
if (newFDs == NULL)
|
|
|
|
return ENOMEM;
|
2007-03-24 00:19:02 +03:00
|
|
|
|
2007-10-01 05:37:28 +04:00
|
|
|
context->fds = newFDs;
|
|
|
|
context->select_infos = (select_info**)(context->fds + newSize);
|
|
|
|
context->fds_close_on_exec = (uint8 *)(context->select_infos + newSize);
|
|
|
|
context->table_size = newSize;
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2007-10-01 05:37:28 +04:00
|
|
|
// copy entries from old tables
|
|
|
|
int toCopy = min_c(oldSize, newSize);
|
2002-07-14 09:13:20 +04:00
|
|
|
|
2007-10-01 05:37:28 +04:00
|
|
|
memcpy(context->fds, oldFDs, sizeof(void*) * toCopy);
|
|
|
|
memcpy(context->select_infos, oldSelectInfos, sizeof(void*) * toCopy);
|
|
|
|
memcpy(context->fds_close_on_exec, oldCloseOnExecTable,
|
|
|
|
min_c(oldCloseOnExitBitmapSize, newCloseOnExitBitmapSize));
|
2007-03-24 00:19:02 +03:00
|
|
|
|
2007-10-01 05:37:28 +04:00
|
|
|
// clear additional entries, if the tables grow
|
|
|
|
if (newSize > oldSize) {
|
|
|
|
memset(context->fds + oldSize, 0, sizeof(void *) * (newSize - oldSize));
|
|
|
|
memset(context->select_infos + oldSize, 0,
|
|
|
|
sizeof(void *) * (newSize - oldSize));
|
|
|
|
memset(context->fds_close_on_exec + oldCloseOnExitBitmapSize, 0,
|
2007-03-24 00:19:02 +03:00
|
|
|
newCloseOnExitBitmapSize - oldCloseOnExitBitmapSize);
|
2002-07-14 09:13:20 +04:00
|
|
|
}
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2007-10-01 05:37:28 +04:00
|
|
|
free(oldFDs);
|
2002-07-14 09:13:20 +04:00
|
|
|
|
2007-10-01 05:37:28 +04:00
|
|
|
return B_OK;
|
2002-07-14 09:13:20 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-02-19 18:48:02 +03:00
|
|
|
static status_t
|
|
|
|
vfs_resize_monitor_table(struct io_context *context, const int newSize)
|
|
|
|
{
|
|
|
|
void *fds;
|
|
|
|
int status = B_OK;
|
|
|
|
|
|
|
|
if (newSize <= 0 || newSize > MAX_NODE_MONITORS)
|
|
|
|
return EINVAL;
|
|
|
|
|
|
|
|
mutex_lock(&context->io_mutex);
|
|
|
|
|
|
|
|
if ((size_t)newSize < context->num_monitors) {
|
|
|
|
status = EBUSY;
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
context->max_monitors = newSize;
|
|
|
|
|
|
|
|
out:
|
|
|
|
mutex_unlock(&context->io_mutex);
|
|
|
|
return status;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2002-07-20 04:16:12 +04:00
|
|
|
int
|
|
|
|
vfs_getrlimit(int resource, struct rlimit * rlp)
|
2002-07-14 09:13:20 +04:00
|
|
|
{
|
2002-07-20 04:16:12 +04:00
|
|
|
if (!rlp)
|
2007-02-19 18:57:58 +03:00
|
|
|
return B_BAD_ADDRESS;
|
2002-07-14 09:13:20 +04:00
|
|
|
|
2002-07-20 04:16:12 +04:00
|
|
|
switch (resource) {
|
|
|
|
case RLIMIT_NOFILE:
|
|
|
|
{
|
|
|
|
struct io_context *ioctx = get_current_io_context(false);
|
2002-07-14 09:13:20 +04:00
|
|
|
|
2002-07-20 04:16:12 +04:00
|
|
|
mutex_lock(&ioctx->io_mutex);
|
2002-07-14 09:13:20 +04:00
|
|
|
|
2002-07-20 04:16:12 +04:00
|
|
|
rlp->rlim_cur = ioctx->table_size;
|
|
|
|
rlp->rlim_max = MAX_FD_TABLE_SIZE;
|
2002-07-14 09:13:20 +04:00
|
|
|
|
2002-07-20 04:16:12 +04:00
|
|
|
mutex_unlock(&ioctx->io_mutex);
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2002-07-20 04:16:12 +04:00
|
|
|
return 0;
|
|
|
|
}
|
2002-07-14 09:13:20 +04:00
|
|
|
|
2007-02-19 18:48:02 +03:00
|
|
|
case RLIMIT_NOVMON:
|
|
|
|
{
|
|
|
|
struct io_context *ioctx = get_current_io_context(false);
|
|
|
|
|
|
|
|
mutex_lock(&ioctx->io_mutex);
|
|
|
|
|
|
|
|
rlp->rlim_cur = ioctx->max_monitors;
|
|
|
|
rlp->rlim_max = MAX_NODE_MONITORS;
|
|
|
|
|
|
|
|
mutex_unlock(&ioctx->io_mutex);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2002-07-20 04:16:12 +04:00
|
|
|
default:
|
2007-02-19 18:57:58 +03:00
|
|
|
return EINVAL;
|
2002-07-20 04:16:12 +04:00
|
|
|
}
|
2002-07-09 16:24:59 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2002-07-20 04:16:12 +04:00
|
|
|
int
|
|
|
|
vfs_setrlimit(int resource, const struct rlimit * rlp)
|
2002-07-09 16:24:59 +04:00
|
|
|
{
|
2002-07-20 04:16:12 +04:00
|
|
|
if (!rlp)
|
2007-02-19 18:57:58 +03:00
|
|
|
return B_BAD_ADDRESS;
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2002-07-20 04:16:12 +04:00
|
|
|
switch (resource) {
|
|
|
|
case RLIMIT_NOFILE:
|
2007-02-19 18:57:58 +03:00
|
|
|
/* TODO: check getuid() */
|
2008-03-04 19:59:59 +03:00
|
|
|
if (rlp->rlim_max != RLIM_SAVED_MAX
|
|
|
|
&& rlp->rlim_max != MAX_FD_TABLE_SIZE)
|
2007-02-19 18:57:58 +03:00
|
|
|
return EPERM;
|
2002-07-20 04:16:12 +04:00
|
|
|
return vfs_resize_fd_table(get_current_io_context(false), rlp->rlim_cur);
|
2002-07-17 11:55:51 +04:00
|
|
|
|
2007-02-19 18:48:02 +03:00
|
|
|
case RLIMIT_NOVMON:
|
2007-02-19 18:57:58 +03:00
|
|
|
/* TODO: check getuid() */
|
2008-03-04 19:59:59 +03:00
|
|
|
if (rlp->rlim_max != RLIM_SAVED_MAX
|
|
|
|
&& rlp->rlim_max != MAX_NODE_MONITORS)
|
2007-02-19 18:57:58 +03:00
|
|
|
return EPERM;
|
2007-02-19 18:48:02 +03:00
|
|
|
return vfs_resize_monitor_table(get_current_io_context(false), rlp->rlim_cur);
|
|
|
|
|
2002-07-20 04:16:12 +04:00
|
|
|
default:
|
2007-02-19 18:57:58 +03:00
|
|
|
return EINVAL;
|
2002-07-20 04:16:12 +04:00
|
|
|
}
|
2002-07-17 11:55:51 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-05-06 05:25:36 +04:00
|
|
|
status_t
|
2004-10-20 04:19:38 +04:00
|
|
|
vfs_init(kernel_args *args)
|
2002-07-09 16:24:59 +04:00
|
|
|
{
|
2004-11-30 00:27:17 +03:00
|
|
|
sVnodeTable = hash_init(VNODE_HASH_TABLE_SIZE, offsetof(struct vnode, next),
|
|
|
|
&vnode_compare, &vnode_hash);
|
|
|
|
if (sVnodeTable == NULL)
|
|
|
|
panic("vfs_init: error creating vnode hash table\n");
|
|
|
|
|
|
|
|
list_init_etc(&sUnusedVnodeList, offsetof(struct vnode, unused_link));
|
|
|
|
|
|
|
|
sMountsTable = hash_init(MOUNTS_HASH_TABLE_SIZE, offsetof(struct fs_mount, next),
|
|
|
|
&mount_compare, &mount_hash);
|
|
|
|
if (sMountsTable == NULL)
|
|
|
|
panic("vfs_init: error creating mounts hash table\n");
|
2003-01-18 17:13:44 +03:00
|
|
|
|
|
|
|
node_monitor_init();
|
|
|
|
|
2003-10-17 18:47:15 +04:00
|
|
|
sRoot = NULL;
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2003-10-17 18:47:15 +04:00
|
|
|
if (mutex_init(&sFileSystemsMutex, "vfs_lock") < 0)
|
2002-09-25 18:10:50 +04:00
|
|
|
panic("vfs_init: error allocating file systems lock\n");
|
2002-07-20 04:16:12 +04:00
|
|
|
|
2004-09-17 16:29:27 +04:00
|
|
|
if (recursive_lock_init(&sMountOpLock, "vfs_mount_op_lock") < 0)
|
2002-09-25 18:10:50 +04:00
|
|
|
panic("vfs_init: error allocating mount op lock\n");
|
2002-07-20 04:16:12 +04:00
|
|
|
|
2003-10-17 18:47:15 +04:00
|
|
|
if (mutex_init(&sMountMutex, "vfs_mount_lock") < 0)
|
2002-09-25 18:10:50 +04:00
|
|
|
panic("vfs_init: error allocating mount lock\n");
|
2002-07-20 04:16:12 +04:00
|
|
|
|
2007-03-03 05:42:36 +03:00
|
|
|
if (mutex_init(&sVnodeCoveredByMutex, "vfs_vnode_covered_by_lock") < 0)
|
|
|
|
panic("vfs_init: error allocating vnode::covered_by lock\n");
|
|
|
|
|
2003-10-17 18:47:15 +04:00
|
|
|
if (mutex_init(&sVnodeMutex, "vfs_vnode_lock") < 0)
|
2002-09-25 18:10:50 +04:00
|
|
|
panic("vfs_init: error allocating vnode lock\n");
|
2002-07-20 04:16:12 +04:00
|
|
|
|
2008-03-30 09:59:54 +04:00
|
|
|
if (benaphore_init(&sIOContextRootLock, "io_context::root lock") < 0)
|
|
|
|
panic("vfs_init: error allocating io_context::root lock\n");
|
|
|
|
|
2005-05-13 22:18:28 +04:00
|
|
|
if (block_cache_init() != B_OK)
|
|
|
|
return B_ERROR;
|
|
|
|
|
2005-08-18 19:07:38 +04:00
|
|
|
#ifdef ADD_DEBUGGER_COMMANDS
|
|
|
|
// add some debugger commands
|
|
|
|
add_debugger_command("vnode", &dump_vnode, "info about the specified vnode");
|
|
|
|
add_debugger_command("vnodes", &dump_vnodes, "list all vnodes (from the specified device)");
|
|
|
|
add_debugger_command("vnode_caches", &dump_vnode_caches, "list all vnode caches");
|
|
|
|
add_debugger_command("mount", &dump_mount, "info about the specified fs_mount");
|
|
|
|
add_debugger_command("mounts", &dump_mounts, "list all fs_mounts");
|
2005-10-06 12:47:03 +04:00
|
|
|
add_debugger_command("io_context", &dump_io_context, "info about the I/O context");
|
2006-03-06 16:39:04 +03:00
|
|
|
add_debugger_command("vnode_usage", &dump_vnode_usage, "info about vnode usage");
|
2005-08-18 19:07:38 +04:00
|
|
|
#endif
|
|
|
|
|
2005-12-16 19:11:36 +03:00
|
|
|
register_low_memory_handler(&vnode_low_memory_handler, NULL, 0);
|
|
|
|
|
2004-12-01 10:41:07 +03:00
|
|
|
return file_cache_init();
|
2002-07-09 16:24:59 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-05-28 18:17:18 +04:00
|
|
|
// #pragma mark - fd_ops implementations
|
2002-07-20 04:16:12 +04:00
|
|
|
|
|
|
|
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
/*!
|
|
|
|
Calls fs_open() on the given vnode and returns a new
|
|
|
|
file descriptor for it
|
|
|
|
*/
|
|
|
|
static int
|
|
|
|
open_vnode(struct vnode *vnode, int openMode, bool kernel)
|
|
|
|
{
|
|
|
|
void *cookie;
|
|
|
|
int status;
|
|
|
|
|
|
|
|
status = FS_CALL(vnode, open, openMode, &cookie);
|
|
|
|
if (status < 0)
|
|
|
|
return status;
|
|
|
|
|
|
|
|
status = get_new_fd(FDTYPE_FILE, NULL, vnode, cookie, openMode, kernel);
|
|
|
|
if (status < 0) {
|
|
|
|
FS_CALL(vnode, close, cookie);
|
|
|
|
FS_CALL(vnode, free_cookie, cookie);
|
|
|
|
}
|
|
|
|
return status;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-05-28 18:17:18 +04:00
|
|
|
/*!
|
|
|
|
Calls fs_open() on the given vnode and returns a new
|
|
|
|
file descriptor for it
|
|
|
|
*/
|
2002-07-20 04:16:12 +04:00
|
|
|
static int
|
2007-05-28 18:17:18 +04:00
|
|
|
create_vnode(struct vnode *directory, const char *name, int openMode,
|
|
|
|
int perms, bool kernel)
|
2002-07-20 04:16:12 +04:00
|
|
|
{
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
void *cookie;
|
2007-06-21 23:50:57 +04:00
|
|
|
ino_t newID;
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
int status = B_ERROR;
|
|
|
|
struct vnode *vnode;
|
2002-07-20 04:16:12 +04:00
|
|
|
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
// This is somewhat tricky: If the entry already exists, the FS responsible
|
|
|
|
// for the directory might not necessarily the one also responsible for the
|
|
|
|
// node the entry refers to. So we can actually never call the create() hook
|
|
|
|
// without O_EXCL. Instead we try to look the entry up first. If it already
|
|
|
|
// exists, we just open the node (unless O_EXCL), otherwise we call create()
|
|
|
|
// with O_EXCL. This introduces a race condition, since we someone else
|
|
|
|
// might have created the entry in the meantime. We hope the respective
|
|
|
|
// FS returns the correct error code and retry (up to 3 times) again.
|
|
|
|
|
|
|
|
for (int i = 0; i < 3 && status != B_OK; i++) {
|
|
|
|
// look the node up
|
|
|
|
status = lookup_dir_entry(directory, name, &vnode);
|
|
|
|
if (status == B_OK) {
|
|
|
|
VNodePutter putter(vnode);
|
|
|
|
|
|
|
|
if ((openMode & O_EXCL) != 0)
|
|
|
|
return B_FILE_EXISTS;
|
|
|
|
|
|
|
|
status = open_vnode(vnode, openMode & ~O_CREAT, kernel);
|
|
|
|
// on success keep the vnode reference for the FD
|
|
|
|
if (status >= 0)
|
|
|
|
putter.Detach();
|
2002-07-20 04:16:12 +04:00
|
|
|
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
return status;
|
|
|
|
}
|
|
|
|
|
|
|
|
// it doesn't exist yet -- try to create it
|
|
|
|
|
|
|
|
if (!HAS_FS_CALL(directory, create))
|
|
|
|
return EROFS;
|
|
|
|
|
|
|
|
status = FS_CALL(directory, create, name, openMode | O_EXCL, perms,
|
|
|
|
&cookie, &newID);
|
|
|
|
if (status != B_OK
|
|
|
|
&& ((openMode & O_EXCL) != 0 || status != B_FILE_EXISTS)) {
|
|
|
|
return status;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (status != B_OK)
|
2002-07-20 04:16:12 +04:00
|
|
|
return status;
|
|
|
|
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
// the node has been created successfully
|
|
|
|
|
2003-10-17 18:47:15 +04:00
|
|
|
mutex_lock(&sVnodeMutex);
|
|
|
|
vnode = lookup_vnode(directory->device, newID);
|
|
|
|
mutex_unlock(&sVnodeMutex);
|
2002-07-20 04:16:12 +04:00
|
|
|
|
|
|
|
if (vnode == NULL) {
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
panic("vfs: fs_create() returned success but there is no vnode, "
|
|
|
|
"mount ID %ld!\n", directory->device);
|
2007-05-28 18:17:18 +04:00
|
|
|
return B_BAD_VALUE;
|
2002-07-20 04:16:12 +04:00
|
|
|
}
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2004-12-14 01:17:00 +03:00
|
|
|
if ((status = get_new_fd(FDTYPE_FILE, NULL, vnode, cookie, openMode, kernel)) >= 0)
|
2002-07-20 04:16:12 +04:00
|
|
|
return status;
|
2002-09-25 06:18:20 +04:00
|
|
|
|
2003-09-04 08:01:25 +04:00
|
|
|
// something went wrong, clean up
|
|
|
|
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
FS_CALL(vnode, close, cookie);
|
|
|
|
FS_CALL(vnode, free_cookie, cookie);
|
2002-07-20 04:16:12 +04:00
|
|
|
put_vnode(vnode);
|
2002-07-09 16:24:59 +04:00
|
|
|
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
FS_CALL(directory, unlink, name);
|
2008-03-04 19:59:59 +03:00
|
|
|
|
2002-07-20 04:16:12 +04:00
|
|
|
return status;
|
2002-07-14 09:13:20 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-10-06 19:33:12 +04:00
|
|
|
/*! Calls fs open_dir() on the given vnode and returns a new
|
|
|
|
file descriptor for it
|
|
|
|
*/
|
2002-07-14 09:13:20 +04:00
|
|
|
static int
|
2002-07-20 04:16:12 +04:00
|
|
|
open_dir_vnode(struct vnode *vnode, bool kernel)
|
2002-07-14 09:13:20 +04:00
|
|
|
{
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
void *cookie;
|
2002-09-26 07:50:14 +04:00
|
|
|
int status;
|
|
|
|
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
status = FS_CALL(vnode, open_dir, &cookie);
|
2003-08-18 07:21:26 +04:00
|
|
|
if (status < B_OK)
|
2002-07-14 09:13:20 +04:00
|
|
|
return status;
|
|
|
|
|
|
|
|
// file is opened, create a fd
|
2004-12-14 01:17:00 +03:00
|
|
|
status = get_new_fd(FDTYPE_DIR, NULL, vnode, cookie, 0, kernel);
|
2002-09-26 07:50:14 +04:00
|
|
|
if (status >= 0)
|
|
|
|
return status;
|
2002-07-14 09:13:20 +04:00
|
|
|
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
FS_CALL(vnode, close_dir, cookie);
|
|
|
|
FS_CALL(vnode, free_dir_cookie, cookie);
|
2002-07-20 04:16:12 +04:00
|
|
|
|
2002-07-14 09:13:20 +04:00
|
|
|
return status;
|
2002-07-09 16:24:59 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-10-06 19:33:12 +04:00
|
|
|
/*! Calls fs open_attr_dir() on the given vnode and returns a new
|
|
|
|
file descriptor for it.
|
|
|
|
Used by attr_dir_open(), and attr_dir_open_fd().
|
|
|
|
*/
|
2002-09-26 07:50:14 +04:00
|
|
|
static int
|
|
|
|
open_attr_dir_vnode(struct vnode *vnode, bool kernel)
|
|
|
|
{
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
void *cookie;
|
2002-09-26 07:50:14 +04:00
|
|
|
int status;
|
|
|
|
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
if (!HAS_FS_CALL(vnode, open_attr_dir))
|
2004-11-23 06:20:20 +03:00
|
|
|
return EOPNOTSUPP;
|
|
|
|
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
status = FS_CALL(vnode, open_attr_dir, &cookie);
|
2002-09-26 07:50:14 +04:00
|
|
|
if (status < 0)
|
|
|
|
return status;
|
|
|
|
|
|
|
|
// file is opened, create a fd
|
2004-12-14 01:17:00 +03:00
|
|
|
status = get_new_fd(FDTYPE_ATTR_DIR, NULL, vnode, cookie, 0, kernel);
|
2002-09-26 07:50:14 +04:00
|
|
|
if (status >= 0)
|
|
|
|
return status;
|
|
|
|
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
FS_CALL(vnode, close_attr_dir, cookie);
|
|
|
|
FS_CALL(vnode, free_attr_dir_cookie, cookie);
|
2002-09-26 07:50:14 +04:00
|
|
|
|
|
|
|
return status;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2002-07-20 04:16:12 +04:00
|
|
|
static int
|
2007-06-21 23:50:57 +04:00
|
|
|
file_create_entry_ref(dev_t mountID, ino_t directoryID, const char *name,
|
|
|
|
int openMode, int perms, bool kernel)
|
2002-07-09 16:24:59 +04:00
|
|
|
{
|
2003-09-04 08:01:25 +04:00
|
|
|
struct vnode *directory;
|
2002-07-20 04:16:12 +04:00
|
|
|
int status;
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2002-09-25 18:10:50 +04:00
|
|
|
FUNCTION(("file_create_entry_ref: name = '%s', omode %x, perms %d, kernel %d\n", name, openMode, perms, kernel));
|
2002-07-20 04:16:12 +04:00
|
|
|
|
2008-03-04 19:59:59 +03:00
|
|
|
// get directory to put the new file in
|
2007-10-08 20:06:32 +04:00
|
|
|
status = get_vnode(mountID, directoryID, &directory, true, false);
|
2002-07-20 04:16:12 +04:00
|
|
|
if (status < B_OK)
|
|
|
|
return status;
|
|
|
|
|
2002-09-25 18:10:50 +04:00
|
|
|
status = create_vnode(directory, name, openMode, perms, kernel);
|
2002-07-20 04:16:12 +04:00
|
|
|
put_vnode(directory);
|
|
|
|
|
|
|
|
return status;
|
2002-07-09 16:24:59 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2002-07-20 04:16:12 +04:00
|
|
|
static int
|
2005-07-12 20:33:10 +04:00
|
|
|
file_create(int fd, char *path, int openMode, int perms, bool kernel)
|
2002-07-09 16:24:59 +04:00
|
|
|
{
|
2002-09-25 16:13:09 +04:00
|
|
|
char name[B_FILE_NAME_LENGTH];
|
2003-09-04 08:01:25 +04:00
|
|
|
struct vnode *directory;
|
2002-07-20 04:16:12 +04:00
|
|
|
int status;
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2002-09-25 06:18:20 +04:00
|
|
|
FUNCTION(("file_create: path '%s', omode %x, perms %d, kernel %d\n", path, openMode, perms, kernel));
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2008-03-04 19:59:59 +03:00
|
|
|
// get directory to put the new file in
|
2005-07-12 20:33:10 +04:00
|
|
|
status = fd_and_path_to_dir_vnode(fd, path, &directory, name, kernel);
|
2002-07-20 04:16:12 +04:00
|
|
|
if (status < 0)
|
|
|
|
return status;
|
|
|
|
|
2002-09-25 16:13:09 +04:00
|
|
|
status = create_vnode(directory, name, openMode, perms, kernel);
|
2002-07-20 04:16:12 +04:00
|
|
|
|
2002-09-25 16:13:09 +04:00
|
|
|
put_vnode(directory);
|
2002-07-20 04:16:12 +04:00
|
|
|
return status;
|
2002-07-09 16:24:59 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static int
|
2008-03-18 19:10:04 +03:00
|
|
|
file_open_entry_ref(dev_t mountID, ino_t directoryID, const char *name,
|
|
|
|
int openMode, bool kernel)
|
2002-07-09 16:24:59 +04:00
|
|
|
{
|
2008-03-18 19:10:04 +03:00
|
|
|
bool traverse = ((openMode & O_NOTRAVERSE) == 0);
|
2002-07-20 04:16:12 +04:00
|
|
|
struct vnode *vnode;
|
|
|
|
int status;
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2002-09-25 16:13:09 +04:00
|
|
|
if (name == NULL || *name == '\0')
|
|
|
|
return B_BAD_VALUE;
|
|
|
|
|
2005-08-26 06:01:21 +04:00
|
|
|
FUNCTION(("file_open_entry_ref(ref = (%ld, %Ld, %s), openMode = %d)\n",
|
|
|
|
mountID, directoryID, name, openMode));
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2002-07-20 04:16:12 +04:00
|
|
|
// get the vnode matching the entry_ref
|
2008-03-30 09:59:54 +04:00
|
|
|
status = entry_ref_to_vnode(mountID, directoryID, name, traverse, kernel,
|
|
|
|
&vnode);
|
2002-07-20 04:16:12 +04:00
|
|
|
if (status < B_OK)
|
|
|
|
return status;
|
|
|
|
|
2002-09-25 18:10:50 +04:00
|
|
|
status = open_vnode(vnode, openMode, kernel);
|
2002-07-20 04:16:12 +04:00
|
|
|
if (status < B_OK)
|
|
|
|
put_vnode(vnode);
|
|
|
|
|
2008-03-18 19:10:04 +03:00
|
|
|
cache_node_opened(vnode, FDTYPE_FILE, vnode->cache, mountID, directoryID,
|
|
|
|
vnode->id, name);
|
2002-07-20 04:16:12 +04:00
|
|
|
return status;
|
2002-07-09 16:24:59 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static int
|
2005-01-18 18:59:18 +03:00
|
|
|
file_open(int fd, char *path, int openMode, bool kernel)
|
2002-07-09 16:24:59 +04:00
|
|
|
{
|
2004-08-29 00:38:39 +04:00
|
|
|
int status = B_OK;
|
2005-01-18 18:59:18 +03:00
|
|
|
bool traverse = ((openMode & O_NOTRAVERSE) == 0);
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2005-01-18 18:59:18 +03:00
|
|
|
FUNCTION(("file_open: fd: %d, entry path = '%s', omode %d, kernel %d\n",
|
|
|
|
fd, path, openMode, kernel));
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2004-08-29 00:38:39 +04:00
|
|
|
// get the vnode matching the vnode + path combination
|
|
|
|
struct vnode *vnode = NULL;
|
2007-06-21 23:50:57 +04:00
|
|
|
ino_t parentID;
|
2005-08-01 16:44:59 +04:00
|
|
|
status = fd_and_path_to_vnode(fd, path, traverse, &vnode, &parentID, kernel);
|
2004-08-29 00:38:39 +04:00
|
|
|
if (status != B_OK)
|
2002-07-20 04:16:12 +04:00
|
|
|
return status;
|
2002-07-19 08:20:07 +04:00
|
|
|
|
2004-08-29 00:38:39 +04:00
|
|
|
// open the vnode
|
2005-01-18 18:59:18 +03:00
|
|
|
status = open_vnode(vnode, openMode, kernel);
|
2004-08-29 00:38:39 +04:00
|
|
|
// put only on error -- otherwise our reference was transferred to the FD
|
2002-07-20 04:16:12 +04:00
|
|
|
if (status < B_OK)
|
|
|
|
put_vnode(vnode);
|
2005-01-18 18:59:18 +03:00
|
|
|
|
2005-08-01 16:44:59 +04:00
|
|
|
cache_node_opened(vnode, FDTYPE_FILE, vnode->cache,
|
|
|
|
vnode->device, parentID, vnode->id, NULL);
|
|
|
|
|
2002-07-20 04:16:12 +04:00
|
|
|
return status;
|
2002-07-09 16:24:59 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2002-10-08 07:24:51 +04:00
|
|
|
static status_t
|
2002-07-20 04:16:12 +04:00
|
|
|
file_close(struct file_descriptor *descriptor)
|
2002-07-09 16:24:59 +04:00
|
|
|
{
|
2002-09-26 07:50:14 +04:00
|
|
|
struct vnode *vnode = descriptor->u.vnode;
|
2005-03-17 16:18:29 +03:00
|
|
|
status_t status = B_OK;
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2002-09-25 06:18:20 +04:00
|
|
|
FUNCTION(("file_close(descriptor = %p)\n", descriptor));
|
|
|
|
|
2005-02-02 09:21:31 +03:00
|
|
|
cache_node_closed(vnode, FDTYPE_FILE, vnode->cache, vnode->device, vnode->id);
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
if (HAS_FS_CALL(vnode, close)) {
|
|
|
|
status = FS_CALL(vnode, close, descriptor->cookie);
|
|
|
|
}
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2005-03-17 16:18:29 +03:00
|
|
|
if (status == B_OK) {
|
|
|
|
// remove all outstanding locks for this team
|
|
|
|
release_advisory_lock(vnode, NULL);
|
|
|
|
}
|
|
|
|
return status;
|
2002-07-20 04:16:12 +04:00
|
|
|
}
|
2002-07-09 16:24:59 +04:00
|
|
|
|
|
|
|
|
2002-09-25 06:18:20 +04:00
|
|
|
static void
|
|
|
|
file_free_fd(struct file_descriptor *descriptor)
|
|
|
|
{
|
2002-09-26 07:50:14 +04:00
|
|
|
struct vnode *vnode = descriptor->u.vnode;
|
2002-09-25 06:18:20 +04:00
|
|
|
|
|
|
|
if (vnode != NULL) {
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
FS_CALL(vnode, free_cookie, descriptor->cookie);
|
2002-09-25 06:18:20 +04:00
|
|
|
put_vnode(vnode);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-06-16 14:32:26 +04:00
|
|
|
static status_t
|
2002-08-09 21:03:03 +04:00
|
|
|
file_read(struct file_descriptor *descriptor, off_t pos, void *buffer, size_t *length)
|
2002-07-20 04:16:12 +04:00
|
|
|
{
|
2002-09-26 07:50:14 +04:00
|
|
|
struct vnode *vnode = descriptor->u.vnode;
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2002-08-05 09:37:17 +04:00
|
|
|
FUNCTION(("file_read: buf %p, pos %Ld, len %p = %ld\n", buffer, pos, length, *length));
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
return FS_CALL(vnode, read, descriptor->cookie, pos, buffer, length);
|
2002-07-09 16:24:59 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-06-16 14:32:26 +04:00
|
|
|
static status_t
|
2002-08-09 21:03:03 +04:00
|
|
|
file_write(struct file_descriptor *descriptor, off_t pos, const void *buffer, size_t *length)
|
2002-07-09 16:24:59 +04:00
|
|
|
{
|
2002-09-26 07:50:14 +04:00
|
|
|
struct vnode *vnode = descriptor->u.vnode;
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2002-08-05 09:37:17 +04:00
|
|
|
FUNCTION(("file_write: buf %p, pos %Ld, len %p\n", buffer, pos, length));
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
return FS_CALL(vnode, write, descriptor->cookie, pos, buffer, length);
|
2002-07-20 04:16:12 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static off_t
|
|
|
|
file_seek(struct file_descriptor *descriptor, off_t pos, int seekType)
|
|
|
|
{
|
2002-10-08 04:42:17 +04:00
|
|
|
off_t offset;
|
|
|
|
|
2004-11-01 22:48:40 +03:00
|
|
|
FUNCTION(("file_seek(pos = %Ld, seekType = %d)\n", pos, seekType));
|
2007-10-08 02:51:41 +04:00
|
|
|
|
|
|
|
// stat() the node
|
|
|
|
struct vnode *vnode = descriptor->u.vnode;
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
if (!HAS_FS_CALL(vnode, read_stat))
|
2007-10-08 02:51:41 +04:00
|
|
|
return EOPNOTSUPP;
|
|
|
|
|
|
|
|
struct stat stat;
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
status_t status = FS_CALL(vnode, read_stat, &stat);
|
2007-10-08 02:51:41 +04:00
|
|
|
if (status < B_OK)
|
|
|
|
return status;
|
|
|
|
|
|
|
|
// some kinds of files are not seekable
|
|
|
|
switch (stat.st_mode & S_IFMT) {
|
|
|
|
case S_IFIFO:
|
2008-04-11 07:35:15 +04:00
|
|
|
case S_IFSOCK:
|
2007-10-08 02:51:41 +04:00
|
|
|
return ESPIPE;
|
2008-04-11 07:35:15 +04:00
|
|
|
|
2007-10-08 02:51:41 +04:00
|
|
|
// The Open Group Base Specs don't mention any file types besides pipes,
|
|
|
|
// fifos, and sockets specially, so we allow seeking them.
|
|
|
|
case S_IFREG:
|
|
|
|
case S_IFBLK:
|
|
|
|
case S_IFDIR:
|
|
|
|
case S_IFLNK:
|
|
|
|
case S_IFCHR:
|
|
|
|
break;
|
|
|
|
}
|
2004-11-01 22:48:40 +03:00
|
|
|
|
2002-10-08 04:42:17 +04:00
|
|
|
switch (seekType) {
|
|
|
|
case SEEK_SET:
|
|
|
|
offset = 0;
|
|
|
|
break;
|
|
|
|
case SEEK_CUR:
|
|
|
|
offset = descriptor->pos;
|
|
|
|
break;
|
|
|
|
case SEEK_END:
|
|
|
|
offset = stat.st_size;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
return B_BAD_VALUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
// assumes off_t is 64 bits wide
|
|
|
|
if (offset > 0 && LONGLONG_MAX - offset < pos)
|
|
|
|
return EOVERFLOW;
|
|
|
|
|
|
|
|
pos += offset;
|
|
|
|
if (pos < 0)
|
|
|
|
return B_BAD_VALUE;
|
2002-07-20 04:16:12 +04:00
|
|
|
|
2002-10-08 04:42:17 +04:00
|
|
|
return descriptor->pos = pos;
|
2002-07-09 16:24:59 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2005-03-18 00:04:25 +03:00
|
|
|
static status_t
|
2007-10-02 23:47:31 +04:00
|
|
|
file_select(struct file_descriptor *descriptor, uint8 event,
|
2007-10-01 05:37:28 +04:00
|
|
|
struct selectsync *sync)
|
2005-03-18 00:04:25 +03:00
|
|
|
{
|
2008-01-11 03:36:44 +03:00
|
|
|
FUNCTION(("file_select(%p, %u, %p)\n", descriptor, event, sync));
|
2005-03-18 00:04:25 +03:00
|
|
|
|
|
|
|
struct vnode *vnode = descriptor->u.vnode;
|
|
|
|
|
|
|
|
// If the FS has no select() hook, notify select() now.
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
if (!HAS_FS_CALL(vnode, select))
|
2007-10-02 23:47:31 +04:00
|
|
|
return notify_select_event(sync, event);
|
2005-03-18 00:04:25 +03:00
|
|
|
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
return FS_CALL(vnode, select, descriptor->cookie, event, 0, sync);
|
2005-03-18 00:04:25 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static status_t
|
|
|
|
file_deselect(struct file_descriptor *descriptor, uint8 event,
|
2007-10-01 05:37:28 +04:00
|
|
|
struct selectsync *sync)
|
2005-03-18 00:04:25 +03:00
|
|
|
{
|
|
|
|
struct vnode *vnode = descriptor->u.vnode;
|
|
|
|
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
if (!HAS_FS_CALL(vnode, deselect))
|
2005-03-18 00:04:25 +03:00
|
|
|
return B_OK;
|
|
|
|
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
return FS_CALL(vnode, deselect, descriptor->cookie, event, sync);
|
2005-03-18 00:04:25 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-06-15 19:35:10 +04:00
|
|
|
static status_t
|
2007-06-21 23:50:57 +04:00
|
|
|
dir_create_entry_ref(dev_t mountID, ino_t parentID, const char *name, int perms, bool kernel)
|
2002-07-23 18:10:12 +04:00
|
|
|
{
|
|
|
|
struct vnode *vnode;
|
2007-06-21 23:50:57 +04:00
|
|
|
ino_t newID;
|
2004-06-15 19:35:10 +04:00
|
|
|
status_t status;
|
2002-07-23 18:10:12 +04:00
|
|
|
|
2002-09-25 16:13:09 +04:00
|
|
|
if (name == NULL || *name == '\0')
|
|
|
|
return B_BAD_VALUE;
|
|
|
|
|
2002-09-25 18:10:50 +04:00
|
|
|
FUNCTION(("dir_create_entry_ref(dev = %ld, ino = %Ld, name = '%s', perms = %d)\n", mountID, parentID, name, perms));
|
2008-03-04 19:59:59 +03:00
|
|
|
|
2007-10-08 20:06:32 +04:00
|
|
|
status = get_vnode(mountID, parentID, &vnode, true, false);
|
2002-07-23 18:10:12 +04:00
|
|
|
if (status < B_OK)
|
|
|
|
return status;
|
|
|
|
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
if (HAS_FS_CALL(vnode, create_dir))
|
|
|
|
status = FS_CALL(vnode, create_dir, name, perms, &newID);
|
2002-07-23 18:10:12 +04:00
|
|
|
else
|
|
|
|
status = EROFS;
|
|
|
|
|
|
|
|
put_vnode(vnode);
|
|
|
|
return status;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-06-15 19:35:10 +04:00
|
|
|
static status_t
|
2004-08-29 00:38:39 +04:00
|
|
|
dir_create(int fd, char *path, int perms, bool kernel)
|
2002-07-09 16:24:59 +04:00
|
|
|
{
|
2004-12-14 01:17:00 +03:00
|
|
|
char filename[B_FILE_NAME_LENGTH];
|
2002-07-14 09:13:20 +04:00
|
|
|
struct vnode *vnode;
|
2007-06-21 23:50:57 +04:00
|
|
|
ino_t newID;
|
2004-06-15 19:35:10 +04:00
|
|
|
status_t status;
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2002-07-20 04:16:12 +04:00
|
|
|
FUNCTION(("dir_create: path '%s', perms %d, kernel %d\n", path, perms, kernel));
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2004-08-29 00:38:39 +04:00
|
|
|
status = fd_and_path_to_dir_vnode(fd, path, &vnode, filename, kernel);
|
2002-07-14 09:13:20 +04:00
|
|
|
if (status < 0)
|
|
|
|
return status;
|
2002-07-09 16:24:59 +04:00
|
|
|
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
if (HAS_FS_CALL(vnode, create_dir)) {
|
|
|
|
status = FS_CALL(vnode, create_dir, filename, perms, &newID);
|
|
|
|
} else
|
2002-07-14 09:13:20 +04:00
|
|
|
status = EROFS;
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2002-07-20 04:16:12 +04:00
|
|
|
put_vnode(vnode);
|
2002-07-14 09:13:20 +04:00
|
|
|
return status;
|
2002-07-09 16:24:59 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2002-07-20 04:16:12 +04:00
|
|
|
static int
|
2007-06-21 23:50:57 +04:00
|
|
|
dir_open_entry_ref(dev_t mountID, ino_t parentID, const char *name, bool kernel)
|
2002-07-09 16:24:59 +04:00
|
|
|
{
|
2002-07-20 04:16:12 +04:00
|
|
|
struct vnode *vnode;
|
|
|
|
int status;
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2002-07-20 04:16:12 +04:00
|
|
|
FUNCTION(("dir_open_entry_ref()\n"));
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2004-08-29 00:38:39 +04:00
|
|
|
if (name && *name == '\0')
|
2002-09-25 16:13:09 +04:00
|
|
|
return B_BAD_VALUE;
|
|
|
|
|
2004-08-29 00:38:39 +04:00
|
|
|
// get the vnode matching the entry_ref/node_ref
|
2008-03-30 09:59:54 +04:00
|
|
|
if (name) {
|
|
|
|
status = entry_ref_to_vnode(mountID, parentID, name, true, kernel,
|
|
|
|
&vnode);
|
|
|
|
} else
|
2007-10-08 20:06:32 +04:00
|
|
|
status = get_vnode(mountID, parentID, &vnode, true, false);
|
2002-07-20 04:16:12 +04:00
|
|
|
if (status < B_OK)
|
|
|
|
return status;
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2002-07-20 04:16:12 +04:00
|
|
|
status = open_dir_vnode(vnode, kernel);
|
|
|
|
if (status < B_OK)
|
|
|
|
put_vnode(vnode);
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2008-03-18 19:10:04 +03:00
|
|
|
cache_node_opened(vnode, FDTYPE_DIR, vnode->cache, mountID, parentID,
|
|
|
|
vnode->id, name);
|
2002-07-20 04:16:12 +04:00
|
|
|
return status;
|
2002-07-09 16:24:59 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2002-07-20 04:16:12 +04:00
|
|
|
static int
|
2004-08-29 00:38:39 +04:00
|
|
|
dir_open(int fd, char *path, bool kernel)
|
2002-07-09 16:24:59 +04:00
|
|
|
{
|
2004-08-29 00:38:39 +04:00
|
|
|
int status = B_OK;
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2004-08-29 00:38:39 +04:00
|
|
|
FUNCTION(("dir_open: fd: %d, entry path = '%s', kernel %d\n", fd, path, kernel));
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2004-08-29 00:38:39 +04:00
|
|
|
// get the vnode matching the vnode + path combination
|
|
|
|
struct vnode *vnode = NULL;
|
2007-06-21 23:50:57 +04:00
|
|
|
ino_t parentID;
|
2005-08-01 16:44:59 +04:00
|
|
|
status = fd_and_path_to_vnode(fd, path, true, &vnode, &parentID, kernel);
|
2004-08-29 00:38:39 +04:00
|
|
|
if (status != B_OK)
|
2002-07-20 04:16:12 +04:00
|
|
|
return status;
|
2002-07-14 09:13:20 +04:00
|
|
|
|
2004-08-29 00:38:39 +04:00
|
|
|
// open the dir
|
2003-08-18 07:21:26 +04:00
|
|
|
status = open_dir_vnode(vnode, kernel);
|
|
|
|
if (status < B_OK)
|
2002-07-20 04:16:12 +04:00
|
|
|
put_vnode(vnode);
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2005-08-01 16:44:59 +04:00
|
|
|
cache_node_opened(vnode, FDTYPE_DIR, vnode->cache, vnode->device, parentID, vnode->id, NULL);
|
2002-07-20 04:16:12 +04:00
|
|
|
return status;
|
2002-07-09 16:24:59 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2002-10-08 07:24:51 +04:00
|
|
|
static status_t
|
2002-09-25 06:18:20 +04:00
|
|
|
dir_close(struct file_descriptor *descriptor)
|
|
|
|
{
|
2002-09-26 07:50:14 +04:00
|
|
|
struct vnode *vnode = descriptor->u.vnode;
|
2002-09-25 06:18:20 +04:00
|
|
|
|
|
|
|
FUNCTION(("dir_close(descriptor = %p)\n", descriptor));
|
|
|
|
|
2005-02-02 09:21:31 +03:00
|
|
|
cache_node_closed(vnode, FDTYPE_DIR, vnode->cache, vnode->device, vnode->id);
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
if (HAS_FS_CALL(vnode, close_dir))
|
|
|
|
return FS_CALL(vnode, close_dir, descriptor->cookie);
|
2002-09-25 06:18:20 +04:00
|
|
|
|
|
|
|
return B_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
dir_free_fd(struct file_descriptor *descriptor)
|
|
|
|
{
|
2002-09-26 07:50:14 +04:00
|
|
|
struct vnode *vnode = descriptor->u.vnode;
|
2002-09-25 06:18:20 +04:00
|
|
|
|
|
|
|
if (vnode != NULL) {
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
FS_CALL(vnode, free_dir_cookie, descriptor->cookie);
|
2002-09-25 06:18:20 +04:00
|
|
|
put_vnode(vnode);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-03-04 19:59:59 +03:00
|
|
|
static status_t
|
2008-03-30 09:59:54 +04:00
|
|
|
dir_read(struct io_context* ioContext, struct file_descriptor *descriptor,
|
|
|
|
struct dirent *buffer, size_t bufferSize, uint32 *_count)
|
2002-07-09 16:24:59 +04:00
|
|
|
{
|
2008-03-30 09:59:54 +04:00
|
|
|
return dir_read(ioContext, descriptor->u.vnode, descriptor->cookie, buffer,
|
|
|
|
bufferSize, _count);
|
2004-09-12 04:05:51 +04:00
|
|
|
}
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2004-09-12 04:05:51 +04:00
|
|
|
|
|
|
|
static void
|
2008-03-30 09:59:54 +04:00
|
|
|
fix_dirent(struct vnode *parent, struct dirent *entry,
|
|
|
|
struct io_context* ioContext)
|
2004-09-12 04:05:51 +04:00
|
|
|
{
|
|
|
|
// set d_pdev and d_pino
|
|
|
|
entry->d_pdev = parent->device;
|
|
|
|
entry->d_pino = parent->id;
|
|
|
|
|
|
|
|
// If this is the ".." entry and the directory is the root of a FS,
|
|
|
|
// we need to replace d_dev and d_ino with the actual values.
|
|
|
|
if (strcmp(entry->d_name, "..") == 0
|
|
|
|
&& parent->mount->root_vnode == parent
|
|
|
|
&& parent->mount->covers_vnode) {
|
2006-03-09 00:42:14 +03:00
|
|
|
inc_vnode_ref_count(parent);
|
|
|
|
// vnode_path_to_vnode() puts the node
|
2004-09-12 04:05:51 +04:00
|
|
|
|
2008-03-30 09:59:54 +04:00
|
|
|
// Make sure the IO context root is not bypassed.
|
|
|
|
if (parent == ioContext->root) {
|
|
|
|
entry->d_dev = parent->device;
|
|
|
|
entry->d_ino = parent->id;
|
|
|
|
} else {
|
|
|
|
// ".." is guaranteed not to be clobbered by this call
|
|
|
|
struct vnode *vnode;
|
|
|
|
status_t status = vnode_path_to_vnode(parent, (char*)"..", false, 0,
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
ioContext, &vnode, NULL);
|
2004-09-12 04:05:51 +04:00
|
|
|
|
2008-03-30 09:59:54 +04:00
|
|
|
if (status == B_OK) {
|
|
|
|
entry->d_dev = vnode->device;
|
|
|
|
entry->d_ino = vnode->id;
|
|
|
|
}
|
2004-09-12 04:05:51 +04:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
// resolve mount points
|
|
|
|
struct vnode *vnode = NULL;
|
2007-10-08 20:06:32 +04:00
|
|
|
status_t status = get_vnode(entry->d_dev, entry->d_ino, &vnode, true,
|
|
|
|
false);
|
2004-09-12 04:05:51 +04:00
|
|
|
if (status != B_OK)
|
|
|
|
return;
|
|
|
|
|
2007-03-03 05:42:36 +03:00
|
|
|
mutex_lock(&sVnodeCoveredByMutex);
|
2004-09-12 04:05:51 +04:00
|
|
|
if (vnode->covered_by) {
|
|
|
|
entry->d_dev = vnode->covered_by->device;
|
|
|
|
entry->d_ino = vnode->covered_by->id;
|
|
|
|
}
|
2007-03-03 05:42:36 +03:00
|
|
|
mutex_unlock(&sVnodeCoveredByMutex);
|
2004-09-12 04:05:51 +04:00
|
|
|
|
|
|
|
put_vnode(vnode);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-03-04 19:59:59 +03:00
|
|
|
static status_t
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
dir_read(struct io_context* ioContext, struct vnode *vnode, void *cookie,
|
2008-03-30 09:59:54 +04:00
|
|
|
struct dirent *buffer, size_t bufferSize, uint32 *_count)
|
2004-09-12 04:05:51 +04:00
|
|
|
{
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
if (!HAS_FS_CALL(vnode, read_dir))
|
2004-09-12 04:05:51 +04:00
|
|
|
return EOPNOTSUPP;
|
|
|
|
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
status_t error = FS_CALL(vnode, read_dir, cookie, buffer, bufferSize,
|
|
|
|
_count);
|
2004-09-12 04:05:51 +04:00
|
|
|
if (error != B_OK)
|
|
|
|
return error;
|
|
|
|
|
|
|
|
// we need to adjust the read dirents
|
|
|
|
if (*_count > 0) {
|
|
|
|
// XXX: Currently reading only one dirent is supported. Make this a loop!
|
2008-03-30 09:59:54 +04:00
|
|
|
fix_dirent(vnode, buffer, ioContext);
|
2004-09-12 04:05:51 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
return error;
|
2002-07-09 16:24:59 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-03-04 19:59:59 +03:00
|
|
|
static status_t
|
2002-07-20 04:16:12 +04:00
|
|
|
dir_rewind(struct file_descriptor *descriptor)
|
2002-07-09 16:24:59 +04:00
|
|
|
{
|
2002-09-26 07:50:14 +04:00
|
|
|
struct vnode *vnode = descriptor->u.vnode;
|
2002-07-09 16:24:59 +04:00
|
|
|
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
if (HAS_FS_CALL(vnode, rewind_dir)) {
|
|
|
|
return FS_CALL(vnode, rewind_dir, descriptor->cookie);
|
|
|
|
}
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2002-07-20 04:16:12 +04:00
|
|
|
return EOPNOTSUPP;
|
2002-07-09 16:24:59 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2002-08-14 00:39:25 +04:00
|
|
|
static status_t
|
2006-01-25 14:12:21 +03:00
|
|
|
dir_remove(int fd, char *path, bool kernel)
|
2002-08-14 00:39:25 +04:00
|
|
|
{
|
|
|
|
char name[B_FILE_NAME_LENGTH];
|
|
|
|
struct vnode *directory;
|
|
|
|
status_t status;
|
2006-01-25 14:12:21 +03:00
|
|
|
|
2006-04-18 21:40:27 +04:00
|
|
|
if (path != NULL) {
|
|
|
|
// we need to make sure our path name doesn't stop with "/", ".", or ".."
|
|
|
|
char *lastSlash = strrchr(path, '/');
|
|
|
|
if (lastSlash != NULL) {
|
|
|
|
char *leaf = lastSlash + 1;
|
|
|
|
if (!strcmp(leaf, ".."))
|
|
|
|
return B_NOT_ALLOWED;
|
|
|
|
|
|
|
|
// omit multiple slashes
|
|
|
|
while (lastSlash > path && lastSlash[-1] == '/') {
|
|
|
|
lastSlash--;
|
|
|
|
}
|
|
|
|
|
2008-03-04 19:59:59 +03:00
|
|
|
if (!leaf[0]
|
2006-04-18 21:40:27 +04:00
|
|
|
|| !strcmp(leaf, ".")) {
|
|
|
|
// "name/" -> "name", or "name/." -> "name"
|
|
|
|
lastSlash[0] = '\0';
|
|
|
|
}
|
|
|
|
} else if (!strcmp(path, ".."))
|
|
|
|
return B_NOT_ALLOWED;
|
|
|
|
}
|
|
|
|
|
2006-01-25 14:12:21 +03:00
|
|
|
status = fd_and_path_to_dir_vnode(fd, path, &directory, name, kernel);
|
2006-04-18 21:40:27 +04:00
|
|
|
if (status < B_OK)
|
2002-08-14 00:39:25 +04:00
|
|
|
return status;
|
|
|
|
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
if (HAS_FS_CALL(directory, remove_dir))
|
|
|
|
status = FS_CALL(directory, remove_dir, name);
|
|
|
|
else
|
2002-08-14 00:39:25 +04:00
|
|
|
status = EROFS;
|
|
|
|
|
|
|
|
put_vnode(directory);
|
|
|
|
return status;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2002-10-08 07:24:51 +04:00
|
|
|
static status_t
|
axeld + bonefish:
* Implemented automatic syscall restarts:
- A syscall can indicate that it has been interrupted and can be
restarted by setting a respective bit in thread::flags. It can
store parameters it wants to be preserved for the restart in
thread::syscall_restart::parameters. Another thread::flags bit
indicates whether it has been restarted.
- handle_signals() clears the restart flag, if the handled signal
has a handler function installed and SA_RESTART is not set. Another
thread flag (THREAD_FLAGS_DONT_RESTART_SYSCALL) can prevent syscalls
from being restarted, even if they could be (not used yet, but we
might want to use it in resume_thread(), so that we stay
behaviorally compatible with BeOS).
- The architecture specific syscall handler restarts the syscall, if
the restart flag is set. Implemented for x86 only.
- Added some support functions in the private <syscall_restart.h> to
simplify the syscall restart code in the syscalls.
- Adjusted all syscalls that can potentially be restarted accordingly.
- _user_ioctl() sets new thread flag THREAD_FLAGS_IOCTL_SYSCALL while
calling the underlying FS's/driver's hook, so that syscall restarts
can also be supported there.
* thread_at_kernel_exit() invokes handle_signals() in a loop now, as
long as the latter indicates that the thread shall be suspended, so
that after waking up signals received in the meantime will be handled
before the thread returns to userland. Adjusted handle_signals()
accordingly -- when encountering a suspending signal we don't check
for further signals.
* Fixed sigsuspend(): Suspending the thread and rescheduling doesn't
result in the correct behavior. Instead we employ a temporary
condition variable and interruptably wait on it. The POSIX test
suite test passes, now.
* Made the switch_sem[_etc]() behavior on interruption consistent.
Depending on when the signal arrived (before the call or when already
waiting) the first semaphore would or wouldn't be released. Now we
consistently release it.
* Refactored _user_{read,write}[v]() syscalls. Use a common function for
either pair. The iovec version doesn't fail anymore, if anything could
be read/written at all. It also checks whether a complete vector
could be read/written, so that we won't skip data, if the underlying
FS/driver couldn't read/write more ATM.
* Some refactoring in the x86 syscall handler: The int 99 and sysenter
handlers use a common subroutine to avoid code duplication.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@23983 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-02-17 18:48:30 +03:00
|
|
|
common_ioctl(struct file_descriptor *descriptor, ulong op, void *buffer,
|
|
|
|
size_t length)
|
2002-07-20 04:16:12 +04:00
|
|
|
{
|
2002-09-26 07:50:14 +04:00
|
|
|
struct vnode *vnode = descriptor->u.vnode;
|
2002-07-09 16:24:59 +04:00
|
|
|
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
if (HAS_FS_CALL(vnode, ioctl))
|
|
|
|
return FS_CALL(vnode, ioctl, descriptor->cookie, op, buffer, length);
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2002-07-20 04:16:12 +04:00
|
|
|
return EOPNOTSUPP;
|
|
|
|
}
|
2002-07-09 16:24:59 +04:00
|
|
|
|
|
|
|
|
2008-03-04 19:59:59 +03:00
|
|
|
static status_t
|
2004-10-05 17:36:44 +04:00
|
|
|
common_fcntl(int fd, int op, uint32 argument, bool kernel)
|
|
|
|
{
|
2005-03-17 16:18:29 +03:00
|
|
|
struct flock flock;
|
2004-10-05 17:36:44 +04:00
|
|
|
|
|
|
|
FUNCTION(("common_fcntl(fd = %d, op = %d, argument = %lx, %s)\n",
|
|
|
|
fd, op, argument, kernel ? "kernel" : "user"));
|
|
|
|
|
2008-04-11 23:21:14 +04:00
|
|
|
struct file_descriptor *descriptor = get_fd(get_current_io_context(kernel),
|
|
|
|
fd);
|
2004-10-05 17:36:44 +04:00
|
|
|
if (descriptor == NULL)
|
|
|
|
return B_FILE_ERROR;
|
|
|
|
|
2008-04-11 23:21:14 +04:00
|
|
|
struct vnode* vnode = fd_vnode(descriptor);
|
|
|
|
|
2008-02-03 18:37:31 +03:00
|
|
|
status_t status = B_OK;
|
|
|
|
|
2005-03-17 16:18:29 +03:00
|
|
|
if (op == F_SETLK || op == F_SETLKW || op == F_GETLK) {
|
|
|
|
if (descriptor->type != FDTYPE_FILE)
|
2008-02-03 18:37:31 +03:00
|
|
|
status = B_BAD_VALUE;
|
|
|
|
else if (user_memcpy(&flock, (struct flock *)argument,
|
|
|
|
sizeof(struct flock)) < B_OK)
|
|
|
|
status = B_BAD_ADDRESS;
|
|
|
|
|
|
|
|
if (status != B_OK) {
|
|
|
|
put_fd(descriptor);
|
|
|
|
return status;
|
|
|
|
}
|
2005-03-17 16:18:29 +03:00
|
|
|
}
|
|
|
|
|
2004-10-05 17:36:44 +04:00
|
|
|
switch (op) {
|
|
|
|
case F_SETFD:
|
2005-10-06 13:02:59 +04:00
|
|
|
{
|
|
|
|
struct io_context *context = get_current_io_context(kernel);
|
2004-10-05 17:36:44 +04:00
|
|
|
// Set file descriptor flags
|
|
|
|
|
|
|
|
// O_CLOEXEC is the only flag available at this time
|
2005-10-06 13:02:59 +04:00
|
|
|
mutex_lock(&context->io_mutex);
|
2007-09-26 04:20:23 +04:00
|
|
|
fd_set_close_on_exec(context, fd, (argument & FD_CLOEXEC) != 0);
|
2005-10-06 13:02:59 +04:00
|
|
|
mutex_unlock(&context->io_mutex);
|
2007-09-26 04:20:23 +04:00
|
|
|
|
2004-10-05 17:36:44 +04:00
|
|
|
status = B_OK;
|
|
|
|
break;
|
2005-10-06 13:02:59 +04:00
|
|
|
}
|
2004-10-05 17:36:44 +04:00
|
|
|
|
|
|
|
case F_GETFD:
|
2005-10-06 13:02:59 +04:00
|
|
|
{
|
|
|
|
struct io_context *context = get_current_io_context(kernel);
|
|
|
|
|
2004-10-05 17:36:44 +04:00
|
|
|
// Get file descriptor flags
|
2005-10-06 13:02:59 +04:00
|
|
|
mutex_lock(&context->io_mutex);
|
|
|
|
status = fd_close_on_exec(context, fd) ? FD_CLOEXEC : 0;
|
|
|
|
mutex_unlock(&context->io_mutex);
|
2004-10-05 17:36:44 +04:00
|
|
|
break;
|
2005-10-06 13:02:59 +04:00
|
|
|
}
|
2004-10-05 17:36:44 +04:00
|
|
|
|
|
|
|
case F_SETFL:
|
|
|
|
// Set file descriptor open mode
|
|
|
|
|
2008-04-11 23:21:14 +04:00
|
|
|
// we only accept changes to O_APPEND and O_NONBLOCK
|
|
|
|
argument &= O_APPEND | O_NONBLOCK;
|
|
|
|
if (descriptor->ops->fd_set_flags != NULL) {
|
|
|
|
status = descriptor->ops->fd_set_flags(descriptor, argument);
|
|
|
|
} else if (vnode != NULL && HAS_FS_CALL(vnode, set_flags)) {
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
status = FS_CALL(vnode, set_flags, descriptor->cookie,
|
|
|
|
(int)argument);
|
2004-10-05 17:36:44 +04:00
|
|
|
} else
|
|
|
|
status = EOPNOTSUPP;
|
2008-04-11 23:21:14 +04:00
|
|
|
|
|
|
|
if (status == B_OK) {
|
|
|
|
// update this descriptor's open_mode field
|
|
|
|
descriptor->open_mode = (descriptor->open_mode
|
|
|
|
& ~(O_APPEND | O_NONBLOCK)) | argument;
|
|
|
|
}
|
|
|
|
|
2004-10-05 17:36:44 +04:00
|
|
|
break;
|
|
|
|
|
|
|
|
case F_GETFL:
|
|
|
|
// Get file descriptor open mode
|
|
|
|
status = descriptor->open_mode;
|
|
|
|
break;
|
|
|
|
|
2004-11-25 05:56:35 +03:00
|
|
|
case F_DUPFD:
|
2005-10-06 13:02:59 +04:00
|
|
|
{
|
|
|
|
struct io_context *context = get_current_io_context(kernel);
|
|
|
|
|
|
|
|
status = new_fd_etc(context, descriptor, (int)argument);
|
|
|
|
if (status >= 0) {
|
|
|
|
mutex_lock(&context->io_mutex);
|
|
|
|
fd_set_close_on_exec(context, fd, false);
|
|
|
|
mutex_unlock(&context->io_mutex);
|
|
|
|
|
2004-11-25 05:56:35 +03:00
|
|
|
atomic_add(&descriptor->ref_count, 1);
|
2005-10-06 13:02:59 +04:00
|
|
|
}
|
2004-11-25 05:56:35 +03:00
|
|
|
break;
|
2005-10-06 13:02:59 +04:00
|
|
|
}
|
2004-11-25 05:56:35 +03:00
|
|
|
|
2005-03-17 16:18:29 +03:00
|
|
|
case F_GETLK:
|
2008-04-11 23:21:14 +04:00
|
|
|
if (vnode != NULL) {
|
|
|
|
status = get_advisory_lock(vnode, &flock);
|
|
|
|
if (status == B_OK) {
|
|
|
|
// copy back flock structure
|
|
|
|
status = user_memcpy((struct flock *)argument, &flock,
|
|
|
|
sizeof(struct flock));
|
|
|
|
}
|
|
|
|
} else
|
|
|
|
status = B_BAD_VALUE;
|
2005-03-17 16:18:29 +03:00
|
|
|
break;
|
|
|
|
|
|
|
|
case F_SETLK:
|
|
|
|
case F_SETLKW:
|
|
|
|
status = normalize_flock(descriptor, &flock);
|
|
|
|
if (status < B_OK)
|
|
|
|
break;
|
|
|
|
|
2008-04-11 23:21:14 +04:00
|
|
|
if (vnode == NULL) {
|
|
|
|
status = B_BAD_VALUE;
|
|
|
|
} else if (flock.l_type == F_UNLCK) {
|
|
|
|
status = release_advisory_lock(vnode, &flock);
|
|
|
|
} else {
|
2005-03-17 16:18:29 +03:00
|
|
|
// the open mode must match the lock type
|
2008-02-03 18:37:31 +03:00
|
|
|
if ((descriptor->open_mode & O_RWMASK) == O_RDONLY
|
|
|
|
&& flock.l_type == F_WRLCK
|
|
|
|
|| (descriptor->open_mode & O_RWMASK) == O_WRONLY
|
|
|
|
&& flock.l_type == F_RDLCK)
|
2005-03-17 16:18:29 +03:00
|
|
|
status = B_FILE_ERROR;
|
2008-02-03 18:37:31 +03:00
|
|
|
else {
|
2008-04-11 23:21:14 +04:00
|
|
|
status = acquire_advisory_lock(vnode, -1,
|
2008-02-03 18:37:31 +03:00
|
|
|
&flock, op == F_SETLKW);
|
|
|
|
}
|
2005-03-17 16:18:29 +03:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
// ToDo: add support for more ops?
|
2004-10-05 17:36:44 +04:00
|
|
|
|
|
|
|
default:
|
|
|
|
status = B_BAD_VALUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
put_fd(descriptor);
|
|
|
|
return status;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2002-10-08 07:24:51 +04:00
|
|
|
static status_t
|
2002-07-20 04:16:12 +04:00
|
|
|
common_sync(int fd, bool kernel)
|
|
|
|
{
|
|
|
|
struct file_descriptor *descriptor;
|
|
|
|
struct vnode *vnode;
|
2004-10-05 17:36:44 +04:00
|
|
|
status_t status;
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2004-10-05 17:36:44 +04:00
|
|
|
FUNCTION(("common_fsync: entry. fd %d kernel %d\n", fd, kernel));
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2002-08-10 00:20:28 +04:00
|
|
|
descriptor = get_fd_and_vnode(fd, &vnode, kernel);
|
2002-07-20 04:16:12 +04:00
|
|
|
if (descriptor == NULL)
|
2003-02-21 16:49:26 +03:00
|
|
|
return B_FILE_ERROR;
|
2002-07-09 16:24:59 +04:00
|
|
|
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
if (HAS_FS_CALL(vnode, fsync))
|
|
|
|
status = FS_CALL_NO_PARAMS(vnode, fsync);
|
2002-07-20 04:16:12 +04:00
|
|
|
else
|
|
|
|
status = EOPNOTSUPP;
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2002-07-20 04:16:12 +04:00
|
|
|
put_fd(descriptor);
|
|
|
|
return status;
|
2002-07-09 16:24:59 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-08-29 00:38:39 +04:00
|
|
|
static status_t
|
|
|
|
common_lock_node(int fd, bool kernel)
|
|
|
|
{
|
2006-06-02 18:16:13 +04:00
|
|
|
struct file_descriptor *descriptor;
|
|
|
|
struct vnode *vnode;
|
|
|
|
|
|
|
|
descriptor = get_fd_and_vnode(fd, &vnode, kernel);
|
|
|
|
if (descriptor == NULL)
|
|
|
|
return B_FILE_ERROR;
|
|
|
|
|
|
|
|
status_t status = B_OK;
|
|
|
|
|
|
|
|
// We need to set the locking atomically - someone
|
|
|
|
// else might set one at the same time
|
|
|
|
if (atomic_test_and_set((vint32 *)&vnode->mandatory_locked_by,
|
2008-03-18 19:10:04 +03:00
|
|
|
(addr_t)descriptor, (addr_t)NULL) != (addr_t)NULL)
|
2006-06-02 18:16:13 +04:00
|
|
|
status = B_BUSY;
|
|
|
|
|
|
|
|
put_fd(descriptor);
|
|
|
|
return status;
|
2004-08-29 00:38:39 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static status_t
|
|
|
|
common_unlock_node(int fd, bool kernel)
|
|
|
|
{
|
2006-06-02 18:16:13 +04:00
|
|
|
struct file_descriptor *descriptor;
|
|
|
|
struct vnode *vnode;
|
|
|
|
|
|
|
|
descriptor = get_fd_and_vnode(fd, &vnode, kernel);
|
|
|
|
if (descriptor == NULL)
|
|
|
|
return B_FILE_ERROR;
|
|
|
|
|
|
|
|
status_t status = B_OK;
|
|
|
|
|
|
|
|
// We need to set the locking atomically - someone
|
|
|
|
// else might set one at the same time
|
|
|
|
if (atomic_test_and_set((vint32 *)&vnode->mandatory_locked_by,
|
2008-03-18 19:10:04 +03:00
|
|
|
(addr_t)NULL, (addr_t)descriptor) != (int32)descriptor)
|
2006-06-02 18:16:13 +04:00
|
|
|
status = B_BAD_VALUE;
|
|
|
|
|
|
|
|
put_fd(descriptor);
|
|
|
|
return status;
|
2004-08-29 00:38:39 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-10-29 17:11:46 +04:00
|
|
|
static status_t
|
2005-04-06 20:07:10 +04:00
|
|
|
common_read_link(int fd, char *path, char *buffer, size_t *_bufferSize,
|
2004-08-29 00:38:39 +04:00
|
|
|
bool kernel)
|
2002-08-03 06:03:27 +04:00
|
|
|
{
|
|
|
|
struct vnode *vnode;
|
2005-08-09 20:25:01 +04:00
|
|
|
status_t status;
|
2002-08-03 06:03:27 +04:00
|
|
|
|
2005-08-01 16:44:59 +04:00
|
|
|
status = fd_and_path_to_vnode(fd, path, false, &vnode, NULL, kernel);
|
2002-08-03 06:03:27 +04:00
|
|
|
if (status < B_OK)
|
|
|
|
return status;
|
|
|
|
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
if (HAS_FS_CALL(vnode, read_symlink)) {
|
|
|
|
status = FS_CALL(vnode, read_symlink, buffer, _bufferSize);
|
2005-04-06 20:07:10 +04:00
|
|
|
} else
|
2002-08-03 06:03:27 +04:00
|
|
|
status = B_BAD_VALUE;
|
|
|
|
|
|
|
|
put_vnode(vnode);
|
|
|
|
return status;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2002-08-14 00:39:25 +04:00
|
|
|
static status_t
|
2004-08-29 00:38:39 +04:00
|
|
|
common_create_symlink(int fd, char *path, const char *toPath, int mode,
|
|
|
|
bool kernel)
|
2002-07-28 22:41:07 +04:00
|
|
|
{
|
|
|
|
// path validity checks have to be in the calling function!
|
|
|
|
char name[B_FILE_NAME_LENGTH];
|
|
|
|
struct vnode *vnode;
|
2005-08-09 20:25:01 +04:00
|
|
|
status_t status;
|
2002-07-28 22:41:07 +04:00
|
|
|
|
2004-08-29 00:38:39 +04:00
|
|
|
FUNCTION(("common_create_symlink(fd = %d, path = %s, toPath = %s, mode = %d, kernel = %d)\n", fd, path, toPath, mode, kernel));
|
2002-08-03 06:03:27 +04:00
|
|
|
|
2004-08-29 00:38:39 +04:00
|
|
|
status = fd_and_path_to_dir_vnode(fd, path, &vnode, name, kernel);
|
2002-07-28 22:41:07 +04:00
|
|
|
if (status < B_OK)
|
|
|
|
return status;
|
|
|
|
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
if (HAS_FS_CALL(vnode, create_symlink))
|
|
|
|
status = FS_CALL(vnode, create_symlink, name, toPath, mode);
|
2002-07-28 22:41:07 +04:00
|
|
|
else
|
|
|
|
status = EROFS;
|
|
|
|
|
|
|
|
put_vnode(vnode);
|
|
|
|
|
|
|
|
return status;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2002-08-14 00:39:25 +04:00
|
|
|
static status_t
|
|
|
|
common_create_link(char *path, char *toPath, bool kernel)
|
|
|
|
{
|
|
|
|
// path validity checks have to be in the calling function!
|
|
|
|
char name[B_FILE_NAME_LENGTH];
|
|
|
|
struct vnode *directory, *vnode;
|
2005-08-09 20:25:01 +04:00
|
|
|
status_t status;
|
2002-08-14 00:39:25 +04:00
|
|
|
|
|
|
|
FUNCTION(("common_create_link(path = %s, toPath = %s, kernel = %d)\n", path, toPath, kernel));
|
|
|
|
|
|
|
|
status = path_to_dir_vnode(path, &directory, name, kernel);
|
|
|
|
if (status < B_OK)
|
|
|
|
return status;
|
|
|
|
|
2005-08-01 16:44:59 +04:00
|
|
|
status = path_to_vnode(toPath, true, &vnode, NULL, kernel);
|
2002-08-14 00:39:25 +04:00
|
|
|
if (status < B_OK)
|
|
|
|
goto err;
|
|
|
|
|
|
|
|
if (directory->mount != vnode->mount) {
|
|
|
|
status = B_CROSS_DEVICE_LINK;
|
|
|
|
goto err1;
|
|
|
|
}
|
|
|
|
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
if (HAS_FS_CALL(directory, link))
|
|
|
|
status = FS_CALL(directory, link, name, vnode);
|
2002-08-14 00:39:25 +04:00
|
|
|
else
|
|
|
|
status = EROFS;
|
|
|
|
|
|
|
|
err1:
|
|
|
|
put_vnode(vnode);
|
|
|
|
err:
|
|
|
|
put_vnode(directory);
|
|
|
|
|
|
|
|
return status;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static status_t
|
2004-08-29 00:38:39 +04:00
|
|
|
common_unlink(int fd, char *path, bool kernel)
|
2002-07-09 16:24:59 +04:00
|
|
|
{
|
2004-12-14 01:17:00 +03:00
|
|
|
char filename[B_FILE_NAME_LENGTH];
|
2002-07-20 04:16:12 +04:00
|
|
|
struct vnode *vnode;
|
2005-08-09 20:25:01 +04:00
|
|
|
status_t status;
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2004-08-29 00:38:39 +04:00
|
|
|
FUNCTION(("common_unlink: fd: %d, path '%s', kernel %d\n", fd, path, kernel));
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2004-08-29 00:38:39 +04:00
|
|
|
status = fd_and_path_to_dir_vnode(fd, path, &vnode, filename, kernel);
|
2002-07-20 04:16:12 +04:00
|
|
|
if (status < 0)
|
|
|
|
return status;
|
2002-07-09 16:24:59 +04:00
|
|
|
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
if (HAS_FS_CALL(vnode, unlink))
|
|
|
|
status = FS_CALL(vnode, unlink, filename);
|
2002-07-20 04:16:12 +04:00
|
|
|
else
|
|
|
|
status = EROFS;
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2002-07-20 04:16:12 +04:00
|
|
|
put_vnode(vnode);
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2002-07-20 04:16:12 +04:00
|
|
|
return status;
|
2002-07-09 16:24:59 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2002-10-08 07:24:51 +04:00
|
|
|
static status_t
|
2002-08-13 17:51:36 +04:00
|
|
|
common_access(char *path, int mode, bool kernel)
|
|
|
|
{
|
|
|
|
struct vnode *vnode;
|
2005-08-09 20:25:01 +04:00
|
|
|
status_t status;
|
2002-08-13 17:51:36 +04:00
|
|
|
|
2005-08-01 16:44:59 +04:00
|
|
|
status = path_to_vnode(path, true, &vnode, NULL, kernel);
|
2002-08-13 17:51:36 +04:00
|
|
|
if (status < B_OK)
|
|
|
|
return status;
|
|
|
|
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
if (HAS_FS_CALL(vnode, access))
|
|
|
|
status = FS_CALL(vnode, access, mode);
|
2002-08-13 17:51:36 +04:00
|
|
|
else
|
2005-11-10 14:17:03 +03:00
|
|
|
status = B_OK;
|
2002-08-13 17:51:36 +04:00
|
|
|
|
|
|
|
put_vnode(vnode);
|
|
|
|
|
|
|
|
return status;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2002-10-08 07:24:51 +04:00
|
|
|
static status_t
|
2004-08-29 00:38:39 +04:00
|
|
|
common_rename(int fd, char *path, int newFD, char *newPath, bool kernel)
|
2002-07-09 16:24:59 +04:00
|
|
|
{
|
2002-09-25 16:13:09 +04:00
|
|
|
struct vnode *fromVnode, *toVnode;
|
2004-12-14 01:17:00 +03:00
|
|
|
char fromName[B_FILE_NAME_LENGTH];
|
|
|
|
char toName[B_FILE_NAME_LENGTH];
|
2005-08-09 20:25:01 +04:00
|
|
|
status_t status;
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2004-08-29 00:38:39 +04:00
|
|
|
FUNCTION(("common_rename(fd = %d, path = %s, newFD = %d, newPath = %s, kernel = %d)\n", fd, path, newFD, newPath, kernel));
|
2002-08-03 06:03:27 +04:00
|
|
|
|
2004-08-29 00:38:39 +04:00
|
|
|
status = fd_and_path_to_dir_vnode(fd, path, &fromVnode, fromName, kernel);
|
2008-04-09 18:21:06 +04:00
|
|
|
if (status < B_OK)
|
2002-09-25 16:13:09 +04:00
|
|
|
return status;
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2004-08-29 00:38:39 +04:00
|
|
|
status = fd_and_path_to_dir_vnode(newFD, newPath, &toVnode, toName, kernel);
|
2008-04-09 18:21:06 +04:00
|
|
|
if (status < B_OK)
|
|
|
|
goto err1;
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2003-10-17 18:47:15 +04:00
|
|
|
if (fromVnode->device != toVnode->device) {
|
2002-09-25 16:13:09 +04:00
|
|
|
status = B_CROSS_DEVICE_LINK;
|
2008-04-09 18:21:06 +04:00
|
|
|
goto err2;
|
2002-07-20 04:16:12 +04:00
|
|
|
}
|
2002-07-09 16:24:59 +04:00
|
|
|
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
if (HAS_FS_CALL(fromVnode, rename))
|
|
|
|
status = FS_CALL(fromVnode, rename, fromName, toVnode, toName);
|
2002-07-20 04:16:12 +04:00
|
|
|
else
|
|
|
|
status = EROFS;
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2008-04-09 18:21:06 +04:00
|
|
|
err2:
|
2002-09-25 16:13:09 +04:00
|
|
|
put_vnode(toVnode);
|
2008-04-09 18:21:06 +04:00
|
|
|
err1:
|
2002-09-25 16:13:09 +04:00
|
|
|
put_vnode(fromVnode);
|
|
|
|
|
2002-07-20 04:16:12 +04:00
|
|
|
return status;
|
2002-07-09 16:24:59 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2002-10-08 07:24:51 +04:00
|
|
|
static status_t
|
2002-09-25 06:18:20 +04:00
|
|
|
common_read_stat(struct file_descriptor *descriptor, struct stat *stat)
|
|
|
|
{
|
2002-09-26 07:50:14 +04:00
|
|
|
struct vnode *vnode = descriptor->u.vnode;
|
2002-09-25 06:18:20 +04:00
|
|
|
|
2002-10-17 07:09:25 +04:00
|
|
|
FUNCTION(("common_read_stat: stat %p\n", stat));
|
2005-04-05 05:09:07 +04:00
|
|
|
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
status_t status = FS_CALL(vnode, read_stat, stat);
|
2004-09-10 03:21:09 +04:00
|
|
|
|
|
|
|
// fill in the st_dev and st_ino fields
|
|
|
|
if (status == B_OK) {
|
|
|
|
stat->st_dev = vnode->device;
|
|
|
|
stat->st_ino = vnode->id;
|
|
|
|
}
|
|
|
|
|
|
|
|
return status;
|
2002-09-25 06:18:20 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2002-10-08 07:24:51 +04:00
|
|
|
static status_t
|
2002-10-17 07:09:25 +04:00
|
|
|
common_write_stat(struct file_descriptor *descriptor, const struct stat *stat, int statMask)
|
|
|
|
{
|
|
|
|
struct vnode *vnode = descriptor->u.vnode;
|
2008-03-04 19:59:59 +03:00
|
|
|
|
2002-10-17 07:09:25 +04:00
|
|
|
FUNCTION(("common_write_stat(vnode = %p, stat = %p, statMask = %d)\n", vnode, stat, statMask));
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
if (!HAS_FS_CALL(vnode, write_stat))
|
2002-10-17 07:09:25 +04:00
|
|
|
return EROFS;
|
|
|
|
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
return FS_CALL(vnode, write_stat, stat, statMask);
|
2002-10-17 07:09:25 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static status_t
|
2004-08-29 00:38:39 +04:00
|
|
|
common_path_read_stat(int fd, char *path, bool traverseLeafLink,
|
|
|
|
struct stat *stat, bool kernel)
|
2002-10-17 07:09:25 +04:00
|
|
|
{
|
|
|
|
struct vnode *vnode;
|
|
|
|
status_t status;
|
|
|
|
|
2004-08-29 00:38:39 +04:00
|
|
|
FUNCTION(("common_path_read_stat: fd: %d, path '%s', stat %p,\n", fd, path, stat));
|
2002-10-17 07:09:25 +04:00
|
|
|
|
2005-08-01 16:44:59 +04:00
|
|
|
status = fd_and_path_to_vnode(fd, path, traverseLeafLink, &vnode, NULL, kernel);
|
2002-10-17 07:09:25 +04:00
|
|
|
if (status < 0)
|
|
|
|
return status;
|
|
|
|
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
status = FS_CALL(vnode, read_stat, stat);
|
2002-10-17 07:09:25 +04:00
|
|
|
|
2004-09-10 03:21:09 +04:00
|
|
|
// fill in the st_dev and st_ino fields
|
|
|
|
if (status == B_OK) {
|
|
|
|
stat->st_dev = vnode->device;
|
|
|
|
stat->st_ino = vnode->id;
|
|
|
|
}
|
|
|
|
|
2002-10-17 07:09:25 +04:00
|
|
|
put_vnode(vnode);
|
|
|
|
return status;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static status_t
|
2004-08-29 00:38:39 +04:00
|
|
|
common_path_write_stat(int fd, char *path, bool traverseLeafLink,
|
|
|
|
const struct stat *stat, int statMask, bool kernel)
|
2002-07-20 04:16:12 +04:00
|
|
|
{
|
|
|
|
struct vnode *vnode;
|
2005-08-09 20:25:01 +04:00
|
|
|
status_t status;
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2004-08-29 00:38:39 +04:00
|
|
|
FUNCTION(("common_write_stat: fd: %d, path '%s', stat %p, stat_mask %d, kernel %d\n", fd, path, stat, statMask, kernel));
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2005-08-01 16:44:59 +04:00
|
|
|
status = fd_and_path_to_vnode(fd, path, traverseLeafLink, &vnode, NULL, kernel);
|
2002-07-20 04:16:12 +04:00
|
|
|
if (status < 0)
|
|
|
|
return status;
|
2002-07-09 16:24:59 +04:00
|
|
|
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
if (HAS_FS_CALL(vnode, write_stat))
|
|
|
|
status = FS_CALL(vnode, write_stat, stat, statMask);
|
2002-07-20 04:16:12 +04:00
|
|
|
else
|
|
|
|
status = EROFS;
|
|
|
|
|
2002-09-25 06:18:20 +04:00
|
|
|
put_vnode(vnode);
|
|
|
|
|
|
|
|
return status;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-12-07 19:15:57 +03:00
|
|
|
static int
|
2002-10-08 07:24:51 +04:00
|
|
|
attr_dir_open(int fd, char *path, bool kernel)
|
2002-09-26 07:50:14 +04:00
|
|
|
{
|
|
|
|
struct vnode *vnode;
|
|
|
|
int status;
|
|
|
|
|
2002-10-08 07:24:51 +04:00
|
|
|
FUNCTION(("attr_dir_open(fd = %d, path = '%s', kernel = %d)\n", fd, path, kernel));
|
2002-09-26 07:50:14 +04:00
|
|
|
|
2005-08-01 16:44:59 +04:00
|
|
|
status = fd_and_path_to_vnode(fd, path, true, &vnode, NULL, kernel);
|
2002-09-26 07:50:14 +04:00
|
|
|
if (status < B_OK)
|
|
|
|
return status;
|
|
|
|
|
|
|
|
status = open_attr_dir_vnode(vnode, kernel);
|
|
|
|
if (status < 0)
|
|
|
|
put_vnode(vnode);
|
|
|
|
|
|
|
|
return status;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2002-10-08 07:24:51 +04:00
|
|
|
static status_t
|
2002-09-26 07:50:14 +04:00
|
|
|
attr_dir_close(struct file_descriptor *descriptor)
|
|
|
|
{
|
|
|
|
struct vnode *vnode = descriptor->u.vnode;
|
|
|
|
|
2004-12-07 19:15:57 +03:00
|
|
|
FUNCTION(("attr_dir_close(descriptor = %p)\n", descriptor));
|
2002-09-26 07:50:14 +04:00
|
|
|
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
if (HAS_FS_CALL(vnode, close_attr_dir))
|
|
|
|
return FS_CALL(vnode, close_attr_dir, descriptor->cookie);
|
2002-09-26 07:50:14 +04:00
|
|
|
|
|
|
|
return B_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
attr_dir_free_fd(struct file_descriptor *descriptor)
|
|
|
|
{
|
|
|
|
struct vnode *vnode = descriptor->u.vnode;
|
|
|
|
|
|
|
|
if (vnode != NULL) {
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
FS_CALL(vnode, free_attr_dir_cookie, descriptor->cookie);
|
2002-09-26 07:50:14 +04:00
|
|
|
put_vnode(vnode);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-03-04 19:59:59 +03:00
|
|
|
static status_t
|
2008-03-30 09:59:54 +04:00
|
|
|
attr_dir_read(struct io_context* ioContext, struct file_descriptor *descriptor,
|
|
|
|
struct dirent *buffer, size_t bufferSize, uint32 *_count)
|
2002-09-26 07:50:14 +04:00
|
|
|
{
|
|
|
|
struct vnode *vnode = descriptor->u.vnode;
|
|
|
|
|
2004-12-07 19:15:57 +03:00
|
|
|
FUNCTION(("attr_dir_read(descriptor = %p)\n", descriptor));
|
|
|
|
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
if (HAS_FS_CALL(vnode, read_attr_dir))
|
|
|
|
return FS_CALL(vnode, read_attr_dir, descriptor->cookie, buffer,
|
|
|
|
bufferSize, _count);
|
2002-09-26 07:50:14 +04:00
|
|
|
|
|
|
|
return EOPNOTSUPP;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-03-04 19:59:59 +03:00
|
|
|
static status_t
|
2002-09-26 07:50:14 +04:00
|
|
|
attr_dir_rewind(struct file_descriptor *descriptor)
|
|
|
|
{
|
|
|
|
struct vnode *vnode = descriptor->u.vnode;
|
|
|
|
|
2004-12-07 19:15:57 +03:00
|
|
|
FUNCTION(("attr_dir_rewind(descriptor = %p)\n", descriptor));
|
|
|
|
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
if (HAS_FS_CALL(vnode, rewind_attr_dir))
|
|
|
|
return FS_CALL(vnode, rewind_attr_dir, descriptor->cookie);
|
2002-09-26 07:50:14 +04:00
|
|
|
|
|
|
|
return EOPNOTSUPP;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2002-09-25 06:18:20 +04:00
|
|
|
static int
|
|
|
|
attr_create(int fd, const char *name, uint32 type, int openMode, bool kernel)
|
|
|
|
{
|
|
|
|
struct vnode *vnode;
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
void *cookie;
|
2002-09-25 06:18:20 +04:00
|
|
|
int status;
|
|
|
|
|
2002-09-25 16:13:09 +04:00
|
|
|
if (name == NULL || *name == '\0')
|
|
|
|
return B_BAD_VALUE;
|
|
|
|
|
2004-08-29 00:38:39 +04:00
|
|
|
vnode = get_vnode_from_fd(fd, kernel);
|
2002-09-25 06:18:20 +04:00
|
|
|
if (vnode == NULL)
|
|
|
|
return B_FILE_ERROR;
|
|
|
|
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
if (!HAS_FS_CALL(vnode, create_attr)) {
|
2002-09-25 06:18:20 +04:00
|
|
|
status = EROFS;
|
|
|
|
goto err;
|
|
|
|
}
|
|
|
|
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
status = FS_CALL(vnode, create_attr, name, type, openMode, &cookie);
|
2002-09-25 06:18:20 +04:00
|
|
|
if (status < B_OK)
|
|
|
|
goto err;
|
|
|
|
|
2004-12-14 01:17:00 +03:00
|
|
|
if ((status = get_new_fd(FDTYPE_ATTR, NULL, vnode, cookie, openMode, kernel)) >= 0)
|
2002-09-25 06:18:20 +04:00
|
|
|
return status;
|
|
|
|
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
FS_CALL(vnode, close_attr, cookie);
|
|
|
|
FS_CALL(vnode, free_attr_cookie, cookie);
|
2002-09-25 06:18:20 +04:00
|
|
|
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
FS_CALL(vnode, remove_attr, name);
|
2002-09-25 06:18:20 +04:00
|
|
|
|
|
|
|
err:
|
|
|
|
put_vnode(vnode);
|
|
|
|
|
|
|
|
return status;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
attr_open(int fd, const char *name, int openMode, bool kernel)
|
|
|
|
{
|
|
|
|
struct vnode *vnode;
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
void *cookie;
|
2002-09-25 06:18:20 +04:00
|
|
|
int status;
|
|
|
|
|
2002-09-25 16:13:09 +04:00
|
|
|
if (name == NULL || *name == '\0')
|
|
|
|
return B_BAD_VALUE;
|
|
|
|
|
2004-08-29 00:38:39 +04:00
|
|
|
vnode = get_vnode_from_fd(fd, kernel);
|
2002-09-25 06:18:20 +04:00
|
|
|
if (vnode == NULL)
|
|
|
|
return B_FILE_ERROR;
|
|
|
|
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
if (!HAS_FS_CALL(vnode, open_attr)) {
|
2002-09-25 06:18:20 +04:00
|
|
|
status = EOPNOTSUPP;
|
|
|
|
goto err;
|
|
|
|
}
|
|
|
|
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
status = FS_CALL(vnode, open_attr, name, openMode, &cookie);
|
2002-09-25 06:18:20 +04:00
|
|
|
if (status < B_OK)
|
|
|
|
goto err;
|
|
|
|
|
2004-12-07 19:15:57 +03:00
|
|
|
// now we only need a file descriptor for this attribute and we're done
|
2004-12-14 01:17:00 +03:00
|
|
|
if ((status = get_new_fd(FDTYPE_ATTR, NULL, vnode, cookie, openMode, kernel)) >= 0)
|
2002-09-25 06:18:20 +04:00
|
|
|
return status;
|
|
|
|
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
FS_CALL(vnode, close_attr, cookie);
|
|
|
|
FS_CALL(vnode, free_attr_cookie, cookie);
|
2002-09-25 06:18:20 +04:00
|
|
|
|
|
|
|
err:
|
|
|
|
put_vnode(vnode);
|
|
|
|
|
|
|
|
return status;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2002-10-08 07:24:51 +04:00
|
|
|
static status_t
|
2002-09-25 06:18:20 +04:00
|
|
|
attr_close(struct file_descriptor *descriptor)
|
|
|
|
{
|
2002-09-26 07:50:14 +04:00
|
|
|
struct vnode *vnode = descriptor->u.vnode;
|
2002-09-25 06:18:20 +04:00
|
|
|
|
|
|
|
FUNCTION(("attr_close(descriptor = %p)\n", descriptor));
|
|
|
|
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
if (HAS_FS_CALL(vnode, close_attr))
|
|
|
|
return FS_CALL(vnode, close_attr, descriptor->cookie);
|
2002-09-25 06:18:20 +04:00
|
|
|
|
|
|
|
return B_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
attr_free_fd(struct file_descriptor *descriptor)
|
|
|
|
{
|
2002-09-26 07:50:14 +04:00
|
|
|
struct vnode *vnode = descriptor->u.vnode;
|
2002-09-25 06:18:20 +04:00
|
|
|
|
|
|
|
if (vnode != NULL) {
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
FS_CALL(vnode, free_attr_cookie, descriptor->cookie);
|
2002-09-25 06:18:20 +04:00
|
|
|
put_vnode(vnode);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-06-16 14:32:26 +04:00
|
|
|
static status_t
|
2002-09-25 06:18:20 +04:00
|
|
|
attr_read(struct file_descriptor *descriptor, off_t pos, void *buffer, size_t *length)
|
|
|
|
{
|
2002-09-26 07:50:14 +04:00
|
|
|
struct vnode *vnode = descriptor->u.vnode;
|
2002-09-25 06:18:20 +04:00
|
|
|
|
|
|
|
FUNCTION(("attr_read: buf %p, pos %Ld, len %p = %ld\n", buffer, pos, length, *length));
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
if (!HAS_FS_CALL(vnode, read_attr))
|
2002-09-25 06:18:20 +04:00
|
|
|
return EOPNOTSUPP;
|
|
|
|
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
return FS_CALL(vnode, read_attr, descriptor->cookie, pos, buffer, length);
|
2002-09-25 06:18:20 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-06-16 14:32:26 +04:00
|
|
|
static status_t
|
2002-09-25 06:18:20 +04:00
|
|
|
attr_write(struct file_descriptor *descriptor, off_t pos, const void *buffer, size_t *length)
|
|
|
|
{
|
2002-09-26 07:50:14 +04:00
|
|
|
struct vnode *vnode = descriptor->u.vnode;
|
2002-09-25 06:18:20 +04:00
|
|
|
|
|
|
|
FUNCTION(("attr_write: buf %p, pos %Ld, len %p\n", buffer, pos, length));
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
if (!HAS_FS_CALL(vnode, write_attr))
|
2002-09-25 06:18:20 +04:00
|
|
|
return EOPNOTSUPP;
|
|
|
|
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
return FS_CALL(vnode, write_attr, descriptor->cookie, pos, buffer, length);
|
2002-09-25 06:18:20 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static off_t
|
|
|
|
attr_seek(struct file_descriptor *descriptor, off_t pos, int seekType)
|
|
|
|
{
|
2002-10-08 04:42:17 +04:00
|
|
|
off_t offset;
|
2002-09-25 06:18:20 +04:00
|
|
|
|
2002-10-08 04:42:17 +04:00
|
|
|
switch (seekType) {
|
|
|
|
case SEEK_SET:
|
|
|
|
offset = 0;
|
|
|
|
break;
|
|
|
|
case SEEK_CUR:
|
|
|
|
offset = descriptor->pos;
|
|
|
|
break;
|
|
|
|
case SEEK_END:
|
|
|
|
{
|
|
|
|
struct vnode *vnode = descriptor->u.vnode;
|
|
|
|
struct stat stat;
|
|
|
|
status_t status;
|
|
|
|
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
if (!HAS_FS_CALL(vnode, read_stat))
|
2002-10-08 04:42:17 +04:00
|
|
|
return EOPNOTSUPP;
|
|
|
|
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
status = FS_CALL(vnode, read_attr_stat, descriptor->cookie, &stat);
|
2002-10-08 04:42:17 +04:00
|
|
|
if (status < B_OK)
|
|
|
|
return status;
|
|
|
|
|
|
|
|
offset = stat.st_size;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
default:
|
|
|
|
return B_BAD_VALUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
// assumes off_t is 64 bits wide
|
|
|
|
if (offset > 0 && LONGLONG_MAX - offset < pos)
|
|
|
|
return EOVERFLOW;
|
|
|
|
|
|
|
|
pos += offset;
|
|
|
|
if (pos < 0)
|
|
|
|
return B_BAD_VALUE;
|
2002-09-25 06:18:20 +04:00
|
|
|
|
2002-10-08 04:42:17 +04:00
|
|
|
return descriptor->pos = pos;
|
2002-09-25 06:18:20 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2002-10-08 07:24:51 +04:00
|
|
|
static status_t
|
2002-09-25 06:18:20 +04:00
|
|
|
attr_read_stat(struct file_descriptor *descriptor, struct stat *stat)
|
|
|
|
{
|
2002-09-26 07:50:14 +04:00
|
|
|
struct vnode *vnode = descriptor->u.vnode;
|
2002-09-25 06:18:20 +04:00
|
|
|
|
|
|
|
FUNCTION(("attr_read_stat: stat 0x%p\n", stat));
|
2004-12-07 19:15:57 +03:00
|
|
|
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
if (!HAS_FS_CALL(vnode, read_attr_stat))
|
2002-09-25 06:18:20 +04:00
|
|
|
return EOPNOTSUPP;
|
|
|
|
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
return FS_CALL(vnode, read_attr_stat, descriptor->cookie, stat);
|
2002-09-25 06:18:20 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2002-10-08 07:24:51 +04:00
|
|
|
static status_t
|
2002-10-17 07:09:25 +04:00
|
|
|
attr_write_stat(struct file_descriptor *descriptor, const struct stat *stat, int statMask)
|
2002-09-25 06:18:20 +04:00
|
|
|
{
|
2002-10-17 07:09:25 +04:00
|
|
|
struct vnode *vnode = descriptor->u.vnode;
|
2002-09-25 06:18:20 +04:00
|
|
|
|
2002-10-17 07:09:25 +04:00
|
|
|
FUNCTION(("attr_write_stat: stat = %p, statMask %d\n", stat, statMask));
|
2002-09-25 06:18:20 +04:00
|
|
|
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
if (!HAS_FS_CALL(vnode, write_attr_stat))
|
2002-10-17 07:09:25 +04:00
|
|
|
return EROFS;
|
2002-07-09 16:24:59 +04:00
|
|
|
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
return FS_CALL(vnode, write_attr_stat, descriptor->cookie, stat, statMask);
|
2002-07-09 16:24:59 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2002-10-08 07:24:51 +04:00
|
|
|
static status_t
|
2002-09-25 16:13:09 +04:00
|
|
|
attr_remove(int fd, const char *name, bool kernel)
|
|
|
|
{
|
|
|
|
struct file_descriptor *descriptor;
|
|
|
|
struct vnode *vnode;
|
2005-08-09 20:25:01 +04:00
|
|
|
status_t status;
|
2002-09-25 16:13:09 +04:00
|
|
|
|
|
|
|
if (name == NULL || *name == '\0')
|
|
|
|
return B_BAD_VALUE;
|
|
|
|
|
|
|
|
FUNCTION(("attr_remove: fd = %d, name = \"%s\", kernel %d\n", fd, name, kernel));
|
|
|
|
|
|
|
|
descriptor = get_fd_and_vnode(fd, &vnode, kernel);
|
|
|
|
if (descriptor == NULL)
|
|
|
|
return B_FILE_ERROR;
|
|
|
|
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
if (HAS_FS_CALL(vnode, remove_attr))
|
|
|
|
status = FS_CALL(vnode, remove_attr, name);
|
2002-09-25 16:13:09 +04:00
|
|
|
else
|
|
|
|
status = EROFS;
|
|
|
|
|
2004-05-17 14:01:17 +04:00
|
|
|
put_fd(descriptor);
|
2002-09-25 16:13:09 +04:00
|
|
|
|
|
|
|
return status;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2002-10-08 07:24:51 +04:00
|
|
|
static status_t
|
2002-09-25 16:13:09 +04:00
|
|
|
attr_rename(int fromfd, const char *fromName, int tofd, const char *toName, bool kernel)
|
|
|
|
{
|
|
|
|
struct file_descriptor *fromDescriptor, *toDescriptor;
|
|
|
|
struct vnode *fromVnode, *toVnode;
|
2005-08-09 20:25:01 +04:00
|
|
|
status_t status;
|
2002-09-25 16:13:09 +04:00
|
|
|
|
|
|
|
if (fromName == NULL || *fromName == '\0' || toName == NULL || *toName == '\0')
|
|
|
|
return B_BAD_VALUE;
|
|
|
|
|
|
|
|
FUNCTION(("attr_rename: from fd = %d, from name = \"%s\", to fd = %d, to name = \"%s\", kernel %d\n", fromfd, fromName, tofd, toName, kernel));
|
|
|
|
|
|
|
|
fromDescriptor = get_fd_and_vnode(fromfd, &fromVnode, kernel);
|
|
|
|
if (fromDescriptor == NULL)
|
|
|
|
return B_FILE_ERROR;
|
|
|
|
|
|
|
|
toDescriptor = get_fd_and_vnode(tofd, &toVnode, kernel);
|
|
|
|
if (toDescriptor == NULL) {
|
|
|
|
status = B_FILE_ERROR;
|
|
|
|
goto err;
|
|
|
|
}
|
|
|
|
|
|
|
|
// are the files on the same volume?
|
2003-10-17 18:47:15 +04:00
|
|
|
if (fromVnode->device != toVnode->device) {
|
2002-09-25 16:13:09 +04:00
|
|
|
status = B_CROSS_DEVICE_LINK;
|
|
|
|
goto err1;
|
|
|
|
}
|
|
|
|
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
if (HAS_FS_CALL(fromVnode, rename_attr)) {
|
|
|
|
status = FS_CALL(fromVnode, rename_attr, fromName, toVnode, toName);
|
|
|
|
} else
|
2002-09-25 16:13:09 +04:00
|
|
|
status = EROFS;
|
|
|
|
|
|
|
|
err1:
|
2004-05-17 14:01:17 +04:00
|
|
|
put_fd(toDescriptor);
|
2002-09-25 16:13:09 +04:00
|
|
|
err:
|
2004-05-17 14:01:17 +04:00
|
|
|
put_fd(fromDescriptor);
|
2002-09-25 16:13:09 +04:00
|
|
|
|
|
|
|
return status;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2002-10-08 07:24:51 +04:00
|
|
|
static status_t
|
2007-06-21 23:50:57 +04:00
|
|
|
index_dir_open(dev_t mountID, bool kernel)
|
2002-09-26 07:50:14 +04:00
|
|
|
{
|
|
|
|
struct fs_mount *mount;
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
void *cookie;
|
2002-09-26 07:50:14 +04:00
|
|
|
|
|
|
|
FUNCTION(("index_dir_open(mountID = %ld, kernel = %d)\n", mountID, kernel));
|
|
|
|
|
2005-09-22 21:45:43 +04:00
|
|
|
status_t status = get_mount(mountID, &mount);
|
|
|
|
if (status < B_OK)
|
|
|
|
return status;
|
2002-09-26 07:50:14 +04:00
|
|
|
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
if (!HAS_FS_MOUNT_CALL(mount, open_index_dir)) {
|
2003-09-04 08:01:25 +04:00
|
|
|
status = EOPNOTSUPP;
|
|
|
|
goto out;
|
|
|
|
}
|
2002-09-26 07:50:14 +04:00
|
|
|
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
status = FS_MOUNT_CALL(mount, open_index_dir, &cookie);
|
2002-09-26 07:50:14 +04:00
|
|
|
if (status < B_OK)
|
2003-09-04 08:01:25 +04:00
|
|
|
goto out;
|
2002-09-26 07:50:14 +04:00
|
|
|
|
|
|
|
// get fd for the index directory
|
2004-12-14 01:17:00 +03:00
|
|
|
status = get_new_fd(FDTYPE_INDEX_DIR, mount, NULL, cookie, 0, kernel);
|
2002-09-26 07:50:14 +04:00
|
|
|
if (status >= 0)
|
2003-09-04 08:01:25 +04:00
|
|
|
goto out;
|
2002-09-26 07:50:14 +04:00
|
|
|
|
2003-09-04 08:01:25 +04:00
|
|
|
// something went wrong
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
FS_MOUNT_CALL(mount, close_index_dir, cookie);
|
|
|
|
FS_MOUNT_CALL(mount, free_index_dir_cookie, cookie);
|
2002-09-26 07:50:14 +04:00
|
|
|
|
2003-09-04 08:01:25 +04:00
|
|
|
out:
|
|
|
|
put_mount(mount);
|
2002-09-26 07:50:14 +04:00
|
|
|
return status;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2002-10-08 07:24:51 +04:00
|
|
|
static status_t
|
2002-09-26 07:50:14 +04:00
|
|
|
index_dir_close(struct file_descriptor *descriptor)
|
|
|
|
{
|
|
|
|
struct fs_mount *mount = descriptor->u.mount;
|
|
|
|
|
2004-12-12 23:39:45 +03:00
|
|
|
FUNCTION(("index_dir_close(descriptor = %p)\n", descriptor));
|
2002-09-26 07:50:14 +04:00
|
|
|
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
if (HAS_FS_MOUNT_CALL(mount, close_index_dir))
|
|
|
|
return FS_MOUNT_CALL(mount, close_index_dir, descriptor->cookie);
|
2002-09-26 07:50:14 +04:00
|
|
|
|
|
|
|
return B_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
index_dir_free_fd(struct file_descriptor *descriptor)
|
|
|
|
{
|
|
|
|
struct fs_mount *mount = descriptor->u.mount;
|
|
|
|
|
|
|
|
if (mount != NULL) {
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
FS_MOUNT_CALL(mount, free_index_dir_cookie, descriptor->cookie);
|
2002-09-26 07:50:14 +04:00
|
|
|
// ToDo: find a replacement ref_count object - perhaps the root dir?
|
|
|
|
//put_vnode(vnode);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-03-04 19:59:59 +03:00
|
|
|
static status_t
|
2008-03-30 09:59:54 +04:00
|
|
|
index_dir_read(struct io_context* ioContext, struct file_descriptor *descriptor,
|
|
|
|
struct dirent *buffer, size_t bufferSize, uint32 *_count)
|
2002-09-26 07:50:14 +04:00
|
|
|
{
|
|
|
|
struct fs_mount *mount = descriptor->u.mount;
|
|
|
|
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
if (HAS_FS_MOUNT_CALL(mount, read_index_dir)) {
|
|
|
|
return FS_MOUNT_CALL(mount, read_index_dir, descriptor->cookie, buffer,
|
|
|
|
bufferSize, _count);
|
|
|
|
}
|
2002-09-26 07:50:14 +04:00
|
|
|
|
|
|
|
return EOPNOTSUPP;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-03-04 19:59:59 +03:00
|
|
|
static status_t
|
2002-09-26 07:50:14 +04:00
|
|
|
index_dir_rewind(struct file_descriptor *descriptor)
|
|
|
|
{
|
|
|
|
struct fs_mount *mount = descriptor->u.mount;
|
|
|
|
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
if (HAS_FS_MOUNT_CALL(mount, rewind_index_dir))
|
|
|
|
return FS_MOUNT_CALL(mount, rewind_index_dir, descriptor->cookie);
|
2002-09-26 07:50:14 +04:00
|
|
|
|
|
|
|
return EOPNOTSUPP;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2002-10-17 23:34:09 +04:00
|
|
|
static status_t
|
2007-06-21 23:50:57 +04:00
|
|
|
index_create(dev_t mountID, const char *name, uint32 type, uint32 flags, bool kernel)
|
2002-10-17 23:34:09 +04:00
|
|
|
{
|
|
|
|
FUNCTION(("index_create(mountID = %ld, name = %s, kernel = %d)\n", mountID, name, kernel));
|
|
|
|
|
2005-09-22 21:45:43 +04:00
|
|
|
struct fs_mount *mount;
|
|
|
|
status_t status = get_mount(mountID, &mount);
|
|
|
|
if (status < B_OK)
|
|
|
|
return status;
|
2002-10-17 23:34:09 +04:00
|
|
|
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
if (!HAS_FS_MOUNT_CALL(mount, create_index)) {
|
2003-09-04 08:01:25 +04:00
|
|
|
status = EROFS;
|
|
|
|
goto out;
|
|
|
|
}
|
2002-10-17 23:34:09 +04:00
|
|
|
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
status = FS_MOUNT_CALL(mount, create_index, name, type, flags);
|
2002-10-17 23:34:09 +04:00
|
|
|
|
2003-09-04 08:01:25 +04:00
|
|
|
out:
|
|
|
|
put_mount(mount);
|
|
|
|
return status;
|
2002-10-17 23:34:09 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2003-09-04 08:07:39 +04:00
|
|
|
#if 0
|
2002-10-17 23:34:09 +04:00
|
|
|
static status_t
|
|
|
|
index_read_stat(struct file_descriptor *descriptor, struct stat *stat)
|
|
|
|
{
|
|
|
|
struct vnode *vnode = descriptor->u.vnode;
|
|
|
|
|
|
|
|
// ToDo: currently unused!
|
|
|
|
FUNCTION(("index_read_stat: stat 0x%p\n", stat));
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
if (!HAS_FS_CALL(vnode, read_index_stat))
|
2002-10-17 23:34:09 +04:00
|
|
|
return EOPNOTSUPP;
|
|
|
|
|
|
|
|
return EOPNOTSUPP;
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
//return FS_CALL(vnode, read_index_stat, descriptor->cookie, stat);
|
2002-10-17 23:34:09 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2003-09-04 08:07:39 +04:00
|
|
|
static void
|
|
|
|
index_free_fd(struct file_descriptor *descriptor)
|
|
|
|
{
|
|
|
|
struct vnode *vnode = descriptor->u.vnode;
|
|
|
|
|
|
|
|
if (vnode != NULL) {
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
FS_CALL(vnode, free_index_cookie, descriptor->cookie);
|
2003-09-04 08:07:39 +04:00
|
|
|
put_vnode(vnode);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
2002-10-17 23:34:09 +04:00
|
|
|
static status_t
|
2007-06-21 23:50:57 +04:00
|
|
|
index_name_read_stat(dev_t mountID, const char *name, struct stat *stat, bool kernel)
|
2002-10-17 23:34:09 +04:00
|
|
|
{
|
|
|
|
FUNCTION(("index_remove(mountID = %ld, name = %s, kernel = %d)\n", mountID, name, kernel));
|
|
|
|
|
2005-09-22 21:45:43 +04:00
|
|
|
struct fs_mount *mount;
|
|
|
|
status_t status = get_mount(mountID, &mount);
|
|
|
|
if (status < B_OK)
|
|
|
|
return status;
|
2002-10-17 23:34:09 +04:00
|
|
|
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
if (!HAS_FS_MOUNT_CALL(mount, read_index_stat)) {
|
2003-09-04 08:01:25 +04:00
|
|
|
status = EOPNOTSUPP;
|
|
|
|
goto out;
|
|
|
|
}
|
2002-10-17 23:34:09 +04:00
|
|
|
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
status = FS_MOUNT_CALL(mount, read_index_stat, name, stat);
|
2002-10-17 23:34:09 +04:00
|
|
|
|
2003-09-04 08:01:25 +04:00
|
|
|
out:
|
|
|
|
put_mount(mount);
|
|
|
|
return status;
|
2002-10-17 23:34:09 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static status_t
|
2007-06-21 23:50:57 +04:00
|
|
|
index_remove(dev_t mountID, const char *name, bool kernel)
|
2002-10-17 23:34:09 +04:00
|
|
|
{
|
|
|
|
FUNCTION(("index_remove(mountID = %ld, name = %s, kernel = %d)\n", mountID, name, kernel));
|
|
|
|
|
2005-09-22 21:45:43 +04:00
|
|
|
struct fs_mount *mount;
|
|
|
|
status_t status = get_mount(mountID, &mount);
|
|
|
|
if (status < B_OK)
|
|
|
|
return status;
|
2002-10-17 23:34:09 +04:00
|
|
|
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
if (!HAS_FS_MOUNT_CALL(mount, remove_index)) {
|
2003-09-04 08:01:25 +04:00
|
|
|
status = EROFS;
|
|
|
|
goto out;
|
|
|
|
}
|
2002-10-17 23:34:09 +04:00
|
|
|
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
status = FS_MOUNT_CALL(mount, remove_index, name);
|
2002-10-17 23:34:09 +04:00
|
|
|
|
2003-09-04 08:01:25 +04:00
|
|
|
out:
|
|
|
|
put_mount(mount);
|
|
|
|
return status;
|
2002-10-17 23:34:09 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-10-06 19:33:12 +04:00
|
|
|
/*! ToDo: the query FS API is still the pretty much the same as in R5.
|
|
|
|
It would be nice if the FS would find some more kernel support
|
|
|
|
for them.
|
|
|
|
For example, query parsing should be moved into the kernel.
|
|
|
|
*/
|
2004-12-12 23:39:45 +03:00
|
|
|
static int
|
|
|
|
query_open(dev_t device, const char *query, uint32 flags,
|
|
|
|
port_id port, int32 token, bool kernel)
|
|
|
|
{
|
|
|
|
struct fs_mount *mount;
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
void *cookie;
|
2004-12-12 23:39:45 +03:00
|
|
|
|
2005-01-19 04:07:30 +03:00
|
|
|
FUNCTION(("query_open(device = %ld, query = \"%s\", kernel = %d)\n", device, query, kernel));
|
2004-12-12 23:39:45 +03:00
|
|
|
|
2005-09-22 21:45:43 +04:00
|
|
|
status_t status = get_mount(device, &mount);
|
|
|
|
if (status < B_OK)
|
|
|
|
return status;
|
2004-12-12 23:39:45 +03:00
|
|
|
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
if (!HAS_FS_MOUNT_CALL(mount, open_query)) {
|
2004-12-12 23:39:45 +03:00
|
|
|
status = EOPNOTSUPP;
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
status = FS_MOUNT_CALL(mount, open_query, query, flags, port, token,
|
|
|
|
&cookie);
|
2004-12-12 23:39:45 +03:00
|
|
|
if (status < B_OK)
|
|
|
|
goto out;
|
|
|
|
|
|
|
|
// get fd for the index directory
|
2004-12-14 01:17:00 +03:00
|
|
|
status = get_new_fd(FDTYPE_QUERY, mount, NULL, cookie, 0, kernel);
|
2004-12-12 23:39:45 +03:00
|
|
|
if (status >= 0)
|
|
|
|
goto out;
|
|
|
|
|
|
|
|
// something went wrong
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
FS_MOUNT_CALL(mount, close_query, cookie);
|
|
|
|
FS_MOUNT_CALL(mount, free_query_cookie, cookie);
|
2004-12-12 23:39:45 +03:00
|
|
|
|
|
|
|
out:
|
|
|
|
put_mount(mount);
|
|
|
|
return status;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static status_t
|
|
|
|
query_close(struct file_descriptor *descriptor)
|
|
|
|
{
|
|
|
|
struct fs_mount *mount = descriptor->u.mount;
|
|
|
|
|
|
|
|
FUNCTION(("query_close(descriptor = %p)\n", descriptor));
|
|
|
|
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
if (HAS_FS_MOUNT_CALL(mount, close_query))
|
|
|
|
return FS_MOUNT_CALL(mount, close_query, descriptor->cookie);
|
2004-12-12 23:39:45 +03:00
|
|
|
|
|
|
|
return B_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
query_free_fd(struct file_descriptor *descriptor)
|
|
|
|
{
|
|
|
|
struct fs_mount *mount = descriptor->u.mount;
|
|
|
|
|
|
|
|
if (mount != NULL) {
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
FS_MOUNT_CALL(mount, free_query_cookie, descriptor->cookie);
|
2004-12-12 23:39:45 +03:00
|
|
|
// ToDo: find a replacement ref_count object - perhaps the root dir?
|
|
|
|
//put_vnode(vnode);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-03-04 19:59:59 +03:00
|
|
|
static status_t
|
2008-03-30 09:59:54 +04:00
|
|
|
query_read(struct io_context *ioContext, struct file_descriptor *descriptor,
|
|
|
|
struct dirent *buffer, size_t bufferSize, uint32 *_count)
|
2004-12-12 23:39:45 +03:00
|
|
|
{
|
|
|
|
struct fs_mount *mount = descriptor->u.mount;
|
|
|
|
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
if (HAS_FS_MOUNT_CALL(mount, read_query)) {
|
|
|
|
return FS_MOUNT_CALL(mount, read_query, descriptor->cookie, buffer,
|
|
|
|
bufferSize, _count);
|
|
|
|
}
|
2004-12-12 23:39:45 +03:00
|
|
|
|
|
|
|
return EOPNOTSUPP;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-03-04 19:59:59 +03:00
|
|
|
static status_t
|
2004-12-12 23:39:45 +03:00
|
|
|
query_rewind(struct file_descriptor *descriptor)
|
|
|
|
{
|
|
|
|
struct fs_mount *mount = descriptor->u.mount;
|
|
|
|
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
if (HAS_FS_MOUNT_CALL(mount, rewind_query))
|
|
|
|
return FS_MOUNT_CALL(mount, rewind_query, descriptor->cookie);
|
2004-12-12 23:39:45 +03:00
|
|
|
|
|
|
|
return EOPNOTSUPP;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-05-28 18:17:18 +04:00
|
|
|
// #pragma mark - General File System functions
|
2002-07-09 16:24:59 +04:00
|
|
|
|
|
|
|
|
2005-10-17 18:01:04 +04:00
|
|
|
static dev_t
|
2004-10-28 02:11:57 +04:00
|
|
|
fs_mount(char *path, const char *device, const char *fsName, uint32 flags,
|
2004-11-01 03:35:27 +03:00
|
|
|
const char *args, bool kernel)
|
2002-07-20 04:16:12 +04:00
|
|
|
{
|
|
|
|
struct fs_mount *mount;
|
2005-08-21 04:41:16 +04:00
|
|
|
status_t status = 0;
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2002-09-28 06:19:26 +04:00
|
|
|
FUNCTION(("fs_mount: entry. path = '%s', fs_name = '%s'\n", path, fsName));
|
2002-09-25 18:10:50 +04:00
|
|
|
|
2002-09-28 06:19:26 +04:00
|
|
|
// The path is always safe, we just have to make sure that fsName is
|
2004-10-28 02:11:57 +04:00
|
|
|
// almost valid - we can't make any assumptions about args, though.
|
2004-10-29 02:31:43 +04:00
|
|
|
// A NULL fsName is OK, if a device was given and the FS is not virtual.
|
|
|
|
// We'll get it from the DDM later.
|
|
|
|
if (fsName == NULL) {
|
|
|
|
if (!device || flags & B_MOUNT_VIRTUAL_DEVICE)
|
|
|
|
return B_BAD_VALUE;
|
|
|
|
} else if (fsName[0] == '\0')
|
2002-09-25 18:10:50 +04:00
|
|
|
return B_BAD_VALUE;
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2004-10-28 19:57:04 +04:00
|
|
|
RecursiveLocker mountOpLocker(sMountOpLock);
|
2004-10-28 02:11:57 +04:00
|
|
|
|
2004-10-29 02:31:43 +04:00
|
|
|
// Helper to delete a newly created file device on failure.
|
|
|
|
// Not exactly beautiful, but helps to keep the code below cleaner.
|
|
|
|
struct FileDeviceDeleter {
|
|
|
|
FileDeviceDeleter() : id(-1) {}
|
|
|
|
~FileDeviceDeleter()
|
|
|
|
{
|
|
|
|
KDiskDeviceManager::Default()->DeleteFileDevice(id);
|
|
|
|
}
|
|
|
|
|
|
|
|
partition_id id;
|
|
|
|
} fileDeviceDeleter;
|
|
|
|
|
2004-10-28 02:11:57 +04:00
|
|
|
// If the file system is not a "virtual" one, the device argument should
|
|
|
|
// point to a real file/device (if given at all).
|
|
|
|
// get the partition
|
2004-11-01 03:35:27 +03:00
|
|
|
KDiskDeviceManager *ddm = KDiskDeviceManager::Default();
|
|
|
|
KPartition *partition = NULL;
|
2006-05-05 15:17:08 +04:00
|
|
|
KPath normalizedDevice;
|
2004-10-29 02:31:43 +04:00
|
|
|
bool newlyCreatedFileDevice = false;
|
2006-05-05 15:17:08 +04:00
|
|
|
|
2004-10-28 02:11:57 +04:00
|
|
|
if (!(flags & B_MOUNT_VIRTUAL_DEVICE) && device) {
|
2004-10-29 02:31:43 +04:00
|
|
|
// normalize the device path
|
2005-08-21 04:41:16 +04:00
|
|
|
status = normalizedDevice.SetTo(device, true);
|
|
|
|
if (status != B_OK)
|
|
|
|
return status;
|
2004-10-29 02:31:43 +04:00
|
|
|
|
2004-10-28 02:11:57 +04:00
|
|
|
// get a corresponding partition from the DDM
|
2007-11-02 02:36:21 +03:00
|
|
|
partition = ddm->RegisterPartition(normalizedDevice.Path());
|
2004-10-29 02:31:43 +04:00
|
|
|
|
2004-10-28 02:11:57 +04:00
|
|
|
if (!partition) {
|
2004-10-29 02:31:43 +04:00
|
|
|
// Partition not found: This either means, the user supplied
|
|
|
|
// an invalid path, or the path refers to an image file. We try
|
|
|
|
// to let the DDM create a file device for the path.
|
2006-05-05 14:54:10 +04:00
|
|
|
partition_id deviceID = ddm->CreateFileDevice(normalizedDevice.Path(),
|
2007-11-02 01:41:22 +03:00
|
|
|
&newlyCreatedFileDevice);
|
2004-10-29 02:31:43 +04:00
|
|
|
if (deviceID >= 0) {
|
2007-11-02 02:36:21 +03:00
|
|
|
partition = ddm->RegisterPartition(deviceID);
|
2004-10-29 02:31:43 +04:00
|
|
|
if (newlyCreatedFileDevice)
|
|
|
|
fileDeviceDeleter.id = deviceID;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!partition) {
|
2005-12-16 20:35:03 +03:00
|
|
|
TRACE(("fs_mount(): Partition `%s' not found.\n",
|
2004-10-29 02:31:43 +04:00
|
|
|
normalizedDevice.Path()));
|
2004-10-28 02:11:57 +04:00
|
|
|
return B_ENTRY_NOT_FOUND;
|
|
|
|
}
|
2006-05-05 15:17:08 +04:00
|
|
|
|
|
|
|
device = normalizedDevice.Path();
|
|
|
|
// correct path to file device
|
2004-10-28 02:11:57 +04:00
|
|
|
}
|
|
|
|
PartitionRegistrar partitionRegistrar(partition, true);
|
|
|
|
|
|
|
|
// Write lock the partition's device. For the time being, we keep the lock
|
|
|
|
// until we're done mounting -- not nice, but ensure, that no-one is
|
|
|
|
// interfering.
|
|
|
|
// TODO: Find a better solution.
|
2004-11-01 03:35:27 +03:00
|
|
|
KDiskDevice *diskDevice = NULL;
|
2004-10-28 02:11:57 +04:00
|
|
|
if (partition) {
|
|
|
|
diskDevice = ddm->WriteLockDevice(partition->Device()->ID());
|
|
|
|
if (!diskDevice) {
|
2005-12-16 20:35:03 +03:00
|
|
|
TRACE(("fs_mount(): Failed to lock disk device!\n"));
|
2004-10-28 02:11:57 +04:00
|
|
|
return B_ERROR;
|
|
|
|
}
|
|
|
|
}
|
2006-05-05 14:54:10 +04:00
|
|
|
|
2004-10-28 02:11:57 +04:00
|
|
|
DeviceWriteLocker writeLocker(diskDevice, true);
|
2006-05-05 14:54:10 +04:00
|
|
|
// this takes over the write lock acquired before
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2004-10-28 02:11:57 +04:00
|
|
|
if (partition) {
|
2004-10-29 02:31:43 +04:00
|
|
|
// make sure, that the partition is not busy
|
2007-11-02 03:29:46 +03:00
|
|
|
if (partition->IsBusy()) {
|
2005-12-16 20:35:03 +03:00
|
|
|
TRACE(("fs_mount(): Partition is busy.\n"));
|
2004-10-28 02:11:57 +04:00
|
|
|
return B_BUSY;
|
|
|
|
}
|
2004-10-29 02:31:43 +04:00
|
|
|
|
|
|
|
// if no FS name had been supplied, we get it from the partition
|
|
|
|
if (!fsName) {
|
|
|
|
KDiskSystem *diskSystem = partition->DiskSystem();
|
|
|
|
if (!diskSystem) {
|
2005-12-16 20:35:03 +03:00
|
|
|
TRACE(("fs_mount(): No FS name was given, and the DDM didn't "
|
2004-10-29 02:31:43 +04:00
|
|
|
"recognize it.\n"));
|
|
|
|
return B_BAD_VALUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!diskSystem->IsFileSystem()) {
|
2005-12-16 20:35:03 +03:00
|
|
|
TRACE(("fs_mount(): No FS name was given, and the DDM found a "
|
2004-10-29 02:31:43 +04:00
|
|
|
"partitioning system.\n"));
|
|
|
|
return B_BAD_VALUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
// The disk system name will not change, and the KDiskSystem
|
|
|
|
// object will not go away while the disk device is locked (and
|
|
|
|
// the partition has a reference to it), so this is safe.
|
|
|
|
fsName = diskSystem->Name();
|
|
|
|
}
|
2002-07-20 04:16:12 +04:00
|
|
|
}
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2004-10-28 02:11:57 +04:00
|
|
|
mount = (struct fs_mount *)malloc(sizeof(struct fs_mount));
|
|
|
|
if (mount == NULL)
|
|
|
|
return B_NO_MEMORY;
|
|
|
|
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
mount->volume = (fs_volume*)malloc(sizeof(fs_volume));
|
|
|
|
if (mount->volume == NULL) {
|
|
|
|
free(mount);
|
|
|
|
return B_NO_MEMORY;
|
|
|
|
}
|
|
|
|
|
2003-01-18 17:13:44 +03:00
|
|
|
list_init_etc(&mount->vnodes, offsetof(struct vnode, mount_link));
|
2002-09-05 15:18:38 +04:00
|
|
|
|
2005-05-23 22:22:04 +04:00
|
|
|
mount->fs_name = get_file_system_name(fsName);
|
2004-08-13 08:20:06 +04:00
|
|
|
if (mount->fs_name == NULL) {
|
2005-08-21 04:41:16 +04:00
|
|
|
status = B_NO_MEMORY;
|
2004-10-05 20:08:31 +04:00
|
|
|
goto err1;
|
2004-08-13 08:20:06 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
mount->device_name = strdup(device);
|
|
|
|
// "device" can be NULL
|
|
|
|
|
2002-09-25 18:10:50 +04:00
|
|
|
mount->fs = get_file_system(fsName);
|
2002-07-20 04:16:12 +04:00
|
|
|
if (mount->fs == NULL) {
|
2005-08-21 04:41:16 +04:00
|
|
|
status = ENODEV;
|
2004-08-13 08:20:06 +04:00
|
|
|
goto err3;
|
2002-07-20 04:16:12 +04:00
|
|
|
}
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2005-08-21 04:41:16 +04:00
|
|
|
status = recursive_lock_init(&mount->rlock, "mount rlock");
|
|
|
|
if (status < B_OK)
|
2004-08-13 08:20:06 +04:00
|
|
|
goto err4;
|
2004-06-08 10:43:46 +04:00
|
|
|
|
2005-09-22 21:45:43 +04:00
|
|
|
// initialize structure
|
2003-10-17 18:47:15 +04:00
|
|
|
mount->id = sNextMountID++;
|
2004-10-28 02:11:57 +04:00
|
|
|
mount->partition = NULL;
|
2005-09-22 21:45:43 +04:00
|
|
|
mount->root_vnode = NULL;
|
|
|
|
mount->covers_vnode = NULL;
|
2004-10-29 02:31:43 +04:00
|
|
|
mount->unmounting = false;
|
|
|
|
mount->owns_file_device = false;
|
2002-07-14 09:13:20 +04:00
|
|
|
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
mount->volume->id = mount->id;
|
|
|
|
mount->volume->layer = 0;
|
|
|
|
mount->volume->private_volume = NULL;
|
|
|
|
mount->volume->ops = NULL;
|
|
|
|
mount->volume->sub_volume = NULL;
|
|
|
|
mount->volume->super_volume = NULL;
|
|
|
|
|
2005-09-22 21:45:43 +04:00
|
|
|
// insert mount struct into list before we call FS's mount() function
|
|
|
|
// so that vnodes can be created for this mount
|
2005-08-21 04:41:16 +04:00
|
|
|
mutex_lock(&sMountMutex);
|
2004-06-08 10:43:46 +04:00
|
|
|
hash_insert(sMountsTable, mount);
|
|
|
|
mutex_unlock(&sMountMutex);
|
|
|
|
|
2007-06-21 23:50:57 +04:00
|
|
|
ino_t rootID;
|
2005-08-21 04:41:16 +04:00
|
|
|
|
2003-10-17 18:47:15 +04:00
|
|
|
if (!sRoot) {
|
2002-07-20 04:16:12 +04:00
|
|
|
// we haven't mounted anything yet
|
|
|
|
if (strcmp(path, "/") != 0) {
|
2005-08-21 04:41:16 +04:00
|
|
|
status = B_ERROR;
|
2004-08-13 08:20:06 +04:00
|
|
|
goto err5;
|
2002-07-20 04:16:12 +04:00
|
|
|
}
|
2002-07-14 09:13:20 +04:00
|
|
|
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
status = mount->fs->mount(mount->volume, device, flags, args, &rootID);
|
2005-08-21 04:41:16 +04:00
|
|
|
if (status < 0) {
|
2003-02-21 16:49:26 +03:00
|
|
|
// ToDo: why should we hide the error code from the file system here?
|
2005-08-21 04:41:16 +04:00
|
|
|
//status = ERR_VFS_GENERAL;
|
2004-08-13 08:20:06 +04:00
|
|
|
goto err5;
|
2002-07-20 04:16:12 +04:00
|
|
|
}
|
|
|
|
} else {
|
2005-08-21 04:41:16 +04:00
|
|
|
struct vnode *coveredVnode;
|
|
|
|
status = path_to_vnode(path, true, &coveredVnode, NULL, kernel);
|
|
|
|
if (status < B_OK)
|
2004-08-13 08:20:06 +04:00
|
|
|
goto err5;
|
2002-07-14 09:13:20 +04:00
|
|
|
|
2004-09-17 16:29:27 +04:00
|
|
|
// make sure covered_vnode is a DIR
|
|
|
|
struct stat coveredNodeStat;
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
status = FS_CALL(coveredVnode, read_stat, &coveredNodeStat);
|
2005-08-21 04:41:16 +04:00
|
|
|
if (status < B_OK)
|
2004-09-17 16:29:27 +04:00
|
|
|
goto err5;
|
|
|
|
|
|
|
|
if (!S_ISDIR(coveredNodeStat.st_mode)) {
|
2005-08-21 04:41:16 +04:00
|
|
|
status = B_NOT_A_DIRECTORY;
|
2004-09-17 16:29:27 +04:00
|
|
|
goto err5;
|
|
|
|
}
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2005-08-21 04:41:16 +04:00
|
|
|
if (coveredVnode->mount->root_vnode == coveredVnode) {
|
|
|
|
// this is already a mount point
|
|
|
|
status = B_BUSY;
|
2004-08-13 08:20:06 +04:00
|
|
|
goto err5;
|
2002-07-20 04:16:12 +04:00
|
|
|
}
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2005-08-21 04:41:16 +04:00
|
|
|
mount->covers_vnode = coveredVnode;
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2002-07-20 04:16:12 +04:00
|
|
|
// mount it
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
status = mount->fs->mount(mount->volume, device, flags, args, &rootID);
|
2005-08-21 04:41:16 +04:00
|
|
|
if (status < B_OK)
|
2004-08-13 08:20:06 +04:00
|
|
|
goto err6;
|
2002-07-20 04:16:12 +04:00
|
|
|
}
|
2002-07-14 09:13:20 +04:00
|
|
|
|
2005-08-21 04:41:16 +04:00
|
|
|
// the root node is supposed to be owned by the file system - it must
|
|
|
|
// exist at this point
|
|
|
|
mount->root_vnode = lookup_vnode(mount->id, rootID);
|
|
|
|
if (mount->root_vnode == NULL || mount->root_vnode->ref_count != 1) {
|
|
|
|
panic("fs_mount: file system does not own its root node!\n");
|
|
|
|
status = B_ERROR;
|
2004-08-13 08:20:06 +04:00
|
|
|
goto err7;
|
2005-08-21 04:41:16 +04:00
|
|
|
}
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2004-09-13 18:53:09 +04:00
|
|
|
// No race here, since fs_mount() is the only function changing
|
2004-09-17 16:29:27 +04:00
|
|
|
// covers_vnode (and holds sMountOpLock at that time).
|
2007-03-03 05:42:36 +03:00
|
|
|
mutex_lock(&sVnodeCoveredByMutex);
|
2002-07-20 04:16:12 +04:00
|
|
|
if (mount->covers_vnode)
|
|
|
|
mount->covers_vnode->covered_by = mount->root_vnode;
|
2007-03-03 05:42:36 +03:00
|
|
|
mutex_unlock(&sVnodeCoveredByMutex);
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2008-03-30 09:59:54 +04:00
|
|
|
if (!sRoot) {
|
2003-10-17 18:47:15 +04:00
|
|
|
sRoot = mount->root_vnode;
|
2008-03-30 09:59:54 +04:00
|
|
|
benaphore_lock(&sIOContextRootLock);
|
|
|
|
get_current_io_context(true)->root = sRoot;
|
|
|
|
benaphore_unlock(&sIOContextRootLock);
|
|
|
|
inc_vnode_ref_count(sRoot);
|
|
|
|
}
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2004-10-28 02:11:57 +04:00
|
|
|
// supply the partition (if any) with the mount cookie and mark it mounted
|
|
|
|
if (partition) {
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
partition->SetMountCookie(mount->volume->private_volume);
|
2005-05-03 05:59:17 +04:00
|
|
|
partition->SetVolumeID(mount->id);
|
2004-10-28 02:11:57 +04:00
|
|
|
|
|
|
|
// keep a partition reference as long as the partition is mounted
|
|
|
|
partitionRegistrar.Detach();
|
|
|
|
mount->partition = partition;
|
2004-10-29 02:31:43 +04:00
|
|
|
mount->owns_file_device = newlyCreatedFileDevice;
|
|
|
|
fileDeviceDeleter.id = -1;
|
2004-10-28 02:11:57 +04:00
|
|
|
}
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2006-03-03 14:48:49 +03:00
|
|
|
notify_mount(mount->id, mount->covers_vnode ? mount->covers_vnode->device : -1,
|
|
|
|
mount->covers_vnode ? mount->covers_vnode->id : -1);
|
|
|
|
|
2005-10-17 18:01:04 +04:00
|
|
|
return mount->id;
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2004-08-13 08:20:06 +04:00
|
|
|
err7:
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
FS_MOUNT_CALL_NO_PARAMS(mount, unmount);
|
2004-08-13 08:20:06 +04:00
|
|
|
err6:
|
2002-07-20 04:16:12 +04:00
|
|
|
if (mount->covers_vnode)
|
2002-09-25 18:10:50 +04:00
|
|
|
put_vnode(mount->covers_vnode);
|
2004-08-13 08:20:06 +04:00
|
|
|
err5:
|
2004-06-08 10:43:46 +04:00
|
|
|
mutex_lock(&sMountMutex);
|
|
|
|
hash_remove(sMountsTable, mount);
|
|
|
|
mutex_unlock(&sMountMutex);
|
|
|
|
|
2002-07-20 04:16:12 +04:00
|
|
|
recursive_lock_destroy(&mount->rlock);
|
2004-08-13 08:20:06 +04:00
|
|
|
err4:
|
2002-09-25 18:10:50 +04:00
|
|
|
put_file_system(mount->fs);
|
2004-08-13 08:20:06 +04:00
|
|
|
free(mount->device_name);
|
|
|
|
err3:
|
|
|
|
free(mount->fs_name);
|
2002-07-20 04:16:12 +04:00
|
|
|
err1:
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
free(mount->volume);
|
2002-10-30 02:07:06 +03:00
|
|
|
free(mount);
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2005-08-21 04:41:16 +04:00
|
|
|
return status;
|
2002-07-09 16:24:59 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2002-10-08 07:24:51 +04:00
|
|
|
static status_t
|
2007-11-12 23:54:17 +03:00
|
|
|
fs_unmount(char *path, dev_t mountID, uint32 flags, bool kernel)
|
2002-07-09 16:24:59 +04:00
|
|
|
{
|
2007-11-13 18:19:21 +03:00
|
|
|
struct vnode *vnode = NULL;
|
2002-07-20 04:16:12 +04:00
|
|
|
struct fs_mount *mount;
|
2004-11-30 01:45:27 +03:00
|
|
|
status_t err;
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2007-11-13 18:19:21 +03:00
|
|
|
FUNCTION(("fs_unmount(path '%s', dev %ld, kernel %d\n", path, mountID,
|
|
|
|
kernel));
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2007-11-12 23:54:17 +03:00
|
|
|
if (path != NULL) {
|
|
|
|
err = path_to_vnode(path, true, &vnode, NULL, kernel);
|
|
|
|
if (err != B_OK)
|
|
|
|
return B_ENTRY_NOT_FOUND;
|
|
|
|
}
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2004-10-28 19:57:04 +04:00
|
|
|
RecursiveLocker mountOpLocker(sMountOpLock);
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2007-11-13 18:19:21 +03:00
|
|
|
mount = find_mount(path != NULL ? vnode->device : mountID);
|
|
|
|
if (mount == NULL) {
|
|
|
|
panic("fs_unmount: find_mount() failed on root vnode @%p of mount\n",
|
|
|
|
vnode);
|
|
|
|
}
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2007-11-12 23:54:17 +03:00
|
|
|
if (path != NULL) {
|
2002-09-25 18:10:50 +04:00
|
|
|
put_vnode(vnode);
|
2007-11-12 23:54:17 +03:00
|
|
|
|
|
|
|
if (mount->root_vnode != vnode) {
|
|
|
|
// not mountpoint
|
|
|
|
return B_BAD_VALUE;
|
|
|
|
}
|
2004-10-28 02:11:57 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
// if the volume is associated with a partition, lock the device of the
|
|
|
|
// partition as long as we are unmounting
|
|
|
|
KDiskDeviceManager* ddm = KDiskDeviceManager::Default();
|
|
|
|
KPartition *partition = mount->partition;
|
|
|
|
KDiskDevice *diskDevice = NULL;
|
|
|
|
if (partition) {
|
2007-11-13 18:19:21 +03:00
|
|
|
if (partition->Device() == NULL) {
|
|
|
|
dprintf("fs_unmount(): There is no device!\n");
|
|
|
|
return B_ERROR;
|
|
|
|
}
|
2004-10-28 02:11:57 +04:00
|
|
|
diskDevice = ddm->WriteLockDevice(partition->Device()->ID());
|
|
|
|
if (!diskDevice) {
|
2005-12-16 20:35:03 +03:00
|
|
|
TRACE(("fs_unmount(): Failed to lock disk device!\n"));
|
2004-10-28 02:11:57 +04:00
|
|
|
return B_ERROR;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
DeviceWriteLocker writeLocker(diskDevice, true);
|
|
|
|
|
|
|
|
// make sure, that the partition is not busy
|
|
|
|
if (partition) {
|
2007-11-12 23:54:17 +03:00
|
|
|
if ((flags & B_UNMOUNT_BUSY_PARTITION) == 0 && partition->IsBusy()) {
|
2005-12-16 20:35:03 +03:00
|
|
|
TRACE(("fs_unmount(): Partition is busy.\n"));
|
2004-10-28 02:11:57 +04:00
|
|
|
return B_BUSY;
|
|
|
|
}
|
2002-07-20 04:16:12 +04:00
|
|
|
}
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2004-11-30 01:45:27 +03:00
|
|
|
// grab the vnode master mutex to keep someone from creating
|
|
|
|
// a vnode while we're figuring out if we can continue
|
2003-10-17 18:47:15 +04:00
|
|
|
mutex_lock(&sVnodeMutex);
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2006-01-15 22:26:42 +03:00
|
|
|
bool disconnectedDescriptors = false;
|
|
|
|
|
|
|
|
while (true) {
|
|
|
|
bool busy = false;
|
|
|
|
|
|
|
|
// cycle through the list of vnodes associated with this mount and
|
|
|
|
// make sure all of them are not busy or have refs on them
|
|
|
|
vnode = NULL;
|
2007-11-13 18:19:21 +03:00
|
|
|
while ((vnode = (struct vnode *)list_get_next_item(&mount->vnodes,
|
|
|
|
vnode)) != NULL) {
|
2007-11-12 23:54:17 +03:00
|
|
|
// The root vnode ref_count needs to be 1 here (the mount has a
|
|
|
|
// reference).
|
2006-03-09 01:57:53 +03:00
|
|
|
if (vnode->busy
|
|
|
|
|| ((vnode->ref_count != 0 && mount->root_vnode != vnode)
|
2007-11-12 23:54:17 +03:00
|
|
|
|| (vnode->ref_count != 1 && mount->root_vnode == vnode))) {
|
2006-01-15 22:26:42 +03:00
|
|
|
// there are still vnodes in use on this mount, so we cannot
|
|
|
|
// unmount yet
|
|
|
|
busy = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!busy)
|
|
|
|
break;
|
|
|
|
|
|
|
|
if ((flags & B_FORCE_UNMOUNT) == 0) {
|
2003-10-17 18:47:15 +04:00
|
|
|
mutex_unlock(&sVnodeMutex);
|
2002-09-25 18:10:50 +04:00
|
|
|
put_vnode(mount->root_vnode);
|
2002-07-28 22:41:07 +04:00
|
|
|
|
2004-11-30 01:45:27 +03:00
|
|
|
return B_BUSY;
|
2002-07-20 04:16:12 +04:00
|
|
|
}
|
2006-01-15 22:26:42 +03:00
|
|
|
|
|
|
|
if (disconnectedDescriptors) {
|
|
|
|
// wait a bit until the last access is finished, and then try again
|
|
|
|
mutex_unlock(&sVnodeMutex);
|
|
|
|
snooze(100000);
|
2006-08-31 03:12:31 +04:00
|
|
|
// TODO: if there is some kind of bug that prevents the ref counts
|
|
|
|
// from getting back to zero, this will fall into an endless loop...
|
2006-01-15 22:26:42 +03:00
|
|
|
mutex_lock(&sVnodeMutex);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
// the file system is still busy - but we're forced to unmount it,
|
|
|
|
// so let's disconnect all open file descriptors
|
|
|
|
|
|
|
|
mount->unmounting = true;
|
|
|
|
// prevent new vnodes from being created
|
|
|
|
|
|
|
|
mutex_unlock(&sVnodeMutex);
|
|
|
|
|
2006-03-28 05:13:12 +04:00
|
|
|
disconnect_mount_or_vnode_fds(mount, NULL);
|
2006-01-15 22:26:42 +03:00
|
|
|
disconnectedDescriptors = true;
|
2006-03-28 05:13:12 +04:00
|
|
|
|
2006-01-15 22:26:42 +03:00
|
|
|
mutex_lock(&sVnodeMutex);
|
2002-07-20 04:16:12 +04:00
|
|
|
}
|
2002-07-14 09:13:20 +04:00
|
|
|
|
2004-11-30 01:45:27 +03:00
|
|
|
// we can safely continue, mark all of the vnodes busy and this mount
|
|
|
|
// structure in unmounting state
|
2002-07-20 04:16:12 +04:00
|
|
|
mount->unmounting = true;
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2004-11-30 01:45:27 +03:00
|
|
|
while ((vnode = (struct vnode *)list_get_next_item(&mount->vnodes, vnode)) != NULL) {
|
|
|
|
vnode->busy = true;
|
2006-03-09 00:42:14 +03:00
|
|
|
|
|
|
|
if (vnode->ref_count == 0) {
|
|
|
|
// this vnode has been unused before
|
|
|
|
list_remove_item(&sUnusedVnodeList, vnode);
|
|
|
|
sUnusedVnodes--;
|
|
|
|
}
|
2004-11-30 01:45:27 +03:00
|
|
|
}
|
2004-01-05 04:03:14 +03:00
|
|
|
|
2007-11-12 23:54:17 +03:00
|
|
|
// The ref_count of the root node is 1 at this point, see above why this is
|
|
|
|
mount->root_vnode->ref_count--;
|
2006-03-09 01:57:53 +03:00
|
|
|
|
2003-10-17 18:47:15 +04:00
|
|
|
mutex_unlock(&sVnodeMutex);
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2007-03-03 05:42:36 +03:00
|
|
|
mutex_lock(&sVnodeCoveredByMutex);
|
2002-07-20 04:16:12 +04:00
|
|
|
mount->covers_vnode->covered_by = NULL;
|
2007-03-03 05:42:36 +03:00
|
|
|
mutex_unlock(&sVnodeCoveredByMutex);
|
2002-09-25 18:10:50 +04:00
|
|
|
put_vnode(mount->covers_vnode);
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2004-11-30 01:45:27 +03:00
|
|
|
// Free all vnodes associated with this mount.
|
|
|
|
// They will be removed from the mount list by free_vnode(), so
|
|
|
|
// we don't have to do this.
|
2007-11-13 18:19:21 +03:00
|
|
|
while ((vnode = (struct vnode *)list_get_first_item(&mount->vnodes))
|
|
|
|
!= NULL) {
|
2004-11-30 01:45:27 +03:00
|
|
|
free_vnode(vnode, false);
|
|
|
|
}
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2004-11-30 01:45:27 +03:00
|
|
|
// remove the mount structure from the hash table
|
2003-10-17 18:47:15 +04:00
|
|
|
mutex_lock(&sMountMutex);
|
|
|
|
hash_remove(sMountsTable, mount);
|
|
|
|
mutex_unlock(&sMountMutex);
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2004-10-28 02:11:57 +04:00
|
|
|
mountOpLocker.Unlock();
|
2002-07-09 16:24:59 +04:00
|
|
|
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
FS_MOUNT_CALL_NO_PARAMS(mount, unmount);
|
2006-03-03 14:48:49 +03:00
|
|
|
notify_unmount(mount->id);
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2002-09-25 18:10:50 +04:00
|
|
|
// release the file system
|
|
|
|
put_file_system(mount->fs);
|
|
|
|
|
2005-08-21 17:45:15 +04:00
|
|
|
// dereference the partition and mark it unmounted
|
2004-10-29 02:31:43 +04:00
|
|
|
if (partition) {
|
2005-08-21 17:45:15 +04:00
|
|
|
partition->SetVolumeID(-1);
|
|
|
|
partition->SetMountCookie(NULL);
|
|
|
|
|
2004-10-29 02:31:43 +04:00
|
|
|
if (mount->owns_file_device)
|
|
|
|
KDiskDeviceManager::Default()->DeleteFileDevice(partition->ID());
|
|
|
|
partition->Unregister();
|
|
|
|
}
|
|
|
|
|
2004-08-13 08:20:06 +04:00
|
|
|
free(mount->device_name);
|
|
|
|
free(mount->fs_name);
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
free(mount->volume);
|
2002-10-30 02:07:06 +03:00
|
|
|
free(mount);
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2005-01-15 03:38:16 +03:00
|
|
|
return B_OK;
|
2002-07-09 16:24:59 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2002-10-08 07:24:51 +04:00
|
|
|
static status_t
|
2005-01-15 03:38:16 +03:00
|
|
|
fs_sync(dev_t device)
|
2002-07-09 16:24:59 +04:00
|
|
|
{
|
2002-07-20 04:16:12 +04:00
|
|
|
struct fs_mount *mount;
|
2005-09-22 21:45:43 +04:00
|
|
|
status_t status = get_mount(device, &mount);
|
|
|
|
if (status < B_OK)
|
|
|
|
return status;
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2008-01-21 13:28:32 +03:00
|
|
|
// First, synchronize all file caches
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2006-04-11 01:22:24 +04:00
|
|
|
struct vnode *previousVnode = NULL;
|
|
|
|
while (true) {
|
|
|
|
// synchronize access to vnode list
|
|
|
|
recursive_lock_lock(&mount->rlock);
|
|
|
|
|
2008-01-21 13:28:32 +03:00
|
|
|
struct vnode *vnode = previousVnode;
|
|
|
|
do {
|
|
|
|
// TODO: we could track writes (and writable mapped vnodes)
|
|
|
|
// and have a simple flag that we could test for here
|
|
|
|
vnode = (struct vnode *)list_get_next_item(&mount->vnodes, vnode);
|
|
|
|
} while (vnode != NULL && vnode->cache == NULL);
|
2006-04-11 01:22:24 +04:00
|
|
|
|
2007-06-21 23:50:57 +04:00
|
|
|
ino_t id = -1;
|
2006-04-11 01:22:24 +04:00
|
|
|
if (vnode != NULL)
|
|
|
|
id = vnode->id;
|
|
|
|
|
|
|
|
recursive_lock_unlock(&mount->rlock);
|
|
|
|
|
|
|
|
if (vnode == NULL)
|
|
|
|
break;
|
|
|
|
|
|
|
|
// acquire a reference to the vnode
|
|
|
|
|
2007-10-08 20:06:32 +04:00
|
|
|
if (get_vnode(mount->id, id, &vnode, true, false) == B_OK) {
|
2006-04-11 01:22:24 +04:00
|
|
|
if (previousVnode != NULL)
|
|
|
|
put_vnode(previousVnode);
|
|
|
|
|
2008-01-21 13:28:32 +03:00
|
|
|
if (vnode->cache != NULL)
|
|
|
|
vm_cache_write_modified(vnode->cache, false);
|
2006-04-11 01:22:24 +04:00
|
|
|
|
|
|
|
// the next vnode might change until we lock the vnode list again,
|
|
|
|
// but this vnode won't go away since we keep a reference to it.
|
|
|
|
previousVnode = vnode;
|
2006-04-18 18:50:36 +04:00
|
|
|
} else {
|
2008-01-21 13:28:32 +03:00
|
|
|
dprintf("syncing of mount %ld stopped due to vnode %Ld.\n",
|
|
|
|
mount->id, id);
|
2006-04-18 18:50:36 +04:00
|
|
|
break;
|
2006-04-11 01:22:24 +04:00
|
|
|
}
|
2005-01-15 03:38:16 +03:00
|
|
|
}
|
|
|
|
|
2006-04-11 01:22:24 +04:00
|
|
|
if (previousVnode != NULL)
|
|
|
|
put_vnode(previousVnode);
|
|
|
|
|
2008-01-21 13:28:32 +03:00
|
|
|
// And then, let the file systems do their synchronizing work
|
|
|
|
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
if (HAS_FS_MOUNT_CALL(mount, sync))
|
|
|
|
status = FS_MOUNT_CALL_NO_PARAMS(mount, sync);
|
2008-01-21 13:28:32 +03:00
|
|
|
|
2005-01-15 03:38:16 +03:00
|
|
|
put_mount(mount);
|
|
|
|
return status;
|
2002-07-09 16:24:59 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2002-10-08 07:24:51 +04:00
|
|
|
static status_t
|
2002-07-23 18:10:12 +04:00
|
|
|
fs_read_info(dev_t device, struct fs_info *info)
|
|
|
|
{
|
|
|
|
struct fs_mount *mount;
|
2005-09-22 21:45:43 +04:00
|
|
|
status_t status = get_mount(device, &mount);
|
|
|
|
if (status < B_OK)
|
|
|
|
return status;
|
2002-07-23 18:10:12 +04:00
|
|
|
|
2004-08-31 07:41:29 +04:00
|
|
|
memset(info, 0, sizeof(struct fs_info));
|
2004-08-13 08:20:06 +04:00
|
|
|
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
if (HAS_FS_MOUNT_CALL(mount, read_fs_info))
|
|
|
|
status = FS_MOUNT_CALL(mount, read_fs_info, info);
|
2004-08-31 07:41:29 +04:00
|
|
|
|
2007-03-01 05:55:41 +03:00
|
|
|
// fill in info the file system doesn't (have to) know about
|
|
|
|
if (status == B_OK) {
|
|
|
|
info->dev = mount->id;
|
|
|
|
info->root = mount->root_vnode->id;
|
|
|
|
strlcpy(info->fsh_name, mount->fs_name, sizeof(info->fsh_name));
|
|
|
|
if (mount->device_name != NULL) {
|
|
|
|
strlcpy(info->device_name, mount->device_name,
|
|
|
|
sizeof(info->device_name));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2004-08-31 07:41:29 +04:00
|
|
|
// if the call is not supported by the file system, there are still
|
|
|
|
// the parts that we filled out ourselves
|
2002-07-23 18:10:12 +04:00
|
|
|
|
2004-12-12 23:39:45 +03:00
|
|
|
put_mount(mount);
|
2002-07-23 18:10:12 +04:00
|
|
|
return status;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2002-10-08 07:24:51 +04:00
|
|
|
static status_t
|
2002-07-28 22:41:07 +04:00
|
|
|
fs_write_info(dev_t device, const struct fs_info *info, int mask)
|
2002-07-23 18:10:12 +04:00
|
|
|
{
|
|
|
|
struct fs_mount *mount;
|
2005-09-22 21:45:43 +04:00
|
|
|
status_t status = get_mount(device, &mount);
|
|
|
|
if (status < B_OK)
|
|
|
|
return status;
|
2002-07-23 18:10:12 +04:00
|
|
|
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
if (HAS_FS_MOUNT_CALL(mount, write_fs_info))
|
|
|
|
status = FS_MOUNT_CALL(mount, write_fs_info, info, mask);
|
2002-07-23 18:10:12 +04:00
|
|
|
else
|
|
|
|
status = EROFS;
|
|
|
|
|
2004-12-12 23:39:45 +03:00
|
|
|
put_mount(mount);
|
2002-07-23 18:10:12 +04:00
|
|
|
return status;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-07-07 20:12:46 +04:00
|
|
|
static dev_t
|
|
|
|
fs_next_device(int32 *_cookie)
|
|
|
|
{
|
|
|
|
struct fs_mount *mount = NULL;
|
|
|
|
dev_t device = *_cookie;
|
|
|
|
|
2008-03-04 19:59:59 +03:00
|
|
|
mutex_lock(&sMountMutex);
|
2004-07-07 20:12:46 +04:00
|
|
|
|
|
|
|
// Since device IDs are assigned sequentially, this algorithm
|
|
|
|
// does work good enough. It makes sure that the device list
|
|
|
|
// returned is sorted, and that no device is skipped when an
|
|
|
|
// already visited device got unmounted.
|
|
|
|
|
|
|
|
while (device < sNextMountID) {
|
|
|
|
mount = find_mount(device++);
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
if (mount != NULL && mount->volume->private_volume != NULL)
|
2004-07-07 20:12:46 +04:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
*_cookie = device;
|
|
|
|
|
|
|
|
if (mount != NULL)
|
|
|
|
device = mount->id;
|
|
|
|
else
|
|
|
|
device = B_BAD_VALUE;
|
|
|
|
|
|
|
|
mutex_unlock(&sMountMutex);
|
2008-03-04 19:59:59 +03:00
|
|
|
|
2004-07-07 20:12:46 +04:00
|
|
|
return device;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2002-10-08 07:24:51 +04:00
|
|
|
static status_t
|
2002-07-20 04:16:12 +04:00
|
|
|
get_cwd(char *buffer, size_t size, bool kernel)
|
2002-07-09 16:24:59 +04:00
|
|
|
{
|
2002-07-20 04:16:12 +04:00
|
|
|
// Get current working directory from io context
|
|
|
|
struct io_context *context = get_current_io_context(kernel);
|
2005-08-09 20:25:01 +04:00
|
|
|
status_t status;
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2002-07-20 04:16:12 +04:00
|
|
|
FUNCTION(("vfs_get_cwd: buf %p, size %ld\n", buffer, size));
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2002-07-20 04:16:12 +04:00
|
|
|
mutex_lock(&context->io_mutex);
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2008-03-30 09:59:54 +04:00
|
|
|
struct vnode* vnode = context->cwd;
|
|
|
|
if (vnode)
|
|
|
|
inc_vnode_ref_count(vnode);
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2002-07-20 04:16:12 +04:00
|
|
|
mutex_unlock(&context->io_mutex);
|
2008-03-30 09:59:54 +04:00
|
|
|
|
|
|
|
if (vnode) {
|
|
|
|
status = dir_vnode_to_path(vnode, buffer, size, kernel);
|
|
|
|
put_vnode(vnode);
|
|
|
|
} else
|
|
|
|
status = B_ERROR;
|
|
|
|
|
2008-03-04 19:59:59 +03:00
|
|
|
return status;
|
2002-07-20 04:16:12 +04:00
|
|
|
}
|
2002-07-09 16:24:59 +04:00
|
|
|
|
|
|
|
|
2002-10-08 07:24:51 +04:00
|
|
|
static status_t
|
2002-08-10 00:20:28 +04:00
|
|
|
set_cwd(int fd, char *path, bool kernel)
|
2002-07-20 04:16:12 +04:00
|
|
|
{
|
|
|
|
struct io_context *context;
|
|
|
|
struct vnode *vnode = NULL;
|
|
|
|
struct vnode *oldDirectory;
|
|
|
|
struct stat stat;
|
2005-08-09 20:25:01 +04:00
|
|
|
status_t status;
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2002-08-03 06:03:27 +04:00
|
|
|
FUNCTION(("set_cwd: path = \'%s\'\n", path));
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2002-07-20 04:16:12 +04:00
|
|
|
// Get vnode for passed path, and bail if it failed
|
2005-08-09 20:25:01 +04:00
|
|
|
status = fd_and_path_to_vnode(fd, path, true, &vnode, NULL, kernel);
|
|
|
|
if (status < 0)
|
|
|
|
return status;
|
2002-07-09 16:24:59 +04:00
|
|
|
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
status = FS_CALL(vnode, read_stat, &stat);
|
2005-08-09 20:25:01 +04:00
|
|
|
if (status < 0)
|
2002-07-20 04:16:12 +04:00
|
|
|
goto err;
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2002-07-20 04:16:12 +04:00
|
|
|
if (!S_ISDIR(stat.st_mode)) {
|
|
|
|
// nope, can't cwd to here
|
2005-08-09 20:25:01 +04:00
|
|
|
status = B_NOT_A_DIRECTORY;
|
2002-07-20 04:16:12 +04:00
|
|
|
goto err;
|
|
|
|
}
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2002-07-20 04:16:12 +04:00
|
|
|
// Get current io context and lock
|
|
|
|
context = get_current_io_context(kernel);
|
|
|
|
mutex_lock(&context->io_mutex);
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2002-07-20 04:16:12 +04:00
|
|
|
// save the old current working directory first
|
|
|
|
oldDirectory = context->cwd;
|
|
|
|
context->cwd = vnode;
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2002-07-20 04:16:12 +04:00
|
|
|
mutex_unlock(&context->io_mutex);
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2002-07-20 04:16:12 +04:00
|
|
|
if (oldDirectory)
|
|
|
|
put_vnode(oldDirectory);
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2002-07-20 04:16:12 +04:00
|
|
|
return B_NO_ERROR;
|
|
|
|
|
|
|
|
err:
|
|
|
|
put_vnode(vnode);
|
2005-08-09 20:25:01 +04:00
|
|
|
return status;
|
2002-07-09 16:24:59 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-05-28 18:17:18 +04:00
|
|
|
// #pragma mark - kernel mirrored syscalls
|
2002-07-09 16:24:59 +04:00
|
|
|
|
|
|
|
|
2005-10-17 18:01:04 +04:00
|
|
|
dev_t
|
2005-05-23 22:22:04 +04:00
|
|
|
_kern_mount(const char *path, const char *device, const char *fsName,
|
2006-02-20 21:04:27 +03:00
|
|
|
uint32 flags, const char *args, size_t argsLength)
|
2002-07-09 16:24:59 +04:00
|
|
|
{
|
2005-05-12 05:14:01 +04:00
|
|
|
KPath pathBuffer(path, false, B_PATH_NAME_LENGTH + 1);
|
2005-05-13 03:31:04 +04:00
|
|
|
if (pathBuffer.InitCheck() != B_OK)
|
|
|
|
return B_NO_MEMORY;
|
2002-07-14 09:13:20 +04:00
|
|
|
|
2005-05-23 22:22:04 +04:00
|
|
|
return fs_mount(pathBuffer.LockBuffer(), device, fsName, flags, args, true);
|
2002-07-14 09:13:20 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-06-15 19:35:10 +04:00
|
|
|
status_t
|
2004-11-30 01:45:27 +03:00
|
|
|
_kern_unmount(const char *path, uint32 flags)
|
2002-07-14 09:13:20 +04:00
|
|
|
{
|
2005-05-12 05:14:01 +04:00
|
|
|
KPath pathBuffer(path, false, B_PATH_NAME_LENGTH + 1);
|
2005-05-13 03:31:04 +04:00
|
|
|
if (pathBuffer.InitCheck() != B_OK)
|
|
|
|
return B_NO_MEMORY;
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2007-11-12 23:54:17 +03:00
|
|
|
return fs_unmount(pathBuffer.LockBuffer(), -1, flags, true);
|
2002-07-09 16:24:59 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2003-09-04 08:19:24 +04:00
|
|
|
status_t
|
|
|
|
_kern_read_fs_info(dev_t device, struct fs_info *info)
|
|
|
|
{
|
|
|
|
if (info == NULL)
|
|
|
|
return B_BAD_VALUE;
|
|
|
|
|
|
|
|
return fs_read_info(device, info);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
status_t
|
|
|
|
_kern_write_fs_info(dev_t device, const struct fs_info *info, int mask)
|
|
|
|
{
|
|
|
|
if (info == NULL)
|
|
|
|
return B_BAD_VALUE;
|
|
|
|
|
|
|
|
return fs_write_info(device, info, mask);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-06-15 19:35:10 +04:00
|
|
|
status_t
|
|
|
|
_kern_sync(void)
|
2002-07-09 16:24:59 +04:00
|
|
|
{
|
2005-01-15 03:38:16 +03:00
|
|
|
// Note: _kern_sync() is also called from _user_sync()
|
|
|
|
int32 cookie = 0;
|
|
|
|
dev_t device;
|
|
|
|
while ((device = next_dev(&cookie)) >= 0) {
|
|
|
|
status_t status = fs_sync(device);
|
|
|
|
if (status != B_OK && status != B_BAD_VALUE)
|
|
|
|
dprintf("sync: device %ld couldn't sync: %s\n", device, strerror(status));
|
|
|
|
}
|
|
|
|
|
|
|
|
return B_OK;
|
2002-07-09 16:24:59 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-07-07 20:12:46 +04:00
|
|
|
dev_t
|
|
|
|
_kern_next_device(int32 *_cookie)
|
|
|
|
{
|
|
|
|
return fs_next_device(_cookie);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-01-17 04:29:18 +03:00
|
|
|
status_t
|
|
|
|
_kern_get_next_fd_info(team_id teamID, uint32 *_cookie, fd_info *info,
|
|
|
|
size_t infoSize)
|
|
|
|
{
|
|
|
|
if (infoSize != sizeof(fd_info))
|
|
|
|
return B_BAD_VALUE;
|
|
|
|
|
|
|
|
struct io_context *context = NULL;
|
|
|
|
sem_id contextMutex = -1;
|
|
|
|
struct team *team = NULL;
|
|
|
|
|
|
|
|
cpu_status state = disable_interrupts();
|
|
|
|
GRAB_TEAM_LOCK();
|
|
|
|
|
|
|
|
team = team_get_team_struct_locked(teamID);
|
|
|
|
if (team) {
|
|
|
|
context = (io_context *)team->io_context;
|
|
|
|
contextMutex = context->io_mutex.sem;
|
|
|
|
}
|
|
|
|
|
|
|
|
RELEASE_TEAM_LOCK();
|
|
|
|
restore_interrupts(state);
|
|
|
|
|
|
|
|
// we now have a context - since we couldn't lock it while having
|
|
|
|
// safe access to the team structure, we now need to lock the mutex
|
|
|
|
// manually
|
|
|
|
|
|
|
|
if (context == NULL || acquire_sem(contextMutex) != B_OK) {
|
|
|
|
// team doesn't exit or seems to be gone
|
|
|
|
return B_BAD_TEAM_ID;
|
|
|
|
}
|
|
|
|
|
|
|
|
// the team cannot be deleted completely while we're owning its
|
|
|
|
// io_context mutex, so we can safely play with it now
|
|
|
|
|
|
|
|
context->io_mutex.holder = thread_get_current_thread_id();
|
|
|
|
|
|
|
|
uint32 slot = *_cookie;
|
|
|
|
|
|
|
|
struct file_descriptor *descriptor;
|
|
|
|
while (slot < context->table_size && (descriptor = context->fds[slot]) == NULL)
|
|
|
|
slot++;
|
|
|
|
|
|
|
|
if (slot >= context->table_size) {
|
|
|
|
mutex_unlock(&context->io_mutex);
|
|
|
|
return B_ENTRY_NOT_FOUND;
|
|
|
|
}
|
|
|
|
|
|
|
|
info->number = slot;
|
|
|
|
info->open_mode = descriptor->open_mode;
|
|
|
|
|
|
|
|
struct vnode *vnode = fd_vnode(descriptor);
|
|
|
|
if (vnode != NULL) {
|
|
|
|
info->device = vnode->device;
|
|
|
|
info->node = vnode->id;
|
|
|
|
} else if (descriptor->u.mount != NULL) {
|
|
|
|
info->device = descriptor->u.mount->id;
|
|
|
|
info->node = -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
mutex_unlock(&context->io_mutex);
|
|
|
|
|
|
|
|
*_cookie = slot + 1;
|
|
|
|
return B_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2002-07-23 18:10:12 +04:00
|
|
|
int
|
2005-02-02 09:21:31 +03:00
|
|
|
_kern_open_entry_ref(dev_t device, ino_t inode, const char *name, int openMode, int perms)
|
2002-07-23 18:10:12 +04:00
|
|
|
{
|
2005-02-02 09:21:31 +03:00
|
|
|
if (openMode & O_CREAT)
|
|
|
|
return file_create_entry_ref(device, inode, name, openMode, perms, true);
|
2002-07-23 18:10:12 +04:00
|
|
|
|
2005-02-02 09:21:31 +03:00
|
|
|
return file_open_entry_ref(device, inode, name, openMode, true);
|
2002-07-23 18:10:12 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-10-06 19:33:12 +04:00
|
|
|
/*! \brief Opens a node specified by a FD + path pair.
|
2004-08-29 00:38:39 +04:00
|
|
|
|
2007-10-06 19:33:12 +04:00
|
|
|
At least one of \a fd and \a path must be specified.
|
|
|
|
If only \a fd is given, the function opens the node identified by this
|
|
|
|
FD. If only a path is given, this path is opened. If both are given and
|
|
|
|
the path is absolute, \a fd is ignored; a relative path is reckoned off
|
|
|
|
of the directory (!) identified by \a fd.
|
|
|
|
|
|
|
|
\param fd The FD. May be < 0.
|
|
|
|
\param path The absolute or relative path. May be \c NULL.
|
|
|
|
\param openMode The open mode.
|
|
|
|
\return A FD referring to the newly opened node, or an error code,
|
|
|
|
if an error occurs.
|
|
|
|
*/
|
2002-07-09 16:24:59 +04:00
|
|
|
int
|
2005-02-02 09:21:31 +03:00
|
|
|
_kern_open(int fd, const char *path, int openMode, int perms)
|
2002-07-09 16:24:59 +04:00
|
|
|
{
|
2005-05-12 05:14:01 +04:00
|
|
|
KPath pathBuffer(path, false, B_PATH_NAME_LENGTH + 1);
|
2005-05-13 03:31:04 +04:00
|
|
|
if (pathBuffer.InitCheck() != B_OK)
|
|
|
|
return B_NO_MEMORY;
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2005-02-02 09:21:31 +03:00
|
|
|
if (openMode & O_CREAT)
|
2005-07-12 20:33:10 +04:00
|
|
|
return file_create(fd, pathBuffer.LockBuffer(), openMode, perms, true);
|
2005-02-02 09:21:31 +03:00
|
|
|
|
2005-05-12 05:14:01 +04:00
|
|
|
return file_open(fd, pathBuffer.LockBuffer(), openMode, true);
|
2002-07-23 18:10:12 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-10-06 19:33:12 +04:00
|
|
|
/*! \brief Opens a directory specified by entry_ref or node_ref.
|
|
|
|
|
|
|
|
The supplied name may be \c NULL, in which case directory identified
|
|
|
|
by \a device and \a inode will be opened. Otherwise \a device and
|
|
|
|
\a inode identify the parent directory of the directory to be opened
|
|
|
|
and \a name its entry name.
|
2002-07-23 18:10:12 +04:00
|
|
|
|
2007-10-06 19:33:12 +04:00
|
|
|
\param device If \a name is specified the ID of the device the parent
|
|
|
|
directory of the directory to be opened resides on, otherwise
|
|
|
|
the device of the directory itself.
|
|
|
|
\param inode If \a name is specified the node ID of the parent
|
|
|
|
directory of the directory to be opened, otherwise node ID of the
|
|
|
|
directory itself.
|
|
|
|
\param name The entry name of the directory to be opened. If \c NULL,
|
|
|
|
the \a device + \a inode pair identify the node to be opened.
|
|
|
|
\return The FD of the newly opened directory or an error code, if
|
|
|
|
something went wrong.
|
|
|
|
*/
|
2002-07-23 18:10:12 +04:00
|
|
|
int
|
2004-06-15 19:35:10 +04:00
|
|
|
_kern_open_dir_entry_ref(dev_t device, ino_t inode, const char *name)
|
2002-07-23 18:10:12 +04:00
|
|
|
{
|
2002-08-14 00:39:25 +04:00
|
|
|
return dir_open_entry_ref(device, inode, name, true);
|
2002-07-09 16:24:59 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-10-06 19:33:12 +04:00
|
|
|
/*! \brief Opens a directory specified by a FD + path pair.
|
2004-08-29 00:38:39 +04:00
|
|
|
|
2007-10-06 19:33:12 +04:00
|
|
|
At least one of \a fd and \a path must be specified.
|
|
|
|
If only \a fd is given, the function opens the directory identified by this
|
|
|
|
FD. If only a path is given, this path is opened. If both are given and
|
|
|
|
the path is absolute, \a fd is ignored; a relative path is reckoned off
|
|
|
|
of the directory (!) identified by \a fd.
|
|
|
|
|
|
|
|
\param fd The FD. May be < 0.
|
|
|
|
\param path The absolute or relative path. May be \c NULL.
|
|
|
|
\return A FD referring to the newly opened directory, or an error code,
|
|
|
|
if an error occurs.
|
|
|
|
*/
|
2002-07-09 16:24:59 +04:00
|
|
|
int
|
2004-08-29 00:38:39 +04:00
|
|
|
_kern_open_dir(int fd, const char *path)
|
2002-07-09 16:24:59 +04:00
|
|
|
{
|
2005-05-12 05:14:01 +04:00
|
|
|
KPath pathBuffer(path, false, B_PATH_NAME_LENGTH + 1);
|
2005-05-13 03:31:04 +04:00
|
|
|
if (pathBuffer.InitCheck() != B_OK)
|
|
|
|
return B_NO_MEMORY;
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2005-05-12 05:14:01 +04:00
|
|
|
return dir_open(fd, pathBuffer.LockBuffer(), true);
|
2002-07-09 16:24:59 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-03-04 19:59:59 +03:00
|
|
|
status_t
|
2004-10-05 17:36:44 +04:00
|
|
|
_kern_fcntl(int fd, int op, uint32 argument)
|
|
|
|
{
|
|
|
|
return common_fcntl(fd, op, argument, true);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-06-15 19:35:10 +04:00
|
|
|
status_t
|
|
|
|
_kern_fsync(int fd)
|
2002-07-09 16:24:59 +04:00
|
|
|
{
|
2002-07-20 04:16:12 +04:00
|
|
|
return common_sync(fd, true);
|
2002-07-09 16:24:59 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-08-29 00:38:39 +04:00
|
|
|
status_t
|
|
|
|
_kern_lock_node(int fd)
|
|
|
|
{
|
|
|
|
return common_lock_node(fd, true);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
status_t
|
|
|
|
_kern_unlock_node(int fd)
|
|
|
|
{
|
|
|
|
return common_unlock_node(fd, true);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-06-15 19:35:10 +04:00
|
|
|
status_t
|
|
|
|
_kern_create_dir_entry_ref(dev_t device, ino_t inode, const char *name, int perms)
|
2002-07-23 18:10:12 +04:00
|
|
|
{
|
2002-08-14 00:39:25 +04:00
|
|
|
return dir_create_entry_ref(device, inode, name, perms, true);
|
2002-07-23 18:10:12 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-10-06 19:33:12 +04:00
|
|
|
/*! \brief Creates a directory specified by a FD + path pair.
|
|
|
|
|
|
|
|
\a path must always be specified (it contains the name of the new directory
|
|
|
|
at least). If only a path is given, this path identifies the location at
|
|
|
|
which the directory shall be created. If both \a fd and \a path are given and
|
|
|
|
the path is absolute, \a fd is ignored; a relative path is reckoned off
|
|
|
|
of the directory (!) identified by \a fd.
|
2004-08-29 00:38:39 +04:00
|
|
|
|
2007-10-06 19:33:12 +04:00
|
|
|
\param fd The FD. May be < 0.
|
|
|
|
\param path The absolute or relative path. Must not be \c NULL.
|
|
|
|
\param perms The access permissions the new directory shall have.
|
|
|
|
\return \c B_OK, if the directory has been created successfully, another
|
|
|
|
error code otherwise.
|
|
|
|
*/
|
2004-06-15 19:35:10 +04:00
|
|
|
status_t
|
2004-08-29 00:38:39 +04:00
|
|
|
_kern_create_dir(int fd, const char *path, int perms)
|
2002-07-20 04:16:12 +04:00
|
|
|
{
|
2005-05-12 05:14:01 +04:00
|
|
|
KPath pathBuffer(path, false, B_PATH_NAME_LENGTH + 1);
|
2005-05-13 03:31:04 +04:00
|
|
|
if (pathBuffer.InitCheck() != B_OK)
|
|
|
|
return B_NO_MEMORY;
|
2002-08-14 00:39:25 +04:00
|
|
|
|
2005-05-12 05:14:01 +04:00
|
|
|
return dir_create(fd, pathBuffer.LockBuffer(), perms, true);
|
2002-08-14 00:39:25 +04:00
|
|
|
}
|
2002-07-14 09:13:20 +04:00
|
|
|
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2004-06-15 19:35:10 +04:00
|
|
|
status_t
|
2006-01-25 14:12:21 +03:00
|
|
|
_kern_remove_dir(int fd, const char *path)
|
2002-08-14 00:39:25 +04:00
|
|
|
{
|
2006-01-25 14:12:21 +03:00
|
|
|
if (path) {
|
|
|
|
KPath pathBuffer(path, false, B_PATH_NAME_LENGTH + 1);
|
|
|
|
if (pathBuffer.InitCheck() != B_OK)
|
|
|
|
return B_NO_MEMORY;
|
2002-08-14 00:39:25 +04:00
|
|
|
|
2006-01-25 14:12:21 +03:00
|
|
|
return dir_remove(fd, pathBuffer.LockBuffer(), true);
|
|
|
|
}
|
|
|
|
|
|
|
|
return dir_remove(fd, NULL, true);
|
2002-07-09 16:24:59 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-10-06 19:33:12 +04:00
|
|
|
/*! \brief Reads the contents of a symlink referred to by a FD + path pair.
|
|
|
|
|
|
|
|
At least one of \a fd and \a path must be specified.
|
|
|
|
If only \a fd is given, the function the symlink to be read is the node
|
|
|
|
identified by this FD. If only a path is given, this path identifies the
|
|
|
|
symlink to be read. If both are given and the path is absolute, \a fd is
|
|
|
|
ignored; a relative path is reckoned off of the directory (!) identified
|
|
|
|
by \a fd.
|
|
|
|
If this function fails with B_BUFFER_OVERFLOW, the \a _bufferSize pointer
|
|
|
|
will still be updated to reflect the required buffer size.
|
2004-08-29 00:38:39 +04:00
|
|
|
|
2007-10-06 19:33:12 +04:00
|
|
|
\param fd The FD. May be < 0.
|
|
|
|
\param path The absolute or relative path. May be \c NULL.
|
|
|
|
\param buffer The buffer into which the contents of the symlink shall be
|
|
|
|
written.
|
|
|
|
\param _bufferSize A pointer to the size of the supplied buffer.
|
|
|
|
\return The length of the link on success or an appropriate error code
|
|
|
|
*/
|
2005-04-06 20:07:10 +04:00
|
|
|
status_t
|
|
|
|
_kern_read_link(int fd, const char *path, char *buffer, size_t *_bufferSize)
|
2002-08-03 06:03:27 +04:00
|
|
|
{
|
2004-10-29 17:11:46 +04:00
|
|
|
status_t status;
|
|
|
|
|
2004-08-29 00:38:39 +04:00
|
|
|
if (path) {
|
2005-05-12 05:14:01 +04:00
|
|
|
KPath pathBuffer(path, false, B_PATH_NAME_LENGTH + 1);
|
2005-05-13 03:31:04 +04:00
|
|
|
if (pathBuffer.InitCheck() != B_OK)
|
|
|
|
return B_NO_MEMORY;
|
2002-08-03 06:03:27 +04:00
|
|
|
|
2008-03-04 19:59:59 +03:00
|
|
|
return common_read_link(fd, pathBuffer.LockBuffer(),
|
2005-05-12 05:14:01 +04:00
|
|
|
buffer, _bufferSize, true);
|
2005-04-06 20:07:10 +04:00
|
|
|
}
|
2004-10-29 17:11:46 +04:00
|
|
|
|
2005-04-06 20:07:10 +04:00
|
|
|
return common_read_link(fd, NULL, buffer, _bufferSize, true);
|
2002-08-03 06:03:27 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-10-06 19:33:12 +04:00
|
|
|
/*! \brief Creates a symlink specified by a FD + path pair.
|
|
|
|
|
|
|
|
\a path must always be specified (it contains the name of the new symlink
|
|
|
|
at least). If only a path is given, this path identifies the location at
|
|
|
|
which the symlink shall be created. If both \a fd and \a path are given and
|
|
|
|
the path is absolute, \a fd is ignored; a relative path is reckoned off
|
|
|
|
of the directory (!) identified by \a fd.
|
2004-08-29 00:38:39 +04:00
|
|
|
|
2007-10-06 19:33:12 +04:00
|
|
|
\param fd The FD. May be < 0.
|
|
|
|
\param toPath The absolute or relative path. Must not be \c NULL.
|
|
|
|
\param mode The access permissions the new symlink shall have.
|
|
|
|
\return \c B_OK, if the symlink has been created successfully, another
|
|
|
|
error code otherwise.
|
|
|
|
*/
|
2004-06-15 19:35:10 +04:00
|
|
|
status_t
|
2004-08-29 00:38:39 +04:00
|
|
|
_kern_create_symlink(int fd, const char *path, const char *toPath, int mode)
|
2002-07-28 22:41:07 +04:00
|
|
|
{
|
2005-05-12 05:14:01 +04:00
|
|
|
KPath pathBuffer(path, false, B_PATH_NAME_LENGTH + 1);
|
2007-10-05 22:42:50 +04:00
|
|
|
if (pathBuffer.InitCheck() != B_OK)
|
2005-05-13 03:31:04 +04:00
|
|
|
return B_NO_MEMORY;
|
|
|
|
|
2008-03-04 19:59:59 +03:00
|
|
|
return common_create_symlink(fd, pathBuffer.LockBuffer(),
|
2007-10-05 22:42:50 +04:00
|
|
|
toPath, mode, true);
|
2002-07-28 22:41:07 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-06-15 19:35:10 +04:00
|
|
|
status_t
|
|
|
|
_kern_create_link(const char *path, const char *toPath)
|
2002-07-09 16:24:59 +04:00
|
|
|
{
|
2005-05-12 05:14:01 +04:00
|
|
|
KPath pathBuffer(path, false, B_PATH_NAME_LENGTH + 1);
|
|
|
|
KPath toPathBuffer(toPath, false, B_PATH_NAME_LENGTH + 1);
|
2005-05-13 03:31:04 +04:00
|
|
|
if (pathBuffer.InitCheck() != B_OK || toPathBuffer.InitCheck() != B_OK)
|
|
|
|
return B_NO_MEMORY;
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2008-03-04 19:59:59 +03:00
|
|
|
return common_create_link(pathBuffer.LockBuffer(),
|
2005-05-12 05:14:01 +04:00
|
|
|
toPathBuffer.LockBuffer(), true);
|
2002-07-20 04:16:12 +04:00
|
|
|
}
|
2002-07-09 16:24:59 +04:00
|
|
|
|
|
|
|
|
2007-10-06 19:33:12 +04:00
|
|
|
/*! \brief Removes an entry specified by a FD + path pair from its directory.
|
|
|
|
|
|
|
|
\a path must always be specified (it contains at least the name of the entry
|
|
|
|
to be deleted). If only a path is given, this path identifies the entry
|
|
|
|
directly. If both \a fd and \a path are given and the path is absolute,
|
|
|
|
\a fd is ignored; a relative path is reckoned off of the directory (!)
|
|
|
|
identified by \a fd.
|
2004-08-29 00:38:39 +04:00
|
|
|
|
2007-10-06 19:33:12 +04:00
|
|
|
\param fd The FD. May be < 0.
|
|
|
|
\param path The absolute or relative path. Must not be \c NULL.
|
|
|
|
\return \c B_OK, if the entry has been removed successfully, another
|
|
|
|
error code otherwise.
|
|
|
|
*/
|
2004-06-15 19:35:10 +04:00
|
|
|
status_t
|
2004-08-29 00:38:39 +04:00
|
|
|
_kern_unlink(int fd, const char *path)
|
2002-07-20 04:16:12 +04:00
|
|
|
{
|
2005-05-12 05:14:01 +04:00
|
|
|
KPath pathBuffer(path, false, B_PATH_NAME_LENGTH + 1);
|
2005-05-13 03:31:04 +04:00
|
|
|
if (pathBuffer.InitCheck() != B_OK)
|
|
|
|
return B_NO_MEMORY;
|
2002-08-14 00:39:25 +04:00
|
|
|
|
2005-05-12 05:14:01 +04:00
|
|
|
return common_unlink(fd, pathBuffer.LockBuffer(), true);
|
2002-08-14 00:39:25 +04:00
|
|
|
}
|
|
|
|
|
2002-07-20 04:16:12 +04:00
|
|
|
|
2007-10-06 19:33:12 +04:00
|
|
|
/*! \brief Moves an entry specified by a FD + path pair to a an entry specified
|
|
|
|
by another FD + path pair.
|
2005-01-18 18:59:18 +03:00
|
|
|
|
2007-10-06 19:33:12 +04:00
|
|
|
\a oldPath and \a newPath must always be specified (they contain at least
|
|
|
|
the name of the entry). If only a path is given, this path identifies the
|
|
|
|
entry directly. If both a FD and a path are given and the path is absolute,
|
|
|
|
the FD is ignored; a relative path is reckoned off of the directory (!)
|
|
|
|
identified by the respective FD.
|
|
|
|
|
|
|
|
\param oldFD The FD of the old location. May be < 0.
|
|
|
|
\param oldPath The absolute or relative path of the old location. Must not
|
|
|
|
be \c NULL.
|
|
|
|
\param newFD The FD of the new location. May be < 0.
|
|
|
|
\param newPath The absolute or relative path of the new location. Must not
|
|
|
|
be \c NULL.
|
|
|
|
\return \c B_OK, if the entry has been moved successfully, another
|
|
|
|
error code otherwise.
|
|
|
|
*/
|
2004-06-15 19:35:10 +04:00
|
|
|
status_t
|
2004-08-29 00:38:39 +04:00
|
|
|
_kern_rename(int oldFD, const char *oldPath, int newFD, const char *newPath)
|
2002-08-14 00:39:25 +04:00
|
|
|
{
|
2005-05-12 05:14:01 +04:00
|
|
|
KPath oldPathBuffer(oldPath, false, B_PATH_NAME_LENGTH + 1);
|
|
|
|
KPath newPathBuffer(newPath, false, B_PATH_NAME_LENGTH + 1);
|
2005-05-13 03:31:04 +04:00
|
|
|
if (oldPathBuffer.InitCheck() != B_OK || newPathBuffer.InitCheck() != B_OK)
|
|
|
|
return B_NO_MEMORY;
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2008-03-04 19:59:59 +03:00
|
|
|
return common_rename(oldFD, oldPathBuffer.LockBuffer(),
|
2005-05-12 05:14:01 +04:00
|
|
|
newFD, newPathBuffer.LockBuffer(), true);
|
2002-07-09 16:24:59 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-06-15 19:35:10 +04:00
|
|
|
status_t
|
|
|
|
_kern_access(const char *path, int mode)
|
2002-08-13 17:51:36 +04:00
|
|
|
{
|
2005-05-12 05:14:01 +04:00
|
|
|
KPath pathBuffer(path, false, B_PATH_NAME_LENGTH + 1);
|
2005-05-13 03:31:04 +04:00
|
|
|
if (pathBuffer.InitCheck() != B_OK)
|
|
|
|
return B_NO_MEMORY;
|
2002-08-13 17:51:36 +04:00
|
|
|
|
2005-05-12 05:14:01 +04:00
|
|
|
return common_access(pathBuffer.LockBuffer(), mode, true);
|
2002-08-13 17:51:36 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-10-06 19:33:12 +04:00
|
|
|
/*! \brief Reads stat data of an entity specified by a FD + path pair.
|
|
|
|
|
|
|
|
If only \a fd is given, the stat operation associated with the type
|
|
|
|
of the FD (node, attr, attr dir etc.) is performed. If only \a path is
|
|
|
|
given, this path identifies the entry for whose node to retrieve the
|
|
|
|
stat data. If both \a fd and \a path are given and the path is absolute,
|
|
|
|
\a fd is ignored; a relative path is reckoned off of the directory (!)
|
|
|
|
identified by \a fd and specifies the entry whose stat data shall be
|
|
|
|
retrieved.
|
2004-08-29 00:38:39 +04:00
|
|
|
|
2007-10-06 19:33:12 +04:00
|
|
|
\param fd The FD. May be < 0.
|
|
|
|
\param path The absolute or relative path. Must not be \c NULL.
|
|
|
|
\param traverseLeafLink If \a path is given, \c true specifies that the
|
|
|
|
function shall not stick to symlinks, but traverse them.
|
|
|
|
\param stat The buffer the stat data shall be written into.
|
|
|
|
\param statSize The size of the supplied stat buffer.
|
|
|
|
\return \c B_OK, if the the stat data have been read successfully, another
|
|
|
|
error code otherwise.
|
|
|
|
*/
|
2004-05-10 18:33:17 +04:00
|
|
|
status_t
|
2004-08-29 00:38:39 +04:00
|
|
|
_kern_read_stat(int fd, const char *path, bool traverseLeafLink,
|
|
|
|
struct stat *stat, size_t statSize)
|
2002-07-09 16:24:59 +04:00
|
|
|
{
|
2004-05-10 18:33:17 +04:00
|
|
|
struct stat completeStat;
|
|
|
|
struct stat *originalStat = NULL;
|
|
|
|
status_t status;
|
|
|
|
|
|
|
|
if (statSize > sizeof(struct stat))
|
|
|
|
return B_BAD_VALUE;
|
|
|
|
|
|
|
|
// this supports different stat extensions
|
|
|
|
if (statSize < sizeof(struct stat)) {
|
|
|
|
originalStat = stat;
|
|
|
|
stat = &completeStat;
|
|
|
|
}
|
|
|
|
|
2008-03-30 03:57:34 +04:00
|
|
|
status = vfs_read_stat(fd, path, traverseLeafLink, stat, true);
|
2004-08-29 00:38:39 +04:00
|
|
|
|
2004-05-10 18:33:17 +04:00
|
|
|
if (status == B_OK && originalStat != NULL)
|
|
|
|
memcpy(originalStat, stat, statSize);
|
|
|
|
|
|
|
|
return status;
|
2002-07-09 16:24:59 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-10-06 19:33:12 +04:00
|
|
|
/*! \brief Writes stat data of an entity specified by a FD + path pair.
|
|
|
|
|
|
|
|
If only \a fd is given, the stat operation associated with the type
|
|
|
|
of the FD (node, attr, attr dir etc.) is performed. If only \a path is
|
|
|
|
given, this path identifies the entry for whose node to write the
|
|
|
|
stat data. If both \a fd and \a path are given and the path is absolute,
|
|
|
|
\a fd is ignored; a relative path is reckoned off of the directory (!)
|
|
|
|
identified by \a fd and specifies the entry whose stat data shall be
|
|
|
|
written.
|
2004-08-29 00:38:39 +04:00
|
|
|
|
2007-10-06 19:33:12 +04:00
|
|
|
\param fd The FD. May be < 0.
|
|
|
|
\param path The absolute or relative path. Must not be \c NULL.
|
|
|
|
\param traverseLeafLink If \a path is given, \c true specifies that the
|
|
|
|
function shall not stick to symlinks, but traverse them.
|
|
|
|
\param stat The buffer containing the stat data to be written.
|
|
|
|
\param statSize The size of the supplied stat buffer.
|
|
|
|
\param statMask A mask specifying which parts of the stat data shall be
|
|
|
|
written.
|
|
|
|
\return \c B_OK, if the the stat data have been written successfully,
|
|
|
|
another error code otherwise.
|
|
|
|
*/
|
2004-05-10 18:33:17 +04:00
|
|
|
status_t
|
2004-08-29 00:38:39 +04:00
|
|
|
_kern_write_stat(int fd, const char *path, bool traverseLeafLink,
|
|
|
|
const struct stat *stat, size_t statSize, int statMask)
|
2002-07-09 16:24:59 +04:00
|
|
|
{
|
2004-05-10 18:33:17 +04:00
|
|
|
struct stat completeStat;
|
|
|
|
|
|
|
|
if (statSize > sizeof(struct stat))
|
|
|
|
return B_BAD_VALUE;
|
|
|
|
|
|
|
|
// this supports different stat extensions
|
|
|
|
if (statSize < sizeof(struct stat)) {
|
|
|
|
memset((uint8 *)&completeStat + statSize, 0, sizeof(struct stat) - statSize);
|
|
|
|
memcpy(&completeStat, stat, statSize);
|
|
|
|
stat = &completeStat;
|
|
|
|
}
|
|
|
|
|
2005-05-13 03:31:04 +04:00
|
|
|
status_t status;
|
2004-08-29 00:38:39 +04:00
|
|
|
|
|
|
|
if (path) {
|
|
|
|
// path given: write the stat of the node referred to by (fd, path)
|
2005-05-12 05:14:01 +04:00
|
|
|
KPath pathBuffer(path, false, B_PATH_NAME_LENGTH + 1);
|
2005-05-13 03:31:04 +04:00
|
|
|
if (pathBuffer.InitCheck() != B_OK)
|
|
|
|
return B_NO_MEMORY;
|
2004-08-29 00:38:39 +04:00
|
|
|
|
2008-03-04 19:59:59 +03:00
|
|
|
status = common_path_write_stat(fd, pathBuffer.LockBuffer(),
|
2005-05-12 05:14:01 +04:00
|
|
|
traverseLeafLink, stat, statMask, true);
|
2004-08-29 00:38:39 +04:00
|
|
|
} else {
|
|
|
|
// no path given: get the FD and use the FD operation
|
|
|
|
struct file_descriptor *descriptor
|
|
|
|
= get_fd(get_current_io_context(true), fd);
|
|
|
|
if (descriptor == NULL)
|
|
|
|
return B_FILE_ERROR;
|
|
|
|
|
|
|
|
if (descriptor->ops->fd_write_stat)
|
|
|
|
status = descriptor->ops->fd_write_stat(descriptor, stat, statMask);
|
|
|
|
else
|
|
|
|
status = EOPNOTSUPP;
|
|
|
|
|
|
|
|
put_fd(descriptor);
|
|
|
|
}
|
|
|
|
|
|
|
|
return status;
|
2002-07-20 04:16:12 +04:00
|
|
|
}
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2002-07-17 11:55:51 +04:00
|
|
|
|
2002-10-08 07:24:51 +04:00
|
|
|
int
|
2004-06-15 19:35:10 +04:00
|
|
|
_kern_open_attr_dir(int fd, const char *path)
|
2002-10-08 07:24:51 +04:00
|
|
|
{
|
2005-05-12 05:14:01 +04:00
|
|
|
KPath pathBuffer(B_PATH_NAME_LENGTH + 1);
|
2005-05-13 03:31:04 +04:00
|
|
|
if (pathBuffer.InitCheck() != B_OK)
|
|
|
|
return B_NO_MEMORY;
|
2002-10-08 07:24:51 +04:00
|
|
|
|
2004-12-07 19:15:57 +03:00
|
|
|
if (path != NULL)
|
2005-05-12 05:14:01 +04:00
|
|
|
pathBuffer.SetTo(path);
|
2002-10-08 07:24:51 +04:00
|
|
|
|
2005-05-12 05:14:01 +04:00
|
|
|
return attr_dir_open(fd, path ? pathBuffer.LockBuffer() : NULL, true);
|
2002-10-08 07:24:51 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int
|
2004-06-15 19:35:10 +04:00
|
|
|
_kern_create_attr(int fd, const char *name, uint32 type, int openMode)
|
2002-10-08 07:24:51 +04:00
|
|
|
{
|
|
|
|
return attr_create(fd, name, type, openMode, true);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int
|
2004-06-15 19:35:10 +04:00
|
|
|
_kern_open_attr(int fd, const char *name, int openMode)
|
2002-10-08 07:24:51 +04:00
|
|
|
{
|
|
|
|
return attr_open(fd, name, openMode, true);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-06-15 19:35:10 +04:00
|
|
|
status_t
|
|
|
|
_kern_remove_attr(int fd, const char *name)
|
2002-10-08 07:24:51 +04:00
|
|
|
{
|
|
|
|
return attr_remove(fd, name, true);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-06-15 19:35:10 +04:00
|
|
|
status_t
|
|
|
|
_kern_rename_attr(int fromFile, const char *fromName, int toFile, const char *toName)
|
2002-10-08 07:24:51 +04:00
|
|
|
{
|
|
|
|
return attr_rename(fromFile, fromName, toFile, toName, true);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2002-10-17 23:34:09 +04:00
|
|
|
int
|
2004-06-15 19:35:10 +04:00
|
|
|
_kern_open_index_dir(dev_t device)
|
2002-10-17 23:34:09 +04:00
|
|
|
{
|
|
|
|
return index_dir_open(device, true);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-06-15 19:35:10 +04:00
|
|
|
status_t
|
|
|
|
_kern_create_index(dev_t device, const char *name, uint32 type, uint32 flags)
|
2002-10-17 23:34:09 +04:00
|
|
|
{
|
|
|
|
return index_create(device, name, type, flags, true);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-06-15 19:35:10 +04:00
|
|
|
status_t
|
|
|
|
_kern_read_index_stat(dev_t device, const char *name, struct stat *stat)
|
2002-10-17 23:34:09 +04:00
|
|
|
{
|
|
|
|
return index_name_read_stat(device, name, stat, true);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-06-15 19:35:10 +04:00
|
|
|
status_t
|
|
|
|
_kern_remove_index(dev_t device, const char *name)
|
2002-10-17 23:34:09 +04:00
|
|
|
{
|
|
|
|
return index_remove(device, name, true);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-06-15 19:35:10 +04:00
|
|
|
status_t
|
|
|
|
_kern_getcwd(char *buffer, size_t size)
|
2002-07-20 04:16:12 +04:00
|
|
|
{
|
2005-12-16 20:35:03 +03:00
|
|
|
TRACE(("_kern_getcwd: buf %p, %ld\n", buffer, size));
|
2002-07-20 04:16:12 +04:00
|
|
|
|
|
|
|
// Call vfs to get current working directory
|
2005-05-12 05:14:01 +04:00
|
|
|
return get_cwd(buffer, size, true);
|
2002-07-09 16:24:59 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-06-15 19:35:10 +04:00
|
|
|
status_t
|
|
|
|
_kern_setcwd(int fd, const char *path)
|
2002-07-09 16:24:59 +04:00
|
|
|
{
|
2005-05-12 05:14:01 +04:00
|
|
|
KPath pathBuffer(B_PATH_NAME_LENGTH + 1);
|
2005-05-13 03:31:04 +04:00
|
|
|
if (pathBuffer.InitCheck() != B_OK)
|
|
|
|
return B_NO_MEMORY;
|
2002-10-08 07:24:51 +04:00
|
|
|
|
2005-04-05 05:09:07 +04:00
|
|
|
if (path != NULL)
|
2005-05-12 05:14:01 +04:00
|
|
|
pathBuffer.SetTo(path);
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2005-05-12 05:14:01 +04:00
|
|
|
return set_cwd(fd, path != NULL ? pathBuffer.LockBuffer() : NULL, true);
|
2002-07-09 16:24:59 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-05-28 18:17:18 +04:00
|
|
|
// #pragma mark - userland syscalls
|
2002-07-09 16:24:59 +04:00
|
|
|
|
|
|
|
|
2005-10-17 18:01:04 +04:00
|
|
|
dev_t
|
2004-11-01 03:35:27 +03:00
|
|
|
_user_mount(const char *userPath, const char *userDevice, const char *userFileSystem,
|
2006-02-20 21:04:27 +03:00
|
|
|
uint32 flags, const char *userArgs, size_t argsLength)
|
2002-07-09 16:24:59 +04:00
|
|
|
{
|
2004-11-01 03:35:27 +03:00
|
|
|
char fileSystem[B_OS_NAME_LENGTH];
|
|
|
|
KPath path, device;
|
|
|
|
char *args = NULL;
|
|
|
|
status_t status;
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2004-11-01 03:35:27 +03:00
|
|
|
if (!IS_USER_ADDRESS(userPath)
|
|
|
|
|| !IS_USER_ADDRESS(userFileSystem)
|
|
|
|
|| !IS_USER_ADDRESS(userDevice))
|
2002-07-23 18:10:12 +04:00
|
|
|
return B_BAD_ADDRESS;
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2004-11-01 03:35:27 +03:00
|
|
|
if (path.InitCheck() != B_OK || device.InitCheck() != B_OK)
|
|
|
|
return B_NO_MEMORY;
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2004-11-01 03:35:27 +03:00
|
|
|
if (user_strlcpy(path.LockBuffer(), userPath, B_PATH_NAME_LENGTH) < B_OK)
|
|
|
|
return B_BAD_ADDRESS;
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2004-11-01 03:35:27 +03:00
|
|
|
if (userFileSystem != NULL
|
|
|
|
&& user_strlcpy(fileSystem, userFileSystem, sizeof(fileSystem)) < B_OK)
|
|
|
|
return B_BAD_ADDRESS;
|
|
|
|
|
|
|
|
if (userDevice != NULL
|
|
|
|
&& user_strlcpy(device.LockBuffer(), userDevice, B_PATH_NAME_LENGTH) < B_OK)
|
|
|
|
return B_BAD_ADDRESS;
|
|
|
|
|
2006-02-20 21:04:27 +03:00
|
|
|
if (userArgs != NULL && argsLength > 0) {
|
2006-02-27 16:23:29 +03:00
|
|
|
// this is a safety restriction
|
2006-02-20 21:04:27 +03:00
|
|
|
if (argsLength >= 65536)
|
2006-02-27 16:23:29 +03:00
|
|
|
return B_NAME_TOO_LONG;
|
|
|
|
|
2006-02-20 21:04:27 +03:00
|
|
|
args = (char *)malloc(argsLength + 1);
|
|
|
|
if (args == NULL)
|
|
|
|
return B_NO_MEMORY;
|
2006-02-27 16:23:29 +03:00
|
|
|
|
2006-02-20 21:04:27 +03:00
|
|
|
if (user_strlcpy(args, userArgs, argsLength + 1) < B_OK) {
|
|
|
|
free(args);
|
2004-11-01 03:35:27 +03:00
|
|
|
return B_BAD_ADDRESS;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
path.UnlockBuffer();
|
|
|
|
device.UnlockBuffer();
|
|
|
|
|
|
|
|
status = fs_mount(path.LockBuffer(), userDevice != NULL ? device.Path() : NULL,
|
|
|
|
userFileSystem ? fileSystem : NULL, flags, args, false);
|
|
|
|
|
|
|
|
free(args);
|
|
|
|
return status;
|
2002-07-09 16:24:59 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-06-15 19:35:10 +04:00
|
|
|
status_t
|
2004-11-30 01:45:27 +03:00
|
|
|
_user_unmount(const char *userPath, uint32 flags)
|
2002-07-09 16:24:59 +04:00
|
|
|
{
|
2005-05-12 05:14:01 +04:00
|
|
|
KPath pathBuffer(B_PATH_NAME_LENGTH + 1);
|
2005-05-13 03:31:04 +04:00
|
|
|
if (pathBuffer.InitCheck() != B_OK)
|
|
|
|
return B_NO_MEMORY;
|
|
|
|
|
2005-05-12 05:14:01 +04:00
|
|
|
char *path = pathBuffer.LockBuffer();
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2005-05-12 05:14:01 +04:00
|
|
|
if (user_strlcpy(path, userPath, B_PATH_NAME_LENGTH) < B_OK)
|
|
|
|
return B_BAD_ADDRESS;
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2007-11-12 23:54:17 +03:00
|
|
|
return fs_unmount(path, -1, flags & ~B_UNMOUNT_BUSY_PARTITION, false);
|
2002-07-20 04:16:12 +04:00
|
|
|
}
|
2002-07-09 16:24:59 +04:00
|
|
|
|
|
|
|
|
2003-09-04 08:19:24 +04:00
|
|
|
status_t
|
|
|
|
_user_read_fs_info(dev_t device, struct fs_info *userInfo)
|
|
|
|
{
|
|
|
|
struct fs_info info;
|
|
|
|
status_t status;
|
|
|
|
|
|
|
|
if (userInfo == NULL)
|
|
|
|
return B_BAD_VALUE;
|
|
|
|
|
2004-02-22 17:52:59 +03:00
|
|
|
if (!IS_USER_ADDRESS(userInfo))
|
2003-09-04 08:19:24 +04:00
|
|
|
return B_BAD_ADDRESS;
|
|
|
|
|
|
|
|
status = fs_read_info(device, &info);
|
|
|
|
if (status != B_OK)
|
|
|
|
return status;
|
|
|
|
|
|
|
|
if (user_memcpy(userInfo, &info, sizeof(struct fs_info)) < B_OK)
|
|
|
|
return B_BAD_ADDRESS;
|
|
|
|
|
|
|
|
return B_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
status_t
|
|
|
|
_user_write_fs_info(dev_t device, const struct fs_info *userInfo, int mask)
|
|
|
|
{
|
|
|
|
struct fs_info info;
|
|
|
|
|
|
|
|
if (userInfo == NULL)
|
|
|
|
return B_BAD_VALUE;
|
|
|
|
|
2004-02-22 17:52:59 +03:00
|
|
|
if (!IS_USER_ADDRESS(userInfo)
|
2003-09-04 08:19:24 +04:00
|
|
|
|| user_memcpy(&info, userInfo, sizeof(struct fs_info)) < B_OK)
|
|
|
|
return B_BAD_ADDRESS;
|
|
|
|
|
|
|
|
return fs_write_info(device, &info, mask);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-07-07 20:12:46 +04:00
|
|
|
dev_t
|
|
|
|
_user_next_device(int32 *_userCookie)
|
|
|
|
{
|
|
|
|
int32 cookie;
|
|
|
|
dev_t device;
|
|
|
|
|
|
|
|
if (!IS_USER_ADDRESS(_userCookie)
|
|
|
|
|| user_memcpy(&cookie, _userCookie, sizeof(int32)) < B_OK)
|
|
|
|
return B_BAD_ADDRESS;
|
|
|
|
|
|
|
|
device = fs_next_device(&cookie);
|
|
|
|
|
|
|
|
if (device >= B_OK) {
|
|
|
|
// update user cookie
|
|
|
|
if (user_memcpy(_userCookie, &cookie, sizeof(int32)) < B_OK)
|
|
|
|
return B_BAD_ADDRESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
return device;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-06-15 19:35:10 +04:00
|
|
|
status_t
|
|
|
|
_user_sync(void)
|
2002-07-20 04:16:12 +04:00
|
|
|
{
|
2005-01-15 03:38:16 +03:00
|
|
|
return _kern_sync();
|
2002-07-09 16:24:59 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-01-17 04:29:18 +03:00
|
|
|
status_t
|
|
|
|
_user_get_next_fd_info(team_id team, uint32 *userCookie, fd_info *userInfo,
|
|
|
|
size_t infoSize)
|
|
|
|
{
|
|
|
|
struct fd_info info;
|
|
|
|
uint32 cookie;
|
|
|
|
|
2006-01-17 04:44:18 +03:00
|
|
|
// only root can do this (or should root's group be enough?)
|
|
|
|
if (geteuid() != 0)
|
|
|
|
return B_NOT_ALLOWED;
|
|
|
|
|
2006-01-17 04:29:18 +03:00
|
|
|
if (infoSize != sizeof(fd_info))
|
|
|
|
return B_BAD_VALUE;
|
|
|
|
|
|
|
|
if (!IS_USER_ADDRESS(userCookie) || !IS_USER_ADDRESS(userInfo)
|
|
|
|
|| user_memcpy(&cookie, userCookie, sizeof(uint32)) < B_OK)
|
|
|
|
return B_BAD_ADDRESS;
|
|
|
|
|
|
|
|
status_t status = _kern_get_next_fd_info(team, &cookie, &info, infoSize);
|
|
|
|
if (status < B_OK)
|
|
|
|
return status;
|
|
|
|
|
|
|
|
if (user_memcpy(userCookie, &cookie, sizeof(uint32)) < B_OK
|
|
|
|
|| user_memcpy(userInfo, &info, infoSize) < B_OK)
|
|
|
|
return B_BAD_ADDRESS;
|
|
|
|
|
|
|
|
return status;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-07-02 22:48:58 +04:00
|
|
|
status_t
|
2004-08-29 00:38:39 +04:00
|
|
|
_user_entry_ref_to_path(dev_t device, ino_t inode, const char *leaf,
|
|
|
|
char *userPath, size_t pathLength)
|
2004-07-02 22:48:58 +04:00
|
|
|
{
|
|
|
|
if (!IS_USER_ADDRESS(userPath))
|
|
|
|
return B_BAD_ADDRESS;
|
|
|
|
|
2008-02-27 19:39:32 +03:00
|
|
|
KPath path(B_PATH_NAME_LENGTH + 1);
|
|
|
|
if (path.InitCheck() != B_OK)
|
|
|
|
return B_NO_MEMORY;
|
|
|
|
|
2004-08-29 00:38:39 +04:00
|
|
|
// copy the leaf name onto the stack
|
|
|
|
char stackLeaf[B_FILE_NAME_LENGTH];
|
|
|
|
if (leaf) {
|
|
|
|
if (!IS_USER_ADDRESS(leaf))
|
|
|
|
return B_BAD_ADDRESS;
|
|
|
|
|
2008-02-27 19:39:32 +03:00
|
|
|
int length = user_strlcpy(stackLeaf, leaf, B_FILE_NAME_LENGTH);
|
|
|
|
if (length < 0)
|
|
|
|
return length;
|
|
|
|
if (length >= B_FILE_NAME_LENGTH)
|
2004-08-29 15:58:04 +04:00
|
|
|
return B_NAME_TOO_LONG;
|
2004-08-29 00:38:39 +04:00
|
|
|
|
2008-02-27 19:39:32 +03:00
|
|
|
leaf = stackLeaf;
|
2004-08-29 00:38:39 +04:00
|
|
|
}
|
|
|
|
|
2008-02-27 19:39:32 +03:00
|
|
|
status_t status = vfs_entry_ref_to_path(device, inode, leaf,
|
|
|
|
path.LockBuffer(), path.BufferSize());
|
2004-07-02 22:48:58 +04:00
|
|
|
if (status < B_OK)
|
|
|
|
return status;
|
|
|
|
|
2008-02-27 19:39:32 +03:00
|
|
|
path.UnlockBuffer();
|
2004-08-29 00:38:39 +04:00
|
|
|
|
2008-02-27 19:39:32 +03:00
|
|
|
int length = user_strlcpy(userPath, path.Path(), pathLength);
|
|
|
|
if (length < 0)
|
|
|
|
return length;
|
|
|
|
if (length >= (int)pathLength)
|
2004-08-29 15:58:04 +04:00
|
|
|
return B_BUFFER_OVERFLOW;
|
2006-03-05 21:11:59 +03:00
|
|
|
|
2004-08-29 15:58:04 +04:00
|
|
|
return B_OK;
|
2004-07-02 22:48:58 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-02-08 06:06:14 +03:00
|
|
|
status_t
|
|
|
|
_user_normalize_path(const char* userPath, bool traverseLink, char* buffer)
|
|
|
|
{
|
|
|
|
if (userPath == NULL || buffer == NULL)
|
|
|
|
return B_BAD_VALUE;
|
|
|
|
if (!IS_USER_ADDRESS(userPath) || !IS_USER_ADDRESS(buffer))
|
|
|
|
return B_BAD_ADDRESS;
|
|
|
|
|
|
|
|
// copy path from userland
|
|
|
|
KPath pathBuffer(B_PATH_NAME_LENGTH + 1);
|
|
|
|
if (pathBuffer.InitCheck() != B_OK)
|
|
|
|
return B_NO_MEMORY;
|
|
|
|
char* path = pathBuffer.LockBuffer();
|
|
|
|
|
|
|
|
if (user_strlcpy(path, userPath, B_PATH_NAME_LENGTH) < B_OK)
|
|
|
|
return B_BAD_ADDRESS;
|
|
|
|
|
|
|
|
// buffer for the leaf part
|
|
|
|
KPath leafBuffer(B_PATH_NAME_LENGTH + 1);
|
|
|
|
if (leafBuffer.InitCheck() != B_OK)
|
|
|
|
return B_NO_MEMORY;
|
|
|
|
char* leaf = leafBuffer.LockBuffer();
|
|
|
|
|
|
|
|
VNodePutter dirPutter;
|
|
|
|
struct vnode* dir = NULL;
|
|
|
|
status_t error;
|
|
|
|
|
|
|
|
for (int i = 0; i < B_MAX_SYMLINKS; i++) {
|
|
|
|
// get dir vnode + leaf name
|
|
|
|
struct vnode* nextDir;
|
|
|
|
error = vnode_and_path_to_dir_vnode(dir, path, &nextDir, leaf, false);
|
|
|
|
if (error != B_OK)
|
|
|
|
return error;
|
|
|
|
|
|
|
|
dir = nextDir;
|
|
|
|
strcpy(path, leaf);
|
|
|
|
dirPutter.SetTo(dir);
|
|
|
|
|
|
|
|
// get file vnode
|
|
|
|
inc_vnode_ref_count(dir);
|
|
|
|
struct vnode* fileVnode;
|
2008-03-30 09:59:54 +04:00
|
|
|
error = vnode_path_to_vnode(dir, path, false, 0, false, &fileVnode,
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
NULL);
|
2008-02-08 06:06:14 +03:00
|
|
|
if (error != B_OK)
|
|
|
|
return error;
|
|
|
|
VNodePutter fileVnodePutter(fileVnode);
|
|
|
|
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
if (!traverseLink || !S_ISLNK(fileVnode->type)) {
|
2008-02-08 06:06:14 +03:00
|
|
|
// we're done -- construct the path
|
|
|
|
bool hasLeaf = true;
|
|
|
|
if (strcmp(leaf, ".") == 0 || strcmp(leaf, "..") == 0) {
|
|
|
|
// special cases "." and ".." -- get the dir, forget the leaf
|
|
|
|
inc_vnode_ref_count(dir);
|
2008-03-30 09:59:54 +04:00
|
|
|
error = vnode_path_to_vnode(dir, leaf, false, 0, false,
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
&nextDir, NULL);
|
2008-02-08 06:06:14 +03:00
|
|
|
if (error != B_OK)
|
|
|
|
return error;
|
|
|
|
dir = nextDir;
|
|
|
|
dirPutter.SetTo(dir);
|
|
|
|
hasLeaf = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
// get the directory path
|
2008-03-30 09:59:54 +04:00
|
|
|
error = dir_vnode_to_path(dir, path, B_PATH_NAME_LENGTH, false);
|
2008-02-08 06:06:14 +03:00
|
|
|
if (error != B_OK)
|
|
|
|
return error;
|
|
|
|
|
|
|
|
// append the leaf name
|
|
|
|
if (hasLeaf) {
|
|
|
|
// insert a directory separator if this is not the file system
|
|
|
|
// root
|
|
|
|
if ((strcmp(path, "/") != 0
|
|
|
|
&& strlcat(path, "/", pathBuffer.BufferSize())
|
|
|
|
>= pathBuffer.BufferSize())
|
|
|
|
|| strlcat(path, leaf, pathBuffer.BufferSize())
|
|
|
|
>= pathBuffer.BufferSize()) {
|
|
|
|
return B_NAME_TOO_LONG;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// copy back to userland
|
|
|
|
int len = user_strlcpy(buffer, path, B_PATH_NAME_LENGTH);
|
|
|
|
if (len < 0)
|
|
|
|
return len;
|
|
|
|
if (len >= B_PATH_NAME_LENGTH)
|
|
|
|
return B_BUFFER_OVERFLOW;
|
2008-03-04 19:59:59 +03:00
|
|
|
|
2008-02-08 06:06:14 +03:00
|
|
|
return B_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
// read link
|
|
|
|
struct stat st;
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
if (HAS_FS_CALL(fileVnode, read_symlink)) {
|
2008-03-18 00:37:40 +03:00
|
|
|
size_t bufferSize = B_PATH_NAME_LENGTH - 1;
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
error = FS_CALL(fileVnode, read_symlink, path, &bufferSize);
|
2008-02-08 06:06:14 +03:00
|
|
|
if (error != B_OK)
|
|
|
|
return error;
|
2008-03-18 00:37:40 +03:00
|
|
|
path[bufferSize] = '\0';
|
2008-02-08 06:06:14 +03:00
|
|
|
} else
|
|
|
|
return B_BAD_VALUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
return B_LINK_LIMIT;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2002-07-23 18:10:12 +04:00
|
|
|
int
|
2005-02-02 09:21:31 +03:00
|
|
|
_user_open_entry_ref(dev_t device, ino_t inode, const char *userName,
|
|
|
|
int openMode, int perms)
|
2002-07-23 18:10:12 +04:00
|
|
|
{
|
|
|
|
char name[B_FILE_NAME_LENGTH];
|
|
|
|
|
2006-05-25 17:03:13 +04:00
|
|
|
if (userName == NULL || device < 0 || inode < 0)
|
|
|
|
return B_BAD_VALUE;
|
2006-03-14 17:27:59 +03:00
|
|
|
if (!IS_USER_ADDRESS(userName)
|
|
|
|
|| user_strlcpy(name, userName, sizeof(name)) < B_OK)
|
2003-02-21 16:49:26 +03:00
|
|
|
return B_BAD_ADDRESS;
|
2002-07-23 18:10:12 +04:00
|
|
|
|
2005-02-02 09:21:31 +03:00
|
|
|
if (openMode & O_CREAT)
|
|
|
|
return file_create_entry_ref(device, inode, name, openMode, perms, false);
|
|
|
|
|
2005-01-18 18:59:18 +03:00
|
|
|
return file_open_entry_ref(device, inode, name, openMode, false);
|
2002-07-23 18:10:12 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2002-07-09 16:24:59 +04:00
|
|
|
int
|
2005-02-02 09:21:31 +03:00
|
|
|
_user_open(int fd, const char *userPath, int openMode, int perms)
|
2002-07-09 16:24:59 +04:00
|
|
|
{
|
2006-03-05 21:11:59 +03:00
|
|
|
KPath path(B_PATH_NAME_LENGTH + 1);
|
|
|
|
if (path.InitCheck() != B_OK)
|
|
|
|
return B_NO_MEMORY;
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2006-03-05 21:11:59 +03:00
|
|
|
char *buffer = path.LockBuffer();
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2006-03-05 21:11:59 +03:00
|
|
|
if (!IS_USER_ADDRESS(userPath)
|
|
|
|
|| user_strlcpy(buffer, userPath, B_PATH_NAME_LENGTH) < B_OK)
|
|
|
|
return B_BAD_ADDRESS;
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2005-02-02 09:21:31 +03:00
|
|
|
if (openMode & O_CREAT)
|
2006-03-05 21:11:59 +03:00
|
|
|
return file_create(fd, buffer, openMode, perms, false);
|
2005-02-02 09:21:31 +03:00
|
|
|
|
2006-03-05 21:11:59 +03:00
|
|
|
return file_open(fd, buffer, openMode, false);
|
2002-07-20 04:16:12 +04:00
|
|
|
}
|
2002-07-09 16:24:59 +04:00
|
|
|
|
|
|
|
|
2002-07-23 18:10:12 +04:00
|
|
|
int
|
2006-03-05 21:11:59 +03:00
|
|
|
_user_open_dir_entry_ref(dev_t device, ino_t inode, const char *userName)
|
2002-07-23 18:10:12 +04:00
|
|
|
{
|
2006-03-05 21:11:59 +03:00
|
|
|
if (userName != NULL) {
|
2004-08-29 00:38:39 +04:00
|
|
|
char name[B_FILE_NAME_LENGTH];
|
|
|
|
|
2006-03-05 21:11:59 +03:00
|
|
|
if (!IS_USER_ADDRESS(userName)
|
|
|
|
|| user_strlcpy(name, userName, sizeof(name)) < B_OK)
|
2004-08-29 00:38:39 +04:00
|
|
|
return B_BAD_ADDRESS;
|
|
|
|
|
|
|
|
return dir_open_entry_ref(device, inode, name, false);
|
|
|
|
}
|
|
|
|
return dir_open_entry_ref(device, inode, NULL, false);
|
2002-07-23 18:10:12 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int
|
2004-08-29 00:38:39 +04:00
|
|
|
_user_open_dir(int fd, const char *userPath)
|
2002-07-23 18:10:12 +04:00
|
|
|
{
|
2006-03-05 21:11:59 +03:00
|
|
|
KPath path(B_PATH_NAME_LENGTH + 1);
|
|
|
|
if (path.InitCheck() != B_OK)
|
|
|
|
return B_NO_MEMORY;
|
2002-07-23 18:10:12 +04:00
|
|
|
|
2006-03-05 21:11:59 +03:00
|
|
|
char *buffer = path.LockBuffer();
|
2002-07-23 18:10:12 +04:00
|
|
|
|
2006-03-05 21:11:59 +03:00
|
|
|
if (!IS_USER_ADDRESS(userPath)
|
|
|
|
|| user_strlcpy(buffer, userPath, B_PATH_NAME_LENGTH) < B_OK)
|
|
|
|
return B_BAD_ADDRESS;
|
2002-07-23 18:10:12 +04:00
|
|
|
|
2006-03-05 21:11:59 +03:00
|
|
|
return dir_open(fd, buffer, false);
|
2002-07-23 18:10:12 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-10-06 19:33:12 +04:00
|
|
|
/*! \brief Opens a directory's parent directory and returns the entry name
|
|
|
|
of the former.
|
2005-01-18 18:59:18 +03:00
|
|
|
|
2007-10-06 19:33:12 +04:00
|
|
|
Aside from that is returns the directory's entry name, this method is
|
|
|
|
equivalent to \code _user_open_dir(fd, "..") \endcode. It really is
|
|
|
|
equivalent, if \a userName is \c NULL.
|
|
|
|
|
|
|
|
If a name buffer is supplied and the name does not fit the buffer, the
|
|
|
|
function fails. A buffer of size \c B_FILE_NAME_LENGTH should be safe.
|
|
|
|
|
|
|
|
\param fd A FD referring to a directory.
|
|
|
|
\param userName Buffer the directory's entry name shall be written into.
|
|
|
|
May be \c NULL.
|
|
|
|
\param nameLength Size of the name buffer.
|
|
|
|
\return The file descriptor of the opened parent directory, if everything
|
|
|
|
went fine, an error code otherwise.
|
|
|
|
*/
|
2002-07-09 16:24:59 +04:00
|
|
|
int
|
2004-08-29 00:38:39 +04:00
|
|
|
_user_open_parent_dir(int fd, char *userName, size_t nameLength)
|
2002-07-09 16:24:59 +04:00
|
|
|
{
|
2004-08-29 00:38:39 +04:00
|
|
|
bool kernel = false;
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2004-09-10 03:21:09 +04:00
|
|
|
if (userName && !IS_USER_ADDRESS(userName))
|
2002-10-08 07:24:51 +04:00
|
|
|
return B_BAD_ADDRESS;
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2004-08-29 00:38:39 +04:00
|
|
|
// open the parent dir
|
|
|
|
int parentFD = dir_open(fd, "..", kernel);
|
|
|
|
if (parentFD < 0)
|
|
|
|
return parentFD;
|
|
|
|
FDCloser fdCloser(parentFD, kernel);
|
|
|
|
|
2004-09-10 03:21:09 +04:00
|
|
|
if (userName) {
|
|
|
|
// get the vnodes
|
|
|
|
struct vnode *parentVNode = get_vnode_from_fd(parentFD, kernel);
|
|
|
|
struct vnode *dirVNode = get_vnode_from_fd(fd, kernel);
|
|
|
|
VNodePutter parentVNodePutter(parentVNode);
|
|
|
|
VNodePutter dirVNodePutter(dirVNode);
|
|
|
|
if (!parentVNode || !dirVNode)
|
|
|
|
return B_FILE_ERROR;
|
2004-08-29 00:38:39 +04:00
|
|
|
|
2004-09-10 03:21:09 +04:00
|
|
|
// get the vnode name
|
2007-03-02 12:34:33 +03:00
|
|
|
char _buffer[sizeof(struct dirent) + B_FILE_NAME_LENGTH];
|
|
|
|
struct dirent *buffer = (struct dirent*)_buffer;
|
|
|
|
status_t status = get_vnode_name(dirVNode, parentVNode, buffer,
|
2008-03-30 09:59:54 +04:00
|
|
|
sizeof(_buffer), get_current_io_context(false));
|
2004-09-10 03:21:09 +04:00
|
|
|
if (status != B_OK)
|
|
|
|
return status;
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2004-09-10 03:21:09 +04:00
|
|
|
// copy the name to the userland buffer
|
2007-03-02 12:34:33 +03:00
|
|
|
int len = user_strlcpy(userName, buffer->d_name, nameLength);
|
2004-09-10 03:21:09 +04:00
|
|
|
if (len < 0)
|
|
|
|
return len;
|
|
|
|
if (len >= (int)nameLength)
|
|
|
|
return B_BUFFER_OVERFLOW;
|
|
|
|
}
|
2004-08-29 15:58:04 +04:00
|
|
|
|
|
|
|
return fdCloser.Detach();
|
2002-07-20 04:16:12 +04:00
|
|
|
}
|
2002-07-09 16:24:59 +04:00
|
|
|
|
|
|
|
|
2008-03-04 19:59:59 +03:00
|
|
|
status_t
|
2004-10-05 17:36:44 +04:00
|
|
|
_user_fcntl(int fd, int op, uint32 argument)
|
|
|
|
{
|
axeld + bonefish:
* Implemented automatic syscall restarts:
- A syscall can indicate that it has been interrupted and can be
restarted by setting a respective bit in thread::flags. It can
store parameters it wants to be preserved for the restart in
thread::syscall_restart::parameters. Another thread::flags bit
indicates whether it has been restarted.
- handle_signals() clears the restart flag, if the handled signal
has a handler function installed and SA_RESTART is not set. Another
thread flag (THREAD_FLAGS_DONT_RESTART_SYSCALL) can prevent syscalls
from being restarted, even if they could be (not used yet, but we
might want to use it in resume_thread(), so that we stay
behaviorally compatible with BeOS).
- The architecture specific syscall handler restarts the syscall, if
the restart flag is set. Implemented for x86 only.
- Added some support functions in the private <syscall_restart.h> to
simplify the syscall restart code in the syscalls.
- Adjusted all syscalls that can potentially be restarted accordingly.
- _user_ioctl() sets new thread flag THREAD_FLAGS_IOCTL_SYSCALL while
calling the underlying FS's/driver's hook, so that syscall restarts
can also be supported there.
* thread_at_kernel_exit() invokes handle_signals() in a loop now, as
long as the latter indicates that the thread shall be suspended, so
that after waking up signals received in the meantime will be handled
before the thread returns to userland. Adjusted handle_signals()
accordingly -- when encountering a suspending signal we don't check
for further signals.
* Fixed sigsuspend(): Suspending the thread and rescheduling doesn't
result in the correct behavior. Instead we employ a temporary
condition variable and interruptably wait on it. The POSIX test
suite test passes, now.
* Made the switch_sem[_etc]() behavior on interruption consistent.
Depending on when the signal arrived (before the call or when already
waiting) the first semaphore would or wouldn't be released. Now we
consistently release it.
* Refactored _user_{read,write}[v]() syscalls. Use a common function for
either pair. The iovec version doesn't fail anymore, if anything could
be read/written at all. It also checks whether a complete vector
could be read/written, so that we won't skip data, if the underlying
FS/driver couldn't read/write more ATM.
* Some refactoring in the x86 syscall handler: The int 99 and sysenter
handlers use a common subroutine to avoid code duplication.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@23983 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-02-17 18:48:30 +03:00
|
|
|
status_t status = common_fcntl(fd, op, argument, false);
|
|
|
|
if (op == F_SETLKW)
|
|
|
|
syscall_restart_handle_post(status);
|
|
|
|
|
|
|
|
return status;
|
2004-10-05 17:36:44 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-06-15 19:35:10 +04:00
|
|
|
status_t
|
|
|
|
_user_fsync(int fd)
|
2002-07-20 04:16:12 +04:00
|
|
|
{
|
|
|
|
return common_sync(fd, false);
|
|
|
|
}
|
2002-07-09 16:24:59 +04:00
|
|
|
|
|
|
|
|
2008-03-04 19:59:59 +03:00
|
|
|
status_t
|
2008-02-03 18:37:31 +03:00
|
|
|
_user_flock(int fd, int op)
|
|
|
|
{
|
|
|
|
struct file_descriptor *descriptor;
|
|
|
|
struct vnode *vnode;
|
|
|
|
struct flock flock;
|
|
|
|
status_t status;
|
|
|
|
|
|
|
|
FUNCTION(("_user_fcntl(fd = %d, op = %d)\n", fd, op));
|
|
|
|
|
|
|
|
descriptor = get_fd_and_vnode(fd, &vnode, false);
|
|
|
|
if (descriptor == NULL)
|
|
|
|
return B_FILE_ERROR;
|
|
|
|
|
|
|
|
if (descriptor->type != FDTYPE_FILE) {
|
|
|
|
put_fd(descriptor);
|
|
|
|
return B_BAD_VALUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
flock.l_start = 0;
|
|
|
|
flock.l_len = OFF_MAX;
|
|
|
|
flock.l_whence = 0;
|
|
|
|
flock.l_type = (op & LOCK_SH) != 0 ? F_RDLCK : F_WRLCK;
|
|
|
|
|
|
|
|
if ((op & LOCK_UN) != 0)
|
2008-04-11 23:21:14 +04:00
|
|
|
status = release_advisory_lock(vnode, &flock);
|
2008-02-03 18:37:31 +03:00
|
|
|
else {
|
2008-04-11 23:21:14 +04:00
|
|
|
status = acquire_advisory_lock(vnode,
|
2008-02-03 18:37:31 +03:00
|
|
|
thread_get_current_thread()->team->session_id, &flock,
|
|
|
|
(op & LOCK_NB) == 0);
|
|
|
|
}
|
|
|
|
|
axeld + bonefish:
* Implemented automatic syscall restarts:
- A syscall can indicate that it has been interrupted and can be
restarted by setting a respective bit in thread::flags. It can
store parameters it wants to be preserved for the restart in
thread::syscall_restart::parameters. Another thread::flags bit
indicates whether it has been restarted.
- handle_signals() clears the restart flag, if the handled signal
has a handler function installed and SA_RESTART is not set. Another
thread flag (THREAD_FLAGS_DONT_RESTART_SYSCALL) can prevent syscalls
from being restarted, even if they could be (not used yet, but we
might want to use it in resume_thread(), so that we stay
behaviorally compatible with BeOS).
- The architecture specific syscall handler restarts the syscall, if
the restart flag is set. Implemented for x86 only.
- Added some support functions in the private <syscall_restart.h> to
simplify the syscall restart code in the syscalls.
- Adjusted all syscalls that can potentially be restarted accordingly.
- _user_ioctl() sets new thread flag THREAD_FLAGS_IOCTL_SYSCALL while
calling the underlying FS's/driver's hook, so that syscall restarts
can also be supported there.
* thread_at_kernel_exit() invokes handle_signals() in a loop now, as
long as the latter indicates that the thread shall be suspended, so
that after waking up signals received in the meantime will be handled
before the thread returns to userland. Adjusted handle_signals()
accordingly -- when encountering a suspending signal we don't check
for further signals.
* Fixed sigsuspend(): Suspending the thread and rescheduling doesn't
result in the correct behavior. Instead we employ a temporary
condition variable and interruptably wait on it. The POSIX test
suite test passes, now.
* Made the switch_sem[_etc]() behavior on interruption consistent.
Depending on when the signal arrived (before the call or when already
waiting) the first semaphore would or wouldn't be released. Now we
consistently release it.
* Refactored _user_{read,write}[v]() syscalls. Use a common function for
either pair. The iovec version doesn't fail anymore, if anything could
be read/written at all. It also checks whether a complete vector
could be read/written, so that we won't skip data, if the underlying
FS/driver couldn't read/write more ATM.
* Some refactoring in the x86 syscall handler: The int 99 and sysenter
handlers use a common subroutine to avoid code duplication.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@23983 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-02-17 18:48:30 +03:00
|
|
|
syscall_restart_handle_post(status);
|
|
|
|
|
2008-02-03 18:37:31 +03:00
|
|
|
put_fd(descriptor);
|
|
|
|
return status;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-08-29 00:38:39 +04:00
|
|
|
status_t
|
|
|
|
_user_lock_node(int fd)
|
|
|
|
{
|
|
|
|
return common_lock_node(fd, false);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
status_t
|
|
|
|
_user_unlock_node(int fd)
|
|
|
|
{
|
|
|
|
return common_unlock_node(fd, false);
|
|
|
|
}
|
|
|
|
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2004-06-15 19:35:10 +04:00
|
|
|
status_t
|
|
|
|
_user_create_dir_entry_ref(dev_t device, ino_t inode, const char *userName, int perms)
|
2002-07-23 18:10:12 +04:00
|
|
|
{
|
|
|
|
char name[B_FILE_NAME_LENGTH];
|
2004-06-15 19:35:10 +04:00
|
|
|
status_t status;
|
2002-07-23 18:10:12 +04:00
|
|
|
|
2004-02-22 17:52:59 +03:00
|
|
|
if (!IS_USER_ADDRESS(userName))
|
2002-08-14 00:39:25 +04:00
|
|
|
return B_BAD_ADDRESS;
|
2002-07-23 18:10:12 +04:00
|
|
|
|
2002-10-08 07:24:51 +04:00
|
|
|
status = user_strlcpy(name, userName, sizeof(name));
|
2002-07-23 18:10:12 +04:00
|
|
|
if (status < 0)
|
|
|
|
return status;
|
|
|
|
|
|
|
|
return dir_create_entry_ref(device, inode, name, perms, false);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-06-15 19:35:10 +04:00
|
|
|
status_t
|
2004-08-29 00:38:39 +04:00
|
|
|
_user_create_dir(int fd, const char *userPath, int perms)
|
2002-07-20 04:16:12 +04:00
|
|
|
{
|
2006-03-05 21:11:59 +03:00
|
|
|
KPath pathBuffer(B_PATH_NAME_LENGTH + 1);
|
|
|
|
if (pathBuffer.InitCheck() != B_OK)
|
|
|
|
return B_NO_MEMORY;
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2006-03-05 21:11:59 +03:00
|
|
|
char *path = pathBuffer.LockBuffer();
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2006-03-05 21:11:59 +03:00
|
|
|
if (!IS_USER_ADDRESS(userPath)
|
|
|
|
|| user_strlcpy(path, userPath, B_PATH_NAME_LENGTH) < B_OK)
|
|
|
|
return B_BAD_ADDRESS;
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2004-08-29 00:38:39 +04:00
|
|
|
return dir_create(fd, path, perms, false);
|
2002-07-09 16:24:59 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-06-15 19:35:10 +04:00
|
|
|
status_t
|
2006-01-25 14:12:21 +03:00
|
|
|
_user_remove_dir(int fd, const char *userPath)
|
2002-08-14 00:39:25 +04:00
|
|
|
{
|
2006-03-05 21:11:59 +03:00
|
|
|
KPath pathBuffer(B_PATH_NAME_LENGTH + 1);
|
|
|
|
if (pathBuffer.InitCheck() != B_OK)
|
|
|
|
return B_NO_MEMORY;
|
2002-08-14 00:39:25 +04:00
|
|
|
|
2006-03-05 21:11:59 +03:00
|
|
|
char *path = pathBuffer.LockBuffer();
|
|
|
|
|
|
|
|
if (userPath != NULL) {
|
|
|
|
if (!IS_USER_ADDRESS(userPath)
|
|
|
|
|| user_strlcpy(path, userPath, B_PATH_NAME_LENGTH) < B_OK)
|
|
|
|
return B_BAD_ADDRESS;
|
|
|
|
}
|
2002-08-14 00:39:25 +04:00
|
|
|
|
2006-01-25 14:12:21 +03:00
|
|
|
return dir_remove(fd, userPath ? path : NULL, false);
|
2002-08-14 00:39:25 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2005-04-06 20:07:10 +04:00
|
|
|
status_t
|
|
|
|
_user_read_link(int fd, const char *userPath, char *userBuffer, size_t *userBufferSize)
|
2002-08-03 06:03:27 +04:00
|
|
|
{
|
2006-03-05 21:11:59 +03:00
|
|
|
KPath pathBuffer(B_PATH_NAME_LENGTH + 1), linkBuffer;
|
|
|
|
if (pathBuffer.InitCheck() != B_OK || linkBuffer.InitCheck() != B_OK)
|
|
|
|
return B_NO_MEMORY;
|
|
|
|
|
2005-04-06 20:07:10 +04:00
|
|
|
size_t bufferSize;
|
2002-08-03 06:03:27 +04:00
|
|
|
|
2005-04-06 20:07:10 +04:00
|
|
|
if (!IS_USER_ADDRESS(userBuffer) || !IS_USER_ADDRESS(userBufferSize)
|
|
|
|
|| user_memcpy(&bufferSize, userBufferSize, sizeof(size_t)) < B_OK)
|
2002-08-03 06:03:27 +04:00
|
|
|
return B_BAD_ADDRESS;
|
|
|
|
|
2006-03-05 21:11:59 +03:00
|
|
|
char *path = pathBuffer.LockBuffer();
|
|
|
|
char *buffer = linkBuffer.LockBuffer();
|
|
|
|
|
2004-08-29 00:38:39 +04:00
|
|
|
if (userPath) {
|
2006-03-05 21:11:59 +03:00
|
|
|
if (!IS_USER_ADDRESS(userPath)
|
|
|
|
|| user_strlcpy(path, userPath, B_PATH_NAME_LENGTH) < B_OK)
|
2004-08-29 00:38:39 +04:00
|
|
|
return B_BAD_ADDRESS;
|
|
|
|
|
2004-10-29 17:11:46 +04:00
|
|
|
if (bufferSize > B_PATH_NAME_LENGTH)
|
|
|
|
bufferSize = B_PATH_NAME_LENGTH;
|
2005-04-06 20:07:10 +04:00
|
|
|
}
|
2004-08-29 00:38:39 +04:00
|
|
|
|
2006-03-05 21:11:59 +03:00
|
|
|
status_t status = common_read_link(fd, userPath ? path : NULL, buffer,
|
|
|
|
&bufferSize, false);
|
2005-04-06 20:07:10 +04:00
|
|
|
|
|
|
|
// we also update the bufferSize in case of errors
|
|
|
|
// (the real length will be returned in case of B_BUFFER_OVERFLOW)
|
|
|
|
if (user_memcpy(userBufferSize, &bufferSize, sizeof(size_t)) < B_OK)
|
|
|
|
return B_BAD_ADDRESS;
|
2002-08-03 06:03:27 +04:00
|
|
|
|
|
|
|
if (status < B_OK)
|
|
|
|
return status;
|
|
|
|
|
2008-03-18 00:37:40 +03:00
|
|
|
if (user_memcpy(userBuffer, buffer, bufferSize) != B_OK)
|
2005-04-06 20:07:10 +04:00
|
|
|
return B_BAD_ADDRESS;
|
|
|
|
|
|
|
|
return B_OK;
|
2002-08-03 06:03:27 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-06-15 19:35:10 +04:00
|
|
|
status_t
|
2004-08-29 00:38:39 +04:00
|
|
|
_user_create_symlink(int fd, const char *userPath, const char *userToPath,
|
|
|
|
int mode)
|
2002-07-28 22:41:07 +04:00
|
|
|
{
|
2006-03-05 21:11:59 +03:00
|
|
|
KPath pathBuffer(B_PATH_NAME_LENGTH + 1);
|
|
|
|
KPath toPathBuffer(B_PATH_NAME_LENGTH + 1);
|
|
|
|
if (pathBuffer.InitCheck() != B_OK || toPathBuffer.InitCheck() != B_OK)
|
|
|
|
return B_NO_MEMORY;
|
|
|
|
|
|
|
|
char *path = pathBuffer.LockBuffer();
|
|
|
|
char *toPath = toPathBuffer.LockBuffer();
|
2004-11-23 06:20:20 +03:00
|
|
|
|
2004-02-22 17:52:59 +03:00
|
|
|
if (!IS_USER_ADDRESS(userPath)
|
2006-03-05 21:11:59 +03:00
|
|
|
|| !IS_USER_ADDRESS(userToPath)
|
|
|
|
|| user_strlcpy(path, userPath, B_PATH_NAME_LENGTH) < B_OK
|
|
|
|
|| user_strlcpy(toPath, userToPath, B_PATH_NAME_LENGTH) < B_OK)
|
2002-07-28 22:41:07 +04:00
|
|
|
return B_BAD_ADDRESS;
|
|
|
|
|
2004-08-29 00:38:39 +04:00
|
|
|
return common_create_symlink(fd, path, toPath, mode, false);
|
2002-07-28 22:41:07 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-06-15 19:35:10 +04:00
|
|
|
status_t
|
|
|
|
_user_create_link(const char *userPath, const char *userToPath)
|
2002-08-14 00:39:25 +04:00
|
|
|
{
|
2006-03-05 21:11:59 +03:00
|
|
|
KPath pathBuffer(B_PATH_NAME_LENGTH + 1);
|
|
|
|
KPath toPathBuffer(B_PATH_NAME_LENGTH + 1);
|
|
|
|
if (pathBuffer.InitCheck() != B_OK || toPathBuffer.InitCheck() != B_OK)
|
|
|
|
return B_NO_MEMORY;
|
|
|
|
|
|
|
|
char *path = pathBuffer.LockBuffer();
|
|
|
|
char *toPath = toPathBuffer.LockBuffer();
|
2002-08-14 00:39:25 +04:00
|
|
|
|
2004-02-22 17:52:59 +03:00
|
|
|
if (!IS_USER_ADDRESS(userPath)
|
2006-03-05 21:11:59 +03:00
|
|
|
|| !IS_USER_ADDRESS(userToPath)
|
|
|
|
|| user_strlcpy(path, userPath, B_PATH_NAME_LENGTH) < B_OK
|
|
|
|
|| user_strlcpy(toPath, userToPath, B_PATH_NAME_LENGTH) < B_OK)
|
2002-08-14 00:39:25 +04:00
|
|
|
return B_BAD_ADDRESS;
|
|
|
|
|
2006-03-05 21:11:59 +03:00
|
|
|
status_t status = check_path(toPath);
|
2002-08-14 00:39:25 +04:00
|
|
|
if (status < B_OK)
|
|
|
|
return status;
|
|
|
|
|
|
|
|
return common_create_link(path, toPath, false);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-06-15 19:35:10 +04:00
|
|
|
status_t
|
2004-08-29 00:38:39 +04:00
|
|
|
_user_unlink(int fd, const char *userPath)
|
2002-07-20 04:16:12 +04:00
|
|
|
{
|
2006-03-05 21:11:59 +03:00
|
|
|
KPath pathBuffer(B_PATH_NAME_LENGTH + 1);
|
|
|
|
if (pathBuffer.InitCheck() != B_OK)
|
|
|
|
return B_NO_MEMORY;
|
2002-07-20 04:16:12 +04:00
|
|
|
|
2006-03-05 21:11:59 +03:00
|
|
|
char *path = pathBuffer.LockBuffer();
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2006-03-05 21:11:59 +03:00
|
|
|
if (!IS_USER_ADDRESS(userPath)
|
|
|
|
|| user_strlcpy(path, userPath, B_PATH_NAME_LENGTH) < B_OK)
|
|
|
|
return B_BAD_ADDRESS;
|
2002-07-20 04:16:12 +04:00
|
|
|
|
2004-08-29 00:38:39 +04:00
|
|
|
return common_unlink(fd, path, false);
|
2002-07-20 04:16:12 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-06-15 19:35:10 +04:00
|
|
|
status_t
|
2004-08-29 00:38:39 +04:00
|
|
|
_user_rename(int oldFD, const char *userOldPath, int newFD,
|
|
|
|
const char *userNewPath)
|
2002-07-09 16:24:59 +04:00
|
|
|
{
|
2006-03-05 21:11:59 +03:00
|
|
|
KPath oldPathBuffer(B_PATH_NAME_LENGTH + 1);
|
|
|
|
KPath newPathBuffer(B_PATH_NAME_LENGTH + 1);
|
|
|
|
if (oldPathBuffer.InitCheck() != B_OK || newPathBuffer.InitCheck() != B_OK)
|
|
|
|
return B_NO_MEMORY;
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2006-03-05 21:11:59 +03:00
|
|
|
char *oldPath = oldPathBuffer.LockBuffer();
|
|
|
|
char *newPath = newPathBuffer.LockBuffer();
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2006-03-05 21:11:59 +03:00
|
|
|
if (!IS_USER_ADDRESS(userOldPath) || !IS_USER_ADDRESS(userNewPath)
|
|
|
|
|| user_strlcpy(oldPath, userOldPath, B_PATH_NAME_LENGTH) < B_OK
|
|
|
|
|| user_strlcpy(newPath, userNewPath, B_PATH_NAME_LENGTH) < B_OK)
|
|
|
|
return B_BAD_ADDRESS;
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2004-08-29 00:38:39 +04:00
|
|
|
return common_rename(oldFD, oldPath, newFD, newPath, false);
|
2002-07-09 16:24:59 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
status_t
|
|
|
|
_user_create_fifo(const char *userPath, mode_t perms)
|
|
|
|
{
|
|
|
|
KPath pathBuffer(B_PATH_NAME_LENGTH + 1);
|
|
|
|
if (pathBuffer.InitCheck() != B_OK)
|
|
|
|
return B_NO_MEMORY;
|
|
|
|
|
|
|
|
char *path = pathBuffer.LockBuffer();
|
|
|
|
|
|
|
|
if (!IS_USER_ADDRESS(userPath)
|
|
|
|
|| user_strlcpy(path, userPath, B_PATH_NAME_LENGTH) < B_OK) {
|
|
|
|
return B_BAD_ADDRESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
// split into directory vnode and filename path
|
|
|
|
char filename[B_FILE_NAME_LENGTH];
|
|
|
|
struct vnode *dir;
|
|
|
|
status_t status = path_to_dir_vnode(path, &dir, filename, false);
|
|
|
|
if (status != B_OK)
|
|
|
|
return status;
|
|
|
|
|
|
|
|
VNodePutter _(dir);
|
|
|
|
|
|
|
|
// the underlying FS needs to support creating FIFOs
|
|
|
|
if (!HAS_FS_CALL(dir, create_special_node))
|
|
|
|
return B_UNSUPPORTED;
|
|
|
|
|
|
|
|
// create the entry -- the FIFO sub node is set up automatically
|
|
|
|
fs_vnode superVnode;
|
|
|
|
ino_t nodeID;
|
2008-04-06 04:26:15 +04:00
|
|
|
status = FS_CALL(dir, create_special_node, filename, NULL,
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
S_IFIFO | (perms & S_IUMSK), 0, &superVnode, &nodeID);
|
2008-04-06 04:26:15 +04:00
|
|
|
|
|
|
|
// create_special_node() acquired a reference for us that we don't need.
|
|
|
|
if (status == B_OK)
|
|
|
|
put_vnode(dir->mount->volume, nodeID);
|
|
|
|
|
|
|
|
return status;
|
* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures.
Those that operate on mounted volumes to fs_volume_ops, those
operating on a vnode to fs_vnode_ops.
- Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void*
again.
- Instead of a void* volume and node cookie hooks are passed a
fs_volume and fs_vnode structure pointer, which contain the cookie
and an ops pointer (fs_volume a few more things).
- The VFS {new,publish,get,...}_vnode() functions take a fs_volume*
instead of the volume ID. So does vfs_get_fs_node_from_path().
- Added type and flags arguments to publish_vnode() and the
get_vnode() hook and removed the type argument from lookup() hook.
Added vnode::type using formerly unused bits to store the node type.
Simplified a few things in the VFS due to the now always available
node type.
- Added fs_volume_ops::{create,delete}_sub_vnode() and
fs_vnode_ops::get_super_vnode() hooks. They are used to support file
system layers, e.g. allowing to extend an FS not supporting BeOS
attribute with attribute support. Needs some more work in the VFS.
- Added fs_vnode_ops::create_special_node() hook for creating special
nodes (e.g. FIFOs).
* Adjusted the built-in file systems and BFS according to the interface
changes. Removed all other FSs from the image for the time being.
We'll see whether further API changes are necessary before porting
them.
* Adjusted the bfs_shell accordingly.
* Implemented create_special_node() in rootfs to support special nodes.
* Added support for FIFOs:
- Added syscall _kern_create_fifo() (used by mkfifo()), which creates
a special node (type S_IFIFO) in the respective file system.
- When a special node is published the VFS creates a respective sub
node. Currently only FIFOs are supported.
- Added a little support for FIFO subnodes by using functionality from
the pipefs.
- Added mkfifo to the image. It can create FIFOs in the rootfs, but
the FIFOs aren't really usable ATM, since they still work like
pipes, i.e. readers and writers need to have them open at the same
time.
* Some smaller changes in the VFS:
- Made the *_CALL macros nicer to use (vargs).
- Refactored FS entry lookup into new function lookup_dir_entry().
- create_vnode() no longer just calls the FS create() hook. First it
looks up the entry and uses open_vnode(), if it already exists. This
is necessary for two reasons: 1) The FS might not support create()
while still allowing to open() entries. 2) When the FS has other
layers on to of it (or the respective node) it might not be
responsible for opening the node.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-04-06 03:05:16 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-04-06 06:49:12 +04:00
|
|
|
status_t
|
|
|
|
_user_create_pipe(int *userFDs)
|
|
|
|
{
|
|
|
|
// rootfs should support creating FIFOs, but let's be sure
|
|
|
|
if (!HAS_FS_CALL(sRoot, create_special_node))
|
|
|
|
return B_UNSUPPORTED;
|
|
|
|
|
|
|
|
// create the node -- the FIFO sub node is set up automatically
|
|
|
|
fs_vnode superVnode;
|
|
|
|
ino_t nodeID;
|
|
|
|
status_t status = FS_CALL(sRoot, create_special_node, NULL, NULL,
|
|
|
|
S_IFIFO | S_IRUSR | S_IWUSR, 0, &superVnode, &nodeID);
|
|
|
|
if (status != B_OK)
|
|
|
|
return status;
|
|
|
|
|
|
|
|
// We've got one reference to the node and need another one.
|
|
|
|
struct vnode* vnode;
|
|
|
|
status = get_vnode(sRoot->mount->id, nodeID, &vnode, true, false);
|
|
|
|
if (status != B_OK) {
|
|
|
|
// that should not happen
|
|
|
|
dprintf("_user_create_pipe(): Failed to lookup vnode (%ld, %lld)\n",
|
|
|
|
sRoot->mount->id, sRoot->id);
|
|
|
|
return status;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Everything looks good so far. Open two FDs for reading respectively
|
|
|
|
// writing.
|
|
|
|
int fds[2];
|
|
|
|
fds[0] = open_vnode(vnode, O_RDONLY, false);
|
|
|
|
fds[1] = open_vnode(vnode, O_WRONLY, false);
|
|
|
|
|
|
|
|
FDCloser closer0(fds[0], false);
|
|
|
|
FDCloser closer1(fds[1], false);
|
|
|
|
|
|
|
|
status = (fds[0] >= 0 ? (fds[1] >= 0 ? B_OK : fds[1]) : fds[0]);
|
|
|
|
|
|
|
|
// copy FDs to userland
|
|
|
|
if (status == B_OK) {
|
|
|
|
if (!IS_USER_ADDRESS(userFDs)
|
|
|
|
|| user_memcpy(userFDs, fds, sizeof(fds)) != B_OK) {
|
|
|
|
status = B_BAD_ADDRESS;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// keep FDs, if everything went fine
|
|
|
|
if (status == B_OK) {
|
|
|
|
closer0.Detach();
|
|
|
|
closer1.Detach();
|
|
|
|
}
|
|
|
|
|
|
|
|
return status;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-06-15 19:35:10 +04:00
|
|
|
status_t
|
|
|
|
_user_access(const char *userPath, int mode)
|
2002-08-13 17:51:36 +04:00
|
|
|
{
|
2006-03-05 21:11:59 +03:00
|
|
|
KPath pathBuffer(B_PATH_NAME_LENGTH + 1);
|
|
|
|
if (pathBuffer.InitCheck() != B_OK)
|
|
|
|
return B_NO_MEMORY;
|
2002-08-13 17:51:36 +04:00
|
|
|
|
2006-03-05 21:11:59 +03:00
|
|
|
char *path = pathBuffer.LockBuffer();
|
2002-08-13 17:51:36 +04:00
|
|
|
|
2006-03-05 21:11:59 +03:00
|
|
|
if (!IS_USER_ADDRESS(userPath)
|
|
|
|
|| user_strlcpy(path, userPath, B_PATH_NAME_LENGTH) < B_OK)
|
|
|
|
return B_BAD_ADDRESS;
|
2002-08-13 17:51:36 +04:00
|
|
|
|
|
|
|
return common_access(path, mode, false);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-05-10 18:33:17 +04:00
|
|
|
status_t
|
2004-08-29 00:38:39 +04:00
|
|
|
_user_read_stat(int fd, const char *userPath, bool traverseLink,
|
|
|
|
struct stat *userStat, size_t statSize)
|
2002-07-09 16:24:59 +04:00
|
|
|
{
|
2002-07-20 04:16:12 +04:00
|
|
|
struct stat stat;
|
2005-08-09 20:25:01 +04:00
|
|
|
status_t status;
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2004-05-10 18:33:17 +04:00
|
|
|
if (statSize > sizeof(struct stat))
|
|
|
|
return B_BAD_VALUE;
|
|
|
|
|
2004-08-29 00:38:39 +04:00
|
|
|
if (!IS_USER_ADDRESS(userStat))
|
2002-08-03 06:03:27 +04:00
|
|
|
return B_BAD_ADDRESS;
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2004-08-29 00:38:39 +04:00
|
|
|
if (userPath) {
|
|
|
|
// path given: get the stat of the node referred to by (fd, path)
|
2004-08-29 15:58:04 +04:00
|
|
|
if (!IS_USER_ADDRESS(userPath))
|
2004-08-29 00:38:39 +04:00
|
|
|
return B_BAD_ADDRESS;
|
2008-03-04 19:59:59 +03:00
|
|
|
|
2006-03-05 21:11:59 +03:00
|
|
|
KPath pathBuffer(B_PATH_NAME_LENGTH + 1);
|
|
|
|
if (pathBuffer.InitCheck() != B_OK)
|
|
|
|
return B_NO_MEMORY;
|
2008-03-04 19:59:59 +03:00
|
|
|
|
2006-03-05 21:11:59 +03:00
|
|
|
char *path = pathBuffer.LockBuffer();
|
2008-03-04 19:59:59 +03:00
|
|
|
|
2006-03-05 21:11:59 +03:00
|
|
|
ssize_t length = user_strlcpy(path, userPath, B_PATH_NAME_LENGTH);
|
|
|
|
if (length < B_OK)
|
|
|
|
return length;
|
|
|
|
if (length >= B_PATH_NAME_LENGTH)
|
2004-08-29 15:58:04 +04:00
|
|
|
return B_NAME_TOO_LONG;
|
2004-08-29 00:38:39 +04:00
|
|
|
|
|
|
|
status = common_path_read_stat(fd, path, traverseLink, &stat, false);
|
|
|
|
} else {
|
|
|
|
// no path given: get the FD and use the FD operation
|
|
|
|
struct file_descriptor *descriptor
|
|
|
|
= get_fd(get_current_io_context(false), fd);
|
|
|
|
if (descriptor == NULL)
|
|
|
|
return B_FILE_ERROR;
|
|
|
|
|
|
|
|
if (descriptor->ops->fd_read_stat)
|
|
|
|
status = descriptor->ops->fd_read_stat(descriptor, &stat);
|
|
|
|
else
|
|
|
|
status = EOPNOTSUPP;
|
|
|
|
|
|
|
|
put_fd(descriptor);
|
|
|
|
}
|
|
|
|
|
2004-05-10 18:33:17 +04:00
|
|
|
if (status < B_OK)
|
2002-10-17 07:09:25 +04:00
|
|
|
return status;
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2004-05-10 18:33:17 +04:00
|
|
|
return user_memcpy(userStat, &stat, statSize);
|
2002-07-20 04:16:12 +04:00
|
|
|
}
|
2002-07-09 16:24:59 +04:00
|
|
|
|
|
|
|
|
2004-05-10 18:33:17 +04:00
|
|
|
status_t
|
2004-08-29 00:38:39 +04:00
|
|
|
_user_write_stat(int fd, const char *userPath, bool traverseLeafLink,
|
|
|
|
const struct stat *userStat, size_t statSize, int statMask)
|
2002-07-20 04:16:12 +04:00
|
|
|
{
|
2004-05-10 18:33:17 +04:00
|
|
|
if (statSize > sizeof(struct stat))
|
|
|
|
return B_BAD_VALUE;
|
|
|
|
|
2006-03-05 21:11:59 +03:00
|
|
|
struct stat stat;
|
|
|
|
|
2004-02-22 17:52:59 +03:00
|
|
|
if (!IS_USER_ADDRESS(userStat)
|
2004-05-10 18:33:17 +04:00
|
|
|
|| user_memcpy(&stat, userStat, statSize) < B_OK)
|
2002-10-08 07:24:51 +04:00
|
|
|
return B_BAD_ADDRESS;
|
2002-07-20 04:16:12 +04:00
|
|
|
|
2004-05-10 18:33:17 +04:00
|
|
|
// clear additional stat fields
|
|
|
|
if (statSize < sizeof(struct stat))
|
|
|
|
memset((uint8 *)&stat + statSize, 0, sizeof(struct stat) - statSize);
|
|
|
|
|
2004-08-29 00:38:39 +04:00
|
|
|
status_t status;
|
|
|
|
|
|
|
|
if (userPath) {
|
|
|
|
// path given: write the stat of the node referred to by (fd, path)
|
2004-08-29 15:58:04 +04:00
|
|
|
if (!IS_USER_ADDRESS(userPath))
|
2004-08-29 00:38:39 +04:00
|
|
|
return B_BAD_ADDRESS;
|
2008-03-04 19:59:59 +03:00
|
|
|
|
2006-03-05 21:11:59 +03:00
|
|
|
KPath pathBuffer(B_PATH_NAME_LENGTH + 1);
|
|
|
|
if (pathBuffer.InitCheck() != B_OK)
|
|
|
|
return B_NO_MEMORY;
|
2008-03-04 19:59:59 +03:00
|
|
|
|
2006-03-05 21:11:59 +03:00
|
|
|
char *path = pathBuffer.LockBuffer();
|
2008-03-04 19:59:59 +03:00
|
|
|
|
2006-03-05 21:11:59 +03:00
|
|
|
ssize_t length = user_strlcpy(path, userPath, B_PATH_NAME_LENGTH);
|
|
|
|
if (length < B_OK)
|
|
|
|
return length;
|
|
|
|
if (length >= B_PATH_NAME_LENGTH)
|
2004-08-29 15:58:04 +04:00
|
|
|
return B_NAME_TOO_LONG;
|
2004-08-29 00:38:39 +04:00
|
|
|
|
|
|
|
status = common_path_write_stat(fd, path, traverseLeafLink, &stat,
|
|
|
|
statMask, false);
|
|
|
|
} else {
|
|
|
|
// no path given: get the FD and use the FD operation
|
|
|
|
struct file_descriptor *descriptor
|
|
|
|
= get_fd(get_current_io_context(false), fd);
|
|
|
|
if (descriptor == NULL)
|
|
|
|
return B_FILE_ERROR;
|
|
|
|
|
|
|
|
if (descriptor->ops->fd_write_stat)
|
|
|
|
status = descriptor->ops->fd_write_stat(descriptor, &stat, statMask);
|
|
|
|
else
|
|
|
|
status = EOPNOTSUPP;
|
|
|
|
|
|
|
|
put_fd(descriptor);
|
|
|
|
}
|
|
|
|
|
|
|
|
return status;
|
2002-07-09 16:24:59 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2002-10-08 07:24:51 +04:00
|
|
|
int
|
2004-06-15 19:35:10 +04:00
|
|
|
_user_open_attr_dir(int fd, const char *userPath)
|
2002-10-08 07:24:51 +04:00
|
|
|
{
|
2006-03-05 21:11:59 +03:00
|
|
|
KPath pathBuffer(B_PATH_NAME_LENGTH + 1);
|
|
|
|
if (pathBuffer.InitCheck() != B_OK)
|
|
|
|
return B_NO_MEMORY;
|
|
|
|
|
|
|
|
char *path = pathBuffer.LockBuffer();
|
2002-10-08 07:24:51 +04:00
|
|
|
|
2004-12-07 19:15:57 +03:00
|
|
|
if (userPath != NULL) {
|
2004-02-22 17:52:59 +03:00
|
|
|
if (!IS_USER_ADDRESS(userPath)
|
2006-03-05 21:11:59 +03:00
|
|
|
|| user_strlcpy(path, userPath, B_PATH_NAME_LENGTH) < B_OK)
|
2002-10-08 07:24:51 +04:00
|
|
|
return B_BAD_ADDRESS;
|
|
|
|
}
|
|
|
|
|
2006-03-05 21:11:59 +03:00
|
|
|
return attr_dir_open(fd, userPath ? path : NULL, false);
|
2002-10-08 07:24:51 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int
|
2004-06-15 19:35:10 +04:00
|
|
|
_user_create_attr(int fd, const char *userName, uint32 type, int openMode)
|
2002-10-08 07:24:51 +04:00
|
|
|
{
|
|
|
|
char name[B_FILE_NAME_LENGTH];
|
|
|
|
|
2004-02-22 17:52:59 +03:00
|
|
|
if (!IS_USER_ADDRESS(userName)
|
2002-10-08 07:24:51 +04:00
|
|
|
|| user_strlcpy(name, userName, B_FILE_NAME_LENGTH) < B_OK)
|
|
|
|
return B_BAD_ADDRESS;
|
|
|
|
|
|
|
|
return attr_create(fd, name, type, openMode, false);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int
|
2004-06-15 19:35:10 +04:00
|
|
|
_user_open_attr(int fd, const char *userName, int openMode)
|
2002-10-08 07:24:51 +04:00
|
|
|
{
|
|
|
|
char name[B_FILE_NAME_LENGTH];
|
|
|
|
|
2004-02-22 17:52:59 +03:00
|
|
|
if (!IS_USER_ADDRESS(userName)
|
2002-10-08 07:24:51 +04:00
|
|
|
|| user_strlcpy(name, userName, B_FILE_NAME_LENGTH) < B_OK)
|
|
|
|
return B_BAD_ADDRESS;
|
|
|
|
|
|
|
|
return attr_open(fd, name, openMode, false);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-06-15 19:35:10 +04:00
|
|
|
status_t
|
|
|
|
_user_remove_attr(int fd, const char *userName)
|
2002-10-08 07:24:51 +04:00
|
|
|
{
|
|
|
|
char name[B_FILE_NAME_LENGTH];
|
|
|
|
|
2004-02-22 17:52:59 +03:00
|
|
|
if (!IS_USER_ADDRESS(userName)
|
2002-10-08 07:24:51 +04:00
|
|
|
|| user_strlcpy(name, userName, B_FILE_NAME_LENGTH) < B_OK)
|
|
|
|
return B_BAD_ADDRESS;
|
|
|
|
|
|
|
|
return attr_remove(fd, name, false);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-06-15 19:35:10 +04:00
|
|
|
status_t
|
|
|
|
_user_rename_attr(int fromFile, const char *userFromName, int toFile, const char *userToName)
|
2002-10-08 07:24:51 +04:00
|
|
|
{
|
2004-02-22 17:52:59 +03:00
|
|
|
if (!IS_USER_ADDRESS(userFromName)
|
|
|
|
|| !IS_USER_ADDRESS(userToName))
|
2002-10-08 07:24:51 +04:00
|
|
|
return B_BAD_ADDRESS;
|
|
|
|
|
2006-03-05 21:11:59 +03:00
|
|
|
KPath fromNameBuffer(B_FILE_NAME_LENGTH);
|
|
|
|
KPath toNameBuffer(B_FILE_NAME_LENGTH);
|
|
|
|
if (fromNameBuffer.InitCheck() != B_OK || toNameBuffer.InitCheck() != B_OK)
|
|
|
|
return B_NO_MEMORY;
|
|
|
|
|
|
|
|
char *fromName = fromNameBuffer.LockBuffer();
|
|
|
|
char *toName = toNameBuffer.LockBuffer();
|
|
|
|
|
2002-10-08 07:24:51 +04:00
|
|
|
if (user_strlcpy(fromName, userFromName, B_FILE_NAME_LENGTH) < B_OK
|
|
|
|
|| user_strlcpy(toName, userToName, B_FILE_NAME_LENGTH) < B_OK)
|
|
|
|
return B_BAD_ADDRESS;
|
|
|
|
|
|
|
|
return attr_rename(fromFile, fromName, toFile, toName, false);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2002-10-17 23:34:09 +04:00
|
|
|
int
|
2004-06-15 19:35:10 +04:00
|
|
|
_user_open_index_dir(dev_t device)
|
2002-10-17 23:34:09 +04:00
|
|
|
{
|
|
|
|
return index_dir_open(device, false);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-06-15 19:35:10 +04:00
|
|
|
status_t
|
|
|
|
_user_create_index(dev_t device, const char *userName, uint32 type, uint32 flags)
|
2002-10-17 23:34:09 +04:00
|
|
|
{
|
|
|
|
char name[B_FILE_NAME_LENGTH];
|
2008-03-04 19:59:59 +03:00
|
|
|
|
2004-02-22 17:52:59 +03:00
|
|
|
if (!IS_USER_ADDRESS(userName)
|
2002-10-17 23:34:09 +04:00
|
|
|
|| user_strlcpy(name, userName, B_FILE_NAME_LENGTH) < B_OK)
|
|
|
|
return B_BAD_ADDRESS;
|
|
|
|
|
|
|
|
return index_create(device, name, type, flags, false);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-06-15 19:35:10 +04:00
|
|
|
status_t
|
|
|
|
_user_read_index_stat(dev_t device, const char *userName, struct stat *userStat)
|
2002-10-17 23:34:09 +04:00
|
|
|
{
|
|
|
|
char name[B_FILE_NAME_LENGTH];
|
|
|
|
struct stat stat;
|
|
|
|
status_t status;
|
|
|
|
|
2004-02-22 17:52:59 +03:00
|
|
|
if (!IS_USER_ADDRESS(userName)
|
|
|
|
|| !IS_USER_ADDRESS(userStat)
|
2002-10-17 23:34:09 +04:00
|
|
|
|| user_strlcpy(name, userName, B_FILE_NAME_LENGTH) < B_OK)
|
|
|
|
return B_BAD_ADDRESS;
|
|
|
|
|
|
|
|
status = index_name_read_stat(device, name, &stat, false);
|
|
|
|
if (status == B_OK) {
|
|
|
|
if (user_memcpy(userStat, &stat, sizeof(stat)) < B_OK)
|
|
|
|
return B_BAD_ADDRESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
return status;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-06-15 19:35:10 +04:00
|
|
|
status_t
|
|
|
|
_user_remove_index(dev_t device, const char *userName)
|
2002-10-17 23:34:09 +04:00
|
|
|
{
|
|
|
|
char name[B_FILE_NAME_LENGTH];
|
2008-03-04 19:59:59 +03:00
|
|
|
|
2004-02-22 17:52:59 +03:00
|
|
|
if (!IS_USER_ADDRESS(userName)
|
2002-10-17 23:34:09 +04:00
|
|
|
|| user_strlcpy(name, userName, B_FILE_NAME_LENGTH) < B_OK)
|
|
|
|
return B_BAD_ADDRESS;
|
|
|
|
|
|
|
|
return index_remove(device, name, false);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-06-15 19:35:10 +04:00
|
|
|
status_t
|
|
|
|
_user_getcwd(char *userBuffer, size_t size)
|
2002-07-09 16:24:59 +04:00
|
|
|
{
|
2004-02-22 17:52:59 +03:00
|
|
|
if (!IS_USER_ADDRESS(userBuffer))
|
2002-08-14 00:39:25 +04:00
|
|
|
return B_BAD_ADDRESS;
|
|
|
|
|
2006-03-05 21:11:59 +03:00
|
|
|
KPath pathBuffer(B_PATH_NAME_LENGTH + 1);
|
|
|
|
if (pathBuffer.InitCheck() != B_OK)
|
|
|
|
return B_NO_MEMORY;
|
|
|
|
|
|
|
|
TRACE(("user_getcwd: buf %p, %ld\n", userBuffer, size));
|
|
|
|
|
2004-11-01 03:35:27 +03:00
|
|
|
if (size > B_PATH_NAME_LENGTH)
|
|
|
|
size = B_PATH_NAME_LENGTH;
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2006-03-05 21:11:59 +03:00
|
|
|
char *path = pathBuffer.LockBuffer();
|
|
|
|
|
|
|
|
status_t status = get_cwd(path, size, false);
|
|
|
|
if (status < B_OK)
|
2002-07-20 04:16:12 +04:00
|
|
|
return status;
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2002-07-20 04:16:12 +04:00
|
|
|
// Copy back the result
|
2006-03-05 21:11:59 +03:00
|
|
|
if (user_strlcpy(userBuffer, path, size) < B_OK)
|
2002-10-08 07:24:51 +04:00
|
|
|
return B_BAD_ADDRESS;
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2002-07-20 04:16:12 +04:00
|
|
|
return status;
|
2002-07-09 16:24:59 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-06-15 19:35:10 +04:00
|
|
|
status_t
|
|
|
|
_user_setcwd(int fd, const char *userPath)
|
2002-07-09 16:24:59 +04:00
|
|
|
{
|
2005-12-16 20:35:03 +03:00
|
|
|
TRACE(("user_setcwd: path = %p\n", userPath));
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2006-03-05 21:11:59 +03:00
|
|
|
KPath pathBuffer(B_PATH_NAME_LENGTH);
|
|
|
|
if (pathBuffer.InitCheck() != B_OK)
|
|
|
|
return B_NO_MEMORY;
|
|
|
|
|
|
|
|
char *path = pathBuffer.LockBuffer();
|
|
|
|
|
2005-04-05 05:09:07 +04:00
|
|
|
if (userPath != NULL) {
|
2004-02-22 17:52:59 +03:00
|
|
|
if (!IS_USER_ADDRESS(userPath)
|
2004-11-01 03:35:27 +03:00
|
|
|
|| user_strlcpy(path, userPath, B_PATH_NAME_LENGTH) < B_OK)
|
2002-08-10 00:20:28 +04:00
|
|
|
return B_BAD_ADDRESS;
|
2002-10-08 07:24:51 +04:00
|
|
|
}
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2005-04-05 05:09:07 +04:00
|
|
|
return set_cwd(fd, userPath != NULL ? path : NULL, false);
|
2002-07-09 16:24:59 +04:00
|
|
|
}
|
2002-07-20 04:16:12 +04:00
|
|
|
|
2004-08-29 00:38:39 +04:00
|
|
|
|
2008-03-30 09:59:54 +04:00
|
|
|
status_t
|
|
|
|
_user_change_root(const char *userPath)
|
|
|
|
{
|
|
|
|
// only root is allowed to chroot()
|
|
|
|
if (geteuid() != 0)
|
|
|
|
return EPERM;
|
|
|
|
|
|
|
|
// alloc path buffer
|
|
|
|
KPath pathBuffer(B_PATH_NAME_LENGTH);
|
|
|
|
if (pathBuffer.InitCheck() != B_OK)
|
|
|
|
return B_NO_MEMORY;
|
|
|
|
|
|
|
|
// copy userland path to kernel
|
|
|
|
char *path = pathBuffer.LockBuffer();
|
|
|
|
if (userPath != NULL) {
|
|
|
|
if (!IS_USER_ADDRESS(userPath)
|
|
|
|
|| user_strlcpy(path, userPath, B_PATH_NAME_LENGTH) < B_OK)
|
|
|
|
return B_BAD_ADDRESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
// get the vnode
|
|
|
|
struct vnode* vnode;
|
|
|
|
status_t status = path_to_vnode(path, true, &vnode, NULL, false);
|
|
|
|
if (status != B_OK)
|
|
|
|
return status;
|
|
|
|
|
|
|
|
// set the new root
|
|
|
|
struct io_context* context = get_current_io_context(false);
|
|
|
|
benaphore_lock(&sIOContextRootLock);
|
|
|
|
struct vnode* oldRoot = context->root;
|
|
|
|
context->root = vnode;
|
|
|
|
benaphore_unlock(&sIOContextRootLock);
|
|
|
|
|
|
|
|
put_vnode(oldRoot);
|
|
|
|
|
|
|
|
return B_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-08-29 00:38:39 +04:00
|
|
|
int
|
2004-12-12 23:39:45 +03:00
|
|
|
_user_open_query(dev_t device, const char *userQuery, size_t queryLength,
|
|
|
|
uint32 flags, port_id port, int32 token)
|
2004-08-29 00:38:39 +04:00
|
|
|
{
|
2004-12-12 23:39:45 +03:00
|
|
|
char *query;
|
|
|
|
|
2006-02-27 16:23:29 +03:00
|
|
|
if (device < 0 || userQuery == NULL || queryLength == 0)
|
2004-12-12 23:39:45 +03:00
|
|
|
return B_BAD_VALUE;
|
|
|
|
|
2006-02-27 16:23:29 +03:00
|
|
|
// this is a safety restriction
|
|
|
|
if (queryLength >= 65536)
|
|
|
|
return B_NAME_TOO_LONG;
|
|
|
|
|
2004-12-12 23:39:45 +03:00
|
|
|
query = (char *)malloc(queryLength + 1);
|
|
|
|
if (query == NULL)
|
|
|
|
return B_NO_MEMORY;
|
|
|
|
if (user_strlcpy(query, userQuery, queryLength + 1) < B_OK) {
|
|
|
|
free(query);
|
|
|
|
return B_BAD_ADDRESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
int fd = query_open(device, query, flags, port, token, false);
|
|
|
|
|
|
|
|
free(query);
|
|
|
|
return fd;
|
2004-08-29 00:38:39 +04:00
|
|
|
}
|