src/dbfs.c
author Tero Marttila <terom@fixme.fi>
Mon, 13 Oct 2008 02:27:59 +0300
changeset 27 461be4cd34a3
parent 26 61668c57f4bb
child 28 e944453ca924
permissions -rw-r--r--
working open/read/close -dir
24
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     1
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     2
/*
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     3
 * A simple PostgreSQL-based filesystem.
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     4
 */
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     5
26
61668c57f4bb preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents: 25
diff changeset
     6
#include <stdlib.h>
24
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     7
#include <string.h>
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     8
#include <errno.h>
26
61668c57f4bb preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents: 25
diff changeset
     9
#include <assert.h>
24
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    10
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    11
#include <event2/event.h>
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    12
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    13
#include "evfuse.h"
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    14
#include "evsql.h"
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    15
#include "dirbuf.h"
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    16
#include "lib/log.h"
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    17
#include "lib/signals.h"
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    18
#include "lib/misc.h"
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    19
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    20
#define SERROR(val) do { (val); goto error; } while(0)
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    21
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    22
struct dbfs {
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    23
    struct event_base *ev_base;
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    24
    struct signals *signals;
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    25
    
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    26
    const char *db_conninfo;
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    27
    struct evsql *db;
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    28
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    29
    struct evfuse *ev_fuse;
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    30
};
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    31
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    32
#define CONNINFO_DEFAULT "dbname=test"
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    33
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    34
// XXX: not sure how this should work
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    35
#define CACHE_TIMEOUT 1.0
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    36
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    37
mode_t _dbfs_mode (const char *type) {
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    38
    if (!strcmp(type, "DIR"))
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    39
        return S_IFDIR;
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    40
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    41
    if (!strcmp(type, "REG"))
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    42
        return S_IFREG;
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    43
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    44
    else {
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    45
        WARNING("[dbfs] weird mode-type: %s", type);
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    46
        return 0;
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    47
    }
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    48
}
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    49
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    50
void dbfs_init (void *userdata, struct fuse_conn_info *conn) {
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    51
    INFO("[dbfs.init] userdata=%p, conn=%p", userdata, conn);
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    52
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    53
}
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    54
27
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
    55
void dbfs_destroy (void *arg) {
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
    56
    struct dbfs *ctx = arg;
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
    57
    INFO("[dbfs.destroy %p]", ctx);
24
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    58
27
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
    59
    // exit libevent
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
    60
    event_base_loopexit(ctx->ev_base, NULL);
24
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    61
}
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    62
25
99a41f48e29b evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents: 24
diff changeset
    63
/*
99a41f48e29b evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents: 24
diff changeset
    64
 * Check the result set.
99a41f48e29b evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents: 24
diff changeset
    65
 *
99a41f48e29b evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents: 24
diff changeset
    66
 * Returns;
27
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
    67
 *  -1  if the query failed, the columns do not match, or there are too many/few rows (unless rows was zero)
25
99a41f48e29b evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents: 24
diff changeset
    68
 *  0   the results match
99a41f48e29b evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents: 24
diff changeset
    69
 *  1   there were no results
99a41f48e29b evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents: 24
diff changeset
    70
 */
99a41f48e29b evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents: 24
diff changeset
    71
int _dbfs_check_res (const struct evsql_result_info *res, size_t rows, size_t cols) {
99a41f48e29b evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents: 24
diff changeset
    72
    int err = 0;
99a41f48e29b evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents: 24
diff changeset
    73
99a41f48e29b evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents: 24
diff changeset
    74
    // check if it failed
99a41f48e29b evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents: 24
diff changeset
    75
    if (res->error)
99a41f48e29b evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents: 24
diff changeset
    76
        NERROR(evsql_result_error(res));
99a41f48e29b evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents: 24
diff changeset
    77
        
99a41f48e29b evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents: 24
diff changeset
    78
    // not found?
99a41f48e29b evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents: 24
diff changeset
    79
    if (evsql_result_rows(res) == 0)
99a41f48e29b evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents: 24
diff changeset
    80
        SERROR(err = 1);
99a41f48e29b evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents: 24
diff changeset
    81
99a41f48e29b evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents: 24
diff changeset
    82
    // duplicate rows?
27
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
    83
    if (rows && evsql_result_rows(res) != rows)
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
    84
        ERROR("wrong number of rows returned");
25
99a41f48e29b evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents: 24
diff changeset
    85
    
99a41f48e29b evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents: 24
diff changeset
    86
    // correct number of columns
27
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
    87
    if (evsql_result_cols(res) != cols)
25
99a41f48e29b evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents: 24
diff changeset
    88
        ERROR("wrong number of columns: %zu", evsql_result_cols(res));
99a41f48e29b evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents: 24
diff changeset
    89
99a41f48e29b evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents: 24
diff changeset
    90
    // good
99a41f48e29b evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents: 24
diff changeset
    91
    return 0;
99a41f48e29b evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents: 24
diff changeset
    92
99a41f48e29b evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents: 24
diff changeset
    93
error:
99a41f48e29b evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents: 24
diff changeset
    94
    if (!err)
99a41f48e29b evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents: 24
diff changeset
    95
        err = -1;
99a41f48e29b evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents: 24
diff changeset
    96
99a41f48e29b evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents: 24
diff changeset
    97
    return err;
99a41f48e29b evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents: 24
diff changeset
    98
}
99a41f48e29b evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents: 24
diff changeset
    99
99a41f48e29b evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents: 24
diff changeset
   100
