src/dbfs/core.c
changeset 28 e944453ca924
child 29 5de62ca9a5aa
equal deleted inserted replaced
27:461be4cd34a3 28:e944453ca924
       
     1 
       
     2 #include "common.h"
       
     3 #include "ops.h"
       
     4 
       
     5 /*
       
     6  * Core fs functionality like lookup, getattr
       
     7  */
       
     8 
       
     9 void _dbfs_lookup_result (const struct evsql_result_info *res, void *arg) {
       
    10     struct fuse_req *req = arg;
       
    11     struct fuse_entry_param e; ZINIT(e);
       
    12     int err = 0;
       
    13     
       
    14     uint32_t ino;
       
    15     
       
    16     // check the results
       
    17     if ((err = _dbfs_check_res(res, 1, 5)))
       
    18         SERROR(err = (err ==  1 ? ENOENT : EIO));
       
    19     
       
    20     // get the data
       
    21     if (0
       
    22         ||  evsql_result_uint32(res, 0, 0, &ino,        0 ) // inodes.ino
       
    23     )
       
    24         EERROR(err = EIO, "invalid db data");
       
    25         
       
    26     INFO("[dbfs.lookup] -> ino=%u", ino);
       
    27     
       
    28     // stat attrs
       
    29     if (_dbfs_stat_info(&e.attr, res, 0, 1))
       
    30         goto error;
       
    31 
       
    32     // other attrs
       
    33     e.ino = e.attr.st_ino = ino;
       
    34     e.attr_timeout = CACHE_TIMEOUT;
       
    35     e.entry_timeout = CACHE_TIMEOUT;
       
    36         
       
    37     // reply
       
    38     if ((err = fuse_reply_entry(req, &e)))
       
    39         EERROR(err, "fuse_reply_entry");
       
    40 
       
    41 error:
       
    42     if (err && (err = fuse_reply_err(req, err)))
       
    43         EWARNING(err, "fuse_reply_err");
       
    44 
       
    45     // free
       
    46     evsql_result_free(res);
       
    47 }
       
    48 
       
    49 void dbfs_lookup (struct fuse_req *req, fuse_ino_t parent, const char *name) {
       
    50     struct dbfs *ctx = fuse_req_userdata(req);
       
    51     int err;
       
    52 
       
    53     INFO("[dbfs.lookup] parent=%lu name=%s", parent, name);
       
    54     
       
    55     // query and params
       
    56     const char *sql = 
       
    57         "SELECT"
       
    58         " inodes.ino, inodes.type, inodes.mode, inodes.size, count(*)"
       
    59         " FROM file_tree INNER JOIN inodes ON (file_tree.inode = inodes.ino)"
       
    60         " WHERE file_tree.parent = $1::int4 AND file_tree.name = $2::varchar"
       
    61         " GROUP BY inodes.ino, inodes.type, inodes.mode, inodes.size";
       
    62     
       
    63     static struct evsql_query_params params = EVSQL_PARAMS(EVSQL_FMT_BINARY) {
       
    64         EVSQL_PARAM ( UINT32 ),
       
    65         EVSQL_PARAM ( STRING ),
       
    66 
       
    67         EVSQL_PARAMS_END
       
    68     };
       
    69     
       
    70     // build params
       
    71     if (0
       
    72         ||  evsql_param_uint32(&params, 0, parent)
       
    73         ||  evsql_param_string(&params, 1, name)
       
    74     )
       
    75         EERROR(err = EIO, "evsql_param_*");
       
    76 
       
    77     // query
       
    78     if (evsql_query_params(ctx->db, NULL, sql, &params, _dbfs_lookup_result, req) == NULL)
       
    79         EERROR(err = EIO, "evsql_query_params");
       
    80 
       
    81     // XXX: handle interrupts
       
    82     
       
    83     // wait
       
    84     return;
       
    85 
       
    86 error:
       
    87     if ((err = fuse_reply_err(req, err)))
       
    88         EWARNING(err, "fuse_reply_err");
       
    89 }
       
    90 
       
    91 void _dbfs_getattr_result (const struct evsql_result_info *res, void *arg) {
       
    92     struct fuse_req *req = arg;
       
    93     struct stat st; ZINIT(st);
       
    94     int err = 0;
       
    95     
       
    96     // check the results
       
    97     if ((err = _dbfs_check_res(res, 1, 4)))
       
    98         SERROR(err = (err ==  1 ? ENOENT : EIO));
       
    99         
       
   100     INFO("[dbfs.getattr %p] -> (stat follows)", req);
       
   101     
       
   102     // stat attrs
       
   103     if (_dbfs_stat_info(&st, res, 0, 0))
       
   104         goto error;
       
   105 
       
   106     // XXX: we don't have the ino
       
   107     st.st_ino = 0;
       
   108 
       
   109     // reply
       
   110     if ((err = fuse_reply_attr(req, &st, CACHE_TIMEOUT)))
       
   111         EERROR(err, "fuse_reply_entry");
       
   112 
       
   113 error:
       
   114     if (err && (err = fuse_reply_err(req, err)))
       
   115         EWARNING(err, "fuse_reply_err");
       
   116 
       
   117     // free
       
   118     evsql_result_free(res);
       
   119 }
       
   120 
       
   121 void dbfs_getattr (struct fuse_req *req, fuse_ino_t ino, struct fuse_file_info *fi) {
       
   122     struct dbfs *ctx = fuse_req_userdata(req);
       
   123     int err;
       
   124     
       
   125     (void) fi;
       
   126 
       
   127     INFO("[dbfs.getattr %p] ino=%lu", req, ino);
       
   128 
       
   129     const char *sql =
       
   130         "SELECT"
       
   131         " inodes.type, inodes.mode, inodes.size, count(*)"
       
   132         " FROM inodes"
       
   133         " WHERE inodes.ino = $1::int4"
       
   134         " GROUP BY inodes.type, inodes.mode, inodes.size";
       
   135 
       
   136     static struct evsql_query_params params = EVSQL_PARAMS(EVSQL_FMT_BINARY) {
       
   137         EVSQL_PARAM ( UINT32 ),
       
   138 
       
   139         EVSQL_PARAMS_END
       
   140     };
       
   141 
       
   142     // build params
       
   143     if (0
       
   144         ||  evsql_param_uint32(&params, 0, ino)
       
   145     )
       
   146         SERROR(err = EIO);
       
   147         
       
   148     // query
       
   149     if (evsql_query_params(ctx->db, NULL, sql, &params, _dbfs_getattr_result, req) == NULL)
       
   150         SERROR(err = EIO);
       
   151 
       
   152     // XXX: handle interrupts
       
   153     
       
   154     // wait
       
   155     return;
       
   156 
       
   157 error:
       
   158     if ((err = fuse_reply_err(req, err)))
       
   159         EWARNING(err, "fuse_reply_err");
       
   160 }
       
   161