src/dbfs/dbfs.h
changeset 56 9dfc861273e5
parent 42 40a3b13ffc9d
child 57 527d23bf6441
equal deleted inserted replaced
42:40a3b13ffc9d 56:9dfc861273e5
     1 #ifndef DBFS_DBFS_H
       
     2 #define DBFS_DBFS_H
       
     3 
       
     4 #include <sys/stat.h>
       
     5 #include <errno.h>
       
     6 
       
     7 #include <event2/event.h>
       
     8 
       
     9 #include "ops.h"
       
    10 #include "../evfuse.h"
       
    11 #include "../evsql.h"
       
    12 #include "../lib/error.h"
       
    13 
       
    14 /*
       
    15  * Structs and functions shared between all dbfs components
       
    16  */
       
    17 
       
    18 struct dbfs {
       
    19     struct event_base *ev_base;
       
    20     
       
    21     const char *db_conninfo;
       
    22     struct evsql *db;
       
    23 
       
    24     struct evfuse *ev_fuse;
       
    25 };
       
    26 
       
    27 // XXX: not sure how this should work
       
    28 #define CACHE_TIMEOUT 1.0
       
    29 
       
    30 // columns used for stat_info
       
    31 #define DBFS_STAT_COLS " inodes.type, inodes.mode, dbfs_size(inodes.type, inodes.data, inodes.link_path), (SELECT COUNT(*) FROM inodes i LEFT JOIN file_tree ft ON (i.ino = ft.ino) WHERE i.ino = inodes.ino) AS nlink"
       
    32 
       
    33 /*
       
    34  * Convert the CHAR(4) inodes.type from SQL into a mode_t.
       
    35  *
       
    36  * Returns zero for unknown types.
       
    37  */
       
    38 mode_t _dbfs_mode (const char *type);
       
    39 
       
    40 /*
       
    41  * Check that the number of rows and columns in the result set matches what we expect.
       
    42  *
       
    43  * If rows is nonzero, there must be exactly that many rows (mostly useful for rows=1).
       
    44  * The number of columns must always be given, and match.
       
    45  *
       
    46  * Returns;
       
    47  *  -1  if the query failed, the columns/rows do not match
       
    48  *  0   the results match
       
    49  *  1   there were no results (zero rows)
       
    50  */
       
    51 int _dbfs_check_res (const struct evsql_result_info *res, size_t rows, size_t cols);
       
    52 
       
    53 /*
       
    54  * Same as _dbfs_check_res, but returns ENOENT/EIO directly
       
    55  */
       
    56 err_t dbfs_check_result (const struct evsql_result_info *res, size_t rows, size_t cols);
       
    57 
       
    58 /*
       
    59  * Fill a `struct state` with info retrieved from a SQL query.
       
    60  *
       
    61  * The result must contain four columns, starting at the given offset:
       
    62  *  inodes.type, inodes.mode, inodes.size, count(*) AS nlink
       
    63  *
       
    64  * Note that this does not fill the st_ino field
       
    65  */
       
    66 int _dbfs_stat_info (struct stat *st, const struct evsql_result_info *res, size_t row, size_t col_offset);
       
    67 
       
    68 /** interrupt.c 
       
    69  *  
       
    70  * Fuse interrupts are handled using fuse_req_interrupt_func. Calling this registers a callback function with the req,
       
    71  * which may or may not be called either by fuse_req_interrupt_func, or later on via evfuse's event handler. It is
       
    72  * assumed that this will never be called after a call to fuse_reply_*.
       
    73  *
       
    74  * Hence, to handle an interrupt, we must first ensure that fuse_reply_* will not be called afterwards (it'll return
       
    75  * an error), and then we must call fuse_reply_err(req, EINTR).
       
    76  *
       
    77  * In the simplest case, we can simply submit a query, and then abort it once the req is interrupted (now or later).
       
    78  * In the more complicated case, we can check if the request was interrupted, if not, do the query and handle
       
    79  * interrupts.
       
    80  */
       
    81 
       
    82 /*
       
    83  * Useable as a callback to fuse_req_interrupt_func, will abort the given query and err the req.
       
    84  *
       
    85  * Due to a locking bug in libfuse 2.7.4, this will actually delay the fuse_req_err until the next event-loop iteration.
       
    86  */
       
    87 void dbfs_interrupt_query (struct fuse_req *req, void *query_ptr);
       
    88 
       
    89 /*
       
    90  * XXX: More complicated state, is this actually needed?
       
    91  */
       
    92 struct dbfs_interrupt_ctx {
       
    93     struct fuse_req *req;
       
    94     struct evsql_query *query;
       
    95 
       
    96     int interrupted : 1;
       
    97 };
       
    98 
       
    99 /*
       
   100  * Register as a fuse interrupt function for simple requests that only run one query without allocating any resources.
       
   101  *
       
   102  * This will abort the query if the interrupt is run, causing it's callback to not be called.
       
   103  *
       
   104  * Returns nonzero if the request was already interrupted, zero otherwise. Be careful that the interrupt does not get
       
   105  * fired between you checking for it and setting query.
       
   106  */
       
   107 int dbfs_interrupt_register (struct fuse_req *req, struct dbfs_interrupt_ctx *ctx);
       
   108 
       
   109 #endif /* DBFS_DBFS_H */