int _dbfs_stat_info (struct stat *st, const struct evsql_result_info *res, size_t row, size_t col_offset) {
99a41f48e29b evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents: 24
diff changeset
   101
    int err = 0;
99a41f48e29b evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents: 24
diff changeset
   102
    
99a41f48e29b evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents: 24
diff changeset
   103
    uint16_t mode;
99a41f48e29b evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents: 24
diff changeset
   104
    uint64_t size, nlink;
99a41f48e29b evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents: 24
diff changeset
   105
    const char *type;
99a41f48e29b evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents: 24
diff changeset
   106
    
99a41f48e29b evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents: 24
diff changeset
   107
    // extract the data
99a41f48e29b evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents: 24
diff changeset
   108
    if (0
99a41f48e29b evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents: 24
diff changeset
   109
        ||  evsql_result_string(res, row, col_offset + 0, &type,       0 ) // inodes.type
99a41f48e29b evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents: 24
diff changeset
   110
        ||  evsql_result_uint16(res, row, col_offset + 1, &mode,       0 ) // inodes.mode
99a41f48e29b evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents: 24
diff changeset
   111
        ||  evsql_result_uint64(res, row, col_offset + 2, &size,       0 ) // inodes.size
99a41f48e29b evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents: 24
diff changeset
   112
        ||  evsql_result_uint64(res, row, col_offset + 3, &nlink,      0 ) // count(*)
99a41f48e29b evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents: 24
diff changeset
   113
    )
99a41f48e29b evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents: 24
diff changeset
   114
        EERROR(err = EIO, "invalid db data");
99a41f48e29b evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents: 24
diff changeset
   115
99a41f48e29b evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents: 24
diff changeset
   116
    INFO("\tst_mode=S_IF%s | %ho, st_nlink=%llu, st_size=%llu", type, mode, (long long unsigned int) nlink, (long long unsigned int) size);
99a41f48e29b evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents: 24
diff changeset
   117
99a41f48e29b evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents: 24
diff changeset
   118
    // convert and store
99a41f48e29b evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents: 24
diff changeset
   119
    st->st_mode = _dbfs_mode(type) | mode;
99a41f48e29b evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents: 24
diff changeset
   120
    st->st_nlink = nlink;
99a41f48e29b evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents: 24
diff changeset
   121
    st->st_size = size;
99a41f48e29b evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents: 24
diff changeset
   122
    
99a41f48e29b evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents: 24
diff changeset
   123
    // good
99a41f48e29b evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents: 24
diff changeset
   124
    return 0;
99a41f48e29b evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents: 24
diff changeset
   125
99a41f48e29b evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents: 24
diff changeset
   126
error:
99a41f48e29b evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents: 24
diff changeset
   127
    return -1;
99a41f48e29b evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents: 24
diff changeset
   128
}
99a41f48e29b evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents: 24
diff changeset
   129
24
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   130
void _dbfs_lookup_result (const struct evsql_result_info *res, void *arg) {
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   131
    struct fuse_req *req = arg;
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   132
    struct fuse_entry_param e; ZINIT(e);
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   133
    int err = 0;
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   134
    
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   135
    uint32_t ino;
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   136
    
25
99a41f48e29b evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents: 24
diff changeset
   137
    // check the results
99a41f48e29b evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents: 24
diff changeset
   138
    if ((err = _dbfs_check_res(res, 1, 5)))
99a41f48e29b evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents: 24
diff changeset
   139
        SERROR(err = (err ==  1 ? ENOENT : EIO));
24
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   140
    
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   141
    // get the data
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   142
    if (0
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   143
        ||  evsql_result_uint32(res, 0, 0, &ino,        0 ) // inodes.ino
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   144
    )
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   145
        EERROR(err = EIO, "invalid db data");
25
99a41f48e29b evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents: 24
diff changeset
   146
        
27
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   147
    INFO("[dbfs.lookup] -> ino=%u", ino);
24
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   148
    
25
99a41f48e29b evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents: 24
diff changeset
   149
    // stat attrs
99a41f48e29b evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents: 24
diff changeset
   150
    if (_dbfs_stat_info(&e.attr, res, 0, 1))
99a41f48e29b evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents: 24
diff changeset
   151
        goto error;
24
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   152
25
99a41f48e29b evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents: 24
diff changeset
   153
    // other attrs
24
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   154
    e.ino = e.attr.st_ino = ino;
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   155
    e.attr_timeout = CACHE_TIMEOUT;
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   156
    e.entry_timeout = CACHE_TIMEOUT;
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   157
        
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   158
    // reply
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   159
    if ((err = fuse_reply_entry(req, &e)))
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   160
        EERROR(err, "fuse_reply_entry");
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   161
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   162
error:
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   163
    if (err && (err = fuse_reply_err(req, err)))
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   164
        EWARNING(err, "fuse_reply_err");
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   165
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   166
    // free
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   167
    evsql_result_free(res);
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   168
}
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   169
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   170
void dbfs_lookup (struct fuse_req *req, fuse_ino_t parent, const char *name) {
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   171
    struct dbfs *ctx = fuse_req_userdata(req);
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   172
    int err;
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   173
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   174
    INFO("[dbfs.lookup] parent=%lu name=%s", parent, name);
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   175
    
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   176
    // query and params
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   177
    const char *sql = 
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   178
        "SELECT"
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   179
        " inodes.ino, inodes.type, inodes.mode, inodes.size, count(*)"
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   180
        " FROM file_tree INNER JOIN inodes ON (file_tree.inode = inodes.ino)"
25
99a41f48e29b evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents: 24
diff changeset
   181
        " WHERE file_tree.parent = $1::int4 AND file_tree.name = $2::varchar"
24
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   182
        " GROUP BY inodes.ino, inodes.type, inodes.mode, inodes.size";
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   183
    
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   184
    static struct evsql_query_params params = EVSQL_PARAMS(EVSQL_FMT_BINARY) {
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   185
        EVSQL_PARAM ( UINT32 ),
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   186
        EVSQL_PARAM ( STRING ),
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   187
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   188
        EVSQL_PARAMS_END
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   189
    };
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   190
    
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   191
    // build params
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   192
    if (0
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   193
        ||  evsql_param_uint32(&params, 0, parent)
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   194
        ||  evsql_param_string(&params, 1, name)
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   195
    )
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   196
        EERROR(err = EIO, "evsql_param_*");
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   197
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   198
    // query
25
99a41f48e29b evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents: 24
diff changeset
   199
    if (evsql_query_params(ctx->db, NULL, sql, &params, _dbfs_lookup_result, req) == NULL)
24
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   200
        EERROR(err = EIO, "evsql_query_params");
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   201
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   202
    // XXX: handle interrupts
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   203
    
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   204
    // wait
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   205
    return;
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   206
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   207
error:
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   208
    if ((err = fuse_reply_err(req, err)))
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   209
        EWARNING(err, "fuse_reply_err");
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   210
}
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   211
25
99a41f48e29b evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents: 24
diff changeset
   212
