All pastes #1397914 Raw Edit

Unnamed

public c v1 · immutable
#1397914 ·published 2009-04-21 02:45 UTC
rendered paste body
#define FUSE_USE_VERSION  26   #include <fuse.h>#include <stdio.h>#include <string.h>#include <errno.h>#include <fcntl.h>#include <unistd.h>#include <stdlib.h>#include <math.h>#include "block_device.h"#include "raw_blockfs_util.h"block_device *bd;void *blockbuf;static int raw_block_getattr(const char *path, struct stat *stbuf){    // Notes: see 'man 2 stat' for stbuf doc    memset(stbuf, 0, sizeof(struct stat));    int is_dir;    int k = parse_path(path, bd->n_block, &is_dir);    if (k < 0)      return -ENOENT;    else if(is_dir) { // This is a directory,       // Make mode mode 555 (ugo+rx), so everyone can read (writing not allowed)      stbuf->st_mode = S_IFDIR | 0555;      // two links, one for '.', one for parent dir      stbuf->st_nlink = 2;     } else { // This is a block file      // Make mode 666 (ugo+rw) so anyone can read/write      stbuf->st_mode = S_IFREG | 0666;       stbuf->st_nlink = 1; // one for parent dir      stbuf->st_size = bd->block_size;    }    return 0;}static int raw_block_readdir(const char *path, void *buf, fuse_fill_dir_t filler,                         off_t offset, struct fuse_file_info *fi){    (void) offset; // just here to keep warnings about unused params away    (void) fi;    int is_dir;    int k = parse_path(path, bd->n_block, &is_dir);    if (k < 0 || !is_dir)        return -ENOENT;    filler(buf, ".", NULL, 0);    filler(buf, "..", NULL, 0);    char entname[2]; // entry name is a single char 0-9    entname[1]='\0';// null terminated string    int i;    for (i = 0;i <= k; i++){      entname[0] = '0' + i; // write the char name in      filler(buf, entname, NULL, 0);    }    return 0;}static int raw_block_open(const char *path, struct fuse_file_info *fi){    int is_dir;    int k = parse_path(path, bd->n_block, &is_dir);    if (k < 0 || is_dir)        return -ENOENT;    // Stash the block number into the file handle field.     // This is field provided by the API for user convenience.      // Further file operations (e.g. read and write) can use    // this instead of manipulating path.     fi->fh = k;     return 0;}char pbuf[1024];static int raw_block_read(const char *path, char *buf, size_t size, off_t offset,                      struct fuse_file_info *fi){    int k = fi->fh; // Use stashed block number    int rc = bd_read(bd, k, blockbuf);    if (rc < 0)      return -EIO;// I/O error    if (offset < bd->block_size) {      if ( (offset + size) > bd->block_size)	size = bd->block_size - offset;      memcpy(buf, blockbuf + offset, size);    } else {      size = 0;    }    return size;}static int raw_block_write(const char *path, const char *buf, size_t size, off_t offset,			   struct fuse_file_info *fi){    int k = fi->fh;    // read the block in    int rc = bd_read(bd, k, blockbuf);    if (rc < 0)      return -EIO;// I/O error    if (offset+size > bd->block_size)      return -EFBIG; // File exceeds max size    memcpy(blockbuf + offset, buf, size);    // write block back out    rc = bd_write(bd, k, blockbuf);    if (rc < 0)      return -EIO;// I/O error    return size;}static int raw_block_truncate(const char *path, off_t size) {  int is_dir;  int k = parse_path(path, bd->n_block, &is_dir);  if (k < 0 || is_dir)    return -ENOENT;  if ( size > bd->block_size)     return -EFBIG; // Too big  return 0; // Pretend any other truncation 'just works'}static struct fuse_operations raw_block_oper = {    .getattr  = raw_block_getattr,    .readdir  = raw_block_readdir,    .open     = raw_block_open,    .read     = raw_block_read,    .write    = raw_block_write,    .truncate = raw_block_truncate};void usage(){  printf("usage: <block_dev> <mount_point>\n");  exit(1);};int main(int argc, char *argv[]){  if (argc != 3)    usage();  // Grab out the block device path first.   char *path = argv[1];  bd = bd_open(path);  if (!bd){    printf("Unable to open block device %s", path);    perror("bd_open");  }  blockbuf = malloc_block(bd);  char *fuse_argv[100];  int fuse_argc = argc-1;  fuse_argv[0] = argv[0];  int i;  for (i = 2; i < argc; i++){    fuse_argv[i-1] = argv[i];  }      int rc = fuse_main(fuse_argc, fuse_argv, &raw_block_oper, NULL);  bd_close(bd);  return rc;}