Пример #1
0
int FuseContext::rename (const char *oldpath, const char *newpath)
{
    namespace fs = boost::filesystem;
    Path_t oldwrap = m_realRoot / oldpath;
    Path_t newwrap = m_realRoot / newpath;

    // if the move overwrites a file then copy data, increment version, and
    // unlink the old file
    if( fs::exists( newwrap ) )
    {
        // perform the move
        int result = ::rename( oldwrap.c_str(), newwrap.c_str() );
        if( result < 0 )
            return -errno;

        m_backend->db().incrementVersion( Path_t(newpath) );
        m_backend->db().unlink( Path_t(oldpath) );

        return result;
    }
    else
    {
        int result = ::rename( oldwrap.c_str(), newwrap.c_str() );
        if( result < 0 )
            return -errno;

        m_backend->db().mknod( Path_t(newpath) );
        m_backend->db().unlink( Path_t(oldpath) );

        return result;
    }
}
Пример #2
0
int FuseContext::link (const char *oldpath, const char *newpath)
{
    Path_t oldwrap = m_realRoot / oldpath;
    Path_t newwrap = m_realRoot / newpath;

    int result = ::link( oldwrap.c_str(), newwrap.c_str() );
    if( result < 0 )
        return -errno;

    return result;
}
Пример #3
0
int FuseContext::getattr (const char *path, struct stat *out)
{
    namespace fs = boost::filesystem;
    Path_t wrapped = m_realRoot / path;

    int result = ::lstat( wrapped.c_str(), out );

    // if we failed to stat the underlying file, then check to see if the
    // file is unsubscribed
    if( result < 0 )
    {
        if( m_backend->db().isSubscribed( m_relDir / path ) )
            return -errno;
        else
        {
            out->st_mode  = S_IFREG | S_IRUSR | S_IWUSR;
            out->st_nlink = 0;
            out->st_uid   = getuid();
            out->st_gid   = getgid();
            out->st_size  = 0;
            out->st_atime = 0;
            out->st_mtime = 0;
            out->st_ctime = 0;

            return 0;
        }
    }

    return result;
}
Пример #4
0
int FuseContext::mkdir (const char *path, mode_t mode)
{
    namespace fs = boost::filesystem;
    Path_t wrapped = m_realRoot / path;

    // first we make sure that the parent directory exists
    Path_t parent   = wrapped.parent_path();
    Path_t filename = wrapped.filename();

    if( !fs::exists(parent) )
      return -ENOENT;

    try
    {
        m_backend->db().mknod( Path_t(path) );
    }
    catch( const std::exception& ex )
    {
        std::cerr << "FuseContext::mkdir: "
              << "\n path: " << path
              << "\n real: " << wrapped
              << "\n  err: " << ex.what()
              << "\n";
        return -EINVAL;
    }

    // create the directory
    int result = ::mkdir( wrapped.c_str(), mode );
    if( result )
        return -errno;

    return 0;
}
Пример #5
0
int FuseContext::getxattr (const char *path,
                            const char *key,
                            char *value,
                            size_t bufsize)
{
    std::string attr(key);
    if( attr == "obfs:checkout" )
    {
        std::stringstream report;
        report << "FuseContext::getxattr : intercepted checkout hook for"
               << path <<"\n";
        std::cout << report.str();
        m_backend->checkout( m_relDir / path );
        return 0;
    }
    else if( attr == "obfs:release" )
    {
        std::stringstream report;
        report << "FuseContext::getxattr : intercepted release hook for"
               << path <<"\n";
        std::cout << report.str();
        m_backend->release( m_relDir / path );
        return 0;
    }
    else
    {
        Path_t wrapped = m_realRoot / path;
        int result = ::getxattr( wrapped.c_str(), key, value, bufsize );
        if( result < 0 )
            return -errno;

        return result;
    }

}
Пример #6
0
int FuseContext::statfs (const char *path, struct statvfs *buf)
{
    Path_t wrapped = m_realRoot / path;
    int result = ::statvfs( wrapped.c_str(), buf );
    if( result < 0 )
        return -errno;

    return result;
}
Пример #7
0
int FuseContext::listxattr (const char *path, char *buf, size_t bufsize)
{
    Path_t wrapped = m_realRoot / path;
    int result = ::listxattr( wrapped.c_str(), buf, bufsize );
    if( result < 0 )
        return -errno;

    return result;
}
Пример #8
0
int FuseContext::removexattr (const char *path, const char *key)
{
    Path_t wrapped = m_realRoot / path;
    int result = ::removexattr( wrapped.c_str(), key );
    if( result < 0 )
        return -errno;

    return result;
}
Пример #9
0
int FuseContext::access (const char *path, int mode)
{
    Path_t wrapped = m_realRoot / path;

    int result = ::access( wrapped.c_str(), mode );
    if( result < 0 )
        return -errno;

    return result;
}
Пример #10
0
int FuseContext::chown (const char *path, uid_t owner, gid_t group)
{
    namespace fs = boost::filesystem;
    Path_t wrapped = (m_realRoot / path);

    int result = ::chown( wrapped.c_str(), owner, group);
    if( result < 0 )
        return -errno;

    return result;
}
Пример #11
0
int FuseContext::write (const char *path,
                        const char *buf,
                        size_t bufsize,
                        off_t offset,
                      struct fuse_file_info *fi)
{
    namespace fs = boost::filesystem;
    Path_t wrapped = (m_realRoot / path);

