blob: 2a645af22394747ad8f57e58399e2820f8d9324c [file] [log] [blame]
// Copyright 2019 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef LIB_FDIO_NAMESPACE_LOCAL_FILESYSTEM_H_
#define LIB_FDIO_NAMESPACE_LOCAL_FILESYSTEM_H_
#include <lib/fdio/fdio.h>
#include <lib/fdio/namespace.h>
#include <lib/zx/channel.h>
#include <lib/zxio/zxio.h>
#include <mutex>
#include <fbl/ref_counted.h>
#include <fbl/ref_ptr.h>
#include "sdk/lib/fdio/namespace/local-vnode.h"
struct fdio;
namespace fdio_internal {
struct DirentIteratorState;
}
// A local filesystem consisting of LocalVnodes, mapping string names
// to remote handles.
//
// This class is thread-safe.
struct fdio_namespace : public fbl::RefCounted<fdio_namespace> {
public:
using LocalVnode = fdio_internal::LocalVnode;
using DirentIteratorState = fdio_internal::DirentIteratorState;
fdio_namespace(const fdio_namespace&) = delete;
fdio_namespace(fdio_namespace&&) = delete;
fdio_namespace& operator=(const fdio_namespace&) = delete;
fdio_namespace& operator=(fdio_namespace&&) = delete;
// Create a new object referring to the root of this namespace.
//
// Returns |nullptr| on failure.
zx::result<fbl::RefPtr<fdio>> OpenRoot() const;
// Change the root of this namespace to match |io|.
//
// Does not take ownership of |io|.
zx_status_t SetRoot(fdio_t* io);
// Export all remote references and their paths in a flat format.
zx_status_t Export(fdio_flat_namespace_t** out) const;
// Reads a single entry from the list of directory entries into |inout_entry|.
// If we have reached the end, ZX_ERR_NOT_FOUND is returned.
zx_status_t Readdir(const LocalVnode& vn, DirentIteratorState* state,
zxio_dirent_t* inout_entry) const;
// Open a remote object within the namespace using deprecated fuchsia.io/Directory.Open1.
//
// Returns an error if |path| does not exist.
// Returns an error if |path| references a non-remote object.
// TODO(https://fxbug.dev/324111518): Remove this after all callers are migrated to |OpenRemote|.
zx_status_t OpenRemoteDeprecated(std::string_view path, fuchsia_io::wire::OpenFlags flags,
fidl::ServerEnd<fuchsia_io::Node> server_end) const;
// Open |path| relative to |vn| with specified |flags|. |path| may represent either a local node,
// or a remote object.
zx::result<fbl::RefPtr<fdio>> OpenAt(fbl::RefPtr<LocalVnode> vn, std::string_view path,
fuchsia_io::Flags flags) const;
// Open a remote node at |path| within the namespace using |flags|. |path| must be an absolute
// path starting from /.
//
// Returns an error if |path| does not exist.
// Returns an error if |path| references a non-remote object.
zx_status_t OpenRemote(std::string_view path, fuchsia_io::Flags flags, zx::channel object) const;
// Attaches a local node defined by |on_open| to |path| within the current namespace.
zx_status_t Bind(std::string_view path, fdio_open_local_func_t on_open, void* context);
// Attaches |remote| to |path| within the current namespace.
zx_status_t Bind(std::string_view path, fidl::ClientEnd<fuchsia_io::Directory> remote);
// Detaches a remote object from |path| within the current namespace.
//
// Returns ZX_ERR_NOT_FOUND if |path| does not correspond with a bound remote.
// Returns ZX_ERR_NOT_SUPPORTED if |path| is the root of the namespace.
// Returns ZX_ERR_INVALID_ARGS for an unsupported |path|.
zx_status_t Unbind(std::string_view path);
bool IsBound(std::string_view path);
private:
friend class fbl::internal::MakeRefCountedHelper<fdio_namespace>;
fdio_namespace();
void ResetRoot() __TA_REQUIRES(lock_);
// Creates a local object with a connection to a vnode.
// This object will increase the number of references to the namespace by
// one.
zx::result<fbl::RefPtr<fdio>> CreateConnection(fbl::RefPtr<LocalVnode> vn) const;
// Lookup repeatedly to traverse vnodes within the local filesystem.
//
// |in_out_vn| and |in_out_path| are input and output parameters.
zx_status_t WalkLocked(fbl::RefPtr<LocalVnode>* in_out_vn, std::string_view* in_out_path) const
__TA_REQUIRES(lock_);
// Attaches the node generated by |builder| to |path| within the current namespace.
zx_status_t Bind(
std::string_view path,
fit::function<zx::result<fbl::RefPtr<LocalVnode>>(std::optional<LocalVnode::ParentAndId>)>
builder);
mutable std::mutex lock_;
fbl::RefPtr<LocalVnode> root_ __TA_GUARDED(lock_);
};
#endif // LIB_FDIO_NAMESPACE_LOCAL_FILESYSTEM_H_