src/simple.c
author Tero Marttila <terom@fixme.fi>
Fri, 26 Sep 2008 21:20:48 +0300
changeset 9 fbd239431dbe
parent 8 21bb5cdca4db
child 10 e74c23297b11
permissions -rw-r--r--
working simple_read
6
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     1
#include <string.h>
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     2
#include <errno.h>
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     3
#include <stdlib.h>
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     4
#include <assert.h>
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     5
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     6
#include "simple.h"
8
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
     7
#include "dirbuf.h"
6
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     8
#include "lib/log.h"
9
fbd239431dbe working simple_read
Tero Marttila <terom@fixme.fi>
parents: 8
diff changeset
     9
#include "lib/math.h"
6
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    10
#include "lib/misc.h"
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    11
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    12
struct simple_fs {
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    13
    const struct simple_node *inode_table;
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    14
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    15
    size_t inode_count;
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    16
};
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    17
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    18
/*
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    19
 * Used for stat/entry timeouts... not sure how this should really be set.
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    20
 */
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    21
#define CACHE_TIMEOUT 1.0
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    22
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    23
static void _simple_stat (struct stat *stat, const struct simple_node *node) {
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    24
    stat->st_ino = node->inode;
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    25
    stat->st_mode = node->mode_type | node->mode_perm;
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    26
    stat->st_nlink = 1;
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    27
    stat->st_size = node->data ? strlen(node->data) : 0;
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    28
}
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    29
8
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
    30
/*
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
    31
 * Fetch the simple_node for the given inode.
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
    32
 *
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
    33
 * Returns NULL for invalid inodes.
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
    34
 */
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
    35
static const struct simple_node *_simple_get_ino (struct simple_fs *fs, fuse_ino_t ino) {
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
    36
    // make sure it's a valid inode
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
    37
    if (ino < 1 || ino > fs->inode_count) {
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
    38
        WARNING("invalid inode=%zu", ino);
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
    39
        return NULL;
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
    40
    }
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
    41
    
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
    42
    // return the node
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
    43
    return fs->inode_table + (ino - 1);
6
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    44
}
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    45
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    46
static void simple_lookup (fuse_req_t req, fuse_ino_t parent, const char *name) {
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    47
    struct simple_fs *fs = fuse_req_userdata(req);
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    48
    const struct simple_node *node;
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    49
    struct fuse_entry_param e; ZINIT(e);
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    50
    int err;
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    51
    
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    52
    INFO("[simple.lookup %p] parent=%lu, name=`%s'", fs, parent, name);
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    53
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    54
    // find the matching node
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    55
    for (node = fs->inode_table; node->inode > 0; node++) {
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    56
        if (node->parent == parent && strcmp(node->name, name) == 0)
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    57
            break;
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    58
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    59
    }
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    60
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    61
    // did we find it?
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    62
    if (node->inode) {
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    63
        // set up the entry
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    64
        e.ino = node->inode;
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    65
        e.generation = 0x01;
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    66
        _simple_stat(&e.attr, node);
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    67
        e.attr_timeout = CACHE_TIMEOUT;
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    68
        e.entry_timeout = CACHE_TIMEOUT;
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    69
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    70
        // reply
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    71
        if ((err = fuse_reply_entry(req, &e)))
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    72
            EERROR(err, "fuse_reply_entry");
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    73
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    74
    } else {
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    75
        // not found
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    76
        err = ENOENT;
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    77
        goto error;
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    78
    }
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    79
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    80
    // success
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    81
    return;
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    82
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    83
error:
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    84
    if ((err = fuse_reply_err(req, err)))
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    85
        EWARNING(err, "fuse_reply_err");
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    86
}
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    87
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    88
static void simple_getattr (fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi) {
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    89
    struct simple_fs *fs = fuse_req_userdata(req);
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    90
    const struct simple_node *node;
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    91
    struct stat stbuf; ZINIT(stbuf);
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    92
    int err;
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    93
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    94
    INFO("[simple.getattr %p] ino=%lu", fs, ino);
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    95
    
8
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
    96
    // look up the node 
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
    97
    if ((node = _simple_get_ino(fs, ino)) == NULL)
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
    98
        EERROR(err = EINVAL, "bad inode");
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
    99
    
6
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   100
    // set up the stbuf
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   101
    _simple_stat(&stbuf, node);
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   102
    
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   103
    // reply
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   104
    if ((err = fuse_reply_attr(req, &stbuf, CACHE_TIMEOUT)))
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   105
        EERROR(err, "fuse_reply_attr");
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   106
    
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   107
    // suceccss
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   108
    return;
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   109
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   110
error:
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   111
    if ((err = fuse_reply_err(req, err)))
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   112
        EWARNING(err, "fuse_reply_err");
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   113
}
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   114
9
fbd239431dbe working simple_read
Tero Marttila <terom@fixme.fi>
parents: 8
diff changeset
   115