void _dbfs_getattr_result (const struct evsql_result_info *res, void *arg) {
99a41f48e29b evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents: 24
diff changeset
   213
    struct fuse_req *req = arg;
99a41f48e29b evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents: 24
diff changeset
   214
    struct stat st; ZINIT(st);
99a41f48e29b evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents: 24
diff changeset
   215
    int err = 0;
99a41f48e29b evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents: 24
diff changeset
   216
    
99a41f48e29b evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents: 24
diff changeset
   217
    // check the results
99a41f48e29b evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents: 24
diff changeset
   218
    if ((err = _dbfs_check_res(res, 1, 4)))
99a41f48e29b evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents: 24
diff changeset
   219
        SERROR(err = (err ==  1 ? ENOENT : EIO));
99a41f48e29b evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents: 24
diff changeset
   220
        
99a41f48e29b evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents: 24
diff changeset
   221
    INFO("[dbfs.getattr %p] -> (stat follows)", req);
99a41f48e29b evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents: 24
diff changeset
   222
    
99a41f48e29b evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents: 24
diff changeset
   223
    // stat attrs
99a41f48e29b evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents: 24
diff changeset
   224
    if (_dbfs_stat_info(&st, res, 0, 0))
99a41f48e29b evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents: 24
diff changeset
   225
        goto error;
99a41f48e29b evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents: 24
diff changeset
   226
99a41f48e29b evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents: 24
diff changeset
   227
    // XXX: we don't have the ino
99a41f48e29b evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents: 24
diff changeset
   228
    st.st_ino = 0;
99a41f48e29b evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents: 24
diff changeset
   229
99a41f48e29b evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents: 24
diff changeset
   230
    // reply
99a41f48e29b evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents: 24
diff changeset
   231
    if ((err = fuse_reply_attr(req, &st, CACHE_TIMEOUT)))
99a41f48e29b evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents: 24
diff changeset
   232
        EERROR(err, "fuse_reply_entry");
99a41f48e29b evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents: 24
diff changeset
   233
99a41f48e29b evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents: 24
diff changeset
   234
error:
99a41f48e29b evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents: 24
diff changeset
   235
    if (err && (err = fuse_reply_err(req, err)))
99a41f48e29b evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents: 24
diff changeset
   236
        EWARNING(err, "fuse_reply_err");
99a41f48e29b evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents: 24
diff changeset
   237
99a41f48e29b evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents: 24
diff changeset
   238
    // free
99a41f48e29b evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents: 24
diff changeset
   239
    evsql_result_free(res);
99a41f48e29b evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents: 24
diff changeset
   240
}
99a41f48e29b evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents: 24
diff changeset
   241
99a41f48e29b evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents: 24
diff changeset
   242
static void dbfs_getattr (struct fuse_req *req, fuse_ino_t ino, struct fuse_file_info *fi) {
99a41f48e29b evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents: 24
diff changeset
   243
    struct dbfs *ctx = fuse_req_userdata(req);
99a41f48e29b evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents: 24
diff changeset
   244
    int err;
99a41f48e29b evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents: 24
diff changeset
   245
    
99a41f48e29b evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents: 24
diff changeset
   246
    (void) fi;
99a41f48e29b evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents: 24
diff changeset
   247
99a41f48e29b evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents: 24
diff changeset
   248
    INFO("[dbfs.getattr %p] ino=%lu", req, ino);
99a41f48e29b evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents: 24
diff changeset
   249
99a41f48e29b evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents: 24
diff changeset
   250
    const char *sql =
99a41f48e29b evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents: 24
diff changeset
   251
        "SELECT"
99a41f48e29b evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents: 24
diff changeset
   252
        " inodes.type, inodes.mode, inodes.size, count(*)"
99a41f48e29b evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents: 24
diff changeset
   253
        " FROM inodes"
27
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   254
        " WHERE inodes.ino = $1::int4"
25
99a41f48e29b evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents: 24
diff changeset
   255
        " GROUP BY inodes.type, inodes.mode, inodes.size";
99a41f48e29b evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents: 24
diff changeset
   256
99a41f48e29b evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents: 24
diff changeset
   257
    static struct evsql_query_params params = EVSQL_PARAMS(EVSQL_FMT_BINARY) {
99a41f48e29b evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents: 24
diff changeset
   258
        EVSQL_PARAM ( UINT32 ),
99a41f48e29b evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents: 24
diff changeset
   259
99a41f48e29b evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents: 24
diff changeset
   260
        EVSQL_PARAMS_END
99a41f48e29b evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents: 24
diff changeset
   261
    };
99a41f48e29b evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents: 24
diff changeset
   262
99a41f48e29b evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents: 24
diff changeset
   263
    // build params
99a41f48e29b evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents: 24
diff changeset
   264
    if (0
99a41f48e29b evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents: 24
diff changeset
   265
        ||  evsql_param_uint32(&params, 0, ino)
99a41f48e29b evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents: 24
diff changeset
   266
    )
99a41f48e29b evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents: 24
diff changeset
   267
        SERROR(err = EIO);
99a41f48e29b evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents: 24
diff changeset
   268
        
99a41f48e29b evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents: 24
diff changeset
   269
    // query
99a41f48e29b evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents: 24
diff changeset
   270
    if (evsql_query_params(ctx->db, NULL, sql, &params, _dbfs_getattr_result, req) == NULL)
99a41f48e29b evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents: 24
diff changeset
   271
        SERROR(err = EIO);
99a41f48e29b evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents: 24
diff changeset
   272
99a41f48e29b evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents: 24
diff changeset
   273
    // XXX: handle interrupts
99a41f48e29b evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents: 24
diff changeset
   274
    
99a41f48e29b evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents: 24
diff changeset
   275
    // wait
99a41f48e29b evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents: 24
diff changeset
   276
    return;
99a41f48e29b evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents: 24
diff changeset
   277
99a41f48e29b evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents: 24
diff changeset
   278
error:
99a41f48e29b evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents: 24
diff changeset
   279
    if ((err = fuse_reply_err(req, err)))
99a41f48e29b evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents: 24
diff changeset
   280
        EWARNING(err, "fuse_reply_err");
99a41f48e29b evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents: 24
diff changeset
   281
}
99a41f48e29b evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents: 24
diff changeset
   282
