Added open(2).
Please note that mount points and file systems do not exist yet.
This commit is contained in:
parent
6447783c12
commit
ae423eaeef
|
@ -46,7 +46,7 @@ __BEGIN_DECLS
|
||||||
#define O_RDONLY 00
|
#define O_RDONLY 00
|
||||||
#define O_WRONLY 01
|
#define O_WRONLY 01
|
||||||
#define O_RDWR 02
|
#define O_RDWR 02
|
||||||
#define O_CREAT 0100
|
#define O_CREAT (1<<5)
|
||||||
#define O_EXCL 0200
|
#define O_EXCL 0200
|
||||||
#define O_NOCTTY 0400
|
#define O_NOCTTY 0400
|
||||||
#define O_TRUNC 01000
|
#define O_TRUNC 01000
|
||||||
|
@ -82,10 +82,10 @@ struct _flock
|
||||||
typedef struct _flock flock;
|
typedef struct _flock flock;
|
||||||
|
|
||||||
/* TODO: These are not implemented in libmaxsi/sortix yet. */
|
/* TODO: These are not implemented in libmaxsi/sortix yet. */
|
||||||
|
int open(const char* path, int oflag, ...);
|
||||||
#ifndef SORTIX_UNIMPLEMENTED
|
#ifndef SORTIX_UNIMPLEMENTED
|
||||||
int creat(const char* path, mode_t mode);
|
int creat(const char* path, mode_t mode);
|
||||||
int fcntl(int fd, int cmd, ...);
|
int fcntl(int fd, int cmd, ...);
|
||||||
int open(const char* path, int oflag, ...);
|
|
||||||
int openat(int fd, const char* path, int oflag, ...);
|
int openat(int fd, const char* path, int oflag, ...);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -35,6 +35,7 @@ namespace Maxsi
|
||||||
DEFN_SYSCALL1(int, SysPipe, 20, int*);
|
DEFN_SYSCALL1(int, SysPipe, 20, int*);
|
||||||
DEFN_SYSCALL1(int, SysClose, 21, int);
|
DEFN_SYSCALL1(int, SysClose, 21, int);
|
||||||
DEFN_SYSCALL1(int, SysDup, 22, int);
|
DEFN_SYSCALL1(int, SysDup, 22, int);
|
||||||
|
DEFN_SYSCALL3(int, SysOpen, 23, const char*, int, mode_t);
|
||||||
|
|
||||||
size_t Print(const char* Message)
|
size_t Print(const char* Message)
|
||||||
{
|
{
|
||||||
|
@ -89,6 +90,11 @@ namespace Maxsi
|
||||||
{
|
{
|
||||||
return SysDup(fd);
|
return SysDup(fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern "C" int open(const char* path, int flags, mode_t mode)
|
||||||
|
{
|
||||||
|
return SysOpen(path, flags, mode);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -71,6 +71,8 @@ initrd.o \
|
||||||
thread.o \
|
thread.o \
|
||||||
io.o \
|
io.o \
|
||||||
pipe.o \
|
pipe.o \
|
||||||
|
filesystem.o \
|
||||||
|
mount.o \
|
||||||
../libmaxsi/libmaxsi-sortix.a
|
../libmaxsi/libmaxsi-sortix.a
|
||||||
|
|
||||||
JSOBJS:=$(subst .o,-js.o,$(OBJS))
|
JSOBJS:=$(subst .o,-js.o,$(OBJS))
|
||||||
|
|
|
@ -0,0 +1,60 @@
|
||||||
|
/******************************************************************************
|
||||||
|
|
||||||
|
COPYRIGHT(C) JONAS 'SORTIE' TERMANSEN 2011.
|
||||||
|
|
||||||
|
This file is part of Sortix.
|
||||||
|
|
||||||
|
Sortix is free software: you can redistribute it and/or modify it under the
|
||||||
|
terms of the GNU General Public License as published by the Free Software
|
||||||
|
Foundation, either version 3 of the License, or (at your option) any later
|
||||||
|
version.
|
||||||
|
|
||||||
|
Sortix is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
|
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||||
|
details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License along
|
||||||
|
with Sortix. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
filesystem.cpp
|
||||||
|
Allows access to stored sequences of bytes in an orderly fashion.
|
||||||
|
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
#include "platform.h"
|
||||||
|
#include "syscall.h"
|
||||||
|
#include "process.h"
|
||||||
|
#include "filesystem.h"
|
||||||
|
#include "mount.h"
|
||||||
|
|
||||||
|
namespace Sortix
|
||||||
|
{
|
||||||
|
namespace FileSystem
|
||||||
|
{
|
||||||
|
Device* Open(const char* path, int flags, mode_t mode)
|
||||||
|
{
|
||||||
|
size_t pathoffset = 0;
|
||||||
|
DevFileSystem* fs = Mount::WhichFileSystem(path, &pathoffset);
|
||||||
|
if ( !fs ) { return NULL; }
|
||||||
|
return fs->Open(path + pathoffset, flags, mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
int SysOpen(const char* path, int flags, mode_t mode)
|
||||||
|
{
|
||||||
|
Process* process = CurrentProcess();
|
||||||
|
Device* dev = Open(path, flags, mode);
|
||||||
|
if ( !dev ) { return -1; /* TODO: errno */ }
|
||||||
|
int fd = process->descriptors.Allocate(dev);
|
||||||
|
if ( fd < 0 ) { dev->Unref(); }
|
||||||
|
return fd;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Init()
|
||||||
|
{
|
||||||
|
Syscall::Register(SYSCALL_OPEN, (void*) SysOpen);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
with Sortix. If not, see <http://www.gnu.org/licenses/>.
|
with Sortix. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
filesystem.h
|
filesystem.h
|
||||||
Abstracts away a file system device.
|
Allows access to stored sequences of bytes in an orderly fashion.
|
||||||
|
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
|
@ -26,71 +26,41 @@
|
||||||
#define SORTIX_FILESYSTEM_H
|
#define SORTIX_FILESYSTEM_H
|
||||||
|
|
||||||
#include "device.h"
|
#include "device.h"
|
||||||
#include "mount.h"
|
|
||||||
|
|
||||||
namespace Sortix
|
namespace Sortix
|
||||||
{
|
{
|
||||||
class Thread;
|
|
||||||
|
|
||||||
namespace FileSystem
|
|
||||||
{
|
|
||||||
struct SysCallback
|
|
||||||
{
|
|
||||||
Device* device;
|
|
||||||
union { int deviceError; nat deviceType; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: These belong in libmaxsi!
|
// TODO: These belong in libmaxsi!
|
||||||
|
|
||||||
const nat O_RDONLY = 1;
|
|
||||||
const nat O_WRONLY = 2;
|
|
||||||
const nat O_RDWR = 3;
|
|
||||||
const nat O_EXEC = 4;
|
|
||||||
const nat O_SEARCH = 5;
|
|
||||||
const nat O_LOWERFLAGS = 0x7;
|
|
||||||
|
|
||||||
// TODO: Sortix might never support all of these flags if they are stupid.
|
// TODO: Sortix might never support all of these flags if they are stupid.
|
||||||
const nat O_APPEND = (1<<3);
|
const int O_RDONLY = 1;
|
||||||
const nat O_CLOEXEC = (1<<4);
|
const int O_WRONLY = 2;
|
||||||
const nat O_CREAT = (1<<5);
|
const int O_RDWR = 3;
|
||||||
const nat O_DIRECTORY = (1<<6);
|
const int O_EXEC = 4;
|
||||||
const nat O_DSYNC = (1<<6);
|
const int O_SEARCH = 5;
|
||||||
const nat O_EXCL = (1<<7);
|
const int O_LOWERFLAGS = 0x7;
|
||||||
const nat O_NOCTTY = (1<<8);
|
const int O_APPEND = (1<<3);
|
||||||
const nat O_NOFOLLOW = (1<<9);
|
const int O_CLOEXEC = (1<<4);
|
||||||
const nat O_RSYNC = (1<<11);
|
const int O_CREAT = (1<<5);
|
||||||
const nat O_SYNC = (1<<12);
|
const int O_DIRECTORY = (1<<6);
|
||||||
const nat O_TRUNC = (1<<13);
|
const int O_DSYNC = (1<<6);
|
||||||
const nat O_TTY_INIT = (1<<13);
|
const int O_EXCL = (1<<7);
|
||||||
|
const int O_NOCTTY = (1<<8);
|
||||||
// If O_RDONLY, then no one is allowed to write to this, or if O_RDWD then
|
const int O_NOFOLLOW = (1<<9);
|
||||||
// no one else is allowed to use this besides me.
|
const int O_RSYNC = (1<<11);
|
||||||
const nat O_EXCLUSIVELY = (1<<14);
|
const int O_SYNC = (1<<12);
|
||||||
const nat O_USERSPACEABLE = ((1<<15)-1);
|
const int O_TRUNC = (1<<13);
|
||||||
|
const int O_TTY_INIT = (1<<13);
|
||||||
const nat O_MOUNT = (1<<31);
|
|
||||||
|
|
||||||
class DevFileSystem : public Device
|
class DevFileSystem : public Device
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
DevFileSystem() { };
|
virtual Device* Open(const char* path, int flags, mode_t mode) = 0;
|
||||||
virtual ~DevFileSystem() { }
|
|
||||||
|
|
||||||
public:
|
|
||||||
bool LegalNodeName(const char* name);
|
|
||||||
|
|
||||||
public:
|
|
||||||
virtual int Initialize(MountPoint* mountPoint, const char* commandLine) = 0;
|
|
||||||
|
|
||||||
public:
|
|
||||||
virtual bool Open(const char* path, nat openFlags, nat mode, FileSystem::SysCallback* callbackInfo, Thread* thread);
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace FileSystem
|
namespace FileSystem
|
||||||
{
|
{
|
||||||
DevFileSystem* CreateDriver(const char* fsType);
|
void Init();
|
||||||
|
Device* Open(const char* path, int flags, mode_t mode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -47,6 +47,8 @@
|
||||||
#include "sound.h"
|
#include "sound.h"
|
||||||
#include "io.h"
|
#include "io.h"
|
||||||
#include "pipe.h"
|
#include "pipe.h"
|
||||||
|
#include "filesystem.h"
|
||||||
|
#include "mount.h"
|
||||||
|
|
||||||
using namespace Maxsi;
|
using namespace Maxsi;
|
||||||
|
|
||||||
|
@ -244,6 +246,12 @@ namespace Sortix
|
||||||
// Initialize the pipe system.
|
// Initialize the pipe system.
|
||||||
Pipe::Init();
|
Pipe::Init();
|
||||||
|
|
||||||
|
// Initialize the filesystem system.
|
||||||
|
FileSystem::Init();
|
||||||
|
|
||||||
|
// Initialize the mount system.
|
||||||
|
Mount::Init();
|
||||||
|
|
||||||
// Initialize the scheduler.
|
// Initialize the scheduler.
|
||||||
Scheduler::Init();
|
Scheduler::Init();
|
||||||
|
|
||||||
|
|
277
sortix/mount.cpp
277
sortix/mount.cpp
|
@ -23,283 +23,22 @@
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
#include "platform.h"
|
#include "platform.h"
|
||||||
#include <libmaxsi/string.h>
|
#include "mount.h"
|
||||||
#include "device.h"
|
|
||||||
#include "filesystem.h"
|
|
||||||
#include "thread.h"
|
|
||||||
#include "process.h"
|
|
||||||
#include "memorymanagement.h"
|
|
||||||
|
|
||||||
namespace Sortix
|
namespace Sortix
|
||||||
{
|
{
|
||||||
namespace Syscall
|
|
||||||
{
|
|
||||||
void SysOpen(Thread* thread)
|
|
||||||
{
|
|
||||||
struct Parameters
|
|
||||||
{
|
|
||||||
struct
|
|
||||||
{
|
|
||||||
const char* USER userPath SYSPARAM;
|
|
||||||
nat openFlags SYSPARAM;
|
|
||||||
nat mode SYSPARAM;
|
|
||||||
};
|
|
||||||
struct
|
|
||||||
{
|
|
||||||
int handle;
|
|
||||||
bool pending;
|
|
||||||
FileSystem::SysCallback callbackInfo;
|
|
||||||
const char* safePath;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
// We store our parameters and data inside the thread object, and we
|
|
||||||
// are passed parameters in a special way, so make sure it works.
|
|
||||||
STATIC_ASSERT(0 * sizeof(size_t) == offsetof(Parameters, userPath));
|
|
||||||
STATIC_ASSERT(1 * sizeof(size_t) == offsetof(Parameters, openflags));
|
|
||||||
STATIC_ASSERT(2 * sizeof(size_t) == offsetof(Parameters, mode));
|
|
||||||
STATIC_ASSERT(sizeof(Parameters) <= sizeof(thread->sysParams));
|
|
||||||
Parameters* params = (Parameters*) thread->sysParams;
|
|
||||||
|
|
||||||
int handle;
|
|
||||||
const char* path;
|
|
||||||
|
|
||||||
// Initialize our variables and validate parameters.
|
|
||||||
if ( !thread->sysParamsInited )
|
|
||||||
{
|
|
||||||
thread->sysParamsInited = true;
|
|
||||||
params->handle = handle = -1;
|
|
||||||
params->pending = false;
|
|
||||||
|
|
||||||
// Make sure the path is a valid string in userspace.
|
|
||||||
params->safePath = path = ValidateUserString(params->userPath)
|
|
||||||
if ( path == NULL ) { thread->SysReturnError(-1); return; }
|
|
||||||
|
|
||||||
params->openFlags &= O_USERSPACEABLE;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
path = params->safePath;
|
|
||||||
handle = param->handle;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get a descriptor for our device.
|
|
||||||
if ( handle == -1 )
|
|
||||||
{
|
|
||||||
param->handle = handle = thread->GetProcess()->_descs.Reserve();
|
|
||||||
if ( handle < 0 ) { thread->SysReturnError(handle); return; }
|
|
||||||
}
|
|
||||||
|
|
||||||
// Attempt to open the path. If the operation is blocking, this
|
|
||||||
// function will re-called when it completes, successful or not.
|
|
||||||
if ( !params->pending )
|
|
||||||
{
|
|
||||||
params->pending = true;
|
|
||||||
|
|
||||||
MountPoint* mount = Mount::GetMountPoint(path);
|
|
||||||
if ( mount == NULL ) { Error::Set(Error::BADINPUT); thread->SysReturnError(-1); return; }
|
|
||||||
|
|
||||||
if ( !mount->fs->Open(path, params->openFlags, params->mode, ¶ms->callbackInfo, thread) ) { return; }
|
|
||||||
}
|
|
||||||
|
|
||||||
// Return an error if the open failed.
|
|
||||||
if ( unlikely(params->callbackInfo.device == NULL) )
|
|
||||||
{
|
|
||||||
handle = thread->GetProcess()->_descs.Free(handle);
|
|
||||||
Error::Set(params->callbackInfo.deviceError);
|
|
||||||
thread->SysReturnError(-1); return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Bind the device to the descriptor and return it.
|
|
||||||
handle = thread->GetProcess()->_descs.UseReservation(handle, params->callbackInfo.device);
|
|
||||||
thread->SysReturn(handle); return;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SysMount(Thread* thread)
|
|
||||||
{
|
|
||||||
struct Parameters
|
|
||||||
{
|
|
||||||
struct
|
|
||||||
{
|
|
||||||
const char* USER userDevicePath SYSPARAM;
|
|
||||||
const char* USER userTargetPath SYSPARAM;
|
|
||||||
const char* USER userDriverName SYSPARAM;
|
|
||||||
nat mode SYSPARAM;
|
|
||||||
};
|
|
||||||
struct
|
|
||||||
{
|
|
||||||
int stage;
|
|
||||||
DevBuffer* storage;
|
|
||||||
DevFileSystem* fsDriver;
|
|
||||||
DevDirectory* directory;
|
|
||||||
FileSystem::SysCallback callbackInfo;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
// We store our parameters and data inside the thread object, and we
|
|
||||||
// are passed parameters in a special way, so make sure it works.
|
|
||||||
STATIC_ASSERT(0 * sizeof(size_t) == offsetof(Parameters, userDevicePath));
|
|
||||||
STATIC_ASSERT(1 * sizeof(size_t) == offsetof(Parameters, userTargetPath));
|
|
||||||
STATIC_ASSERT(2 * sizeof(size_t) == offsetof(Parameters, userDriverName));
|
|
||||||
STATIC_ASSERT(3 * sizeof(size_t) == offsetof(Parameters, mode));
|
|
||||||
STATIC_ASSERT(sizeof(Parameters) <= sizeof(thread->sysParams));
|
|
||||||
Parameters* params = (Parameters*) thread->sysParams;
|
|
||||||
|
|
||||||
// Initialize our variables and validate parameters.
|
|
||||||
if ( !thread->sysParamsInited )
|
|
||||||
{
|
|
||||||
thread->sysParamsInited = true;
|
|
||||||
if ( ValidateUserString(params->userDevicePath) == NULL ||
|
|
||||||
ValidateUserString(params->userTargetPath) == NULL ||
|
|
||||||
( params->userDriverName != NULL &&
|
|
||||||
ValidateUserString(params->userDriverName) == NULL ) )
|
|
||||||
{
|
|
||||||
thread->SysReturnError(-1); return;
|
|
||||||
}
|
|
||||||
|
|
||||||
params->mode &= O_USERSPACEABLE;
|
|
||||||
nat baseMode = params->mode & O_LOWERFLAGS;
|
|
||||||
nat extMode = params->mode & (~O_LOWERFLAGS);
|
|
||||||
|
|
||||||
// Deny unsupported open modes.
|
|
||||||
if ( (baseMode != O_RDWR && baseMode != O_RDONLY) ||
|
|
||||||
(extMode != 0 && extMode != O_EXCLUSIVELY && extMode != O_SYNC) )
|
|
||||||
{
|
|
||||||
Error::Set(Error::BADINPUT);
|
|
||||||
thread->SysReturnError(-1); return;
|
|
||||||
}
|
|
||||||
|
|
||||||
params->stage = 0;
|
|
||||||
params->storage = NULL;
|
|
||||||
params->fsDriver = NULL;
|
|
||||||
params->directory = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
MountPoint* mount;
|
|
||||||
Device* device = NULL;
|
|
||||||
|
|
||||||
switch ( params->stage )
|
|
||||||
{
|
|
||||||
// Get a handle to the storage device.
|
|
||||||
case 0: params->stage++;
|
|
||||||
|
|
||||||
mount = Mount::GetMountPoint(¶ms->userDevicePath);
|
|
||||||
if ( mount == NULL ) { Error::Set(Error::BADINPUT); break; }
|
|
||||||
|
|
||||||
ASSERT(params->mode & O_USERSPACEABLE == 0);
|
|
||||||
if ( !mount->fs->Open(params->userDevicePath, params->mode | O_EXCLUSIVELY, 0, ¶ms->callbackInfo, thread) ) { return; }
|
|
||||||
|
|
||||||
// Validate the properness of the storage device.
|
|
||||||
case 1: params->stage++;
|
|
||||||
device = params->callbackInfo.device;
|
|
||||||
|
|
||||||
// Did it exist/could we open it/did we have permission?
|
|
||||||
if ( unlikely(device == NULL) ) { Error::Set(params->callbackInfo.deviceError); break; }
|
|
||||||
|
|
||||||
// Is it a buffer?
|
|
||||||
if ( unlikely(!device->IsType(Device::BUFFER)) ) { Error::Set(Error::ENOTBLK); break; }
|
|
||||||
|
|
||||||
params->storage = (DevBuffer*) device; device = NULL;
|
|
||||||
|
|
||||||
// Get a handle to the destination directory.
|
|
||||||
case 2: params->stage++;
|
|
||||||
|
|
||||||
mount = Mount::GetMountPoint(¶ms->userTargetPath);
|
|
||||||
if ( mount == NULL ) { Error::Set(Error::BADINPUT); break; }
|
|
||||||
|
|
||||||
// TODO: Figure out some good mode flags here!
|
|
||||||
// TODO: Make sure the FS driver forces the dest dir to be empty!
|
|
||||||
if ( !mount->fs->Open(params->userTargetPath, O_RDWR | O_DIRECTORY | O_MOUNT, 0, ¶ms->callbackInfo, thread) ) { return; }
|
|
||||||
|
|
||||||
// Validate the properness of the destination directory.
|
|
||||||
case 2: params->stage++;
|
|
||||||
device = params->callbackInfo.device;
|
|
||||||
|
|
||||||
// Did it exist/could we open it?
|
|
||||||
if ( unlikely(device == NULL) ) { Error::Set(params->callbackInfo.deviceError); break; }
|
|
||||||
|
|
||||||
// Is it a directory?
|
|
||||||
if ( unlikely(!device->IsType(Device::DIRECTORY)) ) { Error::Set(Error::ENOTDIR); break; }
|
|
||||||
|
|
||||||
params->directory = (DevDirectory*) device; device = NULL;
|
|
||||||
|
|
||||||
// Validate that the user owns the directory.
|
|
||||||
if ( !params->directory->IsOwner(thread->GetProcess()->GetUser()) ) { Error::Set(Error::EPERM); break; }
|
|
||||||
|
|
||||||
// TODO: Add a run-time assertion that the dir is empty!
|
|
||||||
|
|
||||||
// Load the proper driver for this file system type.
|
|
||||||
case 3: params->stage++;
|
|
||||||
|
|
||||||
// TODO: Make an async interface that can scan a device!
|
|
||||||
params->fsDriver = FileSystem::CreateDriver(params->userDriverName);
|
|
||||||
if ( params->fsDriver == NULL ) { Error::Set(Error::ENODEV); break; }
|
|
||||||
|
|
||||||
// Now bind the file system driver to the device and directory.
|
|
||||||
case 4: params->stage++;
|
|
||||||
MountPoint* newMount = new MountPoint();
|
|
||||||
|
|
||||||
newMount->device = params->storage;
|
|
||||||
newMount->fs = params->fsDriver;
|
|
||||||
|
|
||||||
// TODO: Actually do the mounting!
|
|
||||||
|
|
||||||
// Check if everything went well.
|
|
||||||
case 4:
|
|
||||||
// TODO: Check if everything went well!
|
|
||||||
thread->SysReturn(0); return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( device != NULL ) { device->close(); }
|
|
||||||
if ( params->storage != NULL ) { params->storage->close(); }
|
|
||||||
if ( params->directory != NULL ) { params->directory->close(); }
|
|
||||||
if ( params->fsDriver != NULL ) { params->fsDriver->close(); }
|
|
||||||
|
|
||||||
thread->SysReturnError(-1); return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace Mount
|
namespace Mount
|
||||||
{
|
{
|
||||||
MountPoint* GetMountPoint(const char** path, Thread* thread)
|
DevFileSystem* WhichFileSystem(const char* path, size_t* pathoffset)
|
||||||
{
|
{
|
||||||
ASSERT(path != NULL);
|
// TODO: Support some file systems!
|
||||||
ASSERT(*path != NULL);
|
*pathoffset = 0;
|
||||||
ASSERT(thread != NULL);
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
if ( unlikely(**path != '/') ) { return NULL; } (*path)++;
|
void Init()
|
||||||
MountPoint* currentFS = thread->GetProcess->GetRootFS();
|
{
|
||||||
|
|
||||||
ASSERT(currentFS != NULL);
|
|
||||||
|
|
||||||
// Simply check if path belongs to a child mount point.
|
|
||||||
for ( MountPoint* considering = currentFS->child; considering != NULL; considering = considering->nextSibling )
|
|
||||||
{
|
|
||||||
ASSERT(considering->IsSane());
|
|
||||||
|
|
||||||
size_t consideringPathLen = String::Length(considering->path);
|
|
||||||
if ( String::CompareN(*path, considering->path, consideringPathLen) == 0 )
|
|
||||||
{
|
|
||||||
// Check if this is the right dir!
|
|
||||||
char lastChar = (*path)[consideringPathLen];
|
|
||||||
|
|
||||||
if ( lastChar == '/' ) { (*path) += consideringPathLen + 1; }
|
|
||||||
else if ( lastChar == '\0' ) { (*path) += consideringPathLen + 0; }
|
|
||||||
else { continue; }
|
|
||||||
|
|
||||||
// Check if the mountpoint isn't ready.
|
|
||||||
if ( considering->waiting != NULL ) { Error::Set(Error::EBUSY); return NULL; }
|
|
||||||
|
|
||||||
currentFS = considering;
|
|
||||||
considering = currentFS->child;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ASSERT(currentFS->fs != NULL);
|
|
||||||
|
|
||||||
return currentFS;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -27,47 +27,12 @@
|
||||||
|
|
||||||
namespace Sortix
|
namespace Sortix
|
||||||
{
|
{
|
||||||
class Device;
|
|
||||||
class DevFileSystem;
|
class DevFileSystem;
|
||||||
class DevBuffer;
|
|
||||||
class Process;
|
|
||||||
|
|
||||||
class MountPoint
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
MountPoint();
|
|
||||||
~MountPoint();
|
|
||||||
|
|
||||||
public:
|
|
||||||
const char* path;
|
|
||||||
DevFileSystem* fs;
|
|
||||||
DevBuffer* device;
|
|
||||||
nat flags;
|
|
||||||
|
|
||||||
public:
|
|
||||||
Thread* waiting;
|
|
||||||
int* waitingResult;
|
|
||||||
|
|
||||||
public:
|
|
||||||
bool Mount();
|
|
||||||
|
|
||||||
public:
|
|
||||||
bool IsSane() { return path != NULL && fs != NULL && device != NULL; }
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
namespace Mount
|
namespace Mount
|
||||||
{
|
{
|
||||||
void Init();
|
void Init();
|
||||||
MountPoint* GetMountPoint(const char*& path, Thread* thread);
|
DevFileSystem* WhichFileSystem(const char* path, size_t* pathoffset);
|
||||||
void OnMountFailure(MountPoint* mountPoint, int cause);
|
|
||||||
void OnMountSuccess(MountPoint* mountPoint);
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace Syscall
|
|
||||||
{
|
|
||||||
void SysOpen(Thread* thread);
|
|
||||||
void SysMount(Thread* thread);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -48,7 +48,8 @@
|
||||||
#define SYSCALL_PIPE 20
|
#define SYSCALL_PIPE 20
|
||||||
#define SYSCALL_CLOSE 21
|
#define SYSCALL_CLOSE 21
|
||||||
#define SYSCALL_DUP 22
|
#define SYSCALL_DUP 22
|
||||||
#define SYSCALL_MAX_NUM 23 /* index of highest constant + 1 */
|
#define SYSCALL_OPEN 23
|
||||||
|
#define SYSCALL_MAX_NUM 24 /* index of highest constant + 1 */
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue