From d529a1e332098e5326c14d54e002c92d0cd703d6 Mon Sep 17 00:00:00 2001 From: Jonas 'Sortie' Termansen Date: Sat, 22 Oct 2016 23:47:28 +0200 Subject: [PATCH] Add factory inode support. --- kernel/fs/user.cpp | 8 ++++++++ kernel/include/sortix/fcntl.h | 5 ++++- kernel/include/sortix/kernel/inode.h | 4 ++++ kernel/include/sortix/stat.h | 5 +++++ kernel/inode.cpp | 8 ++++++++ kernel/io.cpp | 9 ++++++--- kernel/vnode.cpp | 7 +++++++ 7 files changed, 42 insertions(+), 4 deletions(-) diff --git a/kernel/fs/user.cpp b/kernel/fs/user.cpp index 44b0ed05..0fa28fdd 100644 --- a/kernel/fs/user.cpp +++ b/kernel/fs/user.cpp @@ -214,6 +214,8 @@ public: size_t size, off_t start); virtual Ref open(ioctx_t* ctx, const char* filename, int flags, mode_t mode); + virtual Ref factory(ioctx_t* ctx, const char* filename, int flags, + mode_t mode); virtual int mkdir(ioctx_t* ctx, const char* filename, mode_t mode); virtual int link(ioctx_t* ctx, const char* filename, Ref node); virtual int link_raw(ioctx_t* ctx, const char* filename, Ref node); @@ -1065,6 +1067,12 @@ Ref Unode::open(ioctx_t* ctx, const char* filename, int flags, return ret; } +Ref Unode::factory(ioctx_t* /*ctx*/, const char* /*filename*/, + int /*flags*/, mode_t /*mode*/) +{ + return errno = EBADF, Ref(NULL); +} + int Unode::mkdir(ioctx_t* ctx, const char* filename, mode_t mode) { Channel* channel = server->Connect(ctx); diff --git a/kernel/include/sortix/fcntl.h b/kernel/include/sortix/fcntl.h index df069115..5930e11e 100644 --- a/kernel/include/sortix/fcntl.h +++ b/kernel/include/sortix/fcntl.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2013, 2014 Jonas 'Sortie' Termansen. + * Copyright (c) 2012, 2013, 2014, 2016 Jonas 'Sortie' Termansen. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -44,6 +44,9 @@ extern "C" { #define O_SYMLINK_NOFOLLOW (1<<13) #define O_NOCTTY (1<<14) #define O_TTY_INIT (1<<15) +#ifdef __is_sortix_kernel +#define O_IS_STAT (1<<30) +#endif #define O_ACCMODE (O_READ | O_WRITE | O_EXEC | O_SEARCH) diff --git a/kernel/include/sortix/kernel/inode.h b/kernel/include/sortix/kernel/inode.h index b2017dc5..40354012 100644 --- a/kernel/include/sortix/kernel/inode.h +++ b/kernel/include/sortix/kernel/inode.h @@ -73,6 +73,8 @@ public: size_t size, off_t start) = 0; virtual Ref open(ioctx_t* ctx, const char* filename, int flags, mode_t mode) = 0; + virtual Ref factory(ioctx_t* ctx, const char* filename, int flags, + mode_t mode) = 0; virtual int mkdir(ioctx_t* ctx, const char* filename, mode_t mode) = 0; virtual int link(ioctx_t* ctx, const char* filename, Ref node) = 0; virtual int link_raw(ioctx_t* ctx, const char* filename, Ref node) = 0; @@ -166,6 +168,8 @@ public: size_t size, off_t start); virtual Ref open(ioctx_t* ctx, const char* filename, int flags, mode_t mode); + virtual Ref factory(ioctx_t* ctx, const char* filename, int flags, + mode_t mode); virtual int mkdir(ioctx_t* ctx, const char* filename, mode_t mode); virtual int link(ioctx_t* ctx, const char* filename, Ref node); virtual int link_raw(ioctx_t* ctx, const char* filename, Ref node); diff --git a/kernel/include/sortix/stat.h b/kernel/include/sortix/stat.h index f290bf03..1a05138b 100644 --- a/kernel/include/sortix/stat.h +++ b/kernel/include/sortix/stat.h @@ -84,6 +84,11 @@ struct stat #define S_ISCHR(mode) (((mode) & S_IFMT) == S_IFCHR) #define S_ISFIFO(mode) (((mode) & S_IFMT) == S_IFIFO) +#ifdef __is_sortix_kernel +#define S_IFFACTORY 0x10000 +#define S_IFFACTORY_NOSTAT 0x20000 +#endif + #define UTIME_NOW 0x3FFFFFFF #define UTIME_OMIT 0x3FFFFFFE diff --git a/kernel/inode.cpp b/kernel/inode.cpp index c44b964a..414e7c8c 100644 --- a/kernel/inode.cpp +++ b/kernel/inode.cpp @@ -217,6 +217,14 @@ Ref AbstractInode::open(ioctx_t* /*ctx*/, const char* /*filename*/, return errno = ENOTDIR, Ref(NULL); } +Ref AbstractInode::factory(ioctx_t* /*ctx*/, const char* /*filename*/, + int /*flags*/, mode_t /*mode*/) +{ + if ( inode_type == INODE_TYPE_DIR ) + return errno = EBADF, Ref(NULL); + return errno = ENOTDIR, Ref(NULL); +} + int AbstractInode::mkdir(ioctx_t* /*ctx*/, const char* /*filename*/, mode_t /*mode*/) { diff --git a/kernel/io.cpp b/kernel/io.cpp index 9cd8b172..b0e300fe 100644 --- a/kernel/io.cpp +++ b/kernel/io.cpp @@ -205,7 +205,8 @@ int sys_faccessat(int dirfd, const char* path, int mode, int flags) ioctx_t ctx; SetupUserIOCtx(&ctx); Ref from = PrepareLookup(pathcopy, dirfd); if ( !from ) { delete[] pathcopy; return -1; } - int open_flags = O_READ | (flags & AT_SYMLINK_NOFOLLOW ? O_SYMLINK_NOFOLLOW : 0); + int open_flags = O_READ | O_IS_STAT | + (flags & AT_SYMLINK_NOFOLLOW ? O_SYMLINK_NOFOLLOW : 0); Ref desc = from->open(&ctx, pathcopy, open_flags); delete[] pathcopy; if ( !desc ) @@ -290,7 +291,8 @@ int sys_fstatat(int dirfd, const char* path, struct stat* st, int flags) ioctx_t ctx; SetupUserIOCtx(&ctx); Ref from = PrepareLookup(pathcopy, dirfd); if ( !from ) { delete[] pathcopy; return -1; } - int open_flags = O_READ | (flags & AT_SYMLINK_NOFOLLOW ? O_SYMLINK_NOFOLLOW : 0); + int open_flags = O_READ | O_IS_STAT | + (flags & AT_SYMLINK_NOFOLLOW ? O_SYMLINK_NOFOLLOW : 0); Ref desc = from->open(&ctx, pathcopy, open_flags); delete[] pathcopy; if ( !desc ) @@ -326,7 +328,8 @@ int sys_fstatvfsat(int dirfd, const char* path, struct statvfs* stvfs, int flags ioctx_t ctx; SetupUserIOCtx(&ctx); Ref from = PrepareLookup(pathcopy, dirfd); if ( !from ) { delete[] pathcopy; return -1; } - int open_flags = O_READ | (flags & AT_SYMLINK_NOFOLLOW ? O_SYMLINK_NOFOLLOW : 0); + int open_flags = O_READ | O_IS_STAT | + (flags & AT_SYMLINK_NOFOLLOW ? O_SYMLINK_NOFOLLOW : 0); Ref desc = from->open(&ctx, pathcopy, open_flags); delete[] pathcopy; if ( !desc ) diff --git a/kernel/vnode.cpp b/kernel/vnode.cpp index 94dd28a0..17b27ce4 100644 --- a/kernel/vnode.cpp +++ b/kernel/vnode.cpp @@ -98,6 +98,13 @@ Ref Vnode::open(ioctx_t* ctx, const char* filename, int flags, mode_t mod Ref retinode = inode->open(ctx, filename, flags, mode); if ( !retinode ) return Ref(NULL); + if ( retinode->type & S_IFFACTORY && + !(retinode->type & S_IFFACTORY_NOSTAT && flags & O_IS_STAT) ) + { + retinode = retinode->factory(ctx, filename, flags, mode); + if ( !retinode ) + return Ref(NULL); + } Ref retmountedat = mountedat; ino_t retrootino = rootino; dev_t retrootdev = rootdev;