26
61668c57f4bb preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents: 25
diff changeset
   283
struct dbfs_dirop {
27
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   284
    struct fuse_file_info fi;
26
61668c57f4bb preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents: 25
diff changeset
   285
    struct fuse_req *req;
61668c57f4bb preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents: 25
diff changeset
   286
61668c57f4bb preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents: 25
diff changeset
   287
    struct evsql_trans *trans;
61668c57f4bb preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents: 25
diff changeset
   288
    
27
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   289
    // dir/parent dir inodes
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   290
    uint32_t ino, parent;
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   291
    
26
61668c57f4bb preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents: 25
diff changeset
   292
    // opendir has returned and releasedir hasn't been called yet
61668c57f4bb preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents: 25
diff changeset
   293
    int open;
27
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   294
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   295
    // for readdir
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   296
    struct dirbuf dirbuf;
26
61668c57f4bb preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents: 25
diff changeset
   297
};
61668c57f4bb preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents: 25
diff changeset
   298
61668c57f4bb preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents: 25
diff changeset
   299
/*
61668c57f4bb preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents: 25
diff changeset
   300
 * Free the dirop, aborting any in-progress transaction.
61668c57f4bb preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents: 25
diff changeset
   301
 *
61668c57f4bb preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents: 25
diff changeset
   302
 * req must be NULL.
61668c57f4bb preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents: 25
diff changeset
   303
 */
61668c57f4bb preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents: 25
diff changeset
   304
static void dbfs_dirop_free (struct dbfs_dirop *dirop) {
27
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   305
    assert(dirop);
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   306
    assert(!dirop->open);
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   307
    assert(!dirop->req);
26
61668c57f4bb preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents: 25
diff changeset
   308
27
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   309
    if (dirop->trans) {
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   310
        WARNING("aborting transaction");
26
61668c57f4bb preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents: 25
diff changeset
   311
        evsql_trans_abort(dirop->trans);
27
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   312
    }
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   313
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   314
    dirbuf_release(&dirop->dirbuf);
26
61668c57f4bb preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents: 25
diff changeset
   315
61668c57f4bb preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents: 25
diff changeset
   316
    free(dirop);
61668c57f4bb preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents: 25
diff changeset
   317
}
61668c57f4bb preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents: 25
diff changeset
   318
27
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   319
static void dbfs_opendir_info_res (const struct evsql_result_info *res, void *arg) {
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   320
    struct dbfs_dirop *dirop = arg;
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   321
    struct fuse_req *req = dirop->req; dirop->req = NULL;
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   322
    int err;
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   323
    
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   324
    assert(req != NULL);
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   325
   
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   326
    // check the results
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   327
    if ((err = _dbfs_check_res(res, 1, 2)))
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   328
        SERROR(err = (err ==  1 ? ENOENT : EIO));
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   329
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   330
    const char *type;
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   331
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   332
    // extract the data
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   333
    if (0
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   334
        ||  evsql_result_uint32(res, 0, 0, &dirop->parent,  1 ) // file_tree.parent
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   335
        ||  evsql_result_string(res, 0, 1, &type,           0 ) // inodes.type
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   336
    )
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   337
        SERROR(err = EIO);
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   338
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   339
    // is it a dir?
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   340
    if (_dbfs_mode(type) != S_IFDIR)
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   341
        EERROR(err = ENOTDIR, "wrong type: %s", type);
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   342
    
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   343
    INFO("[dbfs.opendir %p:%p] -> ino=%lu, parent=%lu, type=%s", dirop, req, (unsigned long int) dirop->ino, (unsigned long int) dirop->parent, type);
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   344
    
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   345
    // send the openddir reply
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   346
    if ((err = fuse_reply_open(req, &dirop->fi)))
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   347
        EERROR(err, "fuse_reply_open");
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   348
    
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   349
    // dirop is now open
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   350
    dirop->open = 1;
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   351
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   352
    // ok, wait for the opendir call
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   353
    return;
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   354
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   355
error:
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   356
    if (err) {
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   357
        // abort the trans
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   358
        evsql_trans_abort(dirop->trans);
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   359
        
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   360
        dirop->trans = NULL;
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   361
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   362
        if ((err = fuse_reply_err(req, err)))
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   363
            EWARNING(err, "fuse_reply_err");
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   364
    }
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   365
    
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   366
    // free
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   367
    evsql_result_free(res);
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   368
}
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   369
26
61668c57f4bb preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents: 25
diff changeset
   370
/*
61668c57f4bb preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents: 25
diff changeset
   371
 * The opendir transaction is ready
61668c57f4bb preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents: 25
diff changeset
   372
 */
61668c57f4bb preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents: 25
diff changeset
   373
static void dbfs_dirop_ready (struct evsql_trans *trans, void *arg) {
61668c57f4bb preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents: 25
diff changeset
   374
    struct dbfs_dirop *dirop = arg;
27
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   375
    struct fuse_req *req = dirop->req;
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   376
    struct dbfs *ctx = fuse_req_userdata(req);
26
61668c57f4bb preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents: 25
diff changeset
   377
    int err;
61668c57f4bb preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents: 25
diff changeset
   378
27
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   379
    assert(req != NULL);
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   380
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   381
    INFO("[dbfs.opendir %p:%p] -> trans=%p", dirop, req, trans);
26
61668c57f4bb preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents: 25
diff changeset
   382
61668c57f4bb preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents: 25
diff changeset
   383
    // remember the transaction
61668c57f4bb preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents: 25
diff changeset
   384
    dirop->trans = trans;
27
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   385
    
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   386
    // first fetch info about the dir itself
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   387
    const char *sql =
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   388
        "SELECT"
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   389
        " file_tree.parent, inodes.type"
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   390
        " FROM file_tree LEFT OUTER JOIN inodes ON (file_tree.inode = inodes.ino)"
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   391
        " WHERE file_tree.inode = $1::int4";
26
61668c57f4bb preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents: 25
diff changeset
   392
27
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   393
    static struct evsql_query_params params = EVSQL_PARAMS(EVSQL_FMT_BINARY) {
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   394
        EVSQL_PARAM ( UINT32 ),
26
61668c57f4bb preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents: 25
diff changeset
   395
27
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   396
        EVSQL_PARAMS_END
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   397
    };
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   398
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   399
    // build params
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   400
    if (0
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   401
        ||  evsql_param_uint32(&params, 0, dirop->ino)
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   402
    )
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   403
        SERROR(err = EIO);
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   404
        
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   405
    // query
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   406
    if (evsql_query_params(ctx->db, dirop->trans, sql, &params, dbfs_opendir_info_res, dirop) == NULL)
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   407
        SERROR(err = EIO);
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   408
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   409
    // ok, wait for the info results
26
61668c57f4bb preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents: 25
diff changeset
   410
    return;
61668c57f4bb preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents: 25
diff changeset
   411
61668c57f4bb preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents: 25
diff changeset
   412
error:
27
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   413
    // we handle the req
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   414
    dirop->req = NULL;
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   415
    
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   416
    // free the dirop
26
61668c57f4bb preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents: 25
diff changeset
   417
    dbfs_dirop_free(dirop);
27
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   418
    
26
61668c57f4bb preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents: 25
diff changeset
   419
    if ((err = fuse_reply_err(req, err)))
61668c57f4bb preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents: 25
diff changeset
   420
        EWARNING(err, "fuse_reply_err");
61668c57f4bb preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents: 25
diff changeset
   421
}
61668c57f4bb preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents: 25
diff changeset
   422
61668c57f4bb preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents: 25
diff changeset
   423
static void dbfs_dirop_done (struct evsql_trans *trans, void *arg) {
61668c57f4bb preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents: 25
diff changeset
   424
    struct dbfs_dirop *dirop = arg;
27
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   425
    struct fuse_req *req = dirop->req; dirop->req = NULL;
26
61668c57f4bb preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents: 25
diff changeset
   426
    int err;
61668c57f4bb preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents: 25
diff changeset
   427
    
27
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   428
    assert(req != NULL);
26
61668c57f4bb preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents: 25
diff changeset
   429
27
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   430
    INFO("[dbfs.releasedir %p:%p] -> OK", dirop, req);
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   431
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   432
    // forget trans
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   433
    dirop->trans = NULL;
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   434
    
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   435
    // just reply
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   436
    if ((err = fuse_reply_err(req, 0)))
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   437
        EWARNING(err, "fuse_reply_err");
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   438
    
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   439
    // we can free dirop
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   440
    dbfs_dirop_free(dirop);
26
61668c57f4bb preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents: 25
diff changeset
   441
}
61668c57f4bb preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents: 25
diff changeset
   442
61668c57f4bb preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents: 25
diff changeset
   443
static void dbfs_dirop_error (struct evsql_trans *trans, void *arg) {
61668c57f4bb preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents: 25
diff changeset
   444
    struct dbfs_dirop *dirop = arg;
61668c57f4bb preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents: 25
diff changeset
   445
    int err;
61668c57f4bb preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents: 25
diff changeset
   446
61668c57f4bb preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents: 25
diff changeset
   447
    INFO("[dbfs:dirop %p:%p] evsql transaction error: %s", dirop, dirop->req, evsql_trans_error(trans));
61668c57f4bb preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents: 25
diff changeset
   448
    
61668c57f4bb preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents: 25
diff changeset
   449
    // deassociate the trans
61668c57f4bb preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents: 25
diff changeset
   450
    dirop->trans = NULL;
61668c57f4bb preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents: 25
diff changeset
   451
    
61668c57f4bb preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents: 25
diff changeset
   452
    // error out and pending req
61668c57f4bb preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents: 25
diff changeset
   453
    if (dirop->req) {
61668c57f4bb preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents: 25
diff changeset
   454
        if ((err = fuse_reply_err(dirop->req, EIO)))
61668c57f4bb preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents: 25
diff changeset
   455
            EWARNING(err, "fuse_erply_err");
61668c57f4bb preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents: 25
diff changeset
   456
61668c57f4bb preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents: 25
diff changeset
   457
        dirop->req = NULL;
61668c57f4bb preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents: 25
diff changeset
   458
61668c57f4bb preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents: 25
diff changeset
   459
        // only free the dirop if it isn't open
61668c57f4bb preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents: 25
diff changeset
   460
        if (!dirop->open)
61668c57f4bb preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents: 25
diff changeset
   461
            dbfs_dirop_free(dirop);
61668c57f4bb preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents: 25
diff changeset
   462
    }
61668c57f4bb preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents: 25
diff changeset
   463
}
61668c57f4bb preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents: 25
diff changeset
   464
61668c57f4bb preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents: 25
diff changeset
   465
