1.1 --- a/libfsclient/include/fsclient/client.h Tue Jan 04 23:27:53 2022 +0100 1.2 +++ b/libfsclient/include/fsclient/client.h Tue Jan 04 23:43:56 2022 +0100 1.3 @@ -47,6 +47,11 @@ 1.4 long client_pipe(file_t **reader, file_t **writer, flags_t flags); 1.5 long client_pipe_using(file_t **reader, file_t **writer, flags_t flags, l4_cap_idx_t server); 1.6 1.7 +/* Other file operations. */ 1.8 + 1.9 +long client_remove(const char *name); 1.10 +long client_remove_using(const char *name, l4_cap_idx_t server); 1.11 + 1.12 /* File and region operations. */ 1.13 1.14 long client_flush(file_t *file);
2.1 --- a/libfsclient/include/fsclient/file.h Tue Jan 04 23:27:53 2022 +0100 2.2 +++ b/libfsclient/include/fsclient/file.h Tue Jan 04 23:43:56 2022 +0100 2.3 @@ -84,11 +84,13 @@ 2.4 2.5 void file_close(file_t *file); 2.6 long file_open(file_t *file, const char *filename, flags_t flags, l4_cap_idx_t server); 2.7 +long file_remove(const char *filename, l4_cap_idx_t server); 2.8 2.9 /* File lifecycle operations. */ 2.10 2.11 long file_context(file_t *file, l4_cap_idx_t server); 2.12 long file_context_open(file_t *file, flags_t flags, file_t *context); 2.13 +long file_context_remove(file_t *context); 2.14 void file_init(file_t *file); 2.15 2.16 /* File and region operations. */
3.1 --- a/libfsclient/lib/src/client.cc Tue Jan 04 23:27:53 2022 +0100 3.2 +++ b/libfsclient/lib/src/client.cc Tue Jan 04 23:43:56 2022 +0100 3.3 @@ -359,6 +359,24 @@ 3.4 3.5 3.6 3.7 +/* Remove a file from the filesystem. */ 3.8 + 3.9 +long client_remove(const char *name) 3.10 +{ 3.11 + l4_cap_idx_t server = l4re_env_get_cap("server"); 3.12 + 3.13 + return client_remove_using(name, server); 3.14 +} 3.15 + 3.16 +/* Remove a file from the filesystem via a named capability. */ 3.17 + 3.18 +long client_remove_using(const char *name, l4_cap_idx_t server) 3.19 +{ 3.20 + return file_remove(name, server); 3.21 +} 3.22 + 3.23 + 3.24 + 3.25 /* Obtain the current region of a pipe. */ 3.26 3.27 long client_current_region(file_t *file)
4.1 --- a/libfsclient/lib/src/file.cc Tue Jan 04 23:27:53 2022 +0100 4.2 +++ b/libfsclient/lib/src/file.cc Tue Jan 04 23:43:56 2022 +0100 4.3 @@ -137,6 +137,30 @@ 4.4 return err; 4.5 } 4.6 4.7 +/* Remove a file from the filesystem. This is a convenience function invoking 4.8 + file_context and file_context_remove. */ 4.9 + 4.10 +long file_remove(const char *filename, l4_cap_idx_t server) 4.11 +{ 4.12 + file_t context; 4.13 + long err; 4.14 + 4.15 + err = file_context(&context, server); 4.16 + if (err) 4.17 + return err; 4.18 + 4.19 + if (!file_string_set(&context, filename, 0, NULL)) 4.20 + return -L4_ENOMEM; 4.21 + 4.22 + err = file_context_remove(&context); 4.23 + 4.24 + /* Close the context, although a separate mechanism could permit contexts to 4.25 + open several files. */ 4.26 + 4.27 + file_close(&context); 4.28 + return err; 4.29 +} 4.30 + 4.31 4.32 4.33 /* Initialise a file structure for a context obtained from the given server 4.34 @@ -179,6 +203,14 @@ 4.35 return openercontext.open(flags, &file->size, &file->ref, &file->object_flags); 4.36 } 4.37 4.38 +/* Remove a file using the given context. */ 4.39 + 4.40 +long file_context_remove(file_t *context) 4.41 +{ 4.42 + client_OpenerContext openercontext(context->ref); 4.43 + return openercontext.remove(); 4.44 +} 4.45 + 4.46 4.47 4.48 /* Flush populated data and obtain an updated file size and populated data
5.1 --- a/libfsserver/include/fsserver/accessor.h Tue Jan 04 23:27:53 2022 +0100 5.2 +++ b/libfsserver/include/fsserver/accessor.h Tue Jan 04 23:43:56 2022 +0100 5.3 @@ -57,6 +57,10 @@ 5.4 virtual void fill(Flexpage *flexpage); 5.5 5.6 virtual void flush(Flexpage *flexpage); 5.7 + 5.8 + /* Lifecycle methods. */ 5.9 + 5.10 + virtual void remove(); 5.11 }; 5.12 5.13 // vim: tabstop=4 expandtab shiftwidth=4
6.1 --- a/libfsserver/include/fsserver/ext2_file_accessor.h Tue Jan 04 23:27:53 2022 +0100 6.2 +++ b/libfsserver/include/fsserver/ext2_file_accessor.h Tue Jan 04 23:43:56 2022 +0100 6.3 @@ -51,6 +51,8 @@ 6.4 virtual offset_t get_size(); 6.5 6.6 virtual void set_size(offset_t size); 6.7 + 6.8 + virtual void remove(); 6.9 }; 6.10 6.11 // vim: tabstop=4 expandtab shiftwidth=4
7.1 --- a/libfsserver/include/fsserver/ext2_file_opener.h Tue Jan 04 23:27:53 2022 +0100 7.2 +++ b/libfsserver/include/fsserver/ext2_file_opener.h Tue Jan 04 23:43:56 2022 +0100 7.3 @@ -62,6 +62,10 @@ 7.4 virtual long make_directory_accessor(const char *path, flags_t flags, 7.5 fileid_t fileid, 7.6 DirectoryAccessor **accessor); 7.7 + 7.8 + virtual long remove_object(const char *path, fileid_t fileid); 7.9 + 7.10 + virtual long unlink_object(const char *path, fileid_t fileid); 7.11 }; 7.12 7.13 // vim: tabstop=4 expandtab shiftwidth=4
8.1 --- a/libfsserver/include/fsserver/ext2_file_operations.h Tue Jan 04 23:27:53 2022 +0100 8.2 +++ b/libfsserver/include/fsserver/ext2_file_operations.h Tue Jan 04 23:43:56 2022 +0100 8.3 @@ -61,23 +61,33 @@ 8.4 8.5 bool is_file(ext2_ino_t ino_file); 8.6 8.7 + void close_file(ext2_file_t file); 8.8 + 8.9 long create_file(ext2_ino_t ino_parent, const char *filename, user_t user, 8.10 ext2_ino_t *ino); 8.11 8.12 long find_file(const char *path, ext2_ino_t *ino, const char **remaining); 8.13 8.14 - void close_file(ext2_file_t file); 8.15 + long open_file(ext2_ino_t ino, ext2_file_t *file); 8.16 + 8.17 + long remove(ext2_ino_t ino); 8.18 8.19 - long open_file(ext2_ino_t ino, ext2_file_t *file); 8.20 + long unlink(ext2_ino_t ino_parent, ext2_ino_t ino); 8.21 + 8.22 + /* File property methods. */ 8.23 8.24 offset_t get_size(ext2_file_t file); 8.25 8.26 void set_size(ext2_file_t file, offset_t size); 8.27 8.28 + /* File access methods. */ 8.29 + 8.30 offset_t read_file(ext2_file_t file, offset_t filepos, void *addr, offset_t size); 8.31 8.32 void write_file(ext2_file_t file, offset_t filepos, const void *addr, offset_t size); 8.33 8.34 + /* Directory access. */ 8.35 + 8.36 long directory_iterate(ext2_ino_t dir, 8.37 int func(struct ext2_dir_entry *, int, int, char *, void *), 8.38 void *priv_data);
9.1 --- a/libfsserver/include/fsserver/file_opening.h Tue Jan 04 23:27:53 2022 +0100 9.2 +++ b/libfsserver/include/fsserver/file_opening.h Tue Jan 04 23:43:56 2022 +0100 9.3 @@ -43,6 +43,10 @@ 9.4 virtual long make_directory_accessor(const char *path, flags_t flags, 9.5 fileid_t fileid, 9.6 DirectoryAccessor **accessor) = 0; 9.7 + 9.8 + virtual long remove_object(const char *path, fileid_t fileid) = 0; 9.9 + 9.10 + virtual long unlink_object(const char *path, fileid_t fileid) = 0; 9.11 }; 9.12 9.13 // vim: tabstop=4 expandtab shiftwidth=4
10.1 --- a/libfsserver/include/fsserver/file_provider.h Tue Jan 04 23:27:53 2022 +0100 10.2 +++ b/libfsserver/include/fsserver/file_provider.h Tue Jan 04 23:43:56 2022 +0100 10.3 @@ -44,6 +44,8 @@ 10.4 10.5 virtual long make_resource(offset_t *size, object_flags_t *object_flags, 10.6 Resource **resource); 10.7 + 10.8 + virtual void remove(); 10.9 }; 10.10 10.11 // vim: tabstop=4 expandtab shiftwidth=4
11.1 --- a/libfsserver/include/fsserver/host_file_opener.h Tue Jan 04 23:27:53 2022 +0100 11.2 +++ b/libfsserver/include/fsserver/host_file_opener.h Tue Jan 04 23:43:56 2022 +0100 11.3 @@ -72,6 +72,10 @@ 11.4 virtual long make_directory_accessor(const char *path, flags_t flags, 11.5 fileid_t fileid, 11.6 DirectoryAccessor **accessor); 11.7 + 11.8 + virtual long remove_object(const char *path, fileid_t fileid); 11.9 + 11.10 + virtual long unlink_object(const char *path, fileid_t fileid); 11.11 }; 11.12 11.13 // vim: tabstop=4 expandtab shiftwidth=4
12.1 --- a/libfsserver/include/fsserver/opener_context_resource.h Tue Jan 04 23:27:53 2022 +0100 12.2 +++ b/libfsserver/include/fsserver/opener_context_resource.h Tue Jan 04 23:43:56 2022 +0100 12.3 @@ -60,6 +60,8 @@ 12.4 long open(flags_t flags, offset_t *size, l4_cap_idx_t *file, 12.5 object_flags_t *object_flags); 12.6 12.7 + long remove(); 12.8 + 12.9 /* Pager/dataspace methods. */ 12.10 12.11 long map(unsigned long offset, address_t hot_spot, map_flags_t flags,
13.1 --- a/libfsserver/include/fsserver/opener_resource.h Tue Jan 04 23:27:53 2022 +0100 13.2 +++ b/libfsserver/include/fsserver/opener_resource.h Tue Jan 04 23:43:56 2022 +0100 13.3 @@ -63,6 +63,8 @@ 13.4 long open(const char *path, flags_t flags, offset_t *size, 13.5 l4_cap_idx_t *cap, object_flags_t *object_flags); 13.6 13.7 + long remove(const char *path); 13.8 + 13.9 /* Opener interface methods. */ 13.10 13.11 long context(l4_cap_idx_t *context);
14.1 --- a/libfsserver/include/fsserver/provider.h Tue Jan 04 23:27:53 2022 +0100 14.2 +++ b/libfsserver/include/fsserver/provider.h Tue Jan 04 23:43:56 2022 +0100 14.3 @@ -35,6 +35,7 @@ 14.4 protected: 14.5 fileid_t _fileid; 14.6 ProviderRegistry *_registry; 14.7 + bool _remove = false; 14.8 14.9 public: 14.10 explicit Provider(fileid_t fileid, ProviderRegistry *registry); 14.11 @@ -45,6 +46,14 @@ 14.12 14.13 virtual long make_resource(offset_t *size, object_flags_t *object_flags, 14.14 Resource **resource) = 0; 14.15 + 14.16 + /* Lifecycle methods. */ 14.17 + 14.18 + virtual bool removal_pending(); 14.19 + 14.20 + virtual void remove(); 14.21 + 14.22 + virtual void remove_pending(bool remove); 14.23 }; 14.24 14.25 // vim: tabstop=4 expandtab shiftwidth=4
15.1 --- a/libfsserver/include/fsserver/provider_registry.h Tue Jan 04 23:27:53 2022 +0100 15.2 +++ b/libfsserver/include/fsserver/provider_registry.h Tue Jan 04 23:43:56 2022 +0100 15.3 @@ -49,6 +49,7 @@ 15.4 ProviderMapping _providers; 15.5 std::mutex _lock; 15.6 15.7 +public: 15.8 /* Filesystem object access. */ 15.9 15.10 Provider *get(fileid_t fileid); 15.11 @@ -57,7 +58,6 @@ 15.12 15.13 void set(fileid_t fileid, Provider *obj); 15.14 15.15 -public: 15.16 /* Methods for resources. */ 15.17 15.18 void detach(fileid_t fileid, Provider *mapper);
16.1 --- a/libfsserver/include/fsserver/resource_registry.h Tue Jan 04 23:27:53 2022 +0100 16.2 +++ b/libfsserver/include/fsserver/resource_registry.h Tue Jan 04 23:43:56 2022 +0100 16.3 @@ -56,7 +56,8 @@ 16.4 public: 16.5 explicit ResourceRegistry(Pages *pages); 16.6 16.7 - /* Resource discovery methods. */ 16.8 + /* Provider discovery methods. 16.9 + NOTE: To be protected, potentially. */ 16.10 16.11 long find_provider(fileid_t fileid, Provider **provider); 16.12 16.13 @@ -65,6 +66,10 @@ 16.14 long get_resource(FileOpening *opening, const char *path, flags_t flags, 16.15 offset_t *size, object_flags_t *object_flags, 16.16 Resource **resource); 16.17 + 16.18 + /* Provider manipulation methods. */ 16.19 + 16.20 + long remove_provider(FileOpening *opening, const char *path); 16.21 }; 16.22 16.23 // vim: tabstop=4 expandtab shiftwidth=4
17.1 --- a/libfsserver/include/fsserver/test_file_opener.h Tue Jan 04 23:27:53 2022 +0100 17.2 +++ b/libfsserver/include/fsserver/test_file_opener.h Tue Jan 04 23:43:56 2022 +0100 17.3 @@ -53,6 +53,10 @@ 17.4 virtual long make_directory_accessor(const char *path, flags_t flags, 17.5 fileid_t fileid, 17.6 DirectoryAccessor **accessor); 17.7 + 17.8 + virtual long remove_object(const char *path, fileid_t fileid); 17.9 + 17.10 + virtual long unlink_object(const char *path, fileid_t fileid); 17.11 }; 17.12 17.13 // vim: tabstop=4 expandtab shiftwidth=4
18.1 --- a/libfsserver/lib/files/ext2_file_accessor.cc Tue Jan 04 23:27:53 2022 +0100 18.2 +++ b/libfsserver/lib/files/ext2_file_accessor.cc Tue Jan 04 23:43:56 2022 +0100 18.3 @@ -100,4 +100,15 @@ 18.4 _ops->write_file(_file, filepos, (const void *) addr, populated_size); 18.5 } 18.6 18.7 + 18.8 + 18.9 +/* Lifecycle methods. */ 18.10 + 18.11 +/* Remove the underlying filesystem object. */ 18.12 + 18.13 +void Ext2FileAccessor::remove() 18.14 +{ 18.15 + _ops->remove(fileid); 18.16 +} 18.17 + 18.18 // vim: tabstop=4 expandtab shiftwidth=4
19.1 --- a/libfsserver/lib/files/ext2_file_opener.cc Tue Jan 04 23:27:53 2022 +0100 19.2 +++ b/libfsserver/lib/files/ext2_file_opener.cc Tue Jan 04 23:43:56 2022 +0100 19.3 @@ -120,4 +120,26 @@ 19.4 return L4_EOK; 19.5 } 19.6 19.7 +/* Remove a filesystem object. */ 19.8 + 19.9 +long Ext2FileOpener::remove_object(const char *path, fileid_t fileid) 19.10 +{ 19.11 + (void) path; 19.12 + 19.13 + return _ops->remove((ext2_ino_t) fileid); 19.14 +} 19.15 + 19.16 +/* Unlink a filesystem object. */ 19.17 + 19.18 +long Ext2FileOpener::unlink_object(const char *path, fileid_t fileid) 19.19 +{ 19.20 + fileid_t parent; 19.21 + long err = get_parent(path, &parent); 19.22 + 19.23 + if (err) 19.24 + return err; 19.25 + 19.26 + return _ops->unlink((ext2_ino_t) parent, (ext2_ino_t) fileid); 19.27 +} 19.28 + 19.29 // vim: tabstop=4 expandtab shiftwidth=4
20.1 --- a/libfsserver/lib/files/ext2_file_operations.cc Tue Jan 04 23:27:53 2022 +0100 20.2 +++ b/libfsserver/lib/files/ext2_file_operations.cc Tue Jan 04 23:43:56 2022 +0100 20.3 @@ -113,6 +113,38 @@ 20.4 return L4_EOK; 20.5 } 20.6 20.7 +/* Remove an object from a directory. */ 20.8 + 20.9 +long Ext2FileOperations::remove(ext2_ino_t ino) 20.10 +{ 20.11 + std::lock_guard<std::mutex> guard(_lock); 20.12 + 20.13 + errcode_t retval = image_remove_by_inode(_fs, ino); 20.14 + 20.15 + // NOTE: Map error conditions. 20.16 + 20.17 + if (retval) 20.18 + return -L4_EIO; 20.19 + 20.20 + return L4_EOK; 20.21 +} 20.22 + 20.23 +/* Unlink an object from a directory. */ 20.24 + 20.25 +long Ext2FileOperations::unlink(ext2_ino_t ino_parent, ext2_ino_t ino) 20.26 +{ 20.27 + std::lock_guard<std::mutex> guard(_lock); 20.28 + 20.29 + errcode_t retval = image_unlink_by_inode(_fs, ino_parent, ino); 20.30 + 20.31 + // NOTE: Map error conditions. 20.32 + 20.33 + if (retval) 20.34 + return -L4_EIO; 20.35 + 20.36 + return L4_EOK; 20.37 +} 20.38 + 20.39 /* Obtain the size of a file. */ 20.40 20.41 offset_t Ext2FileOperations::get_size(ext2_file_t file)
21.1 --- a/libfsserver/lib/files/file_provider.cc Tue Jan 04 23:27:53 2022 +0100 21.2 +++ b/libfsserver/lib/files/file_provider.cc Tue Jan 04 23:43:56 2022 +0100 21.3 @@ -73,4 +73,13 @@ 21.4 return L4_EOK; 21.5 } 21.6 21.7 +/* Lifecycle methods. */ 21.8 + 21.9 +/* Remove the file using the accessor. */ 21.10 + 21.11 +void FileProvider::remove() 21.12 +{ 21.13 + _mapper->accessor()->remove(); 21.14 +} 21.15 + 21.16 // vim: tabstop=4 expandtab shiftwidth=4
22.1 --- a/libfsserver/lib/files/host_file_opener.cc Tue Jan 04 23:27:53 2022 +0100 22.2 +++ b/libfsserver/lib/files/host_file_opener.cc Tue Jan 04 23:43:56 2022 +0100 22.3 @@ -20,6 +20,7 @@ 22.4 */ 22.5 22.6 #include <sys/stat.h> 22.7 +#include <unistd.h> 22.8 22.9 #include <fsclient/client.h> 22.10 22.11 @@ -131,4 +132,39 @@ 22.12 return L4_EOK; 22.13 } 22.14 22.15 +/* Remove a filesystem object. */ 22.16 + 22.17 +long HostFileOpener::remove_object(const char *path, fileid_t fileid) 22.18 +{ 22.19 + (void) path; (void) fileid; 22.20 + return L4_EOK; 22.21 +} 22.22 + 22.23 +/* Unlink a filesystem object. */ 22.24 + 22.25 +long HostFileOpener::unlink_object(const char *path, fileid_t fileid) 22.26 +{ 22.27 + /* Ignore the fileid and always use the path. */ 22.28 + 22.29 + (void) fileid; 22.30 + 22.31 + // NOTE: Return code may need converting. 22.32 + 22.33 + int err = unlink(path); 22.34 + 22.35 + if (err) 22.36 + return err; 22.37 + 22.38 + /* Remove the file identifier mapping. */ 22.39 + 22.40 + std::string s(path); 22.41 + 22.42 + HostFileIdentifiers::iterator it = _fileids.find(s); 22.43 + 22.44 + if (it != _fileids.end()) 22.45 + _fileids.erase(it); 22.46 + 22.47 + return L4_EOK; 22.48 +} 22.49 + 22.50 // vim: tabstop=4 expandtab shiftwidth=4
23.1 --- a/libfsserver/lib/files/opener_context_resource.cc Tue Jan 04 23:27:53 2022 +0100 23.2 +++ b/libfsserver/lib/files/opener_context_resource.cc Tue Jan 04 23:43:56 2022 +0100 23.3 @@ -78,4 +78,14 @@ 23.4 return _opener->open(path, flags, size, file, object_flags); 23.5 } 23.6 23.7 +long OpenerContextResource::remove() 23.8 +{ 23.9 + char *path = get_path(); 23.10 + 23.11 + if (path == NULL) 23.12 + return -L4_EINVAL; 23.13 + 23.14 + return _opener->remove(path); 23.15 +} 23.16 + 23.17 // vim: tabstop=4 expandtab shiftwidth=4
24.1 --- a/libfsserver/lib/files/opener_resource.cc Tue Jan 04 23:27:53 2022 +0100 24.2 +++ b/libfsserver/lib/files/opener_resource.cc Tue Jan 04 23:43:56 2022 +0100 24.3 @@ -74,7 +74,8 @@ 24.4 } 24.5 24.6 /* Obtain any active parent directory for a path, notifying its subscribers of 24.7 - the file opening event. */ 24.8 + the file opening event. 24.9 + NOTE: This might need to happen in the registry due to concurrency issues. */ 24.10 24.11 long OpenerResource::notify_parent(const char *path) 24.12 { 24.13 @@ -124,6 +125,13 @@ 24.14 return ResourceServer(resource).start_thread(cap); 24.15 } 24.16 24.17 +/* Request the removal of the named filesystem object. */ 24.18 + 24.19 +long OpenerResource::remove(const char *path) 24.20 +{ 24.21 + return _registry->remove_provider(this, path); 24.22 +} 24.23 + 24.24 24.25 24.26 /* Opener interface methods. */
25.1 --- a/libfsserver/lib/files/test_file_opener.cc Tue Jan 04 23:27:53 2022 +0100 25.2 +++ b/libfsserver/lib/files/test_file_opener.cc Tue Jan 04 23:43:56 2022 +0100 25.3 @@ -79,4 +79,20 @@ 25.4 return -L4_EIO; 25.5 } 25.6 25.7 +/* Remove a filesystem object. */ 25.8 + 25.9 +long TestFileOpener::remove_object(const char *path, fileid_t fileid) 25.10 +{ 25.11 + (void) path; (void) fileid; 25.12 + return L4_EOK; 25.13 +} 25.14 + 25.15 +/* Unlink a filesystem object. */ 25.16 + 25.17 +long TestFileOpener::unlink_object(const char *path, fileid_t fileid) 25.18 +{ 25.19 + (void) path; (void) fileid; 25.20 + return -L4_EIO; 25.21 +} 25.22 + 25.23 // vim: tabstop=4 expandtab shiftwidth=4
26.1 --- a/libfsserver/lib/generic/accessor.cc Tue Jan 04 23:27:53 2022 +0100 26.2 +++ b/libfsserver/lib/generic/accessor.cc Tue Jan 04 23:43:56 2022 +0100 26.3 @@ -76,4 +76,12 @@ 26.4 (void) flexpage; 26.5 } 26.6 26.7 +/* Lifecycle methods. */ 26.8 + 26.9 +/* Remove a filesystem object. */ 26.10 + 26.11 +void Accessor::remove() 26.12 +{ 26.13 +} 26.14 + 26.15 // vim: tabstop=4 expandtab shiftwidth=4
27.1 --- a/libfsserver/lib/generic/provider.cc Tue Jan 04 23:27:53 2022 +0100 27.2 +++ b/libfsserver/lib/generic/provider.cc Tue Jan 04 23:43:56 2022 +0100 27.3 @@ -37,4 +37,18 @@ 27.4 return _registry; 27.5 } 27.6 27.7 +bool Provider::removal_pending() 27.8 +{ 27.9 + return _remove; 27.10 +} 27.11 + 27.12 +void Provider::remove() 27.13 +{ 27.14 +} 27.15 + 27.16 +void Provider::remove_pending(bool remove) 27.17 +{ 27.18 + _remove = remove; 27.19 +} 27.20 + 27.21 // vim: tabstop=4 expandtab shiftwidth=4
28.1 --- a/libfsserver/lib/generic/provider_registry.cc Tue Jan 04 23:27:53 2022 +0100 28.2 +++ b/libfsserver/lib/generic/provider_registry.cc Tue Jan 04 23:43:56 2022 +0100 28.3 @@ -74,7 +74,16 @@ 28.4 std::lock_guard<std::mutex> guard(_lock); 28.5 28.6 if (!provider->detach()) 28.7 + { 28.8 + /* Remove any underlying object if pending. */ 28.9 + 28.10 + if (provider->removal_pending()) 28.11 + provider->remove(); 28.12 + 28.13 + /* Remove from the registry. */ 28.14 + 28.15 remove(fileid, provider); 28.16 + } 28.17 } 28.18 28.19 // vim: tabstop=4 expandtab shiftwidth=4
29.1 --- a/libfsserver/lib/generic/resource_registry.cc Tue Jan 04 23:27:53 2022 +0100 29.2 +++ b/libfsserver/lib/generic/resource_registry.cc Tue Jan 04 23:43:56 2022 +0100 29.3 @@ -169,4 +169,44 @@ 29.4 return provider->make_resource(size, object_flags, resource); 29.5 } 29.6 29.7 +/* Request the removal of a filesystem object through any active provider. */ 29.8 + 29.9 +long ResourceRegistry::remove_provider(FileOpening *opening, const char *path) 29.10 +{ 29.11 + std::lock_guard<std::mutex> guard(_lock); 29.12 + 29.13 + /* Obtain an identifier for any recognised object. */ 29.14 + 29.15 + fileid_t fileid; 29.16 + long err = opening->get_fileid(path, 0, &fileid); 29.17 + 29.18 + if (err) 29.19 + return err; 29.20 + 29.21 + /* Obtain a provider for the object. */ 29.22 + 29.23 + Provider *provider; 29.24 + err = find_provider(fileid, &provider); 29.25 + 29.26 + if (err && (err != -L4_ENOENT)) 29.27 + return err; 29.28 + 29.29 + /* Unlink the object regardless of whether it can be removed. */ 29.30 + 29.31 + err = opening->unlink_object(path, fileid); 29.32 + 29.33 + if (err) 29.34 + return err; 29.35 + 29.36 + /* Without a provider being active, remove the object directly. */ 29.37 + 29.38 + if (err) 29.39 + return opening->remove_object(path, fileid); 29.40 + 29.41 + /* With a provider active, request the object's removal upon closure. */ 29.42 + 29.43 + provider->remove_pending(true); 29.44 + return L4_EOK; 29.45 +} 29.46 + 29.47 // vim: tabstop=4 expandtab shiftwidth=4
30.1 --- a/libsystypes/idl/opener_context.idl Tue Jan 04 23:27:53 2022 +0100 30.2 +++ b/libsystypes/idl/opener_context.idl Tue Jan 04 23:43:56 2022 +0100 30.3 @@ -1,7 +1,8 @@ 30.4 #include <systypes/base.h> /* flags_t, object_flags_t, offset_t */ 30.5 30.6 -/* An interface providing a way of opening filesystem objects relying on a 30.7 - dataspace to transfer filesystem paths. */ 30.8 +/* An interface providing a way of opening or manipulating filesystem objects 30.9 + relying on a dataspace to transfer filesystem paths specifying the objects 30.10 + involved. */ 30.11 30.12 interface OpenerContext 30.13 { 30.14 @@ -18,6 +19,10 @@ 30.15 30.16 [opcode(12)] void open(in flags_t flags, out offset_t size, out cap file, 30.17 out object_flags_t object_flags); 30.18 + 30.19 + /* Remove a file using a path written to the context's dataspace. */ 30.20 + 30.21 + [opcode(14)] void remove(); 30.22 }; 30.23 30.24 /* vim: tabstop=2 expandtab shiftwidth=2
31.1 --- a/tests/dstest_file_readdir_concurrent.cc Tue Jan 04 23:27:53 2022 +0100 31.2 +++ b/tests/dstest_file_readdir_concurrent.cc Tue Jan 04 23:43:56 2022 +0100 31.3 @@ -79,6 +79,30 @@ 31.4 } 31.5 } 31.6 31.7 +static long remove_file(char *filename, bool have_uid, sys_uid_t uid) 31.8 +{ 31.9 + /* With a user, open a user-specific file opener. */ 31.10 + 31.11 + if (have_uid) 31.12 + { 31.13 + l4_cap_idx_t opener = client_open_for_user((user_t) {uid, uid, 0022}); 31.14 + 31.15 + if (l4_is_invalid_cap(opener)) 31.16 + { 31.17 + printf("Could not obtain opener for file.\n"); 31.18 + return -L4_EIO; 31.19 + } 31.20 + 31.21 + /* Invoke the remove method to remove the file. */ 31.22 + 31.23 + return client_remove_using(filename, opener); 31.24 + } 31.25 + else 31.26 + { 31.27 + return client_remove(filename); 31.28 + } 31.29 +} 31.30 + 31.31 31.32 31.33 int main(int argc, char *argv[]) 31.34 @@ -108,7 +132,9 @@ 31.35 struct dirent *dirent; 31.36 int filenum = 1000, remaining = 100; 31.37 char buffer[strlen(filename) + strlen("/file-XXXX.txt") + 10]; 31.38 + char data[256]; 31.39 int found = 0; 31.40 + file_t *files[100]; 31.41 31.42 while ((dirent = client_readdir(reader)) != NULL) 31.43 { 31.44 @@ -129,6 +155,15 @@ 31.45 return 1; 31.46 } 31.47 31.48 + /* Write something to each file. */ 31.49 + 31.50 + sprintf(data, "Data in file-%d.txt", filenum - 1); 31.51 + client_write(file, data, strlen(data)); 31.52 + 31.53 + /* Remember the file for later. */ 31.54 + 31.55 + files[remaining - 1] = file; 31.56 + 31.57 remaining--; 31.58 } 31.59 } 31.60 @@ -155,6 +190,54 @@ 31.61 31.62 printf("Files found: %d\n", found); 31.63 31.64 + /* Remove some files. */ 31.65 + 31.66 + for (filenum = 1000, remaining = 100; remaining > 0; remaining--) 31.67 + { 31.68 + sprintf(buffer, "%s/file-%d.txt", filename, filenum++); 31.69 + 31.70 + long err = remove_file(buffer, have_uid, uid); 31.71 + 31.72 + if (err) 31.73 + { 31.74 + printf("Could not remove file: %s\n", buffer); 31.75 + return 1; 31.76 + } 31.77 + } 31.78 + 31.79 + /* Re-read, counting files. */ 31.80 + 31.81 + reader = open_directory(filename, have_uid, uid); 31.82 + 31.83 + if (reader == NULL) 31.84 + { 31.85 + printf("Could not read from directory.\n"); 31.86 + return 1; 31.87 + } 31.88 + 31.89 + found = 0; 31.90 + 31.91 + while ((dirent = client_readdir(reader)) != NULL) 31.92 + { 31.93 + free(dirent); 31.94 + found++; 31.95 + } 31.96 + 31.97 + printf("Files found: %d\n", found); 31.98 + 31.99 + /* Read from the still-open but now removed files. */ 31.100 + 31.101 + for (remaining = 0; remaining < 100; remaining++) 31.102 + { 31.103 + file_t *file = files[remaining]; 31.104 + 31.105 + client_seek(file, SEEK_SET, 0); 31.106 + offset_t nread = client_read(file, data, 256); 31.107 + 31.108 + data[nread] = '\0'; 31.109 + printf("Read: %s\n", data); 31.110 + } 31.111 + 31.112 return 0; 31.113 } 31.114