L4Re/departure

Annotated libfsserver/lib/files/opener_resource.cc

645:3047b11cc814
7 months ago Paul Boddie Fixed the file_data_available result to return zero if the populated span has somehow become less than the current position in the memory region.
paul@93 1
/*
paul@93 2
 * A resource offering support for creating contexts and opening files.
paul@93 3
 *
paul@484 4
 * Copyright (C) 2021, 2022, 2023 Paul Boddie <paul@boddie.org.uk>
paul@93 5
 *
paul@93 6
 * This program is free software; you can redistribute it and/or
paul@93 7
 * modify it under the terms of the GNU General Public License as
paul@93 8
 * published by the Free Software Foundation; either version 2 of
paul@93 9
 * the License, or (at your option) any later version.
paul@93 10
 *
paul@93 11
 * This program is distributed in the hope that it will be useful,
paul@93 12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
paul@93 13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
paul@93 14
 * GNU General Public License for more details.
paul@93 15
 *
paul@93 16
 * You should have received a copy of the GNU General Public License
paul@93 17
 * along with this program; if not, write to the Free Software
paul@93 18
 * Foundation, Inc., 51 Franklin Street, Fifth Floor,
paul@93 19
 * Boston, MA  02110-1301, USA
paul@93 20
 */
paul@93 21
paul@535 22
#include <resource/resource_server.h>
paul@535 23
paul@10 24
#include "opener_server.h"
paul@10 25
#include "opener_resource.h"
paul@9 26
paul@9 27
/* Support for providing access to files. */
paul@9 28
paul@224 29
OpenerResource::OpenerResource(ResourceRegistry *registry)
paul@209 30
: _registry(registry)
paul@9 31
{
paul@9 32
}
paul@9 33
paul@156 34
OpenerResource::~OpenerResource()
paul@156 35
{
paul@156 36
}
paul@156 37
paul@459 38
ipc_server_default_config_type OpenerResource::config()
paul@9 39
{
paul@459 40
    return config_Opener;
paul@10 41
}
paul@10 42
paul@10 43
paul@10 44
paul@214 45
/* Obtain any active parent directory for a path, notifying its subscribers of
paul@232 46
   the file opening event.
paul@232 47
   NOTE: This might need to happen in the registry due to concurrency issues. */
paul@214 48
paul@214 49
long OpenerResource::notify_parent(const char *path)
paul@214 50
{
paul@220 51
    Provider *provider;
paul@214 52
    fileid_t fileid;
paul@214 53
    long err;
paul@214 54
paul@214 55
    err = get_parent(path, &fileid);
paul@214 56
paul@211 57
    if (err)
paul@211 58
        return err;
paul@211 59
paul@211 60
    /* Obtain the provider of the parent directory. */
paul@211 61
paul@220 62
    err = _registry->find_provider(fileid, &provider);
paul@211 63
paul@211 64
    if (err)
paul@211 65
        return err;
paul@211 66
paul@211 67
    /* With any active provider, send a notification.
paul@211 68
       NOTE: This should also communicate which file was involved, probably
paul@211 69
       NOTE: using the file identifier of the opened file. */
paul@211 70
paul@484 71
    provider->notify_all(NOTIFY_FILE_OPENED, NOTIFY_VALUES_NULL);
paul@211 72
    return L4_EOK;
paul@211 73
}
paul@211 74
paul@211 75
paul@211 76
paul@271 77
/* Make a directory. */
paul@271 78
paul@271 79
long OpenerResource::mkdir(const char *path, sys_mode_t mode)
paul@271 80
{
paul@271 81
    return make_directory_object(path, mode);
paul@271 82
}
paul@271 83
paul@205 84
/* Return an object for the given path and flags. */
paul@10 85
paul@171 86
long OpenerResource::open(const char *path, flags_t flags, offset_t *size,
paul@475 87
                          l4_cap_idx_t *file, object_flags_t *object_flags)
paul@9 88
{
paul@218 89
    Resource *resource;
paul@218 90
    long err = _registry->get_resource(this, path, flags, size, object_flags, &resource);
paul@156 91
paul@156 92
    if (err)
paul@156 93
        return err;
paul@156 94
paul@211 95
    /* Notify listeners subscribed to the parent of the opened object. */
paul@211 96
paul@211 97
    notify_parent(path);
paul@211 98
paul@218 99
    /* Start a server for the resource. */
paul@202 100
paul@475 101
    return ResourceServer(resource).start_thread(file);
paul@9 102
}
paul@9 103
paul@232 104
/* Request the removal of the named filesystem object. */
paul@232 105
paul@232 106
long OpenerResource::remove(const char *path)
paul@232 107
{
paul@232 108
    return _registry->remove_provider(this, path);
paul@232 109
}
paul@232 110
paul@236 111
/* Request the renaming of the named filesystem object. */
paul@236 112
paul@236 113
long OpenerResource::rename(const char *source, const char *target)
paul@236 114
{
paul@236 115
    return _registry->rename_provider(this, source, target);
paul@236 116
}
paul@236 117
paul@266 118
/* Obtain statistics metadata for the named filesystem object. */
paul@266 119
paul@266 120
long OpenerResource::stat(const char *path, void *base, offset_t size)
paul@266 121
{
paul@266 122
    return stat_object(path, base, size);
paul@266 123
}
paul@266 124
paul@10 125
paul@10 126
paul@10 127
/* Opener interface methods. */
paul@10 128
paul@10 129
long OpenerResource::context(l4_cap_idx_t *context)
paul@10 130
{
paul@10 131
    OpenerContextResource *resource = new OpenerContextResource(this);
paul@10 132
paul@62 133
    /* Complete the initialisation and start a server in a new thread.
paul@120 134
       If the thread does not start, the resource will be finalised. */
paul@10 135
paul@120 136
    return ResourceServer(resource).start_thread(context);
paul@10 137
}
paul@10 138
paul@9 139
// vim: tabstop=4 expandtab shiftwidth=4