static void dbfs_opendir (struct fuse_req *req, fuse_ino_t ino, struct fuse_file_info *fi) {
61668c57f4bb preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents: 25
diff changeset
   466
    struct dbfs *ctx = fuse_req_userdata(req);
61668c57f4bb preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents: 25
diff changeset
   467
    struct dbfs_dirop *dirop = NULL;
61668c57f4bb preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents: 25
diff changeset
   468
    int err;
61668c57f4bb preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents: 25
diff changeset
   469
    
61668c57f4bb preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents: 25
diff changeset
   470
    // allocate it
61668c57f4bb preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents: 25
diff changeset
   471
    if ((dirop = calloc(1, sizeof(*dirop))) == NULL && (err = EIO))
61668c57f4bb preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents: 25
diff changeset
   472
        ERROR("calloc");
61668c57f4bb preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents: 25
diff changeset
   473
61668c57f4bb preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents: 25
diff changeset
   474
    INFO("[dbfs.opendir %p:%p] ino=%lu, fi=%p", dirop, req, ino, fi);
27
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   475
    
26
61668c57f4bb preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents: 25
diff changeset
   476
    // store the dirop
27
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   477
    // copy *fi since it's on the stack
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   478
    dirop->fi = *fi;
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   479
    dirop->fi.fh = (uint64_t) dirop;
26
61668c57f4bb preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents: 25
diff changeset
   480
    dirop->req = req;
27
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   481
    dirop->ino = ino;
26
61668c57f4bb preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents: 25
diff changeset
   482
61668c57f4bb preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents: 25
diff changeset
   483
    // start a new transaction
27
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   484
    if ((dirop->trans = evsql_trans(ctx->db, EVSQL_TRANS_SERIALIZABLE, dbfs_dirop_error, dbfs_dirop_ready, dbfs_dirop_done, dirop)) == NULL)
26
61668c57f4bb preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents: 25
diff changeset
   485
        SERROR(err = EIO);
61668c57f4bb preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents: 25
diff changeset
   486
    
61668c57f4bb preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents: 25
diff changeset
   487
    // XXX: handle interrupts
61668c57f4bb preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents: 25
diff changeset
   488
    
61668c57f4bb preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents: 25
diff changeset
   489
    // wait
61668c57f4bb preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents: 25
diff changeset
   490
    return;
61668c57f4bb preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents: 25
diff changeset
   491
61668c57f4bb preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents: 25
diff changeset
   492
error:
61668c57f4bb preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents: 25
diff changeset
   493
    // we handle the req
61668c57f4bb preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents: 25
diff changeset
   494
    dirop->req = NULL;
61668c57f4bb preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents: 25
diff changeset
   495
61668c57f4bb preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents: 25
diff changeset
   496
    dbfs_dirop_free(dirop);
61668c57f4bb preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents: 25
diff changeset
   497
61668c57f4bb preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents: 25
diff changeset
   498
    if ((err = fuse_reply_err(req, err)))
61668c57f4bb preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents: 25
diff changeset
   499
        EWARNING(err, "fuse_reply_err");
61668c57f4bb preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents: 25
diff changeset
   500
}
61668c57f4bb preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents: 25
diff changeset
   501
27
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   502
static void dbfs_readdir_files_res (const struct evsql_result_info *res, void *arg) {
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   503
    struct dbfs_dirop *dirop = arg;
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   504
    struct fuse_req *req = dirop->req; dirop->req = NULL;
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   505
    int err;
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   506
    size_t row;
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   507
    
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   508
    assert(req != NULL);
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   509
    
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   510
    // check the results
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   511
    if ((err = _dbfs_check_res(res, 0, 4)) < 0)
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   512
        SERROR(err = EIO);
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   513
        
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   514
    INFO("[dbfs.readdir %p:%p] -> files: res_rows=%zu", dirop, req, evsql_result_rows(res));
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   515
        
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   516
    // iterate over the rows
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   517
    for (row = 0; row < evsql_result_rows(res); row++) {
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   518
        uint32_t off, ino;
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   519
        const char *name, *type;
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   520
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   521
        // extract the data
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   522
        if (0
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   523
            ||  evsql_result_uint32(res, row, 0, &off,          0 ) // file_tree.offset
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   524
            ||  evsql_result_string(res, row, 1, &name,         0 ) // file_tree.name
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   525
            ||  evsql_result_uint32(res, row, 2, &ino,          0 ) // inodes.ino
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   526
            ||  evsql_result_string(res, row, 3, &type,         0 ) // inodes.type
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   527
        )
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   528
            SERROR(err = EIO);
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   529
        
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   530
        INFO("\t%zu: off=%lu+2, name=%s, ino=%lu, type=%s", row, (long unsigned int) off, name, (long unsigned int) ino, type);
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   531
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   532
        // add to the dirbuf
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   533
        // offsets are just offset + 2
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   534
        if ((err = dirbuf_add(req, &dirop->dirbuf, off + 2, off + 3, name, ino, _dbfs_mode(type))) < 0 && (err = EIO))
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   535
            ERROR("failed to add dirent for inode=%lu", (long unsigned int) ino);
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   536
        
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   537
        // stop if it's full
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   538
        if (err > 0)
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   539
            break;
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   540
    }
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   541
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   542
    // send it
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   543
    if ((err = dirbuf_done(req, &dirop->dirbuf)))
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   544
        EERROR(err, "failed to send buf");
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   545
    
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   546
    // good, fallthrough
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   547
    err = 0;
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   548
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   549
error:
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   550
    if (err) {
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   551
        // abort the trans
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   552
        evsql_trans_abort(dirop->trans);
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   553
        
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   554
        dirop->trans = NULL;
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   555
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   556
        // we handle the req
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   557
        dirop->req = NULL;
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   558
    
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   559
        if ((err = fuse_reply_err(req, err)))
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   560
            EWARNING(err, "fuse_reply_err");
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   561
    }
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   562
    
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   563
    // free
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   564
    evsql_result_free(res);
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   565
}
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   566
26
61668c57f4bb preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents: 25
diff changeset
   567
