src/simple.c
author Tero Marttila <terom@fixme.fi>
Sat, 13 Dec 2008 19:55:50 +0200
branchnew-evsql
changeset 53 0d6e07f4c9a1
parent 27 461be4cd34a3
permissions -rw-r--r--
separate evsql documentation
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
10
e74c23297b11 add some subdirs, plus symlink support
Tero Marttila <terom@fixme.fi>
parents: 9
diff changeset
   115
static void simple_readlink (fuse_req_t req, fuse_ino_t ino) {
e74c23297b11 add some subdirs, plus symlink support
Tero Marttila <terom@fixme.fi>
parents: 9
diff changeset
   116
    struct simple_fs *fs = fuse_req_userdata(req);
e74c23297b11 add some subdirs, plus symlink support
Tero Marttila <terom@fixme.fi>
parents: 9
diff changeset
   117
    const struct simple_node *node;
e74c23297b11 add some subdirs, plus symlink support
Tero Marttila <terom@fixme.fi>
parents: 9
diff changeset
   118
    int err;
e74c23297b11 add some subdirs, plus symlink support
Tero Marttila <terom@fixme.fi>
parents: 9
diff changeset
   119
e74c23297b11 add some subdirs, plus symlink support
Tero Marttila <terom@fixme.fi>
parents: 9
diff changeset
   120
    INFO("[simple.readlink %p] ino=%lu", fs, ino);
e74c23297b11 add some subdirs, plus symlink support
Tero Marttila <terom@fixme.fi>
parents: 9
diff changeset
   121
    
e74c23297b11 add some subdirs, plus symlink support
Tero Marttila <terom@fixme.fi>
parents: 9
diff changeset
   122
    // look up the node 
e74c23297b11 add some subdirs, plus symlink support
Tero Marttila <terom@fixme.fi>
parents: 9
diff changeset
   123
    if ((node = _simple_get_ino(fs, ino)) == NULL)
e74c23297b11 add some subdirs, plus symlink support
Tero Marttila <terom@fixme.fi>
parents: 9
diff changeset
   124
        EERROR(err = EINVAL, "bad inode");
e74c23297b11 add some subdirs, plus symlink support
Tero Marttila <terom@fixme.fi>
parents: 9
diff changeset
   125
e74c23297b11 add some subdirs, plus symlink support
Tero Marttila <terom@fixme.fi>
parents: 9
diff changeset
   126
    // check that it's a symlink
e74c23297b11 add some subdirs, plus symlink support
Tero Marttila <terom@fixme.fi>
parents: 9
diff changeset
   127
    if (node->mode_type != S_IFLNK)
e74c23297b11 add some subdirs, plus symlink support
Tero Marttila <terom@fixme.fi>
parents: 9
diff changeset
   128
        EERROR(err = EINVAL, "bad mode");
e74c23297b11 add some subdirs, plus symlink support
Tero Marttila <terom@fixme.fi>
parents: 9
diff changeset
   129
e74c23297b11 add some subdirs, plus symlink support
Tero Marttila <terom@fixme.fi>
parents: 9
diff changeset
   130
    // return the contents
e74c23297b11 add some subdirs, plus symlink support
Tero Marttila <terom@fixme.fi>
parents: 9
diff changeset
   131
    if ((err = fuse_reply_readlink(req, node->data)))
e74c23297b11 add some subdirs, plus symlink support
Tero Marttila <terom@fixme.fi>
parents: 9
diff changeset
   132
        EERROR(err, "fuse_reply_readlink");
e74c23297b11 add some subdirs, plus symlink support
Tero Marttila <terom@fixme.fi>
parents: 9
diff changeset
   133
e74c23297b11 add some subdirs, plus symlink support
Tero Marttila <terom@fixme.fi>
parents: 9
diff changeset
   134
    // suceccss
e74c23297b11 add some subdirs, plus symlink support
Tero Marttila <terom@fixme.fi>
parents: 9
diff changeset
   135
    return;
e74c23297b11 add some subdirs, plus symlink support
Tero Marttila <terom@fixme.fi>
parents: 9
diff changeset
   136
e74c23297b11 add some subdirs, plus symlink support
Tero Marttila <terom@fixme.fi>
parents: 9
diff changeset
   137
error:
e74c23297b11 add some subdirs, plus symlink support
Tero Marttila <terom@fixme.fi>
parents: 9
diff changeset
   138
    if ((err = fuse_reply_err(req, err)))
e74c23297b11 add some subdirs, plus symlink support
Tero Marttila <terom@fixme.fi>
parents: 9
diff changeset
   139
        EWARNING(err, "fuse_reply_err");
e74c23297b11 add some subdirs, plus symlink support
Tero Marttila <terom@fixme.fi>
parents: 9
diff changeset
   140
e74c23297b11 add some subdirs, plus symlink support
Tero Marttila <terom@fixme.fi>
parents: 9
diff changeset
   141
}
e74c23297b11 add some subdirs, plus symlink support
Tero Marttila <terom@fixme.fi>
parents: 9
diff changeset
   142