static void simple_readdir (fuse_req_t req, fuse_ino_t ino, size_t size, off_t off, struct fuse_file_info *fi) {
8
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
   116
    struct simple_fs *fs = fuse_req_userdata(req);
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
   117
    const struct simple_node *dir_node, *node;
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
   118
    struct dirbuf buf;
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
   119
    int err;
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
   120
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
   121
    INFO("[simple.readdir] ino=%lu, size=%zu, off=%zu, fi=%p", ino, size, off, fi);
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
   122
    
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
   123
    // look up the inode
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
   124
    if ((dir_node = _simple_get_ino(fs, ino)) == NULL)
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
   125
        EERROR(err = EINVAL, "bad inode");
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
   126
    
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
   127
    // check that it's a dir
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
   128
    if (dir_node->mode_type != S_IFDIR)
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
   129
        EERROR(err = ENOTDIR, "bad mode");
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
   130
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
   131
    // fill in the dirbuf
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
   132
    if (dirbuf_init(&buf, size))
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
   133
        ERROR("failed to init dirbuf");
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
   134
    
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
   135
    // add . and ..
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
   136
    // we set the next offset to 2, because all dirent offsets will be larger than that
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
   137
    err =   dirbuf_add(req, off, &buf, 0, 1, ".",   dir_node->inode,    S_IFDIR )
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
   138
        ||  dirbuf_add(req, off, &buf, 1, 2, "..",  dir_node->inode,    S_IFDIR );
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
   139
    
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
   140
    if (err != 0)
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
   141
        EERROR(err, "failed to add . and .. dirents");
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
   142
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
   143
    // look up all child nodes
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
   144
    for (node = fs->inode_table; node->inode; node++) {
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
   145
        // skip non-children
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
   146
        if (node->parent != dir_node->inode)
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
   147
            continue;
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
   148
        
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
   149
        // child node offsets are just inode + 2
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
   150
        if ((err = dirbuf_add(req, off, &buf, node->inode + 2, node->inode + 3, node->name, node->inode, node->mode_type)) < 0)
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
   151
            EERROR(err, "failed to add dirent for inode=%lu", node->inode);
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
   152
        
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
   153
        // stop if it's full
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
   154
        if (err > 0)
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
   155
            break;
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
   156
    }
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
   157
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
   158
    // send it
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
   159
    if ((err = -dirbuf_done(req, &buf)))
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
   160
        EERROR(err, "failed to send buf");
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
   161
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
   162
    // success
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
   163
    return;
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
   164
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
   165
error:
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
   166
    if ((err = fuse_reply_err(req, err)))
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
   167
        EWARNING(err, "fuse_reply_err");
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
   168
}
6
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   169
9
fbd239431dbe working simple_read
Tero Marttila <terom@fixme.fi>
parents: 8
diff changeset
   170