static void dbfs_readdir (struct fuse_req *req, fuse_ino_t ino, size_t size, off_t off, struct fuse_file_info *fi) {
61668c57f4bb preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents: 25
diff changeset
   568
    struct dbfs *ctx = fuse_req_userdata(req);
61668c57f4bb preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents: 25
diff changeset
   569
    struct dbfs_dirop *dirop = (struct dbfs_dirop *) fi->fh;
61668c57f4bb preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents: 25
diff changeset
   570
    int err;
61668c57f4bb preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents: 25
diff changeset
   571
27
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   572
    assert(!dirop->req);
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   573
    assert(dirop->trans);
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   574
    assert(dirop->ino == ino);
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   575
    
26
61668c57f4bb preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents: 25
diff changeset
   576
    INFO("[dbfs.readdir %p:%p] ino=%lu, size=%zu, off=%zu, fi=%p : trans=%p", dirop, req, ino, size, off, fi, dirop->trans);
61668c57f4bb preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents: 25
diff changeset
   577
61668c57f4bb preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents: 25
diff changeset
   578
    // update dirop
61668c57f4bb preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents: 25
diff changeset
   579
    dirop->req = req;
27
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   580
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   581
    // create the dirbuf
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   582
    if (dirbuf_init(&dirop->dirbuf, size, off))
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   583
        SERROR(err = EIO);
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   584
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   585
    // add . and ..
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   586
    // we set the next offset to 2, because all dirent offsets will be larger than that
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   587
    if ((err = (0
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   588
        ||  dirbuf_add(req, &dirop->dirbuf, 0, 1, ".",   dirop->ino,    S_IFDIR )
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   589
        ||  dirbuf_add(req, &dirop->dirbuf, 1, 2, "..",  
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   590
                        dirop->parent ? dirop->parent : dirop->ino,     S_IFDIR )
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   591
    )) && (err = EIO))
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   592
        ERROR("failed to add . and .. dirents");
26
61668c57f4bb preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents: 25
diff changeset
   593
61668c57f4bb preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents: 25
diff changeset
   594
    // select all relevant file entries
61668c57f4bb preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents: 25
diff changeset
   595
    const char *sql = 
61668c57f4bb preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents: 25
diff changeset
   596
        "SELECT"
27
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   597
        " file_tree.\"offset\", file_tree.name, inodes.ino, inodes.type"
26
61668c57f4bb preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents: 25
diff changeset
   598
        " FROM file_tree LEFT OUTER JOIN inodes ON (file_tree.inode = inodes.ino)"
27
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   599
        " WHERE file_tree.parent = $1::int4 AND file_tree.\"offset\" >= $2::int4"
26
61668c57f4bb preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents: 25
diff changeset
   600
        " LIMIT $3::int4";
61668c57f4bb preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents: 25
diff changeset
   601
61668c57f4bb preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents: 25
diff changeset
   602
    static struct evsql_query_params params = EVSQL_PARAMS(EVSQL_FMT_BINARY) {
61668c57f4bb preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents: 25
diff changeset
   603
        EVSQL_PARAM ( UINT32 ),
61668c57f4bb preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents: 25
diff changeset
   604
        EVSQL_PARAM ( UINT32 ),
61668c57f4bb preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents: 25
diff changeset
   605
        EVSQL_PARAM ( UINT32 ),
61668c57f4bb preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents: 25
diff changeset
   606
61668c57f4bb preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents: 25
diff changeset
   607
        EVSQL_PARAMS_END
61668c57f4bb preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents: 25
diff changeset
   608
    };
61668c57f4bb preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents: 25
diff changeset
   609
27
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   610
    // adjust offset to take . and .. into account
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   611
    if (off > 2)
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   612
        off -= 2;
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   613
    
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   614
    // build params
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   615
    if (0
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   616
        ||  evsql_param_uint32(&params, 0, dirop->ino)
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   617
        ||  evsql_param_uint32(&params, 1, off)
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   618
        ||  evsql_param_uint32(&params, 2, dirbuf_estimate(&dirop->dirbuf, 0))
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   619
    )
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   620
        SERROR(err = EIO);
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   621
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   622
    // query
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   623
    if (evsql_query_params(ctx->db, dirop->trans, sql, &params, dbfs_readdir_files_res, dirop) == NULL)
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   624
        SERROR(err = EIO);
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   625
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   626
    // good, wait
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   627
    return;
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   628
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   629
error:
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   630
    // we handle the req
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   631
    dirop->req = NULL;
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   632
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   633
    // abort the trans
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   634
    evsql_trans_abort(dirop->trans); dirop->trans = NULL;
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   635
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   636
    if ((err = fuse_reply_err(req, err)))
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   637
        EWARNING(err, "fuse_reply_err");
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   638
26
61668c57f4bb preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents: 25
diff changeset
   639
}
61668c57f4bb preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents: 25
diff changeset
   640
61668c57f4bb preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents: 25
diff changeset
   641
