* Introduced dedicated syscalls for the deprecated BeOS fs_attr API. Before,

each attribute access needed 3 syscalls, now only one as it should.
* Renamed the new Haiku call fs_open_attr() to fs_fopen_attr(), and added a new
  function fs_open_attr() that takes a path (same semantics as the
  fs_[f]open_attr_dir() functions already present in BeOS).
* Merged former _kern_open_attr(), and _kern_create_attr() into one syscall.
* Cleaned up vfs.h.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@31881 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler
2009-07-29 00:34:44 +00:00
parent b237fdf90a
commit 8ae594ffd4
7 changed files with 357 additions and 276 deletions
+14 -11
View File
@@ -1,7 +1,7 @@
/* File System attributes
**
** Distributed under the terms of the OpenBeOS License.
*/
/*
* Copyright 2004-2009, Haiku Inc. All Rights Reserved.
* Distributed under the terms of the MIT License.
*/
#ifndef _FS_ATTR_H
#define _FS_ATTR_H
@@ -20,15 +20,18 @@ typedef struct attr_info {
extern "C" {
#endif
extern ssize_t fs_read_attr(int fd, const char *attribute, uint32 type, off_t pos, void *buffer, size_t readBytes);
extern ssize_t fs_write_attr(int fd, const char *attribute, uint32 type, off_t pos, const void *buffer, size_t readBytes);
extern ssize_t fs_read_attr(int fd, const char *attribute, uint32 type,
off_t pos, void *buffer, size_t readBytes);
extern ssize_t fs_write_attr(int fd, const char *attribute, uint32 type,
off_t pos, const void *buffer, size_t readBytes);
extern int fs_remove_attr(int fd, const char *attribute);
extern int fs_stat_attr(int fd, const char *attribute, struct attr_info *attrInfo);
extern int fs_stat_attr(int fd, const char *attribute,
struct attr_info *attrInfo);
// ToDo: the following three functions are not part of the R5 API, and
// are only preliminary - they may change or be removed at any point
//extern int fs_open_attr(const char *path, const char *attribute, uint32 type, int openMode);
extern int fs_open_attr(int fd, const char *attribute, uint32 type, int openMode);
extern int fs_open_attr(const char *path, const char *attribute,
uint32 type, int openMode);
extern int fs_fopen_attr(int fd, const char *attribute, uint32 type,
int openMode);
extern int fs_close_attr(int fd);
extern DIR *fs_open_attr_dir(const char *path);
+187 -171
View File
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2008, Axel Dörfler, [email protected]. All rights reserved.
* Copyright 2002-2009, Axel Dörfler, [email protected].
* Distributed under the terms of the MIT License.
*
* Copyright 2001-2002, Travis Geiselbrecht. All rights reserved.
@@ -31,10 +31,12 @@
#define B_UNMOUNT_BUSY_PARTITION 0x80000000
struct attr_info;
struct file_descriptor;
struct kernel_args;
struct net_stat;
struct pollfd;
struct rlimit;
struct selectsync;
struct select_info;
struct VMCache;
@@ -67,191 +69,206 @@ typedef struct io_context {
extern "C" {
#endif
status_t vfs_init(struct kernel_args *args);
status_t vfs_bootstrap_file_systems(void);
void vfs_mount_boot_file_system(struct kernel_args *args);
void vfs_exec_io_context(io_context *context);
status_t vfs_init(struct kernel_args *args);
status_t vfs_bootstrap_file_systems(void);
void vfs_mount_boot_file_system(struct kernel_args *args);
void vfs_exec_io_context(io_context *context);
io_context *vfs_new_io_context(io_context *parentContext);
void vfs_get_io_context(io_context *context);
void vfs_put_io_context(io_context *context);
void vfs_get_io_context(io_context *context);
void vfs_put_io_context(io_context *context);
struct rlimit;
int vfs_getrlimit(int resource, struct rlimit * rlp);
int vfs_setrlimit(int resource, const struct rlimit * rlp);
int vfs_getrlimit(int resource, struct rlimit *rlp);
int vfs_setrlimit(int resource, const struct rlimit *rlp);
/* calls needed by the VM for paging and by the file cache */
int vfs_get_vnode_from_fd(int fd, bool kernel, struct vnode **_vnode);
status_t vfs_get_vnode_from_path(const char *path, bool kernel,
struct vnode **_vnode);
status_t vfs_get_vnode(dev_t mountID, ino_t vnodeID, bool canWait,
struct vnode **_vnode);
status_t vfs_entry_ref_to_vnode(dev_t mountID, ino_t directoryID,
const char *name, struct vnode **_vnode);
void vfs_vnode_to_node_ref(struct vnode *vnode, dev_t *_mountID,
ino_t *_vnodeID);
int vfs_get_vnode_from_fd(int fd, bool kernel, struct vnode **_vnode);
status_t vfs_get_vnode_from_path(const char *path, bool kernel,
struct vnode **_vnode);
status_t vfs_get_vnode(dev_t mountID, ino_t vnodeID, bool canWait,
struct vnode **_vnode);
status_t vfs_entry_ref_to_vnode(dev_t mountID, ino_t directoryID,
const char *name, struct vnode **_vnode);
void vfs_vnode_to_node_ref(struct vnode *vnode, dev_t *_mountID,
ino_t *_vnodeID);
status_t vfs_lookup_vnode(dev_t mountID, ino_t vnodeID, struct vnode **_vnode);
void vfs_put_vnode(struct vnode *vnode);
void vfs_acquire_vnode(struct vnode *vnode);
status_t vfs_get_cookie_from_fd(int fd, void **_cookie);
bool vfs_can_page(struct vnode *vnode, void *cookie);
status_t vfs_read_pages(struct vnode *vnode, void *cookie, off_t pos,
const iovec *vecs, size_t count, uint32 flags, size_t *_numBytes);
status_t vfs_write_pages(struct vnode *vnode, void *cookie, off_t pos,
const iovec *vecs, size_t count, uint32 flags, size_t *_numBytes);
status_t vfs_vnode_io(struct vnode* vnode, void* cookie, io_request* request);
status_t vfs_synchronous_io(io_request* request,
status_t (*doIO)(void* cookie, off_t offset, void* buffer,
status_t vfs_lookup_vnode(dev_t mountID, ino_t vnodeID,
struct vnode **_vnode);
void vfs_put_vnode(struct vnode *vnode);
void vfs_acquire_vnode(struct vnode *vnode);
status_t vfs_get_cookie_from_fd(int fd, void **_cookie);
bool vfs_can_page(struct vnode *vnode, void *cookie);
status_t vfs_read_pages(struct vnode *vnode, void *cookie, off_t pos,
const iovec *vecs, size_t count, uint32 flags,
size_t *_numBytes);
status_t vfs_write_pages(struct vnode *vnode, void *cookie, off_t pos,
const iovec *vecs, size_t count, uint32 flags,
size_t *_numBytes);
status_t vfs_vnode_io(struct vnode* vnode, void* cookie,
io_request* request);
status_t vfs_synchronous_io(io_request* request,
status_t (*doIO)(void* cookie, off_t offset, void* buffer,
size_t* length),
void* cookie);
status_t vfs_get_vnode_cache(struct vnode *vnode, struct VMCache **_cache,
bool allocate);
status_t vfs_get_file_map(struct vnode *vnode, off_t offset, size_t size,
struct file_io_vec *vecs, size_t *_count);
status_t vfs_get_fs_node_from_path(fs_volume *volume, const char *path,
bool kernel, void **_node);
status_t vfs_stat_vnode(struct vnode *vnode, struct stat *stat);
status_t vfs_stat_node_ref(dev_t device, ino_t inode, struct stat *stat);
status_t vfs_get_vnode_name(struct vnode *vnode, char *name, size_t nameSize);
status_t vfs_entry_ref_to_path(dev_t device, ino_t inode, const char *leaf,
char *path, size_t pathLength);
status_t vfs_get_cwd(dev_t *_mountID, ino_t *_vnodeID);
void vfs_unlock_vnode_if_locked(struct file_descriptor *descriptor);
status_t vfs_unmount(dev_t mountID, uint32 flags);
status_t vfs_disconnect_vnode(dev_t mountID, ino_t vnodeID);
void vfs_free_unused_vnodes(int32 level);
status_t vfs_get_vnode_cache(struct vnode *vnode, struct VMCache **_cache,
bool allocate);
status_t vfs_get_file_map(struct vnode *vnode, off_t offset, size_t size,
struct file_io_vec *vecs, size_t *_count);
status_t vfs_get_fs_node_from_path(fs_volume *volume, const char *path,
bool kernel, void **_node);
status_t vfs_stat_vnode(struct vnode *vnode, struct stat *stat);
status_t vfs_stat_node_ref(dev_t device, ino_t inode, struct stat *stat);
status_t vfs_get_vnode_name(struct vnode *vnode, char *name,
size_t nameSize);
status_t vfs_entry_ref_to_path(dev_t device, ino_t inode, const char *leaf,
char *path, size_t pathLength);
status_t vfs_get_cwd(dev_t *_mountID, ino_t *_vnodeID);
void vfs_unlock_vnode_if_locked(struct file_descriptor *descriptor);
status_t vfs_unmount(dev_t mountID, uint32 flags);
status_t vfs_disconnect_vnode(dev_t mountID, ino_t vnodeID);
void vfs_free_unused_vnodes(int32 level);
status_t vfs_read_stat(int fd, const char *path, bool traverseLeafLink,
struct stat *stat, bool kernel);
status_t vfs_read_stat(int fd, const char *path, bool traverseLeafLink,
struct stat *stat, bool kernel);
/* special module convenience call */
status_t vfs_get_module_path(const char *basePath, const char *moduleName,
char *pathBuffer, size_t bufferSize);
status_t vfs_get_module_path(const char *basePath, const char *moduleName,
char *pathBuffer, size_t bufferSize);
/* service call for whoever needs a normalized path */
status_t vfs_normalize_path(const char *path, char *buffer, size_t bufferSize,
bool traverseLink, bool kernel);
status_t vfs_normalize_path(const char *path, char *buffer,
size_t bufferSize, bool traverseLink, bool kernel);
/* service call for whoever wants to create a special node */
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);
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);
/* service call for the node monitor */
status_t resolve_mount_point_to_volume_root(dev_t mountID, ino_t nodeID,
dev_t *resolvedMountID, ino_t *resolvedNodeID);
status_t resolve_mount_point_to_volume_root(dev_t mountID, ino_t nodeID,
dev_t *resolvedMountID, ino_t *resolvedNodeID);
/* calls the syscall dispatcher should use for user file I/O */
dev_t _user_mount(const char *path, const char *device, const char *fs_name,
uint32 flags, const char *args, size_t argsLength);
status_t _user_unmount(const char *path, uint32 flags);
status_t _user_read_fs_info(dev_t device, struct fs_info *info);
status_t _user_write_fs_info(dev_t device, const struct fs_info *info, int mask);
dev_t _user_next_device(int32 *_cookie);
status_t _user_sync(void);
status_t _user_get_next_fd_info(team_id team, uint32 *cookie, struct fd_info *info,
size_t infoSize);
status_t _user_entry_ref_to_path(dev_t device, ino_t inode, const char *leaf,
char *userPath, size_t pathLength);
status_t _user_normalize_path(const char* userPath, bool traverseLink,
char* buffer);
int _user_open_entry_ref(dev_t device, ino_t inode, const char *name, int openMode, int perms);
int _user_open(int fd, const char *path, int openMode, int perms);
int _user_open_dir_node_ref(dev_t device, ino_t inode);
int _user_open_dir_entry_ref(dev_t device, ino_t inode, const char *uname);
int _user_open_dir(int fd, const char *path);
int _user_open_parent_dir(int fd, char *name, size_t nameLength);
status_t _user_fcntl(int fd, int op, uint32 argument);
status_t _user_fsync(int fd);
status_t _user_flock(int fd, int op);
status_t _user_read_stat(int fd, const char *path, bool traverseLink,
struct stat *stat, size_t statSize);
status_t _user_write_stat(int fd, const char *path, bool traverseLink,
const struct stat *stat, size_t statSize, int statMask);
off_t _user_seek(int fd, off_t pos, int seekType);
status_t _user_create_dir_entry_ref(dev_t device, ino_t inode, const char *name, int perms);
status_t _user_create_dir(int fd, const char *path, int perms);
status_t _user_remove_dir(int fd, const char *path);
status_t _user_read_link(int fd, const char *path, char *buffer, size_t *_bufferSize);
status_t _user_write_link(const char *path, const char *toPath);
status_t _user_create_symlink(int fd, const char *path, const char *toPath,
int mode);
status_t _user_create_link(const char *path, const char *toPath);
status_t _user_unlink(int fd, const char *path);
status_t _user_rename(int oldFD, const char *oldpath, int newFD,
const char *newpath);
status_t _user_create_fifo(const char *path, mode_t perms);
status_t _user_create_pipe(int *fds);
status_t _user_access(const char *path, int mode);
ssize_t _user_select(int numfds, fd_set *readSet, fd_set *writeSet, fd_set *errorSet,
bigtime_t timeout, const sigset_t *sigMask);
ssize_t _user_poll(struct pollfd *fds, int numfds, bigtime_t timeout);
int _user_open_attr_dir(int fd, const char *path);
int _user_create_attr(int fd, const char *name, uint32 type, int openMode);
int _user_open_attr(int fd, const char *name, int openMode);
status_t _user_remove_attr(int fd, const char *name);
status_t _user_rename_attr(int fromFile, const char *fromName, int toFile, const char *toName);
int _user_open_index_dir(dev_t device);
status_t _user_create_index(dev_t device, const char *name, uint32 type, uint32 flags);
status_t _user_read_index_stat(dev_t device, const char *name, struct stat *stat);
status_t _user_remove_index(dev_t device, const char *name);
status_t _user_getcwd(char *buffer, size_t size);
status_t _user_setcwd(int fd, const char *path);
status_t _user_change_root(const char *path);
int _user_open_query(dev_t device, const char *query, size_t queryLength, uint32 flags,
port_id port, int32 token);
dev_t _user_mount(const char *path, const char *device,
const char *fs_name, uint32 flags, const char *args,
size_t argsLength);
status_t _user_unmount(const char *path, uint32 flags);
status_t _user_read_fs_info(dev_t device, struct fs_info *info);
status_t _user_write_fs_info(dev_t device, const struct fs_info *info,
int mask);
dev_t _user_next_device(int32 *_cookie);
status_t _user_sync(void);
status_t _user_get_next_fd_info(team_id team, uint32 *cookie,
struct fd_info *info, size_t infoSize);
status_t _user_entry_ref_to_path(dev_t device, ino_t inode, const char *leaf,
char *userPath, size_t pathLength);
status_t _user_normalize_path(const char* userPath, bool traverseLink,
char* buffer);
int _user_open_entry_ref(dev_t device, ino_t inode, const char *name,
int openMode, int perms);
int _user_open(int fd, const char *path, int openMode, int perms);
int _user_open_dir_node_ref(dev_t device, ino_t inode);
int _user_open_dir_entry_ref(dev_t device, ino_t inode,
const char *name);
int _user_open_dir(int fd, const char *path);
int _user_open_parent_dir(int fd, char *name, size_t nameLength);
status_t _user_fcntl(int fd, int op, uint32 argument);
status_t _user_fsync(int fd);
status_t _user_flock(int fd, int op);
status_t _user_read_stat(int fd, const char *path, bool traverseLink,
struct stat *stat, size_t statSize);
status_t _user_write_stat(int fd, const char *path, bool traverseLink,
const struct stat *stat, size_t statSize, int statMask);
off_t _user_seek(int fd, off_t pos, int seekType);
status_t _user_create_dir_entry_ref(dev_t device, ino_t inode,
const char *name, int perms);
status_t _user_create_dir(int fd, const char *path, int perms);
status_t _user_remove_dir(int fd, const char *path);
status_t _user_read_link(int fd, const char *path, char *buffer,
size_t *_bufferSize);
status_t _user_write_link(const char *path, const char *toPath);
status_t _user_create_symlink(int fd, const char *path, const char *toPath,
int mode);
status_t _user_create_link(const char *path, const char *toPath);
status_t _user_unlink(int fd, const char *path);
status_t _user_rename(int oldFD, const char *oldpath, int newFD,
const char *newpath);
status_t _user_create_fifo(const char *path, mode_t perms);
status_t _user_create_pipe(int *fds);
status_t _user_access(const char *path, int mode);
ssize_t _user_select(int numfds, fd_set *readSet, fd_set *writeSet,
fd_set *errorSet, bigtime_t timeout, const sigset_t *sigMask);
ssize_t _user_poll(struct pollfd *fds, int numfds, bigtime_t timeout);
int _user_open_attr_dir(int fd, const char *path);
ssize_t _user_read_attr(int fd, const char *attribute, off_t pos,
void *buffer, size_t readBytes);
ssize_t _user_write_attr(int fd, const char *attribute, uint32 type,
off_t pos, const void *buffer, size_t readBytes);
status_t _user_stat_attr(int fd, const char *attribute,
struct attr_info *attrInfo);
int _user_open_attr(int fd, const char* path, const char *name,
uint32 type, int openMode);
status_t _user_remove_attr(int fd, const char *name);
status_t _user_rename_attr(int fromFile, const char *fromName, int toFile,
const char *toName);
int _user_open_index_dir(dev_t device);
status_t _user_create_index(dev_t device, const char *name, uint32 type,
uint32 flags);
status_t _user_read_index_stat(dev_t device, const char *name,
struct stat *stat);
status_t _user_remove_index(dev_t device, const char *name);
status_t _user_getcwd(char *buffer, size_t size);
status_t _user_setcwd(int fd, const char *path);
status_t _user_change_root(const char *path);
int _user_open_query(dev_t device, const char *query,
size_t queryLength, uint32 flags, port_id port, int32 token);
/* fd user prototypes (implementation located in fd.cpp) */
extern ssize_t _user_read(int fd, off_t pos, void *buffer, size_t bufferSize);
extern ssize_t _user_readv(int fd, off_t pos, const iovec *vecs, size_t count);
extern ssize_t _user_write(int fd, off_t pos, const void *buffer, size_t bufferSize);
extern ssize_t _user_writev(int fd, off_t pos, const iovec *vecs, size_t count);
extern status_t _user_ioctl(int fd, ulong cmd, void *data, size_t length);
extern ssize_t _user_read_dir(int fd, struct dirent *buffer, size_t bufferSize, uint32 maxCount);
extern status_t _user_rewind_dir(int fd);
extern status_t _user_close(int fd);
extern int _user_dup(int fd);
extern int _user_dup2(int ofd, int nfd);
extern status_t _user_lock_node(int fd);
extern status_t _user_unlock_node(int fd);
ssize_t _user_read(int fd, off_t pos, void *buffer, size_t bufferSize);
ssize_t _user_readv(int fd, off_t pos, const iovec *vecs, size_t count);
ssize_t _user_write(int fd, off_t pos, const void *buffer,
size_t bufferSize);
ssize_t _user_writev(int fd, off_t pos, const iovec *vecs, size_t count);
status_t _user_ioctl(int fd, ulong cmd, void *data, size_t length);
ssize_t _user_read_dir(int fd, struct dirent *buffer, size_t bufferSize,
uint32 maxCount);
status_t _user_rewind_dir(int fd);
status_t _user_close(int fd);
int _user_dup(int fd);
int _user_dup2(int ofd, int nfd);
status_t _user_lock_node(int fd);
status_t _user_unlock_node(int fd);
/* socket user prototypes (implementation in socket.cpp) */
extern int _user_socket(int family, int type, int protocol);
extern status_t _user_bind(int socket, const struct sockaddr *address,
socklen_t addressLength);
extern status_t _user_shutdown_socket(int socket, int how);
extern status_t _user_connect(int socket, const struct sockaddr *address,
socklen_t addressLength);
extern status_t _user_listen(int socket, int backlog);
extern int _user_accept(int socket, struct sockaddr *address,
socklen_t *_addressLength);
extern ssize_t _user_recv(int socket, void *data, size_t length,
int flags);
extern ssize_t _user_recvfrom(int socket, void *data, size_t length,
int flags, struct sockaddr *address,
socklen_t *_addressLength);
extern ssize_t _user_recvmsg(int socket, struct msghdr *message,
int flags);
extern ssize_t _user_send(int socket, const void *data, size_t length,
int flags);
extern ssize_t _user_sendto(int socket, const void *data, size_t length,
int flags, const struct sockaddr *address,
socklen_t addressLength);
extern ssize_t _user_sendmsg(int socket, const struct msghdr *message,
int flags);
extern status_t _user_getsockopt(int socket, int level, int option,
void *value, socklen_t *_length);
extern status_t _user_setsockopt(int socket, int level, int option,
const void *value, socklen_t length);
extern status_t _user_getpeername(int socket, struct sockaddr *address,
socklen_t *_addressLength);
extern status_t _user_getsockname(int socket, struct sockaddr *address,
socklen_t *_addressLength);
extern int _user_sockatmark(int socket);
extern status_t _user_socketpair(int family, int type, int protocol,
int *socketVector);
extern status_t _user_get_next_socket_stat(int family, uint32 *cookie,
struct net_stat *stat);
int _user_socket(int family, int type, int protocol);
status_t _user_bind(int socket, const struct sockaddr *address,
socklen_t addressLength);
status_t _user_shutdown_socket(int socket, int how);
status_t _user_connect(int socket, const struct sockaddr *address,
socklen_t addressLength);
status_t _user_listen(int socket, int backlog);
int _user_accept(int socket, struct sockaddr *address,
socklen_t *_addressLength);
ssize_t _user_recv(int socket, void *data, size_t length, int flags);
ssize_t _user_recvfrom(int socket, void *data, size_t length, int flags,
struct sockaddr *address, socklen_t *_addressLength);
ssize_t _user_recvmsg(int socket, struct msghdr *message, int flags);
ssize_t _user_send(int socket, const void *data, size_t length, int flags);
ssize_t _user_sendto(int socket, const void *data, size_t length, int flags,
const struct sockaddr *address, socklen_t addressLength);
ssize_t _user_sendmsg(int socket, const struct msghdr *message, int flags);
status_t _user_getsockopt(int socket, int level, int option, void *value,
socklen_t *_length);
status_t _user_setsockopt(int socket, int level, int option,
const void *value, socklen_t length);
status_t _user_getpeername(int socket, struct sockaddr *address,
socklen_t *_addressLength);
status_t _user_getsockname(int socket, struct sockaddr *address,
socklen_t *_addressLength);
int _user_sockatmark(int socket);
status_t _user_socketpair(int family, int type, int protocol,
int *socketVector);
status_t _user_get_next_socket_stat(int family, uint32 *cookie,
struct net_stat *stat);
#ifdef __cplusplus
}
@@ -286,14 +303,13 @@ protected:
};
status_t vfs_asynchronous_read_pages(struct vnode* vnode, void* cookie,
off_t pos, const iovec* vecs, size_t count, size_t numBytes,
uint32 flags, AsyncIOCallback* callback);
status_t vfs_asynchronous_write_pages(struct vnode* vnode, void* cookie,
off_t pos, const iovec* vecs, size_t count, size_t numBytes,
uint32 flags, AsyncIOCallback* callback);
status_t vfs_asynchronous_read_pages(struct vnode* vnode, void* cookie,
off_t pos, const iovec* vecs, size_t count, size_t numBytes,
uint32 flags, AsyncIOCallback* callback);
status_t vfs_asynchronous_write_pages(struct vnode* vnode, void* cookie,
off_t pos, const iovec* vecs, size_t count, size_t numBytes,
uint32 flags, AsyncIOCallback* callback);
#endif // __cplusplus
+10 -3
View File
@@ -19,6 +19,7 @@
extern "C" {
#endif
struct attr_info;
struct dirent;
struct Elf32_Sym;
struct fd_info;
@@ -250,10 +251,16 @@ extern ssize_t _kern_select(int numfds, struct fd_set *readSet,
bigtime_t timeout, const sigset_t *sigMask);
extern ssize_t _kern_poll(struct pollfd *fds, int numFDs,
bigtime_t timeout);
extern int _kern_open_attr_dir(int fd, const char *path);
extern int _kern_create_attr(int fd, const char *name, uint32 type,
int openMode);
extern int _kern_open_attr(int fd, const char *name, int openMode);
extern ssize_t _kern_read_attr(int fd, const char *attribute, off_t pos,
void *buffer, size_t readBytes);
extern ssize_t _kern_write_attr(int fd, const char *attribute, uint32 type,
off_t pos, const void *buffer, size_t readBytes);
extern status_t _kern_stat_attr(int fd, const char *attribute,
struct attr_info *attrInfo);
extern int _kern_open_attr(int fd, const char* path, const char *name,
uint32 type, int openMode);
extern status_t _kern_remove_attr(int fd, const char *name);
extern status_t _kern_rename_attr(int fromFile, const char *fromName,
int toFile, const char *toName);
+1 -1
View File
@@ -1202,7 +1202,7 @@ AboutView::_AddCopyrightsFromAttribute()
}
// open the attribute
int attrFD = fs_open_attr(appFD, "COPYRIGHTS", B_STRING_TYPE, O_RDONLY);
int attrFD = fs_fopen_attr(appFD, "COPYRIGHTS", B_STRING_TYPE, O_RDONLY);
close(appFD);
if (attrFD < 0)
return;
+1 -1
View File
@@ -168,7 +168,7 @@ sv_rewind(struct irs_sv *sv)
return;
// open the attribute
int attrFD = fs_open_attr(libraryFD, "services", B_STRING_TYPE, O_RDONLY);
int attrFD = fs_fopen_attr(libraryFD, "services", B_STRING_TYPE, O_RDONLY);
close(libraryFD);
if (attrFD < 0)
return;
+128 -41
View File
@@ -21,6 +21,7 @@
#include <sys/stat.h>
#include <unistd.h>
#include <fs_attr.h>
#include <fs_info.h>
#include <fs_interface.h>
#include <fs_volume.h>
@@ -1251,7 +1252,8 @@ static status_t
get_vnode(dev_t mountID, ino_t vnodeID, struct vnode** _vnode, bool canWait,
int reenter)
{
FUNCTION(("get_vnode: mountid %ld vnid 0x%Lx %p\n", mountID, vnodeID, _vnode));
FUNCTION(("get_vnode: mountid %ld vnid 0x%Lx %p\n", mountID, vnodeID,
_vnode));
mutex_lock(&sVnodeMutex);
@@ -1263,7 +1265,8 @@ restart:
mutex_unlock(&sVnodeMutex);
if (!canWait || --tries < 0) {
// vnode doesn't seem to become unbusy
dprintf("vnode %ld:%Ld is not becoming unbusy!\n", mountID, vnodeID);
dprintf("vnode %ld:%Ld is not becoming unbusy!\n", mountID,
vnodeID);
return B_BUSY;
}
snooze(10000); // 10 ms
@@ -5155,7 +5158,8 @@ file_create(int fd, char* path, int openMode, int perms, bool kernel)
struct vnode* directory;
int status;
FUNCTION(("file_create: path '%s', omode %x, perms %d, kernel %d\n", path, openMode, perms, kernel));
FUNCTION(("file_create: path '%s', omode %x, perms %d, kernel %d\n", path,
openMode, perms, kernel));
// get directory to put the new file in
status = fd_and_path_to_dir_vnode(fd, path, &directory, name, kernel);
@@ -6247,30 +6251,33 @@ attr_dir_rewind(struct file_descriptor* descriptor)
static int
attr_create(int fd, const char* name, uint32 type, int openMode, bool kernel)
attr_create(int fd, char* path, const char* name, uint32 type,
int openMode, bool kernel)
{
struct vnode* vnode;
void* cookie;
int status;
if (name == NULL || *name == '\0')
return B_BAD_VALUE;
vnode = get_vnode_from_fd(fd, kernel);
if (vnode == NULL)
return B_FILE_ERROR;
struct vnode* vnode;
status_t status = fd_and_path_to_vnode(fd, path,
(openMode & O_NOTRAVERSE) != 0, &vnode, NULL, kernel);
if (status != B_OK)
return status;
if (!HAS_FS_CALL(vnode, create_attr)) {
status = EROFS;
goto err;
}
void* cookie;
status = FS_CALL(vnode, create_attr, name, type, openMode, &cookie);
if (status < B_OK)
if (status != B_OK)
goto err;
if ((status = get_new_fd(FDTYPE_ATTR, NULL, vnode, cookie, openMode, kernel)) >= 0)
return status;
fd = get_new_fd(FDTYPE_ATTR, NULL, vnode, cookie, openMode, kernel);
if (fd >= 0)
return fd;
status = fd;
FS_CALL(vnode, close_attr, cookie);
FS_CALL(vnode, free_attr_cookie, cookie);
@@ -6285,31 +6292,33 @@ err:
static int
attr_open(int fd, const char* name, int openMode, bool kernel)
attr_open(int fd, char* path, const char* name, int openMode, bool kernel)
{
struct vnode* vnode;
void* cookie;
int status;
if (name == NULL || *name == '\0')
return B_BAD_VALUE;
vnode = get_vnode_from_fd(fd, kernel);
if (vnode == NULL)
return B_FILE_ERROR;
struct vnode* vnode;
status_t status = fd_and_path_to_vnode(fd, path,
(openMode & O_NOTRAVERSE) != 0, &vnode, NULL, kernel);
if (status != B_OK)
return status;
if (!HAS_FS_CALL(vnode, open_attr)) {
status = EOPNOTSUPP;
goto err;
}
void* cookie;
status = FS_CALL(vnode, open_attr, name, openMode, &cookie);
if (status < B_OK)
if (status != B_OK)
goto err;
// now we only need a file descriptor for this attribute and we're done
if ((status = get_new_fd(FDTYPE_ATTR, NULL, vnode, cookie, openMode, kernel)) >= 0)
return status;
fd = get_new_fd(FDTYPE_ATTR, NULL, vnode, cookie, openMode, kernel);
if (fd >= 0)
return fd;
status = fd;
FS_CALL(vnode, close_attr, cookie);
FS_CALL(vnode, free_attr_cookie, cookie);
@@ -8105,16 +8114,19 @@ _kern_open_attr_dir(int fd, const char* path)
int
_kern_create_attr(int fd, const char* name, uint32 type, int openMode)
_kern_open_attr(int fd, const char* path, const char* name, uint32 type,
int openMode)
{
return attr_create(fd, name, type, openMode, true);
}
KPath pathBuffer(path, false, B_PATH_NAME_LENGTH + 1);
if (pathBuffer.InitCheck() != B_OK)
return B_NO_MEMORY;
if ((openMode & O_CREAT) != 0) {
return attr_create(fd, pathBuffer.LockBuffer(), name, type, openMode,
true);
}
int
_kern_open_attr(int fd, const char* name, int openMode)
{
return attr_open(fd, name, openMode, true);
return attr_open(fd, pathBuffer.LockBuffer(), name, openMode, true);
}
@@ -9069,21 +9081,79 @@ _user_open_attr_dir(int fd, const char* userPath)
}
int
_user_create_attr(int fd, const char* userName, uint32 type, int openMode)
ssize_t
_user_read_attr(int fd, const char* attribute, off_t pos, void* userBuffer,
size_t readBytes)
{
char name[B_FILE_NAME_LENGTH];
int attr = attr_open(fd, NULL, attribute, O_RDONLY, false);
if (attr < 0)
return attr;
if (!IS_USER_ADDRESS(userName)
|| user_strlcpy(name, userName, B_FILE_NAME_LENGTH) < B_OK)
return B_BAD_ADDRESS;
ssize_t bytes = _user_read(attr, pos, userBuffer, readBytes);
_user_close(attr);
return attr_create(fd, name, type, openMode, false);
return bytes;
}
ssize_t
_user_write_attr(int fd, const char* attribute, uint32 type, off_t pos,
const void* buffer, size_t writeBytes)
{
// Try to support the BeOS typical truncation as well as the position
// argument
int attr = attr_create(fd, NULL, attribute, type,
O_CREAT | O_WRONLY | (pos != 0 ? 0 : O_TRUNC), false);
if (attr < 0)
return attr;
ssize_t bytes = _user_write(attr, pos, buffer, writeBytes);
_user_close(attr);
return bytes;
}
status_t
_user_stat_attr(int fd, const char* attribute, struct attr_info* userAttrInfo)
{
int attr = attr_open(fd, NULL, attribute, O_RDONLY, false);
if (attr < 0)
return attr;
struct file_descriptor* descriptor
= get_fd(get_current_io_context(false), attr);
if (descriptor == NULL) {
_user_close(attr);
return B_FILE_ERROR;
}
struct stat stat;
status_t status;
if (descriptor->ops->fd_read_stat)
status = descriptor->ops->fd_read_stat(descriptor, &stat);
else
status = EOPNOTSUPP;
put_fd(descriptor);
_user_close(attr);
if (status == B_OK) {
attr_info info;
info.type = stat.st_type;
info.size = stat.st_size;
if (user_memcpy(userAttrInfo, &info, sizeof(struct attr_info)) != B_OK)
return B_BAD_ADDRESS;
}
return status;
}
int
_user_open_attr(int fd, const char* userName, int openMode)
_user_open_attr(int fd, const char* userPath, const char* userName,
uint32 type, int openMode)
{
char name[B_FILE_NAME_LENGTH];
@@ -9091,7 +9161,24 @@ _user_open_attr(int fd, const char* userName, int openMode)
|| user_strlcpy(name, userName, B_FILE_NAME_LENGTH) < B_OK)
return B_BAD_ADDRESS;
return attr_open(fd, name, openMode, false);
KPath pathBuffer(B_PATH_NAME_LENGTH + 1);
if (pathBuffer.InitCheck() != B_OK)
return B_NO_MEMORY;
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;
}
if ((openMode & O_CREAT) != 0) {
return attr_create(fd, userPath ? path : NULL, name, type, openMode,
false);
}
return attr_open(fd, userPath ? path : NULL, name, openMode, false);
}
+16 -48
View File
@@ -59,13 +59,7 @@ extern "C" ssize_t
fs_read_attr(int fd, const char* attribute, uint32 /*type*/, off_t pos,
void* buffer, size_t readBytes)
{
int attr = _kern_open_attr(fd, attribute, O_RDONLY);
if (attr < 0)
RETURN_AND_SET_ERRNO(attr);
ssize_t bytes = _kern_read(attr, pos, buffer, readBytes);
_kern_close(attr);
ssize_t bytes = _kern_read_attr(fd, attribute, pos, buffer, readBytes);
RETURN_AND_SET_ERRNO(bytes);
}
@@ -74,14 +68,15 @@ extern "C" ssize_t
fs_write_attr(int fd, const char* attribute, uint32 type, off_t pos,
const void* buffer, size_t writeBytes)
{
// TODO: move this documentation into the Haiku book!
// NOTE: This call is deprecated in Haiku and has a number of problems:
// On BeOS, it was documented that the "pos" argument is ignored.
// However, a number of programs tried to use this call to write large
// attributes in a loop anyways. These programs all relied on the broken
// or at least inconsistent behaviour to truncate/clobber an existing
// attribute. In other words, writing 5 bytes at position 0 into an
// attribute that was already 10 bytes long resulted in an attribute of
// only 5 bytes length.
// On BeOS, it was documented that the "pos" argument is ignored, however,
// that did not actually happen if the attribute was backed up by a real
// file.
// Also, it will truncate any existing attribute, disregarding the specified
// position.
// The implementation of this function tries to stay compatible with
// BeOS in that it clobbers the existing attribute when you write at offset
// 0, but it also tries to support programs which continue to write more
@@ -91,14 +86,8 @@ fs_write_attr(int fd, const char* attribute, uint32 type, off_t pos,
// see from this implementation, it saves 2 syscalls per writing a chunk
// of data.
int attr = _kern_create_attr(fd, attribute, type,
O_WRONLY | (pos != 0 ? 0 : O_TRUNC));
if (attr < 0)
RETURN_AND_SET_ERRNO(attr);
ssize_t bytes = _kern_write(attr, pos, buffer, writeBytes);
_kern_close(attr);
ssize_t bytes = _kern_write_attr(fd, attribute, type, pos, buffer,
writeBytes);
RETURN_AND_SET_ERRNO(bytes);
}
@@ -115,44 +104,23 @@ fs_remove_attr(int fd, const char* attribute)
extern "C" int
fs_stat_attr(int fd, const char* attribute, struct attr_info* attrInfo)
{
int attr = _kern_open_attr(fd, attribute, O_RDONLY);
if (attr < 0)
RETURN_AND_SET_ERRNO(attr);
struct stat stat;
status_t status = _kern_read_stat(attr, NULL, false, &stat,
sizeof(struct stat));
if (status == B_OK) {
attrInfo->type = stat.st_type;
attrInfo->size = stat.st_size;
}
_kern_close(attr);
status_t status = _kern_stat_attr(fd, attribute, attrInfo);
RETURN_AND_SET_ERRNO(status);
}
/*
int
fs_open_attr(const char *path, const char *attribute, uint32 type, int openMode)
{
// TODO: implement fs_open_attr() - or remove it completely
// if it will be implemented, rename the current fs_open_attr() to fs_fopen_attr()
return B_ERROR;
status_t status = _kern_open_attr(-1, path, attribute, type, openMode);
RETURN_AND_SET_ERRNO(status);
}
*/
extern "C" int
fs_open_attr(int fd, const char* attribute, uint32 type, int openMode)
fs_fopen_attr(int fd, const char* attribute, uint32 type, int openMode)
{
status_t status;
if ((openMode & O_CREAT) != 0)
status = _kern_create_attr(fd, attribute, type, openMode);
else
status = _kern_open_attr(fd, attribute, openMode);
status_t status = _kern_open_attr(fd, NULL, attribute, type, openMode);
RETURN_AND_SET_ERRNO(status);
}