Added the write_link() call (currently only local to the VFS).

Added a mode parameter to sys_create_symlink().
Added an open_mode field to struct file_descriptor.


git-svn-id: file:///srv/svn/repos/haiku/trunk/current@592 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler
2002-08-05 05:37:17 +00:00
parent dfa8e8ef78
commit 1e3eaf3b95
7 changed files with 115 additions and 102 deletions
-1
View File
@@ -490,7 +490,6 @@ KernelLd libc.so :
; ;
KernelLd libroot.so : KernelLd libroot.so :
# libglue2.o
libglue.o libglue.o
<$(SOURCE_GRIST)!libroot>libroot.o <$(SOURCE_GRIST)!libroot>libroot.o
: :
+12 -23
View File
@@ -16,12 +16,7 @@
#define CHECK_USER_ADDR(x) \ #define CHECK_USER_ADDR(x) \
if ((addr)(x) >= KERNEL_BASE && (addr)(x) <= KERNEL_TOP) \ if ((addr)(x) >= KERNEL_BASE && (addr)(x) <= KERNEL_TOP) \
return EINVAL; return B_BAD_ADDRESS;
#define CHECK_SYS_ADDR(x) \
if ((addr)(x) < KERNEL_BASE && (addr)(x) >= KERNEL_TOP) \
return EINVAL;
#define TRACE_FD 0 #define TRACE_FD 0
#if TRACE_FD #if TRACE_FD
@@ -53,15 +48,18 @@ dump_fd(int fd,struct file_descriptor *descriptor)
struct file_descriptor * struct file_descriptor *
alloc_fd(void) alloc_fd(void)
{ {
struct file_descriptor *f; struct file_descriptor *descriptor;
f = kmalloc(sizeof(struct file_descriptor)); descriptor = kmalloc(sizeof(struct file_descriptor));
if (f) { if (descriptor == NULL)
f->vnode = NULL; return NULL;
f->cookie = NULL;
f->ref_count = 1; descriptor->vnode = NULL;
} descriptor->cookie = NULL;
return f; descriptor->ref_count = 1;
descriptor->open_mode = 0;
return descriptor;
} }
@@ -446,11 +444,6 @@ sys_read(int fd, void *buffer, off_t pos, size_t length)
struct file_descriptor *descriptor; struct file_descriptor *descriptor;
ssize_t retval; ssize_t retval;
/* This is a sys_function, so abort if we have a kernel address */
// I've removed those checks because we have to be able to load things
// into user memory as well -- axeld.
//CHECK_SYS_ADDR(buffer)
descriptor = get_fd(get_current_io_context(true), fd); descriptor = get_fd(get_current_io_context(true), fd);
if (!descriptor) if (!descriptor)
return EBADF; return EBADF;
@@ -473,8 +466,6 @@ sys_write(int fd, const void *buffer, off_t pos, size_t length)
struct file_descriptor *descriptor; struct file_descriptor *descriptor;
ssize_t retval; ssize_t retval;
// CHECK_SYS_ADDR(buffer)
descriptor = get_fd(get_current_io_context(true), fd); descriptor = get_fd(get_current_io_context(true), fd);
if (descriptor == NULL) if (descriptor == NULL)
return EBADF; return EBADF;
@@ -520,8 +511,6 @@ sys_ioctl(int fd, ulong op, void *buffer, size_t length)
PRINT(("sys_ioctl: fd %d\n", fd)); PRINT(("sys_ioctl: fd %d\n", fd));
CHECK_SYS_ADDR(buffer)
descriptor = get_fd(get_current_io_context(true), fd); descriptor = get_fd(get_current_io_context(true), fd);
if (descriptor == NULL) if (descriptor == NULL)
return EBADF; return EBADF;
+1
View File
@@ -1029,6 +1029,7 @@ static struct fs_calls bootfs_calls = {
&bootfs_fsync, &bootfs_fsync,
NULL, // read_link NULL, // read_link
NULL, // write_link
NULL, // symlink NULL, // symlink
&bootfs_unlink, &bootfs_unlink,
&bootfs_rename, &bootfs_rename,
+2 -1
View File
@@ -24,7 +24,7 @@
#include <stdio.h> #include <stdio.h>
#define DEVFS_TRACE 0 #define DEVFS_TRACE 1
#if DEVFS_TRACE #if DEVFS_TRACE
# define TRACE(x) dprintf x # define TRACE(x) dprintf x
@@ -1068,6 +1068,7 @@ static struct fs_calls devfs_calls = {
&devfs_fsync, &devfs_fsync,
NULL, // read_link NULL, // read_link
NULL, // write_link
NULL, // symlink NULL, // symlink
&devfs_unlink, &devfs_unlink,
&devfs_rename, &devfs_rename,
+2 -1
View File
@@ -699,7 +699,7 @@ rootfs_read_link(fs_cookie _fs, fs_vnode _link, char *buffer, size_t bufferSize)
static int static int
rootfs_symlink(fs_cookie _fs, fs_vnode _dir, const char *name, const char *path) rootfs_symlink(fs_cookie _fs, fs_vnode _dir, const char *name, const char *path, int mode)
{ {
struct rootfs *fs = _fs; struct rootfs *fs = _fs;
struct rootfs_vnode *dir = _dir; struct rootfs_vnode *dir = _dir;
@@ -920,6 +920,7 @@ static struct fs_calls rootfs_calls = {
&rootfs_fsync, &rootfs_fsync,
&rootfs_read_link, &rootfs_read_link,
NULL, // fs_write_link()
&rootfs_symlink, &rootfs_symlink,
&rootfs_unlink, &rootfs_unlink,
&rootfs_rename, &rootfs_rename,
+97 -75
View File
@@ -37,7 +37,7 @@
#include <fcntl.h> #include <fcntl.h>
#ifndef TRACE_VFS #ifndef TRACE_VFS
# define TRACE_VFS 0 # define TRACE_VFS 1
#endif #endif
#if TRACE_VFS #if TRACE_VFS
# define PRINT(x) dprintf x # define PRINT(x) dprintf x
@@ -101,10 +101,10 @@ struct fs_mount {
bool unmounting; bool unmounting;
}; };
static mutex vfs_mutex; static mutex gRegisterMutex;
static mutex vfs_mount_mutex; static mutex gMountMutex;
static mutex vfs_mount_op_mutex; static mutex gMountOpMutex;
static mutex vfs_vnode_mutex; static mutex gVnodeMutex;
/* function declarations */ /* function declarations */
static int vfs_mount(char *path, const char *device, const char *fs_name, void *args, bool kernel); static int vfs_mount(char *path, const char *device, const char *fs_name, void *args, bool kernel);
@@ -205,11 +205,11 @@ find_mount(fs_id id)
{ {
struct fs_mount *mount; struct fs_mount *mount;
mutex_lock(&vfs_mount_mutex); mutex_lock(&gMountMutex);
mount = hash_lookup(mounts_table, &id); mount = hash_lookup(mounts_table, &id);
mutex_unlock(&vfs_mount_mutex); mutex_unlock(&gMountMutex);
return mount; return mount;
} }
@@ -300,7 +300,7 @@ dec_vnode_ref_count(struct vnode *vnode, bool reenter)
int err; int err;
int old_ref; int old_ref;
mutex_lock(&vfs_vnode_mutex); mutex_lock(&gVnodeMutex);
if (vnode->busy == true) if (vnode->busy == true)
panic("dec_vnode_ref_count called on vnode that was busy! vnode %p\n", vnode); panic("dec_vnode_ref_count called on vnode that was busy! vnode %p\n", vnode);
@@ -312,7 +312,7 @@ dec_vnode_ref_count(struct vnode *vnode, bool reenter)
if (old_ref == 1) { if (old_ref == 1) {
vnode->busy = true; vnode->busy = true;
mutex_unlock(&vfs_vnode_mutex); mutex_unlock(&gVnodeMutex);
/* if we have a vm_cache attached, remove it */ /* if we have a vm_cache attached, remove it */
if (vnode->cache) if (vnode->cache)
@@ -326,14 +326,14 @@ dec_vnode_ref_count(struct vnode *vnode, bool reenter)
remove_vnode_from_mount_list(vnode, vnode->mount); remove_vnode_from_mount_list(vnode, vnode->mount);
mutex_lock(&vfs_vnode_mutex); mutex_lock(&gVnodeMutex);
hash_remove(vnode_table, vnode); hash_remove(vnode_table, vnode);
mutex_unlock(&vfs_vnode_mutex); mutex_unlock(&gVnodeMutex);
kfree(vnode); kfree(vnode);
err = 1; err = 1;
} else { } else {
mutex_unlock(&vfs_vnode_mutex); mutex_unlock(&gVnodeMutex);
err = 0; err = 0;
} }
return err; return err;
@@ -369,15 +369,15 @@ get_vnode(fs_id fsID, vnode_id vnodeID, struct vnode **_vnode, int reenter)
FUNCTION(("get_vnode: fsid %d vnid 0x%Lx 0x%p\n", fsID, vnodeID,_vnode)); FUNCTION(("get_vnode: fsid %d vnid 0x%Lx 0x%p\n", fsID, vnodeID,_vnode));
mutex_lock(&vfs_vnode_mutex); mutex_lock(&gVnodeMutex);
do { do {
vnode = lookup_vnode(fsID, vnodeID); vnode = lookup_vnode(fsID, vnodeID);
if (vnode) { if (vnode) {
if (vnode->busy) { if (vnode->busy) {
mutex_unlock(&vfs_vnode_mutex); mutex_unlock(&gVnodeMutex);
snooze(10000); // 10 ms snooze(10000); // 10 ms
mutex_lock(&vfs_vnode_mutex); mutex_lock(&gVnodeMutex);
continue; continue;
} }
} }
@@ -403,7 +403,7 @@ get_vnode(fs_id fsID, vnode_id vnodeID, struct vnode **_vnode, int reenter)
} }
vnode->busy = true; vnode->busy = true;
hash_insert(vnode_table, vnode); hash_insert(vnode_table, vnode);
mutex_unlock(&vfs_vnode_mutex); mutex_unlock(&gVnodeMutex);
add_vnode_to_mount_list(vnode, vnode->mount); add_vnode_to_mount_list(vnode, vnode->mount);
@@ -413,7 +413,7 @@ get_vnode(fs_id fsID, vnode_id vnodeID, struct vnode **_vnode, int reenter)
if (vnode->private_node == NULL) if (vnode->private_node == NULL)
err = EINVAL; err = EINVAL;
} }
mutex_lock(&vfs_vnode_mutex); mutex_lock(&gVnodeMutex);
if (err < 0) if (err < 0)
goto err1; goto err1;
@@ -421,7 +421,7 @@ get_vnode(fs_id fsID, vnode_id vnodeID, struct vnode **_vnode, int reenter)
vnode->ref_count = 1; vnode->ref_count = 1;
} }
mutex_unlock(&vfs_vnode_mutex); mutex_unlock(&gVnodeMutex);
PRINT(("get_vnode: returning 0x%p\n", vnode)); PRINT(("get_vnode: returning 0x%p\n", vnode));
@@ -431,7 +431,7 @@ get_vnode(fs_id fsID, vnode_id vnodeID, struct vnode **_vnode, int reenter)
err1: err1:
hash_remove(vnode_table, vnode); hash_remove(vnode_table, vnode);
err: err:
mutex_unlock(&vfs_vnode_mutex); mutex_unlock(&gVnodeMutex);
if (vnode) if (vnode)
kfree(vnode); kfree(vnode);
@@ -541,9 +541,9 @@ entry_ref_to_vnode(fs_id fsID,vnode_id directoryID,const char *name,struct vnode
if (status < 0) if (status < 0)
return status; return status;
mutex_lock(&vfs_vnode_mutex); mutex_lock(&gVnodeMutex);
vnode = lookup_vnode(fsID, id); vnode = lookup_vnode(fsID, id);
mutex_unlock(&vfs_vnode_mutex); mutex_unlock(&gVnodeMutex);
if (vnode == NULL) { if (vnode == NULL) {
// fs_lookup() should have left the vnode referenced, so chances // fs_lookup() should have left the vnode referenced, so chances
@@ -609,9 +609,9 @@ vnode_path_to_vnode(struct vnode *vnode, char *path, bool traverseLeafLink, stru
// lookup the vnode, the call to fs_lookup should have caused a get_vnode to be called // lookup the vnode, the call to fs_lookup should have caused a get_vnode to be called
// from inside the filesystem, thus the vnode would have to be in the list and it's // from inside the filesystem, thus the vnode would have to be in the list and it's
// ref count incremented at this point // ref count incremented at this point
mutex_lock(&vfs_vnode_mutex); mutex_lock(&gVnodeMutex);
nextVnode = lookup_vnode(vnode->fs_id, vnodeID); nextVnode = lookup_vnode(vnode->fs_id, vnodeID);
mutex_unlock(&vfs_vnode_mutex); mutex_unlock(&gVnodeMutex);
if (!nextVnode) { if (!nextVnode) {
// pretty screwed up here // pretty screwed up here
@@ -797,9 +797,9 @@ dir_vnode_to_path(struct vnode *vnode, char *buffer, size_t bufferSize)
if (status < B_OK) if (status < B_OK)
goto out; goto out;
mutex_lock(&vfs_vnode_mutex); mutex_lock(&gVnodeMutex);
parentVnode = lookup_vnode(vnode->fs_id, parentID); parentVnode = lookup_vnode(vnode->fs_id, parentID);
mutex_unlock(&vfs_vnode_mutex); mutex_unlock(&gVnodeMutex);
if (parentVnode == NULL) { if (parentVnode == NULL) {
panic("dir_vnode_to_path: could not lookup vnode (fsid 0x%x vnid 0x%Lx)\n", vnode->fs_id, parentID); panic("dir_vnode_to_path: could not lookup vnode (fsid 0x%x vnid 0x%Lx)\n", vnode->fs_id, parentID);
@@ -903,7 +903,7 @@ check_path(char *to)
char *begin; char *begin;
if (*to == '/') if (*to == '/')
to++, length++; to++, length++;
begin = to; begin = to;
while (*to != '/' && *to) while (*to != '/' && *to)
to++, length++; to++, length++;
@@ -911,7 +911,7 @@ check_path(char *to)
if (to - begin > B_FILE_NAME_LENGTH) if (to - begin > B_FILE_NAME_LENGTH)
return B_NAME_TOO_LONG; return B_NAME_TOO_LONG;
} }
if (length == 0) if (length == 0)
return B_ENTRY_NOT_FOUND; return B_ENTRY_NOT_FOUND;
@@ -924,7 +924,7 @@ check_path(char *to)
to[0] = '.'; to[0] = '.';
to[1] = '\0'; to[1] = '\0';
} }
return B_OK; return B_OK;
} }
@@ -952,9 +952,9 @@ vfs_put_vnode(fs_id fsID, vnode_id vnodeID)
{ {
struct vnode *vnode; struct vnode *vnode;
mutex_lock(&vfs_vnode_mutex); mutex_lock(&gVnodeMutex);
vnode = lookup_vnode(fsID, vnodeID); vnode = lookup_vnode(fsID, vnodeID);
mutex_unlock(&vfs_vnode_mutex); mutex_unlock(&gVnodeMutex);
if (vnode) if (vnode)
dec_vnode_ref_count(vnode, true); dec_vnode_ref_count(vnode, true);
@@ -984,13 +984,13 @@ vfs_remove_vnode(fs_id fsid, vnode_id vnid)
{ {
struct vnode *vnode; struct vnode *vnode;
mutex_lock(&vfs_vnode_mutex); mutex_lock(&gVnodeMutex);
vnode = lookup_vnode(fsid, vnid); vnode = lookup_vnode(fsid, vnid);
if (vnode) if (vnode)
vnode->delete_me = true; vnode->delete_me = true;
mutex_unlock(&vfs_vnode_mutex); mutex_unlock(&gVnodeMutex);
return 0; return 0;
} }
@@ -1489,12 +1489,12 @@ vfs_register_filesystem(const char *name, struct fs_calls *calls)
container->name = name; container->name = name;
container->calls = calls; container->calls = calls;
mutex_lock(&vfs_mutex); mutex_lock(&gRegisterMutex);
container->next = fs_list; container->next = fs_list;
fs_list = container; fs_list = container;
mutex_unlock(&vfs_mutex); mutex_unlock(&gRegisterMutex);
return 0; return 0;
} }
@@ -1519,16 +1519,16 @@ vfs_init(kernel_args *ka)
fs_list = NULL; fs_list = NULL;
root_vnode = NULL; root_vnode = NULL;
if (mutex_init(&vfs_mutex, "vfs_lock") < 0) if (mutex_init(&gRegisterMutex, "vfs_lock") < 0)
panic("vfs_init: error allocating vfs lock\n"); panic("vfs_init: error allocating vfs lock\n");
if (mutex_init(&vfs_mount_op_mutex, "vfs_mount_op_lock") < 0) if (mutex_init(&gMountOpMutex, "vfs_mount_op_lock") < 0)
panic("vfs_init: error allocating vfs_mount_op lock\n"); panic("vfs_init: error allocating vfs_mount_op lock\n");
if (mutex_init(&vfs_mount_mutex, "vfs_mount_lock") < 0) if (mutex_init(&gMountMutex, "vfs_mount_lock") < 0)
panic("vfs_init: error allocating vfs_mount lock\n"); panic("vfs_init: error allocating vfs_mount lock\n");
if (mutex_init(&vfs_vnode_mutex, "vfs_vnode_lock") < 0) if (mutex_init(&gVnodeMutex, "vfs_vnode_lock") < 0)
panic("vfs_init: error allocating vfs_vnode lock\n"); panic("vfs_init: error allocating vfs_vnode lock\n");
return 0; return 0;
@@ -1540,7 +1540,7 @@ vfs_init(kernel_args *ka)
static int static int
new_file_fd(struct vnode *vnode,file_cookie cookie, bool kernel) new_file_fd(struct vnode *vnode, file_cookie cookie, int openMode, bool kernel)
{ {
struct file_descriptor *descriptor; struct file_descriptor *descriptor;
int fd; int fd;
@@ -1553,6 +1553,7 @@ new_file_fd(struct vnode *vnode,file_cookie cookie, bool kernel)
descriptor->cookie = cookie; descriptor->cookie = cookie;
descriptor->ops = &file_ops; descriptor->ops = &file_ops;
descriptor->type = FDTYPE_FILE; descriptor->type = FDTYPE_FILE;
descriptor->open_mode = openMode;
fd = new_fd(get_current_io_context(kernel), descriptor); fd = new_fd(get_current_io_context(kernel), descriptor);
if (fd < 0) if (fd < 0)
@@ -1581,16 +1582,16 @@ create_vnode(struct vnode *directory, const char *name, int omode, int perms, bo
if (status < B_OK) if (status < B_OK)
return status; return status;
mutex_lock(&vfs_vnode_mutex); mutex_lock(&gVnodeMutex);
vnode = lookup_vnode(directory->fs_id, newID); vnode = lookup_vnode(directory->fs_id, newID);
mutex_unlock(&vfs_vnode_mutex); mutex_unlock(&gVnodeMutex);
if (vnode == NULL) { if (vnode == NULL) {
dprintf("vfs: fs_create() returned success but there is no vnode!"); dprintf("vfs: fs_create() returned success but there is no vnode!");
return EINVAL; return EINVAL;
} }
if ((status = new_file_fd(vnode,cookie,kernel)) >= 0) if ((status = new_file_fd(vnode,cookie,omode,kernel)) >= 0)
return status; return status;
FS_CALL(vnode,fs_close)(vnode->mount->cookie, vnode->private_node, cookie); FS_CALL(vnode,fs_close)(vnode->mount->cookie, vnode->private_node, cookie);
@@ -1617,7 +1618,7 @@ open_vnode(struct vnode *vnode, int omode, bool kernel)
if (status < 0) if (status < 0)
return status; return status;
status = new_file_fd(vnode,cookie,kernel); status = new_file_fd(vnode, cookie, omode, kernel);
if (status < 0) { if (status < 0) {
FS_CALL(vnode,fs_close)(vnode->mount->cookie, vnode->private_node, cookie); FS_CALL(vnode,fs_close)(vnode->mount->cookie, vnode->private_node, cookie);
FS_CALL(vnode,fs_free_cookie)(vnode->mount->cookie, vnode->private_node, cookie); FS_CALL(vnode,fs_free_cookie)(vnode->mount->cookie, vnode->private_node, cookie);
@@ -1657,7 +1658,7 @@ open_dir_vnode(struct vnode *vnode, bool kernel)
return fd; return fd;
err1: err1:
status = ERR_VFS_FD_TABLE_FULL; status = B_NO_MORE_FDS;
kfree(descriptor); kfree(descriptor);
err: err:
@@ -1743,7 +1744,7 @@ file_open(char *path, int omode, bool kernel)
FUNCTION(("file_open: entry. path = '%s', omode %d, kernel %d\n", path, omode, kernel)); FUNCTION(("file_open: entry. path = '%s', omode %d, kernel %d\n", path, omode, kernel));
// get the vnode matching the path // get the vnode matching the path
status = path_to_vnode(path, true, &vnode, kernel); status = path_to_vnode(path, (omode & O_NOTRAVERSE) == 0, &vnode, kernel);
if (status < B_OK) if (status < B_OK)
return status; return status;
@@ -1774,7 +1775,7 @@ file_read(struct file_descriptor *descriptor, void *buffer, off_t pos, size_t *l
{ {
struct vnode *vnode = descriptor->vnode; struct vnode *vnode = descriptor->vnode;
FUNCTION(("file_read: buf %p, pos %Ld, len 0x%p\n", buffer, pos, length)); FUNCTION(("file_read: buf %p, pos %Ld, len %p = %ld\n", buffer, pos, length, *length));
return FS_CALL(vnode,fs_read)(vnode->mount->cookie, vnode->private_node, descriptor->cookie, buffer, pos, length); return FS_CALL(vnode,fs_read)(vnode->mount->cookie, vnode->private_node, descriptor->cookie, buffer, pos, length);
} }
@@ -1784,7 +1785,7 @@ file_write(struct file_descriptor *descriptor, const void *buffer, off_t pos, si
{ {
struct vnode *vnode = descriptor->vnode; struct vnode *vnode = descriptor->vnode;
FUNCTION(("file_write: buf %p, pos %Ld, len 0x%p\n", buffer, pos, length)); FUNCTION(("file_write: buf %p, pos %Ld, len %p\n", buffer, pos, length));
return FS_CALL(vnode,fs_write)(vnode->mount->cookie, vnode->private_node, descriptor->cookie, buffer, pos, length); return FS_CALL(vnode,fs_write)(vnode->mount->cookie, vnode->private_node, descriptor->cookie, buffer, pos, length);
} }
@@ -2013,21 +2014,42 @@ common_read_link(char *path, char *buffer, size_t bufferSize, bool kernel)
static int static int
common_symlink(char *path, const char *toPath, bool kernel) common_write_link(char *path, char *toPath, bool kernel)
{
struct vnode *vnode;
int status;
status = path_to_vnode(path, false, &vnode, kernel);
if (status < B_OK)
return status;
if (FS_CALL(vnode,fs_write_link) != NULL)
status = FS_CALL(vnode,fs_write_link)(vnode->mount->cookie, vnode->private_node, toPath);
else
status = EOPNOTSUPP;
put_vnode(vnode);
return status;
}
static int
common_create_symlink(char *path, const char *toPath, int mode, bool kernel)
{ {
// path validity checks have to be in the calling function! // path validity checks have to be in the calling function!
char name[B_FILE_NAME_LENGTH]; char name[B_FILE_NAME_LENGTH];
struct vnode *vnode; struct vnode *vnode;
int status; int status;
FUNCTION(("common_symlink(path = %s, toPath = %s, kernel = %d)\n", path, toPath, kernel)); FUNCTION(("common_create_alias(path = %s, toPath = %s, mode = %d, kernel = %d)\n", path, toPath, mode, kernel));
status = path_to_dir_vnode(path, &vnode, name, kernel); status = path_to_dir_vnode(path, &vnode, name, kernel);
if (status < B_OK) if (status < B_OK)
return status; return status;
if (FS_CALL(vnode,fs_symlink) != NULL) if (FS_CALL(vnode,fs_symlink) != NULL)
status = FS_CALL(vnode,fs_symlink)(vnode->mount->cookie, vnode->private_node, name, toPath); status = FS_CALL(vnode,fs_symlink)(vnode->mount->cookie, vnode->private_node, name, toPath, mode);
else else
status = EROFS; status = EROFS;
@@ -2135,7 +2157,7 @@ fs_mount(char *path, const char *device, const char *fs_name, void *args, bool k
FUNCTION(("vfs_mount: entry. path = '%s', fs_name = '%s'\n", path, fs_name)); FUNCTION(("vfs_mount: entry. path = '%s', fs_name = '%s'\n", path, fs_name));
mutex_lock(&vfs_mount_op_mutex); mutex_lock(&gMountOpMutex);
mount = (struct fs_mount *)kmalloc(sizeof(struct fs_mount)); mount = (struct fs_mount *)kmalloc(sizeof(struct fs_mount));
if (mount == NULL) { if (mount == NULL) {
@@ -2198,12 +2220,12 @@ fs_mount(char *path, const char *device, const char *fs_name, void *args, bool k
goto err4; goto err4;
} }
mutex_lock(&vfs_mount_mutex); mutex_lock(&gMountMutex);
// insert mount struct into list // insert mount struct into list
hash_insert(mounts_table, mount); hash_insert(mounts_table, mount);
mutex_unlock(&vfs_mount_mutex); mutex_unlock(&gMountMutex);
err = get_vnode(mount->id, root_id, &mount->root_vnode, 0); err = get_vnode(mount->id, root_id, &mount->root_vnode, 0);
if (err < 0) if (err < 0)
@@ -2216,7 +2238,7 @@ fs_mount(char *path, const char *device, const char *fs_name, void *args, bool k
if (!root_vnode) if (!root_vnode)
root_vnode = mount->root_vnode; root_vnode = mount->root_vnode;
mutex_unlock(&vfs_mount_op_mutex); mutex_unlock(&gMountOpMutex);
return 0; return 0;
@@ -2232,7 +2254,7 @@ err2:
err1: err1:
kfree(mount); kfree(mount);
err: err:
mutex_unlock(&vfs_mount_op_mutex); mutex_unlock(&gMountOpMutex);
return err; return err;
} }
@@ -2251,7 +2273,7 @@ fs_unmount(char *path, bool kernel)
if (err < 0) if (err < 0)
return ERR_VFS_PATH_NOT_FOUND; return ERR_VFS_PATH_NOT_FOUND;
mutex_lock(&vfs_mount_op_mutex); mutex_lock(&gMountOpMutex);
mount = find_mount(vnode->fs_id); mount = find_mount(vnode->fs_id);
if (!mount) if (!mount)
@@ -2266,7 +2288,7 @@ fs_unmount(char *path, bool kernel)
/* grab the vnode master mutex to keep someone from creating a vnode /* grab the vnode master mutex to keep someone from creating a vnode
while we're figuring out if we can continue */ while we're figuring out if we can continue */
mutex_lock(&vfs_vnode_mutex); mutex_lock(&gVnodeMutex);
/* simulate the root vnode having it's refcount decremented */ /* simulate the root vnode having it's refcount decremented */
mount->root_vnode->ref_count -= 2; mount->root_vnode->ref_count -= 2;
@@ -2276,7 +2298,7 @@ fs_unmount(char *path, bool kernel)
for (vnode = mount->vnodes_head; vnode != NULL; vnode = vnode->mount_next) { for (vnode = mount->vnodes_head; vnode != NULL; vnode = vnode->mount_next) {
if (vnode->busy || vnode->ref_count != 0) { if (vnode->busy || vnode->ref_count != 0) {
mount->root_vnode->ref_count += 2; mount->root_vnode->ref_count += 2;
mutex_unlock(&vfs_vnode_mutex); mutex_unlock(&gVnodeMutex);
dec_vnode_ref_count(mount->root_vnode, false); dec_vnode_ref_count(mount->root_vnode, false);
err = EBUSY; err = EBUSY;
@@ -2291,7 +2313,7 @@ fs_unmount(char *path, bool kernel)
vnode->busy = true; vnode->busy = true;
mount->unmounting = true; mount->unmounting = true;
mutex_unlock(&vfs_vnode_mutex); mutex_unlock(&gVnodeMutex);
mount->covers_vnode->covered_by = NULL; mount->covers_vnode->covered_by = NULL;
dec_vnode_ref_count(mount->covers_vnode, false); dec_vnode_ref_count(mount->covers_vnode, false);
@@ -2304,11 +2326,11 @@ fs_unmount(char *path, bool kernel)
// a putvnode/removevnode here // a putvnode/removevnode here
/* remove the mount structure from the hash table */ /* remove the mount structure from the hash table */
mutex_lock(&vfs_mount_mutex); mutex_lock(&gMountMutex);
hash_remove(mounts_table, mount); hash_remove(mounts_table, mount);
mutex_unlock(&vfs_mount_mutex); mutex_unlock(&gMountMutex);
mutex_unlock(&vfs_mount_op_mutex); mutex_unlock(&gMountOpMutex);
mount->fs->calls->fs_unmount(mount->cookie); mount->fs->calls->fs_unmount(mount->cookie);
@@ -2318,7 +2340,7 @@ fs_unmount(char *path, bool kernel)
return 0; return 0;
err: err:
mutex_unlock(&vfs_mount_op_mutex); mutex_unlock(&gMountOpMutex);
return err; return err;
} }
@@ -2332,8 +2354,8 @@ fs_sync(void)
FUNCTION(("vfs_sync: entry.\n")); FUNCTION(("vfs_sync: entry.\n"));
/* cycle through and call sync on each mounted fs */ /* cycle through and call sync on each mounted fs */
mutex_lock(&vfs_mount_op_mutex); mutex_lock(&gMountOpMutex);
mutex_lock(&vfs_mount_mutex); mutex_lock(&gMountMutex);
hash_open(mounts_table, &iter); hash_open(mounts_table, &iter);
while ((mount = hash_next(mounts_table, &iter))) { while ((mount = hash_next(mounts_table, &iter))) {
@@ -2341,8 +2363,8 @@ fs_sync(void)
} }
hash_close(mounts_table, &iter, false); hash_close(mounts_table, &iter, false);
mutex_unlock(&vfs_mount_mutex); mutex_unlock(&gMountMutex);
mutex_unlock(&vfs_mount_op_mutex); mutex_unlock(&gMountOpMutex);
return 0; return 0;
} }
@@ -2354,7 +2376,7 @@ fs_read_info(dev_t device, struct fs_info *info)
struct fs_mount *mount; struct fs_mount *mount;
int status; int status;
mutex_lock(&vfs_mount_mutex); mutex_lock(&gMountMutex);
mount = find_mount(device); mount = find_mount(device);
if (mount == NULL) { if (mount == NULL) {
@@ -2372,7 +2394,7 @@ fs_read_info(dev_t device, struct fs_info *info)
info->root = mount->root_vnode->id; info->root = mount->root_vnode->id;
error: error:
mutex_unlock(&vfs_mount_mutex); mutex_unlock(&gMountMutex);
return status; return status;
} }
@@ -2383,7 +2405,7 @@ fs_write_info(dev_t device, const struct fs_info *info, int mask)
struct fs_mount *mount; struct fs_mount *mount;
int status; int status;
mutex_lock(&vfs_mount_mutex); mutex_lock(&gMountMutex);
mount = find_mount(device); mount = find_mount(device);
if (mount == NULL) { if (mount == NULL) {
@@ -2397,7 +2419,7 @@ fs_write_info(dev_t device, const struct fs_info *info, int mask)
status = EROFS; status = EROFS;
error: error:
mutex_unlock(&vfs_mount_mutex); mutex_unlock(&gMountMutex);
return status; return status;
} }
@@ -2630,7 +2652,7 @@ sys_read_link(const char *path, char *buffer, size_t bufferSize)
int int
sys_create_symlink(const char *userPath, const char *userToPath) sys_create_symlink(const char *userPath, const char *userToPath, int mode)
{ {
char path[SYS_MAX_PATH_LEN + 1]; char path[SYS_MAX_PATH_LEN + 1];
char toPath[SYS_MAX_PATH_LEN + 1]; char toPath[SYS_MAX_PATH_LEN + 1];
@@ -2646,7 +2668,7 @@ sys_create_symlink(const char *userPath, const char *userToPath)
if (status < B_OK) if (status < B_OK)
return status; return status;
return common_symlink(path, toPath, true); return common_create_symlink(path, toPath, mode, true);
} }
@@ -2993,7 +3015,7 @@ user_read_link(const char *userPath, char *userBuffer, size_t bufferSize)
int int
user_create_symlink(const char *userPath, const char *userToPath) user_create_symlink(const char *userPath, const char *userToPath, int mode)
{ {
char path[SYS_MAX_PATH_LEN + 1]; char path[SYS_MAX_PATH_LEN + 1];
char toPath[SYS_MAX_PATH_LEN + 1]; char toPath[SYS_MAX_PATH_LEN + 1];
@@ -3017,7 +3039,7 @@ user_create_symlink(const char *userPath, const char *userToPath)
if (status < B_OK) if (status < B_OK)
return status; return status;
return common_symlink(path, toPath, false); return common_create_symlink(path, toPath, mode, false);
} }
+1 -1
View File
@@ -112,7 +112,7 @@ int syscall_dispatcher(unsigned long call_num, void *arg_buffer, uint64 *call_re
*call_ret = user_create_dir((const char *)arg0, (int)arg1); *call_ret = user_create_dir((const char *)arg0, (int)arg1);
break; break;
case SYSCALL_CREATE_SYMLINK: case SYSCALL_CREATE_SYMLINK:
*call_ret = user_create_symlink((const char *)arg0, (const char *)arg1); *call_ret = user_create_symlink((const char *)arg0, (const char *)arg1, (int)arg2);
break; break;
case SYSCALL_READ_LINK: case SYSCALL_READ_LINK:
*call_ret = user_read_link((const char *)arg0, (char *)arg1, (size_t)arg2); *call_ret = user_read_link((const char *)arg0, (char *)arg1, (size_t)arg2);