static void dbfs_releasedir (struct fuse_req *req, fuse_ino_t ino, struct fuse_file_info *fi) {
61668c57f4bb preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents: 25
diff changeset
   642
    struct dbfs *ctx = fuse_req_userdata(req);
61668c57f4bb preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents: 25
diff changeset
   643
    struct dbfs_dirop *dirop = (struct dbfs_dirop *) fi->fh;
61668c57f4bb preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents: 25
diff changeset
   644
    int err;
61668c57f4bb preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents: 25
diff changeset
   645
61668c57f4bb preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents: 25
diff changeset
   646
    (void) ctx;
27
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   647
    
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   648
    assert(!dirop->req);
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   649
    assert(dirop->ino == ino);
26
61668c57f4bb preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents: 25
diff changeset
   650
61668c57f4bb preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents: 25
diff changeset
   651
    INFO("[dbfs.releasedir %p:%p] ino=%lu, fi=%p : trans=%p", dirop, req, ino, fi, dirop->trans);
61668c57f4bb preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents: 25
diff changeset
   652
61668c57f4bb preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents: 25
diff changeset
   653
    // update dirop. Must keep it open so that dbfs_dirop_error won't free it
27
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   654
    // copy *fi since it's on the stack
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   655
    dirop->fi = *fi;
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   656
    dirop->fi.fh = (uint64_t) dirop;
26
61668c57f4bb preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents: 25
diff changeset
   657
    dirop->req = req;
27
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   658
    
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   659
    if (dirop->trans) {
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   660
        // we can commit the transaction, although we didn't make any changes
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   661
        // if this fails the transaction, then dbfs_dirop_error will take care of sending the error, and dirop->req will be
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   662
        // NULL
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   663
        if (evsql_trans_commit(dirop->trans))
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   664
            SERROR(err = EIO);
26
61668c57f4bb preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents: 25
diff changeset
   665
27
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   666
    } else {
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   667
        // trans failed earlier, so have releasedir just succeed
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   668
        if ((err = fuse_reply_err(req, 0)))
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   669
            EERROR(err, "fuse_reply_err");
26
61668c57f4bb preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents: 25
diff changeset
   670
27
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   671
        // req is done
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   672
        dirop->req = NULL;
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   673
    }
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   674
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   675
    // fall-through to cleanup
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   676
    err = 0;
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   677
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   678
error:
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   679
    // the dirop is not open anymore and can be freed once done with
26
61668c57f4bb preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents: 25
diff changeset
   680
    dirop->open = 0;
61668c57f4bb preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents: 25
diff changeset
   681
27
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   682
    // if trans_commit triggered an error but didn't call dbfs_dirop_error, we need to take care of it
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   683
    if (err && dirop->req) {
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   684
        int err2;
26
61668c57f4bb preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents: 25
diff changeset
   685
61668c57f4bb preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents: 25
diff changeset
   686
        // we handle the req
61668c57f4bb preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents: 25
diff changeset
   687
        dirop->req = NULL;
61668c57f4bb preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents: 25
diff changeset
   688
27
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   689
        if ((err2 = fuse_reply_err(req, err)))
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   690
            EWARNING(err2, "fuse_reply_err");
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   691
    } 
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   692
    
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   693
    // same for trans, we need to abort it if trans_commit failed and fs_dirop_error didn't get called
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   694
    if (err && dirop->trans) {
26
61668c57f4bb preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents: 25
diff changeset
   695
        dbfs_dirop_free(dirop);
27
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   696
    
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   697
    } else
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   698
      // alternatively, if the trans error'd itself away (now or earlier), we don't need to keep the dirop around
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   699
      // anymore now that we've checkd its state
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   700
      if (!dirop->trans) {
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   701
        dbfs_dirop_free(dirop);
26
61668c57f4bb preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents: 25
diff changeset
   702
    }
61668c57f4bb preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents: 25
diff changeset
   703
}
61668c57f4bb preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents: 25
diff changeset
   704
24
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   705
struct fuse_lowlevel_ops dbfs_llops = {
25
99a41f48e29b evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents: 24
diff changeset
   706
24
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   707
    .init           = dbfs_init,
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   708
    .destroy        = dbfs_destroy,
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   709
    
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   710
    .lookup         = dbfs_lookup,
25
99a41f48e29b evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents: 24
diff changeset
   711
99a41f48e29b evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents: 24
diff changeset
   712
    .getattr        = dbfs_getattr,
26
61668c57f4bb preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents: 25
diff changeset
   713
61668c57f4bb preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents: 25
diff changeset
   714
    .opendir        = dbfs_opendir,
27
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   715
    .readdir        = dbfs_readdir,
26
61668c57f4bb preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents: 25
diff changeset
   716
    .releasedir     = dbfs_releasedir,
24
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   717
};
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   718
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   719
void dbfs_sql_error (struct evsql *evsql, void *arg) {
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   720
    struct dbfs *ctx = arg;
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   721
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   722
    // AAAAAAAAAA.... panic
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   723
    WARNING("[dbfs] SQL error: BREAKING MAIN LOOP LIEK NAO");
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   724
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   725
    event_base_loopbreak(ctx->ev_base);
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   726
}
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   727
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   728
int main (int argc, char **argv) {
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   729
    struct fuse_args fuse_args = FUSE_ARGS_INIT(argc, argv);
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   730
    struct dbfs ctx; ZINIT(ctx);
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   731
    
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   732
    // parse args, XXX: fuse_args
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   733
    ctx.db_conninfo = CONNINFO_DEFAULT;
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   734
    
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   735
    // init libevent
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   736
    if ((ctx.ev_base = event_base_new()) == NULL)
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   737
        ERROR("event_base_new");
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   738
    
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   739
    // setup signals
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   740
    if ((ctx.signals = signals_default(ctx.ev_base)) == NULL)
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   741
        ERROR("signals_default");
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   742
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   743
    // open sql
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   744
    if ((ctx.db = evsql_new_pq(ctx.ev_base, ctx.db_conninfo, dbfs_sql_error, &ctx)) == NULL)
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   745
        ERROR("evsql_new_pq");
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   746
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   747
    // open fuse
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   748
    if ((ctx.ev_fuse = evfuse_new(ctx.ev_base, &fuse_args, &dbfs_llops, &ctx)) == NULL)
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   749
        ERROR("evfuse_new");
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   750
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   751
    // run libevent
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   752
    INFO("running libevent loop");
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   753
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   754
    if (event_base_dispatch(ctx.ev_base))
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   755
        PERROR("event_base_dispatch");
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   756
    
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   757
    // clean shutdown
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   758
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   759
error :
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   760
    // cleanup
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   761
    if (ctx.ev_fuse)
27
461be4cd34a3 working open/read/close -dir
Tero Marttila <terom@fixme.fi>
parents: 26
diff changeset
   762
        evfuse_free(ctx.ev_fuse);
24
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   763
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   764
    // XXX: ctx.db
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   765
    
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   766
    if (ctx.signals)
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   767
        signals_free(ctx.signals);
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   768
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   769
    if (ctx.ev_base)
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   770
        event_base_free(ctx.ev_base);
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   771
    
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   772
    fuse_opt_free_args(&fuse_args);
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   773
}
82cfdb6680d1 working dbfs.lookup
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   774