9
fbd239431dbe working simple_read
Tero Marttila <terom@fixme.fi>
parents: 8
diff changeset
   143
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
   144
    struct simple_fs *fs = fuse_req_userdata(req);
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
   145
    const struct simple_node *dir_node, *node;
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
   146
    struct dirbuf buf;
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
   147
    int err;
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
    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
   150
    
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
   151
    // look up the inode
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
   152
    if ((dir_node = _simple_get_ino(fs, ino)) == NULL)
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
   153
        EERROR(err = EINVAL, "bad inode");
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
   154
    
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
   155
    // check that it's a dir
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
   156
    if (dir_node->mode_type != S_IFDIR)
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
   157
        EERROR(err = ENOTDIR, "bad mode");
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
   158
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
   159
    // fill in the dirbuf
27
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 10
diff changeset
   160
    if (dirbuf_init(&buf, size, off))
8
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
   161
        ERROR("failed to init dirbuf");
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
   162
    
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
   163
    // add . and ..
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
   164
    // we set the next offset to 2, because all dirent offsets will be larger than that
27
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 10
diff changeset
   165
    err =   dirbuf_add(req, &buf, 0, 1, ".",   dir_node->inode,    S_IFDIR )
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 10
diff changeset
   166
        ||  dirbuf_add(req, &buf, 1, 2, "..",  dir_node->inode,    S_IFDIR );
8
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
   167
    
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
   168
    if (err != 0)
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
   169
        EERROR(err, "failed to add . and .. dirents");
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
   170
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
   171
    // look up all child nodes
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
   172
    for (node = fs->inode_table; node->inode; node++) {
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
   173
        // skip non-children
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
   174
        if (node->parent != dir_node->inode)
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
   175
            continue;
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
        // child node offsets are just inode + 2
27
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 10
diff changeset
   178
        if ((err = dirbuf_add(req, &buf, node->inode + 2, node->inode + 3, node->name, node->inode, node->mode_type)) < 0)
8
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
   179
            EERROR(err, "failed to add dirent for inode=%lu", node->inode);
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
   180
        
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
   181
        // stop if it's full
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
   182
        if (err > 0)
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
   183
            break;
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
   184
    }
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
   185
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
   186
    // send it
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
   187
    if ((err = -dirbuf_done(req, &buf)))
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
   188
        EERROR(err, "failed to send buf");
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
   189
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
   190
    // success
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
   191
    return;
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
   192
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
   193
error:
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
   194
    if ((err = fuse_reply_err(req, err)))
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
   195
        EWARNING(err, "fuse_reply_err");
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
   196
}
6
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   197
9
fbd239431dbe working simple_read
Tero Marttila <terom@fixme.fi>
parents: 8
diff changeset
   198
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
   199
    struct simple_fs *fs = fuse_req_userdata(req);
fbd239431dbe working simple_read
Tero Marttila <terom@fixme.fi>
parents: 8
diff changeset
   200
    const struct simple_node *node;
fbd239431dbe working simple_read
Tero Marttila <terom@fixme.fi>
parents: 8
diff changeset
   201
    int err ;
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
    // fi is unused
fbd239431dbe working simple_read
Tero Marttila <terom@fixme.fi>
parents: 8
diff changeset
   204
    (void) fi;
fbd239431dbe working simple_read
Tero Marttila <terom@fixme.fi>
parents: 8
diff changeset
   205
fbd239431dbe working simple_read
Tero Marttila <terom@fixme.fi>
parents: 8
diff changeset
   206
    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
   207
    
fbd239431dbe working simple_read
Tero Marttila <terom@fixme.fi>
parents: 8
diff changeset
   208
    // look up the inode
fbd239431dbe working simple_read
Tero Marttila <terom@fixme.fi>
parents: 8
diff changeset
   209
    if ((node = _simple_get_ino(fs, ino)) == NULL)
fbd239431dbe working simple_read
Tero Marttila <terom@fixme.fi>
parents: 8
diff changeset
   210
        EERROR(err = EINVAL, "bad inode");
fbd239431dbe working simple_read
Tero Marttila <terom@fixme.fi>
parents: 8
diff changeset
   211
    
fbd239431dbe working simple_read
Tero Marttila <terom@fixme.fi>
parents: 8
diff changeset
   212
    // check that it's a dir
fbd239431dbe working simple_read
Tero Marttila <terom@fixme.fi>
parents: 8
diff changeset
   213
    if (node->mode_type != S_IFREG)
fbd239431dbe working simple_read
Tero Marttila <terom@fixme.fi>
parents: 8
diff changeset
   214
        EERROR(err = (node->mode_type == S_IFDIR ? EISDIR : EINVAL), "bad mode");