    // if fi has a file handle then we simply read from the file handle
    if( fi->fh )
    {
        RefPtr<FileContext> file = m_openedFiles[fi->fh];
        if(file)
        {
            int result = ::pwrite(file->fd(),buf,bufsize,offset);
            if( result < 0 )
                return -errno;
            else
            {
                file->mark();
                return result;
            }
        }
        else
            return -EBADF;
    }
    else
    {
        // otherwise open the file
        int result = ::open( wrapped.c_str(), O_WRONLY );
        if( result < 0 )
            return -errno;

        // get the file handle
        int fh = result;

        // perform the write
        result = ::pwrite(fh,buf,bufsize,offset);

        // close the file
        ::close(fh);

        // check for error
        if( result < 0 )
            return -errno;

        // increment the version
        m_backend->db().incrementVersion( Path_t(path) );

        return result;
    }
}
Пример #12
0
int FuseContext::chmod (const char *path, mode_t mode)
{
    namespace fs = boost::filesystem;
    Path_t wrapped = m_realRoot / path;

    // if it's not a directory
    int result = ::chmod( wrapped.c_str(), mode );
    if( result < 0 )
        return -errno;

    return result;
}
Пример #13
0
int FuseContext::truncate (const char *path, off_t length)
{
    namespace fs = boost::filesystem;
    Path_t wrapped = (m_realRoot / path).string();
    int result = ::truncate( wrapped.c_str(), length  );
    if( result <  0 )
        return -errno;

    // update metadata
    m_backend->db().incrementVersion( Path_t(path) );

    return result;
}
Пример #14
0
int FuseContext::setxattr (const char *path,
                            const char *key,
                            const char *value,
                            size_t bufsize,
                            int flags)
{
    Path_t wrapped = m_realRoot / path;
    int result = ::setxattr( wrapped.c_str(), key, value, bufsize, flags );
    if( result < 0 )
        return -errno;

    return result;
}
Пример #15
0
int FuseContext::open (const char *path, struct fuse_file_info *fi)
{
    namespace fs = boost::filesystem;
    Path_t wrapped = m_realRoot / path;

    // first we make sure that the file exists
    Path_t parent   = wrapped.parent_path();
    Path_t filename = wrapped.filename();

    if( !fs::exists(parent) )
      return -ENOENT;

    // make sure that the file exists, if it doesn't exist check for the
    // O_CREAT flag
    if( !fs::exists(wrapped) )
    {
        if( fi->flags | O_CREAT )
            return this->create(path,0777,fi);
        else
            return -EEXIST;
    }

    // open the file
    int result = ::open( wrapped.c_str(), fi->flags );
    if( result < 0 )
        return -errno;

    // create a file descriptor for the opened file
    int os_fd = result;
    int my_fd = -1;
    try
    {
        my_fd   = m_openedFiles.registerFile( Path_t(path) ,os_fd);
        result  = 0;
    }
    catch( const std::exception& ex )
    {
        my_fd   = -1;
        result  = -ENOMEM;
        ::close(os_fd);

        std::cerr << "FuseContext::open"
                  << "\n path: " << path
                  << "\n real: " << wrapped
                  << "\n  err: " << ex.what();
    }

    fi->fh = my_fd;
    return result;
}
Пример #16
0
int FuseContext::read (const char *path,
                        char *buf,
                        size_t bufsize,
                        off_t offset,
                        struct fuse_file_info *fi)
{
    namespace fs = boost::filesystem;
    Path_t wrapped = (m_realRoot / path);

