/* * Copyright (c) 2016, Facebook, Inc. * All rights reserved. * * This source code is licensed under the BSD-style license found in the * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. * */ #pragma once #include #include #include #include #include #include "eden/fuse/EdenStats.h" #include "eden/fuse/FileHandleMap.h" #include "eden/fuse/fuse_headers.h" #include "eden/utils/PathFuncs.h" namespace facebook { namespace eden { namespace fusell { #define FUSELL_NOT_IMPL() \ do { \ LOG_FIRST_N(ERROR, 1) << __PRETTY_FUNCTION__ << " not implemented"; \ folly::throwSystemErrorExplicit(ENOSYS, __PRETTY_FUNCTION__); \ } while (0) class Dispatcher; class SessionDeleter; class Channel; class RequestData; class FileHandle; class DirHandle; class MountPoint; class Dispatcher { fuse_conn_info connInfo_; Channel* chan_{nullptr}; /** * The MountPoint using this dispatcher. * * This pointer is not set until the MountPoint is started. */ MountPoint* mountPoint_{nullptr}; EdenStats stats_; FileHandleMap fileHandles_; public: virtual ~Dispatcher(); static void disp_init(void* userdata, struct fuse_conn_info* conn); std::unique_ptr makeSession( Channel& channel, bool debug); EdenStats& getStats(); const EdenStats& getStats() const; Channel& getChannel() const; const fuse_conn_info& getConnInfo() const; FileHandleMap& getFileHandles(); // delegates to FileHandleMap::getGenericFileHandle std::shared_ptr getGenericFileHandle(uint64_t fh); // delegates to FileHandleMap::getFileHandle std::shared_ptr getFileHandle(uint64_t fh); // delegates to FileHandleMap::getDirHandle std::shared_ptr getDirHandle(uint64_t dh); /** * Set the MountPoint currently using this Dispatcher. * * This is called when the MountPoint begins the mounting process. */ void setMountPoint(MountPoint* mountPoint); /** * Clear the MountPoint. * * This is called once the MountPoint is unmounted. */ void unsetMountPoint(); /** * Called during filesystem mounting. It informs the filesystem * of kernel capabilities and provides an opportunity to poke some * flags and limits in the conn_info to report capabilities back * to the kernel */ virtual void initConnection(fuse_conn_info& conn); /** * Called when fuse is tearing down the session */ virtual void destroy(); /** * Lookup a directory entry by name and get its attributes */ virtual folly::Future lookup( fuse_ino_t parent, PathComponentPiece name); /** * Forget about an inode * * The nlookup parameter indicates the number of lookups * previously performed on this inode. * * If the filesystem implements inode lifetimes, it is recommended * that inodes acquire a single reference on each lookup, and lose * nlookup references on each forget. * * The filesystem may ignore forget calls, if the inodes don't * need to have a limited lifetime. * * On unmount it is not guaranteed, that all referenced inodes * will receive a forget message. * * @param ino the inode number * @param nlookup the number of lookups to forget */ virtual folly::Future forget(fuse_ino_t ino, unsigned long nlookup); /** * The stat information and the cache TTL for the kernel * * The timeout value is measured in seconds and indicates how long * the kernel side of the FUSE will cache the values in the * struct stat before calling getattr() again to refresh it. */ struct Attr { struct stat st; double timeout; explicit Attr(const MountPoint* mountPoint); }; /** * Get file attributes * * @param ino the inode number */ virtual folly::Future getattr(fuse_ino_t ino); /** * Set file attributes * * In the 'attr' argument only members indicated by the 'to_set' * bitmask contain valid values. Other members contain undefined * values. * * @param ino the inode number * @param attr the attributes * @param to_set bit mask of attributes which should be set * * Changed in version 2.5: * file information filled in for ftruncate */ virtual folly::Future setattr(fuse_ino_t ino, const struct stat& attr, int to_set); /** * Read symbolic link * * @param ino the inode number */ virtual folly::Future readlink(fuse_ino_t ino); /** * Create file node * * Create a regular file, character device, block device, fifo or * socket node. * * @param parent inode number of the parent directory * @param name to create * @param mode file type and mode with which to create the new file * @param rdev the device number (only valid if created file is a device) */ virtual folly::Future mknod(fuse_ino_t parent, PathComponentPiece name, mode_t mode, dev_t rdev); /** * Create a directory * * @param parent inode number of the parent directory * @param name to create * @param mode with which to create the new file */ virtual folly::Future mkdir(fuse_ino_t parent, PathComponentPiece name, mode_t mode); /** * Remove a file * * @param parent inode number of the parent directory * @param name to remove */ virtual folly::Future unlink( fuse_ino_t parent, PathComponentPiece name); /** * Remove a directory * * @param parent inode number of the parent directory * @param name to remove */ virtual folly::Future rmdir( fuse_ino_t parent, PathComponentPiece name); /** * Create a symbolic link * * @param parent inode number of the parent directory * @param name to create * @param link the contents of the symbolic link */ virtual folly::Future symlink(fuse_ino_t parent, PathComponentPiece name, folly::StringPiece link); /** * Rename a file * * @param parent inode number of the old parent directory * @param name old name * @param newparent inode number of the new parent directory * @param newname new name */ virtual folly::Future rename( fuse_ino_t parent, PathComponentPiece name, fuse_ino_t newparent, PathComponentPiece newname); /** * Create a hard link * * @param ino the old inode number * @param newparent inode number of the new parent directory * @param newname new name to create */ virtual folly::Future link(fuse_ino_t ino, fuse_ino_t newparent, PathComponentPiece newname); /** * Open a file * * Open flags (with the exception of O_CREAT, O_EXCL, O_NOCTTY and * O_TRUNC) are available in fi->flags. * * Filesystem may store an arbitrary file handle (pointer, index, * etc) in fi->fh, and use this in other all other file operations * (read, write, flush, release, fsync). * * There are also some flags (direct_io, keep_cache) which the * filesystem may set in fi, to change the way the file is opened. * See fuse_file_info structure in for more details. * * @param ino the inode number * @param fi file information */ virtual folly::Future> open( fuse_ino_t ino, const struct fuse_file_info& fi); /** * Open a directory * * Filesystem may store an arbitrary file handle (pointer, index, * etc) in fi->fh, and use this in other all other directory * stream operations (readdir, releasedir, fsyncdir). * * Filesystem may also implement stateless directory I/O and not * store anything in fi->fh, though that makes it impossible to * implement standard conforming directory stream operations in * case the contents of the directory can change between opendir * and releasedir. * * @param ino the inode number * @param fi file information */ virtual folly::Future> opendir( fuse_ino_t ino, const struct fuse_file_info& fi); /** * Get file system statistics * * @param ino the inode number, zero means "undefined" */ virtual folly::Future statfs(fuse_ino_t ino); /** * Set an extended attribute */ virtual folly::Future setxattr(fuse_ino_t ino, folly::StringPiece name, folly::StringPiece value, int flags); /** * Get an extended attribute */ virtual folly::Future getxattr(fuse_ino_t ino, folly::StringPiece name); static const int kENOATTR; /** * List extended attribute names */ virtual folly::Future> listxattr(fuse_ino_t ino); /** * Remove an extended attribute * * @param ino the inode number * @param name of the extended attribute */ virtual folly::Future removexattr(fuse_ino_t ino, folly::StringPiece name); /** * Check file access permissions * * This will be called for the access() system call. If the * 'default_permissions' mount option is given, this method is not * called. * * This method is not called under Linux kernel versions 2.4.x * * Introduced in version 2.5 * * @param ino the inode number * @param mask requested access mode */ virtual folly::Future access(fuse_ino_t ino, int mask); struct Create { fuse_entry_param entry; std::shared_ptr fh; }; /** * Create and open a file * * If the file does not exist, first create it with the specified * mode, and then open it. * * Open flags (with the exception of O_NOCTTY) are available in * fi->flags. * * If this method is not implemented or under Linux kernel * versions earlier than 2.6.15, the mknod() and open() methods * will be called instead. * * Introduced in version 2.5 * * @param parent inode number of the parent directory * @param name to create * @param mode file type and mode with which to create the new file */ virtual folly::Future create(fuse_ino_t parent, PathComponentPiece name, mode_t mode, int flags); /** * Map block index within file to block index within device * * Note: This makes sense only for block device backed filesystems * mounted with the 'blkdev' option * * Introduced in version 2.6 * * @param ino the inode number * @param blocksize unit of block index * @param idx block index within file */ virtual folly::Future bmap(fuse_ino_t ino, size_t blocksize, uint64_t idx); }; } } }