static void simple_read (fuse_req_t req, fuse_ino_t ino, size_t size, off_t off, struct fuse_file_info *fi) {
fbd239431dbe working simple_read
Tero Marttila <terom@fixme.fi>
parents: 8
diff changeset
   171
    struct simple_fs *fs = fuse_req_userdata(req);
fbd239431dbe working simple_read
Tero Marttila <terom@fixme.fi>
parents: 8
diff changeset
   172
    const struct simple_node *node;
fbd239431dbe working simple_read
Tero Marttila <terom@fixme.fi>
parents: 8
diff changeset
   173
    int err ;
fbd239431dbe working simple_read
Tero Marttila <terom@fixme.fi>
parents: 8
diff changeset
   174
fbd239431dbe working simple_read
Tero Marttila <terom@fixme.fi>
parents: 8
diff changeset
   175
    // fi is unused
fbd239431dbe working simple_read
Tero Marttila <terom@fixme.fi>
parents: 8
diff changeset
   176
    (void) fi;
fbd239431dbe working simple_read
Tero Marttila <terom@fixme.fi>
parents: 8
diff changeset
   177
fbd239431dbe working simple_read
Tero Marttila <terom@fixme.fi>
parents: 8
diff changeset
   178
    INFO("[simple.read] ino=%lu, size=%zu, off=%zu, fi=%p", ino, size, off, fi);
fbd239431dbe working simple_read
Tero Marttila <terom@fixme.fi>
parents: 8
diff changeset
   179
    
fbd239431dbe working simple_read
Tero Marttila <terom@fixme.fi>
parents: 8
diff changeset
   180
    // look up the inode
fbd239431dbe working simple_read
Tero Marttila <terom@fixme.fi>
parents: 8
diff changeset
   181
    if ((node = _simple_get_ino(fs, ino)) == NULL)
fbd239431dbe working simple_read
Tero Marttila <terom@fixme.fi>
parents: 8
diff changeset
   182
        EERROR(err = EINVAL, "bad inode");
fbd239431dbe working simple_read
Tero Marttila <terom@fixme.fi>
parents: 8
diff changeset
   183
    
fbd239431dbe working simple_read
Tero Marttila <terom@fixme.fi>
parents: 8
diff changeset
   184
    // check that it's a dir
fbd239431dbe working simple_read
Tero Marttila <terom@fixme.fi>
parents: 8
diff changeset
   185
    if (node->mode_type != S_IFREG)
fbd239431dbe working simple_read
Tero Marttila <terom@fixme.fi>
parents: 8
diff changeset
   186
        EERROR(err = (node->mode_type == S_IFDIR ? EISDIR : EINVAL), "bad mode");
fbd239431dbe working simple_read
Tero Marttila <terom@fixme.fi>
parents: 8
diff changeset
   187
    
fbd239431dbe working simple_read
Tero Marttila <terom@fixme.fi>
parents: 8
diff changeset
   188
    // seek past EOF?
fbd239431dbe working simple_read
Tero Marttila <terom@fixme.fi>
parents: 8
diff changeset
   189
    if (off >= strlen(node->data)) {
fbd239431dbe working simple_read
Tero Marttila <terom@fixme.fi>
parents: 8
diff changeset
   190
        // offset is out-of-file, so return EOF
fbd239431dbe working simple_read
Tero Marttila <terom@fixme.fi>
parents: 8
diff changeset
   191
        if ((err = fuse_reply_buf(req, NULL, 0)))
fbd239431dbe working simple_read
Tero Marttila <terom@fixme.fi>
parents: 8
diff changeset
   192
            EERROR(err, "fuse_reply_buf size=0");
fbd239431dbe working simple_read
Tero Marttila <terom@fixme.fi>
parents: 8
diff changeset
   193
fbd239431dbe working simple_read
Tero Marttila <terom@fixme.fi>
parents: 8
diff changeset
   194
    } else {
fbd239431dbe working simple_read
Tero Marttila <terom@fixme.fi>
parents: 8
diff changeset
   195
        // reply with the requested file data
fbd239431dbe working simple_read
Tero Marttila <terom@fixme.fi>
parents: 8
diff changeset
   196
        if ((err = fuse_reply_buf(req, node->data + off, MIN(strlen(node->data) - off, size))))
fbd239431dbe working simple_read
Tero Marttila <terom@fixme.fi>
parents: 8
diff changeset
   197
            EERROR(err, "fuse_reply_buf buf=%p + %zu, size=MIN(%zu, %zu)", node->data, off, strlen(node->data) - off, size);
fbd239431dbe working simple_read
Tero Marttila <terom@fixme.fi>
parents: 8
diff changeset
   198
    }
fbd239431dbe working simple_read
Tero Marttila <terom@fixme.fi>
parents: 8
diff changeset
   199
fbd239431dbe working simple_read
Tero Marttila <terom@fixme.fi>
parents: 8
diff changeset
   200
    // success
fbd239431dbe working simple_read
Tero Marttila <terom@fixme.fi>
parents: 8
diff changeset
   201
    return;
fbd239431dbe working simple_read
Tero Marttila <terom@fixme.fi>
parents: 8
diff changeset
   202
fbd239431dbe working simple_read
Tero Marttila <terom@fixme.fi>
parents: 8
diff changeset
   203
error:
fbd239431dbe working simple_read
Tero Marttila <terom@fixme.fi>
parents: 8
diff changeset
   204
    if ((err = fuse_reply_err(req, err)))
fbd239431dbe working simple_read
Tero Marttila <terom@fixme.fi>
parents: 8
diff changeset
   205
        EWARNING(err, "fuse_reply_err");
fbd239431dbe working simple_read
Tero Marttila <terom@fixme.fi>
parents: 8
diff changeset
   206
}
fbd239431dbe working simple_read
Tero Marttila <terom@fixme.fi>
parents: 8
diff changeset
   207
fbd239431dbe working simple_read
Tero Marttila <terom@fixme.fi>
parents: 8
diff changeset
   208
6
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   209
/*
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   210
 * Define our fuse_lowlevel_ops struct.
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   211
 */
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   212
static struct fuse_lowlevel_ops simple_ops = {
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   213
    .lookup = simple_lookup,
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   214
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   215
    .getattr = simple_getattr,
8
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
   216
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
   217
    .readdir = simple_readdir,
9
fbd239431dbe working simple_read
Tero Marttila <terom@fixme.fi>
parents: 8
diff changeset
   218
fbd239431dbe working simple_read
Tero Marttila <terom@fixme.fi>
parents: 8
diff changeset
   219
    .read = simple_read,
6
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   220
};
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   221
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   222
struct fuse_lowlevel_ops *simple_init () {
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   223
    return &simple_ops;
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   224
}
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   225
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   226
struct simple_fs *simple_new (const struct simple_node *node_list) {
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   227
    struct simple_fs *fs = NULL;
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   228
    const struct simple_node *node;
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   229
    
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   230
    // generate
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   231
    if ((fs = calloc(1, sizeof(*fs))) == NULL)
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   232
        ERROR("calloc");
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   233
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   234
    // remember node_list
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   235
    fs->inode_count = 0;
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   236
    fs->inode_table = node_list;
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   237
    
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   238
    // validate it
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   239
    for (node = fs->inode_table; node->inode; node++) {
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   240
        // update inode_count
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   241
        fs->inode_count++;
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   242
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   243
        // check that parent is valid
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   244
        assert(node->inode == fs->inode_count);
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   245
        assert(node->parent < node->inode);
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   246
    }
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   247
    
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   248
    // success
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   249
    return fs;
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   250
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   251
error:
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   252
    return NULL;
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   253
}