# HG changeset patch # User Paul Boddie # Date 1627247919 -7200 # Node ID 5be26f9f495e53972bae93ff14584c0738c7b727 # Parent 88af0701edffe6d8e76b625a5a443d3ff9a81b7f Introduced file creation support to the ext2 file opener, switching the file facilities test to use the ext2 opener and filesystem. diff -r 88af0701edff -r 5be26f9f495e conf/dstest_file.cfg --- a/conf/dstest_file.cfg Sun Jul 25 17:14:53 2021 +0200 +++ b/conf/dstest_file.cfg Sun Jul 25 23:18:39 2021 +0200 @@ -4,20 +4,32 @@ local l = L4.default_loader; -local server = l:new_channel(); +local blocksvr = l:new_channel(); + +l:startv({ + caps = { + server = blocksvr:svr(), + }, + log = { "blocksvr", "r" }, + }, + "rom/dstest_block_server", "10"); + +local ext2svr = l:new_channel(); l:startv({ caps = { - server = server:svr(), + blocksvr = blocksvr, + ext2svr = ext2svr:svr(), }, - log = { "server", "r" }, + log = { "ext2svr", "y" }, }, - "rom/dstest_block_server", "10"); + "rom/dstest_ext2_server", "blocksvr", "rom/e2test.fs", "10", "ext2svr"); l:startv({ caps = { - server = server, + server = ext2svr, }, log = { "client", "g" }, }, - "rom/dstest_file_client", "new file"); + -- program, file to create, user identifier + "rom/dstest_file_client", "home/paulb/new file", "1000"); diff -r 88af0701edff -r 5be26f9f495e conf/dstest_file.list --- a/conf/dstest_file.list Sun Jul 25 17:14:53 2021 +0200 +++ b/conf/dstest_file.list Sun Jul 25 23:18:39 2021 +0200 @@ -1,9 +1,11 @@ entry dstest_file roottask moe rom/dstest_file.cfg module dstest_file.cfg +module e2test.fs module l4re module ned module dstest_file_client +module dstest_ext2_server module dstest_block_server module lib4re-c.so module lib4re-c-util.so diff -r 88af0701edff -r 5be26f9f495e libfsserver/lib/files/ext2_file_opener.cc --- a/libfsserver/lib/files/ext2_file_opener.cc Sun Jul 25 17:14:53 2021 +0200 +++ b/libfsserver/lib/files/ext2_file_opener.cc Sun Jul 25 23:18:39 2021 +0200 @@ -19,7 +19,11 @@ * Boston, MA 02110-1301, USA */ +#include #include +#include + +#include #include "ext2_file_accessor.h" #include "ext2_file_opener.h" @@ -28,15 +32,52 @@ long Ext2FileOpener::get_fileid(const char *path, flags_t flags, fileid_t *fileid) { + const char *filename = path; + /* Obtain the inode number. */ ext2_ino_t ino; - errcode_t retval = image_find_path(_fs, &path, &ino); + errcode_t retval = image_find_path(_fs, &filename, &ino); - // NOTE: Support file creation. + /* Handle a missing file. */ if (retval) + { + /* Create a missing file if possible. */ + + if (flags & O_CREAT) + { + /* Determine whether only the leafname is left of the path, with + the inode number referring to the parent directory. */ + + if (path_is_leafname(filename)) + { + struct ext2_inode inode_parent; + + /* Determine write access in the directory. */ + + retval = ext2fs_read_inode(_fs, ino, &inode_parent); + + if (retval) + return -L4_EIO; + + if (!access_can_write(_user, &inode_parent)) + return -L4_EPERM; + + /* If so, use the parent directory inode to create a new file. */ + + if (image_create_file(_fs, ino, filename, 0666 & ~_user.umask, + _user.uid, _user.gid, &ino)) + return -L4_EIO; + + *fileid = (fileid_t) ino; + return L4_EOK; + } + } + + *fileid = FILEID_INVALID; return -L4_ENOENT; + } *fileid = (fileid_t) ino; return L4_EOK; diff -r 88af0701edff -r 5be26f9f495e tests/dstest_file_client.cc --- a/tests/dstest_file_client.cc Sun Jul 25 17:14:53 2021 +0200 +++ b/tests/dstest_file_client.cc Sun Jul 25 23:18:39 2021 +0200 @@ -137,16 +137,36 @@ { if (argc < 2) { - printf("Need a filename.\n"); + printf("Need a filename and an optional user identifier (if used with a filesystem).\n"); return 1; } char *filename = argv[1]; + sys_uid_t uid = argc > 2 ? atoi(argv[2]) : 0; + file_t *file1, *file2; - /* Invoke the open function to receive each file reference. */ + /* With a user, open a user-specific file opener. */ + + if (uid) + { + l4_cap_idx_t opener = client_open_for_user(uid, uid, 0022); - file_t *file1 = client_open(filename, O_RDWR | O_CREAT); - file_t *file2 = client_open(filename, O_RDWR); + if (l4_is_invalid_cap(opener)) + { + printf("Could not obtain opener for file.\n"); + return 1; + } + + /* Invoke the open method to receive the file reference. */ + + file1 = client_open_using(filename, O_RDWR | O_CREAT, opener); + file2 = client_open_using(filename, O_RDWR, opener); + } + else + { + file1 = client_open(filename, O_RDWR | O_CREAT); + file2 = client_open(filename, O_RDWR); + } if ((file1 == NULL) || (file2 == NULL)) {