fbd239431dbe working simple_read
Tero Marttila <terom@fixme.fi>
parents: 8
diff changeset
   215
    
fbd239431dbe working simple_read
Tero Marttila <terom@fixme.fi>
parents: 8
diff changeset
   216
    // seek past EOF?
fbd239431dbe working simple_read
Tero Marttila <terom@fixme.fi>
parents: 8
diff changeset
   217
    if (off >= strlen(node->data)) {
fbd239431dbe working simple_read
Tero Marttila <terom@fixme.fi>
parents: 8
diff changeset
   218
        // offset is out-of-file, so return EOF
fbd239431dbe working simple_read
Tero Marttila <terom@fixme.fi>
parents: 8
diff changeset
   219
        if ((err = fuse_reply_buf(req, NULL, 0)))
fbd239431dbe working simple_read
Tero Marttila <terom@fixme.fi>
parents: 8
diff changeset
   220
            EERROR(err, "fuse_reply_buf size=0");
fbd239431dbe working simple_read
Tero Marttila <terom@fixme.fi>
parents: 8
diff changeset
   221
fbd239431dbe working simple_read
Tero Marttila <terom@fixme.fi>
parents: 8
diff changeset
   222
    } else {
fbd239431dbe working simple_read
Tero Marttila <terom@fixme.fi>
parents: 8
diff changeset
   223
        // reply with the requested file data
fbd239431dbe working simple_read
Tero Marttila <terom@fixme.fi>
parents: 8
diff changeset
   224
        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
   225
            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
   226
    }
fbd239431dbe working simple_read
Tero Marttila <terom@fixme.fi>
parents: 8
diff changeset
   227
fbd239431dbe working simple_read
Tero Marttila <terom@fixme.fi>
parents: 8
diff changeset
   228
    // success
fbd239431dbe working simple_read
Tero Marttila <terom@fixme.fi>
parents: 8
diff changeset
   229
    return;
fbd239431dbe working simple_read
Tero Marttila <terom@fixme.fi>
parents: 8
diff changeset
   230
fbd239431dbe working simple_read
Tero Marttila <terom@fixme.fi>
parents: 8
diff changeset
   231
error:
fbd239431dbe working simple_read
Tero Marttila <terom@fixme.fi>
parents: 8
diff changeset
   232
    if ((err = fuse_reply_err(req, err)))
fbd239431dbe working simple_read
Tero Marttila <terom@fixme.fi>
parents: 8
diff changeset
   233
        EWARNING(err, "fuse_reply_err");
fbd239431dbe working simple_read
Tero Marttila <terom@fixme.fi>
parents: 8
diff changeset
   234
}
fbd239431dbe working simple_read
Tero Marttila <terom@fixme.fi>
parents: 8
diff changeset
   235
fbd239431dbe working simple_read
Tero Marttila <terom@fixme.fi>
parents: 8
diff changeset
   236
6
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
 * Define our fuse_lowlevel_ops struct.
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   239
 */
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   240
static struct fuse_lowlevel_ops simple_ops = {
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   241
    .lookup = simple_lookup,
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
    .getattr = simple_getattr,
8
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
   244
10
e74c23297b11 add some subdirs, plus symlink support
Tero Marttila <terom@fixme.fi>
parents: 9
diff changeset
   245
    .readlink = simple_readlink,
e74c23297b11 add some subdirs, plus symlink support
Tero Marttila <terom@fixme.fi>
parents: 9
diff changeset
   246
8
21bb5cdca4db working simple_readdir
Tero Marttila <terom@fixme.fi>
parents: 6
diff changeset
   247
    .readdir = simple_readdir,
9
fbd239431dbe working simple_read
Tero Marttila <terom@fixme.fi>
parents: 8
diff changeset
   248
fbd239431dbe working simple_read
Tero Marttila <terom@fixme.fi>
parents: 8
diff changeset
   249
    .read = simple_read,
6
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
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   252
struct fuse_lowlevel_ops *simple_init () {
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   253
    return &simple_ops;
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   254
}
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   255
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   256
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
   257
    struct simple_fs *fs = NULL;
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   258
    const struct simple_node *node;
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   259
    
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   260
    // generate
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   261
    if ((fs = calloc(1, sizeof(*fs))) == NULL)
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   262
        ERROR("calloc");
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   263
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   264
    // remember node_list
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   265
    fs->inode_count = 0;
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   266
    fs->inode_table = node_list;
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   267
    
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   268
    // validate it
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   269
    for (node = fs->inode_table; node->inode; node++) {
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   270
        // update inode_count
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   271
        fs->inode_count++;
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   272
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   273
        // check that parent is valid
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   274
        assert(node->inode == fs->inode_count);
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   275
        assert(node->parent < node->inode);
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   276
    }
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   277
    
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   278
    // success
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   279
    return fs;
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   280
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   281
error:
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   282
    return NULL;
d2036d7799fd new 'simple' module, plus hello_simple
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   283
}