1.1 --- a/libfsserver/lib/files/ext2_file_opener.cc Sat Sep 18 18:51:43 2021 +0200
1.2 +++ b/libfsserver/lib/files/ext2_file_opener.cc Mon Sep 20 01:16:59 2021 +0200
1.3 @@ -19,70 +19,16 @@
1.4 * Boston, MA 02110-1301, USA
1.5 */
1.6
1.7 -#include <dirent.h>
1.8 #include <string.h>
1.9
1.10 -#include <thread>
1.11 -
1.12 #include <e2access/path.h>
1.13 #include <fsclient/client.h>
1.14 #include <systypes/fcntl.h>
1.15
1.16 +#include "ext2_directory_accessor.h"
1.17 #include "ext2_file_accessor.h"
1.18 #include "ext2_file_opener.h"
1.19 -
1.20 -
1.21 -
1.22 -/* Common definitions. */
1.23 -
1.24 -#define DIRENT_CORE_SIZE (sizeof(struct dirent) - sizeof(((struct dirent *) 0)->d_name))
1.25 -
1.26 -/* File type conversion. */
1.27 -
1.28 -static int convert_file_type(int type)
1.29 -{
1.30 - switch (type)
1.31 - {
1.32 - case EXT2_FT_REG_FILE: return DT_REG;
1.33 - case EXT2_FT_DIR: return DT_DIR;
1.34 - case EXT2_FT_CHRDEV: return DT_CHR;
1.35 - case EXT2_FT_BLKDEV: return DT_BLK;
1.36 - case EXT2_FT_FIFO: return DT_FIFO;
1.37 - case EXT2_FT_SOCK: return DT_SOCK;
1.38 - case EXT2_FT_SYMLINK: return DT_LNK;
1.39 - default: return DT_UNKNOWN;
1.40 - }
1.41 -}
1.42 -
1.43 -/* Helper function to ensure alignment in generated entries. */
1.44 -
1.45 -static int pad_align(int value)
1.46 -{
1.47 - return value + (sizeof(unsigned int) - (value % sizeof(unsigned int)));
1.48 -}
1.49 -
1.50 -/* Callback function. */
1.51 -
1.52 -static int read_directory_entry(struct ext2_dir_entry *dir_entry, int offset,
1.53 - int blocksize, char *buf, void *priv_data)
1.54 -{
1.55 - (void) offset; (void) blocksize; (void) buf;
1.56 -
1.57 - struct Ext2FileOpenerDir *dir = reinterpret_cast<struct Ext2FileOpenerDir *>(priv_data);
1.58 -
1.59 - dir->entry = dir_entry;
1.60 - dir->offset = offset;
1.61 - return dir->opener->write_directory_entry(dir);
1.62 -}
1.63 -
1.64 -/* Thread payload. */
1.65 -
1.66 -static void _read_directory(Ext2FileOpener *opener, fileid_t fileid, file_t *writer)
1.67 -{
1.68 - opener->read_directory(fileid, writer);
1.69 -
1.70 - client_close(writer);
1.71 -}
1.72 +#include "resource_server.h"
1.73
1.74
1.75
1.76 @@ -106,104 +52,6 @@
1.77 return _ops->is_file((ext2_ino_t) fileid);
1.78 }
1.79
1.80 -// NOTE: This is mostly the same as the HostFileOpener implementation.
1.81 -
1.82 -long Ext2FileOpener::get_directory(const char *path, flags_t flags,
1.83 - fileid_t fileid, offset_t *size,
1.84 - l4_cap_idx_t *cap, object_flags_t *object_flags)
1.85 -{
1.86 - /* The file identifier is used to obtain the directory. */
1.87 -
1.88 - (void) path; (void) flags;
1.89 -
1.90 - file_t *reader, *writer;
1.91 -
1.92 - // Mapping of the reader's memory region should be avoided because no use
1.93 - // of the reader will be made here.
1.94 -
1.95 - long err = client_pipe(&reader, &writer, 0);
1.96 -
1.97 - if (err)
1.98 - return err;
1.99 -
1.100 - *size = reader->size;
1.101 - *cap = reader->ref;
1.102 - *object_flags = 0; /* does not support mmap, has no fixed size */
1.103 -
1.104 - /* Spawn a independent thread for reading the directory details and writing
1.105 - them to the pipe. */
1.106 -
1.107 - std::thread(_read_directory, this, fileid, writer).detach();
1.108 -
1.109 - /* Discard the reader structure but preserve the capability. */
1.110 -
1.111 - reader->ref = L4_INVALID_CAP;
1.112 - client_close(reader);
1.113 -
1.114 - /* Return an indication that the capability will be propagated and not
1.115 - retained. This is explicitly supported by the opener context. */
1.116 -
1.117 - return IPC_MESSAGE_SENT;
1.118 -}
1.119 -
1.120 -/* Thread payload helper method. */
1.121 -
1.122 -void Ext2FileOpener::read_directory(fileid_t fileid, file_t *writer)
1.123 -{
1.124 - /* Initialise directory reading state: opener, writer, entry, offset. */
1.125 -
1.126 - struct Ext2FileOpenerDir dir = {this, writer, NULL, 0};
1.127 -
1.128 - /* Call the handler function for each directory entry. */
1.129 -
1.130 - _ops->directory_iterate((ext2_ino_t) fileid, read_directory_entry, &dir);
1.131 -}
1.132 -
1.133 -/* Callback method for directory entry output. */
1.134 -
1.135 -int Ext2FileOpener::write_directory_entry(struct Ext2FileOpenerDir *dir)
1.136 -{
1.137 - struct ext2_inode inode;
1.138 -
1.139 - /* Obtain the inode details for metadata. */
1.140 -
1.141 - if (_ops->read_inode(dir->entry->inode, &inode))
1.142 - return DIRENT_ABORT;
1.143 -
1.144 - /* Align the size of the entry to avoid problems on architectures which
1.145 - require aligned accesses and where the compiler needs to assume an
1.146 - aligned structure. */
1.147 -
1.148 - offset_t namelen = ext2fs_dirent_name_len(dir->entry);
1.149 - offset_t reclen = pad_align(DIRENT_CORE_SIZE + namelen);
1.150 -
1.151 - /* Construct a directory entry structure of the calculated size. */
1.152 -
1.153 - char buffer[reclen];
1.154 - struct dirent *dirent = (struct dirent *) buffer;
1.155 -
1.156 - dirent->d_ino = dir->entry->inode;
1.157 - dirent->d_off = dir->offset;
1.158 - dirent->d_reclen = reclen;
1.159 - dirent->d_type = convert_file_type(ext2fs_dirent_file_type(dir->entry));
1.160 -
1.161 - /* Copy the name, padding the memory after it to the alignment boundary. */
1.162 -
1.163 - memcpy(dirent->d_name, dir->entry->name, namelen);
1.164 - memset(dirent->d_name + namelen, 0, reclen - namelen);
1.165 -
1.166 - /* Write the structure to the pipe. */
1.167 -
1.168 - offset_t nwritten = client_write(dir->writer, (const void *) dirent, reclen);
1.169 -
1.170 - /* Stop writing if the pipe is closed. */
1.171 -
1.172 - if (nwritten < reclen)
1.173 - return DIRENT_ABORT;
1.174 -
1.175 - return 0;
1.176 -}
1.177 -
1.178 /* Return a file identifier for the given 'path'. */
1.179
1.180 long Ext2FileOpener::get_fileid(const char *path, flags_t flags, fileid_t *fileid)
1.181 @@ -245,7 +93,8 @@
1.182
1.183 /* Return a new accessor for 'fileid'. */
1.184
1.185 -long Ext2FileOpener::make_accessor(const char *path, flags_t flags, fileid_t fileid, Accessor **accessor)
1.186 +long Ext2FileOpener::make_accessor(const char *path, flags_t flags,
1.187 + fileid_t fileid, Accessor **accessor)
1.188 {
1.189 (void) path; (void) flags;
1.190
1.191 @@ -259,4 +108,16 @@
1.192 return L4_EOK;
1.193 }
1.194
1.195 +/* Return a directory object reference for the given file identifier. */
1.196 +
1.197 +long Ext2FileOpener::make_directory_accessor(const char *path, flags_t flags,
1.198 + fileid_t fileid,
1.199 + DirectoryAccessor **accessor)
1.200 +{
1.201 + (void) path; (void) flags;
1.202 +
1.203 + *accessor = new Ext2DirectoryAccessor(_ops, fileid);
1.204 + return L4_EOK;
1.205 +}
1.206 +
1.207 // vim: tabstop=4 expandtab shiftwidth=4