1.1 --- a/conf/dstest_file.cfg Sun Jul 25 17:14:53 2021 +0200
1.2 +++ b/conf/dstest_file.cfg Sun Jul 25 23:18:39 2021 +0200
1.3 @@ -4,20 +4,32 @@
1.4
1.5 local l = L4.default_loader;
1.6
1.7 -local server = l:new_channel();
1.8 +local blocksvr = l:new_channel();
1.9 +
1.10 +l:startv({
1.11 + caps = {
1.12 + server = blocksvr:svr(),
1.13 + },
1.14 + log = { "blocksvr", "r" },
1.15 + },
1.16 + "rom/dstest_block_server", "10");
1.17 +
1.18 +local ext2svr = l:new_channel();
1.19
1.20 l:startv({
1.21 caps = {
1.22 - server = server:svr(),
1.23 + blocksvr = blocksvr,
1.24 + ext2svr = ext2svr:svr(),
1.25 },
1.26 - log = { "server", "r" },
1.27 + log = { "ext2svr", "y" },
1.28 },
1.29 - "rom/dstest_block_server", "10");
1.30 + "rom/dstest_ext2_server", "blocksvr", "rom/e2test.fs", "10", "ext2svr");
1.31
1.32 l:startv({
1.33 caps = {
1.34 - server = server,
1.35 + server = ext2svr,
1.36 },
1.37 log = { "client", "g" },
1.38 },
1.39 - "rom/dstest_file_client", "new file");
1.40 + -- program, file to create, user identifier
1.41 + "rom/dstest_file_client", "home/paulb/new file", "1000");
2.1 --- a/conf/dstest_file.list Sun Jul 25 17:14:53 2021 +0200
2.2 +++ b/conf/dstest_file.list Sun Jul 25 23:18:39 2021 +0200
2.3 @@ -1,9 +1,11 @@
2.4 entry dstest_file
2.5 roottask moe rom/dstest_file.cfg
2.6 module dstest_file.cfg
2.7 +module e2test.fs
2.8 module l4re
2.9 module ned
2.10 module dstest_file_client
2.11 +module dstest_ext2_server
2.12 module dstest_block_server
2.13 module lib4re-c.so
2.14 module lib4re-c-util.so
3.1 --- a/libfsserver/lib/files/ext2_file_opener.cc Sun Jul 25 17:14:53 2021 +0200
3.2 +++ b/libfsserver/lib/files/ext2_file_opener.cc Sun Jul 25 23:18:39 2021 +0200
3.3 @@ -19,7 +19,11 @@
3.4 * Boston, MA 02110-1301, USA
3.5 */
3.6
3.7 +#include <e2access/access.h>
3.8 #include <e2access/image.h>
3.9 +#include <e2access/path.h>
3.10 +
3.11 +#include <systypes/fcntl.h>
3.12
3.13 #include "ext2_file_accessor.h"
3.14 #include "ext2_file_opener.h"
3.15 @@ -28,15 +32,52 @@
3.16
3.17 long Ext2FileOpener::get_fileid(const char *path, flags_t flags, fileid_t *fileid)
3.18 {
3.19 + const char *filename = path;
3.20 +
3.21 /* Obtain the inode number. */
3.22
3.23 ext2_ino_t ino;
3.24 - errcode_t retval = image_find_path(_fs, &path, &ino);
3.25 + errcode_t retval = image_find_path(_fs, &filename, &ino);
3.26
3.27 - // NOTE: Support file creation.
3.28 + /* Handle a missing file. */
3.29
3.30 if (retval)
3.31 + {
3.32 + /* Create a missing file if possible. */
3.33 +
3.34 + if (flags & O_CREAT)
3.35 + {
3.36 + /* Determine whether only the leafname is left of the path, with
3.37 + the inode number referring to the parent directory. */
3.38 +
3.39 + if (path_is_leafname(filename))
3.40 + {
3.41 + struct ext2_inode inode_parent;
3.42 +
3.43 + /* Determine write access in the directory. */
3.44 +
3.45 + retval = ext2fs_read_inode(_fs, ino, &inode_parent);
3.46 +
3.47 + if (retval)
3.48 + return -L4_EIO;
3.49 +
3.50 + if (!access_can_write(_user, &inode_parent))
3.51 + return -L4_EPERM;
3.52 +
3.53 + /* If so, use the parent directory inode to create a new file. */
3.54 +
3.55 + if (image_create_file(_fs, ino, filename, 0666 & ~_user.umask,
3.56 + _user.uid, _user.gid, &ino))
3.57 + return -L4_EIO;
3.58 +
3.59 + *fileid = (fileid_t) ino;
3.60 + return L4_EOK;
3.61 + }
3.62 + }
3.63 +
3.64 + *fileid = FILEID_INVALID;
3.65 return -L4_ENOENT;
3.66 + }
3.67
3.68 *fileid = (fileid_t) ino;
3.69 return L4_EOK;
4.1 --- a/tests/dstest_file_client.cc Sun Jul 25 17:14:53 2021 +0200
4.2 +++ b/tests/dstest_file_client.cc Sun Jul 25 23:18:39 2021 +0200
4.3 @@ -137,16 +137,36 @@
4.4 {
4.5 if (argc < 2)
4.6 {
4.7 - printf("Need a filename.\n");
4.8 + printf("Need a filename and an optional user identifier (if used with a filesystem).\n");
4.9 return 1;
4.10 }
4.11
4.12 char *filename = argv[1];
4.13 + sys_uid_t uid = argc > 2 ? atoi(argv[2]) : 0;
4.14 + file_t *file1, *file2;
4.15
4.16 - /* Invoke the open function to receive each file reference. */
4.17 + /* With a user, open a user-specific file opener. */
4.18 +
4.19 + if (uid)
4.20 + {
4.21 + l4_cap_idx_t opener = client_open_for_user(uid, uid, 0022);
4.22
4.23 - file_t *file1 = client_open(filename, O_RDWR | O_CREAT);
4.24 - file_t *file2 = client_open(filename, O_RDWR);
4.25 + if (l4_is_invalid_cap(opener))
4.26 + {
4.27 + printf("Could not obtain opener for file.\n");
4.28 + return 1;
4.29 + }
4.30 +
4.31 + /* Invoke the open method to receive the file reference. */
4.32 +
4.33 + file1 = client_open_using(filename, O_RDWR | O_CREAT, opener);
4.34 + file2 = client_open_using(filename, O_RDWR, opener);
4.35 + }
4.36 + else
4.37 + {
4.38 + file1 = client_open(filename, O_RDWR | O_CREAT);
4.39 + file2 = client_open(filename, O_RDWR);
4.40 + }
4.41
4.42 if ((file1 == NULL) || (file2 == NULL))
4.43 {