root/native_client_sdk/src/libraries/nacl_io/fuse.h

/* [<][>][^][v][top][bottom][index][help] */

INCLUDED FROM


// Copyright (c) 2013 The Chromium 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 LIBRARIES_NACL_IO_FUSE_H_
#define LIBRARIES_NACL_IO_FUSE_H_

#include "osinttypes.h"
#include "ostypes.h"

// These interfaces are copied from the FUSE library.
//
// FUSE has two interfaces that can be implemented: low-level and high-level.
// In nacl_io, we only support the high-level interface.
//
// See http://fuse.sourceforge.net/ for more information.

// This struct is typically passed to functions that would normally use return
// or receive an fd; that is, operations to open/create a node, or operations
// that act on an already opened node.
struct fuse_file_info {
  // This is filled with the flags passed to open()
  int flags;
  // Deprecated in FUSE. Use fh instead.
  unsigned long fh_old;
  int writepage;
  // Currently unsupported
  unsigned int direct_io : 1;
  // Currently unsupported
  unsigned int keep_cache : 1;
  // Currently unsupported
  unsigned int flush : 1;
  // Currently unsupported
  unsigned int nonseekable : 1;
  // Currently unsupported
  unsigned int padding : 27;
  // This value is not used by nacl_io. It can be filled by the developer when
  // open() is called, and reused for subsequent calls on the same node.
  uint64_t fh;
  // Currently unsupported
  uint64_t lock_owner;
  // Currently unsupported
  uint32_t poll_events;
};

// A dummy structure that currently exists only to match the FUSE interface.
struct fuse_conn_info {};

// A function of this type will be passed to readdir (see below). The developer
// should call this function once for each directory entry.
//
// See the documentation for readdir() below for more information on how to use
// this function.
typedef int (*fuse_fill_dir_t)(void* buf,
                               const char* name,
                               const struct stat* stbuf,
                               off_t off);

// This structure defines the interface to create a user filesystem. Pass this
// to
// nacl_io_register_fs_type(). (see nacl_io.h)
//
// Example:
//
//     struct fuse_operations g_my_fuse_operations = { ... };
//     ...
//     nacl_io_register_fs_type("myfusefs", &g_my_fuse_operations);
//     ...
//     mount("", "/fs/fuse", "myfusefs", 0, NULL);
//
// It is not necessary to implement every function -- nacl_io will first check
// if the function pointer is NULL before calling it. If it is NULL and
// required by the current operation, the call will fail and return ENOSYS in
// errno.
//
// Except where specified below, each function should return one of the
// following values:
// == 0: operation completed successfully.
// <  0: operation failed. The error is a negative errno. e.g. -EACCES, -EPERM,
//       etc. The sign will be flipped when the error is actually set.
//
// Some functions (e.g. read, write) also return a positive count, which is the
// number of bytes read/written.
//
struct fuse_operations {
  // Currently unsupported
  unsigned int flag_nopath : 1;
  unsigned int flag_reserved : 31;

  // Called when a filesystem of this type is initialized.
  void* (*init)(struct fuse_conn_info* conn);
  // Called when a filesystem of this type is unmounted.
  void (*destroy)(void*);
  // Called by access()
  int (*access)(const char* path, int mode);
  // Called when O_CREAT is passed to open()
  int (*create)(const char* path, mode_t mode, struct fuse_file_info*);
  // Called by stat()/fstat(). If this function pointer is non-NULL, it is
  // called, otherwise fuse_operations.getattr will be called.
  int (*fgetattr)(const char* path, struct stat*, struct fuse_file_info*);
  // Called by fsync(). The datasync paramater is not currently supported.
  int (*fsync)(const char* path, int datasync, struct fuse_file_info*);
  // Called by ftruncate()
  int (*ftruncate)(const char* path, off_t, struct fuse_file_info*);
  // Called by stat()/fstat(), but only when fuse_operations.fgetattr is NULL.
  // Also called by open() to determine if the path is a directory or a regular
  // file.
  int (*getattr)(const char* path, struct stat*);
  // Called by mkdir()
  int (*mkdir)(const char* path, mode_t);
  // Called when O_CREAT is passed to open(), but only if fuse_operations.create
  // is non-NULL.
  int (*mknod)(const char* path, mode_t, dev_t);
  // Called by open()
  int (*open)(const char* path, struct fuse_file_info*);
  // Called by getdents(), which is called by the more standard functions
  // opendir()/readdir().
  int (*opendir)(const char* path, struct fuse_file_info*);
  // Called by read(). Note that FUSE specifies that all reads will fill the
  // entire requested buffer. If this function returns less than that, the
  // remainder of the buffer is zeroed.
  int (*read)(const char* path, char* buf, size_t count, off_t,
              struct fuse_file_info*);
  // Called by getdents(), which is called by the more standard function
  // readdir().
  //
  // NOTE: it is the responsibility of this function to add the "." and ".."
  // entries.
  //
  // This function can be implemented one of two ways:
  // 1) Ignore the offset, and always write every entry in a given directory.
  //    In this case, you should always call filler() with an offset of 0. You
  //    can ignore the return value of the filler.
  //
  //   int my_readdir(const char* path, void* buf, fuse_fill_dir_t filler,
  //                  off_t offset, struct fuse_file_info*) {
  //     ...
  //     filler(buf, ".", NULL, 0);
  //     filler(buf, "..", NULL, 0);
  //     filler(buf, "file1", &file1stat, 0);
  //     filler(buf, "file2", &file2stat, 0);
  //     return 0;
  //   }
  //
  // 2) Only write entries starting from offset. Always pass the correct offset
  //    to the filler function. When the filler function returns 1, the buffer
  //    is full so you can exit readdir.
  //
  //   int my_readdir(const char* path, void* buf, fuse_fill_dir_t filler,
  //                  off_t offset, struct fuse_file_info*) {
  //     ...
  //     size_t kNumEntries = 4;
  //     const char* my_entries[] = { ".", "..", "file1", "file2" };
  //     int entry_index = offset / sizeof(dirent);
  //     offset = entry_index * sizeof(dirent);
  //     while (entry_index < kNumEntries) {
  //       int result = filler(buf, my_entries[entry_index], NULL, offset);
  //       if (filler == 1) {
  //         // buffer filled, we're done.
  //         return 0;
  //       }
  //       offset += sizeof(dirent);
  //       entry_index++;
  //     }
  //
  //     // No more entries, we're done.
  //     return 0;
  //   }
  //
  int (*readdir)(const char* path, void* buf, fuse_fill_dir_t filldir, off_t,
                 struct fuse_file_info*);
  // Called when the last reference to this node is released. This is only
  // called for regular files. For directories, fuse_operations.releasedir is
  // called instead.
  int (*release)(const char* path, struct fuse_file_info*);
  // Called when the last reference to this node is released. This is only
  // called for directories. For regular files, fuse_operations.release is
  // called instead.
  int (*releasedir)(const char* path, struct fuse_file_info*);
  // Called by rename()
  int (*rename)(const char* path, const char* new_path);
  // Called by rmdir()
  int (*rmdir)(const char* path);
  // Called by truncate(), as well as open() when O_TRUNC is passed.
  int (*truncate)(const char* path, off_t);
  // Called by unlink()
  int (*unlink)(const char* path);
  // Called by write(). Note that FUSE specifies that a write should always
  // return the full count, unless an error occurs.
  int (*write)(const char* path, const char* buf, size_t count, off_t,
               struct fuse_file_info*);

  // The following functions are not currently called by the nacl_io
  // implementation of FUSE.
  int (*bmap)(const char*, size_t blocksize, uint64_t* idx);
  int (*chmod)(const char*, mode_t);
  int (*chown)(const char*, uid_t, gid_t);
  int (*fallocate)(const char*, int, off_t, off_t, struct fuse_file_info*);
  int (*flock)(const char*, struct fuse_file_info*, int op);
  int (*flush)(const char*, struct fuse_file_info*);
  int (*fsyncdir)(const char*, int, struct fuse_file_info*);
  int (*getxattr)(const char*, const char*, char*, size_t);
  int (*ioctl)(const char*, int cmd, void* arg, struct fuse_file_info*,
               unsigned int flags, void* data);
  int (*link)(const char*, const char*);
  int (*listxattr)(const char*, char*, size_t);
  int (*lock)(const char*, struct fuse_file_info*, int cmd, struct flock*);
  int (*poll)(const char*, struct fuse_file_info*, struct fuse_pollhandle* ph,
              unsigned* reventsp);
  int (*read_buf)(const char*, struct fuse_bufvec** bufp, size_t size,
                  off_t off, struct fuse_file_info*);
  int (*readlink)(const char*, char*, size_t);
  int (*removexattr)(const char*, const char*);
  int (*setxattr)(const char*, const char*, const char*, size_t, int);
  int (*statfs)(const char*, struct statvfs*);
  int (*symlink)(const char*, const char*);
  int (*utimens)(const char*, const struct timespec tv[2]);
  int (*write_buf)(const char*, struct fuse_bufvec* buf, off_t off,
                   struct fuse_file_info*);
};

#endif  // LIBRARIES_NACL_IO_FUSE_H_

/* [<][>][^][v][top][bottom][index][help] */