    // if fi has a file handle then we simply read from the file handle
    if( fi->fh )
    {
        RefPtr<FileContext> file = m_openedFiles[fi->fh];
        if(file)
        {
            int result = ::pread(file->fd(),buf,bufsize,offset);
            if( result < 0 )
                return -errno;
            else
                return result;
        }
        else
            return -EBADF;
    }
    // otherwise we open the file and perform the read
    else
    {
        // open the local version of the file
        int result = ::open( wrapped.c_str(), O_RDONLY );
        if( result < 0 )
            return -errno;

        // get the file andle
        int fh = result;

        // perform the read
        result = ::pread(fh,buf,bufsize,offset);

        // close the file
        ::close(fh);

        if( result < 0 )
            return -errno;
        else
            return result;
    }


}
Пример #17
0
int FuseContext::create (const char *path,
                            mode_t mode,
                            struct fuse_file_info *fi)
{
    namespace fs = boost::filesystem;
    Path_t wrapped = (m_realRoot / path);

    // first we make sure that the parent directory exists
    Path_t parent   = wrapped.parent_path();
    Path_t filename = wrapped.filename();

    if( !fs::exists(parent) || !fs::is_directory(parent) )
      return -ENOENT;

    // create the local version of the file
    int result = ::creat( wrapped.c_str(), mode );
    if( result < 0 )
        return -errno;

    // create a file descriptor for the opened file
    int os_fd = result;
    int my_fd = -1;
    try
    {
        // add an entry to the directory listing
        m_backend->db().mknod( Path_t(path) );

        my_fd   = m_openedFiles.registerFile( Path_t(path) ,os_fd);
        result  = 0;
    }
    catch( const std::exception& ex )
    {
        my_fd   = -1;
        result  = -EIO;
        ::close(os_fd);

        std::cerr << "FuseContext::create: "
             << "\n   path: " << path
             << "\n   real: " << wrapped
             << "\n   mode: " << std::hex << mode << std::dec
             << "\n";
    }

    fi->fh = my_fd;
    return result;
}
Пример #18
0
int FuseContext::utimens (const char *path, const struct timespec tv[2])
{
    Path_t wrapped = m_realRoot / path;

    timeval times[2];
    for(int i=0; i < 2; i++)
    {
        times[i].tv_sec = tv[i].tv_sec;
        times[i].tv_usec= tv[i].tv_nsec / 1000;
    }

    int result = ::utimes( wrapped.c_str(), times );
    if( result < 0 )
        return -errno;

    return result;
}
Пример #19
0
int FuseContext::mknod (const char *path, mode_t mode, dev_t dev)
{
    namespace fs = boost::filesystem;

    Path_t wrapped = (m_realRoot / path);

    // we do not allow special files
    if( mode & ( S_IFCHR | S_IFBLK ) )
      return -EINVAL;

    // first we make sure that the parent directory exists
    Path_t parent   = wrapped.parent_path();
    Path_t filename = wrapped.filename();

    if( !fs::exists(parent) || !fs::is_directory(parent) )
      return -ENOENT;

    // create the local version of the file
    int result = ::mknod( wrapped.c_str(), mode, 0 );
    if( result )
        return -errno;

    // add an entry to the directory listing
    try
    {
        mode_t modeMask = 0777;
        mode_t typeMask = ~modeMask;
        m_backend->db().mknod( Path_t(path) );
    }
    catch( const std::exception& ex )
    {
        std::cerr << "FuseContext::mknod: "
                  << "\n path: " << path
                  << "\n real: " << wrapped
                  << "\n  err: " << ex.what()
                  << "\n";
    }


    return 0;
}