src/simple.c
author Tero Marttila <terom@fixme.fi>
Fri, 26 Sep 2008 21:13:35 +0300
changeset 8 21bb5cdca4db
parent 6 d2036d7799fd
child 9 fbd239431dbe
permissions -rw-r--r--
working simple_readdir
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"
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     9
#include "lib/misc.h"
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    10
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    11
struct simple_fs {
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    12
    const struct simple_node *inode_table;
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    13
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    14
    size_t inode_count;
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    15
};
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
 * 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
    19
 */
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    20
#define CACHE_TIMEOUT 1.0
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    21
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    22
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
    23
    stat->st_ino = node->inode;
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    24
    stat->st_mode = node->mode_type | node->mode_perm;
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    25
    stat->st_nlink = 1;
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    26
    stat->st_size = node->data ? strlen(node->data) : 0;
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    27
}
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    28
8
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
    29
/*
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
    30
 * Fetch the simple_node for the given inode.
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
    31
 *
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
    32
 * Returns NULL for invalid inodes.
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
    33
 */
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
    34
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
    35
    // make sure it's a valid inode
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
    36
    if (ino < 1 || ino > fs->inode_count) {
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
    37
        WARNING("invalid inode=%zu", ino);
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
    38
        return NULL;
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
    39
    }
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
    // return the node
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
    42
    return fs->inode_table + (ino - 1);
6
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    43
}
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
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
    46
    struct simple_fs *fs = fuse_req_userdata(req);
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    47
    const struct simple_node *node;
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    48
    struct fuse_entry_param e; ZINIT(e);
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    49
    int err;
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    50
    
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    51
    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
    52
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    53
    // find the matching node
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    54
    for (node = fs->inode_table; node->inode > 0; node++) {
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    55
        if (node->parent == parent && strcmp(node->name, name) == 0)
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    56
            break;
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    57
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
    // did we find it?
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    61
    if (node->inode) {
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    62
        // set up the entry
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    63
        e.ino = node->inode;
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    64
        e.generation = 0x01;
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    65
        _simple_stat(&e.attr, node);
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    66
        e.attr_timeout = CACHE_TIMEOUT;
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    67
        e.entry_timeout = CACHE_TIMEOUT;
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    68
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    69
        // reply
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    70
        if ((err = fuse_reply_entry(req, &e)))
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    71
            EERROR(err, "fuse_reply_entry");
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    72
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    73
    } else {
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    74
        // not found
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    75
        err = ENOENT;
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    76
        goto error;
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    77
    }
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
    // success
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    80
    return;
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    81
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    82
error:
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    83
    if ((err = fuse_reply_err(req, err)))
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    84
        EWARNING(err, "fuse_reply_err");
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    85
}
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
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
    88
    struct simple_fs *fs = fuse_req_userdata(req);
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    89
    const struct simple_node *node;
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    90
    struct stat stbuf; ZINIT(stbuf);
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    91
    int err;
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    92
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    93
    INFO("[simple.getattr %p] ino=%lu", fs, ino);
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    94
    
8
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
    95
    // look up the node 
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
    96
    if ((node = _simple_get_ino(fs, ino)) == NULL)
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
    97
        EERROR(err = EINVAL, "bad inode");
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
    98
    
6
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    99
    // set up the stbuf
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   100
    _simple_stat(&stbuf, node);
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   101
    
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   102
    // reply
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   103
    if ((err = fuse_reply_attr(req, &stbuf, CACHE_TIMEOUT)))
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   104
        EERROR(err, "fuse_reply_attr");
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   105
    
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   106
    // suceccss
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   107
    return;
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   108
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   109
error:
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   110
    if ((err = fuse_reply_err(req, err)))
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   111
        EWARNING(err, "fuse_reply_err");
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   112
}
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   113
8
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
   114
void simple_readdir (fuse_req_t req, fuse_ino_t ino, size_t size, off_t off, struct fuse_file_info *fi) {
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
   115
    struct simple_fs *fs = fuse_req_userdata(req);
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
   116
    const struct simple_node *dir_node, *node;
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
   117
    struct dirbuf buf;
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
   118
    int err;
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
   119
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
   120
    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
   121
    
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
   122
    // look up the inode
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
   123
    if ((dir_node = _simple_get_ino(fs, ino)) == NULL)
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
   124
        EERROR(err = EINVAL, "bad inode");
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
   125
    
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
   126
    // check that it's a dir
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
   127
    if (dir_node->mode_type != S_IFDIR)
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
   128
        EERROR(err = ENOTDIR, "bad mode");
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
   129
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
   130
    // fill in the dirbuf
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
   131
    if (dirbuf_init(&buf, size))
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
   132
        ERROR("failed to init dirbuf");
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
   133
    
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
   134
    // add . and ..
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
   135
    // 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
   136
    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
   137
        ||  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
   138
    
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
   139
    if (err != 0)
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
   140
        EERROR(err, "failed to add . and .. dirents");
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
   141
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
   142
    // look up all child nodes
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
   143
    for (node = fs->inode_table; node->inode; node++) {
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
   144
        // skip non-children
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
   145
        if (node->parent != dir_node->inode)
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
   146
            continue;
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
   147
        
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
   148
        // child node offsets are just inode + 2
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
   149
        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
   150
            EERROR(err, "failed to add dirent for inode=%lu", node->inode);
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
   151
        
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
   152
        // stop if it's full
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
   153
        if (err > 0)
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
   154
            break;
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
   155
    }
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
    // send it
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
   158
    if ((err = -dirbuf_done(req, &buf)))
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
   159
        EERROR(err, "failed to send buf");
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
   160
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
   161
    // success
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
   162
    return;
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
   163
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
   164
error:
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
   165
    if ((err = fuse_reply_err(req, err)))
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
   166
        EWARNING(err, "fuse_reply_err");
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
   167
}
6
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   168
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   169
/*
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   170
 * Define our fuse_lowlevel_ops struct.
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   171
 */
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   172
static struct fuse_lowlevel_ops simple_ops = {
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   173
    .lookup = simple_lookup,
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   174
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   175
    .getattr = simple_getattr,
8
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
   176
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
   177
    .readdir = simple_readdir,
6
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   178
};
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   179
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   180
struct fuse_lowlevel_ops *simple_init () {
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   181
    return &simple_ops;
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   182
}
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   183
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   184
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
   185
    struct simple_fs *fs = NULL;
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   186
    const struct simple_node *node;
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   187
    
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   188
    // generate
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   189
    if ((fs = calloc(1, sizeof(*fs))) == NULL)
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   190
        ERROR("calloc");
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   191
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   192
    // remember node_list
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   193
    fs->inode_count = 0;
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   194
    fs->inode_table = node_list;
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   195
    
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   196
    // validate it
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   197
    for (node = fs->inode_table; node->inode; node++) {
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   198
        // update inode_count
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   199
        fs->inode_count++;
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   200
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   201
        // check that parent is valid
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   202
        assert(node->inode == fs->inode_count);
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   203
        assert(node->parent < node->inode);
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   204
    }
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   205
    
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   206
    // success
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   207
    return fs;
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   208
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   209
error:
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   210
    return NULL;
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   211
}