src/dbfs/mk.c
author Tero Marttila <terom@fixme.fi>
Fri, 17 Oct 2008 20:12:20 +0300
changeset 35 4f10421681d2
child 38 1fd4da071575
permissions -rw-r--r--
working mknod, mkdir, symlink
35
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     1
#include <stdlib.h>
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     2
#include <assert.h>
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     3
#include <string.h>
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     4
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     5
#include "trans.h"
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     6
#include "../lib/log.h"
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     7
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     8
struct dbfs_mk_ctx {
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     9
    struct dbfs_trans base;
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    10
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    11
    const char *type, *data_expr;
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    12
    char *link, *name;
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    13
    uint16_t mode;
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    14
    uint32_t ino, parent;
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    15
};
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    16
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    17
// default mode for symlinks
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    18
#define DBFS_SYMLINK_MODE 0777
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    19
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    20
// max. size for an dbfs_mk INSERT query
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    21
#define DBFS_MK_SQL_MAX 512
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    22
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    23
void dbfs_mk_free (struct dbfs_trans *ctx_base) {
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    24
    struct dbfs_mk_ctx *ctx = (struct dbfs_mk_ctx *) ctx_base;
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    25
    
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    26
    free(ctx->link);
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    27
    free(ctx->name);
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    28
}
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    29
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    30
void dbfs_mk_commit (struct dbfs_trans *ctx_base) {
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    31
    struct dbfs_mk_ctx *ctx = (struct dbfs_mk_ctx *) ctx_base;
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    32
    struct fuse_entry_param e;
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    33
    int err;
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    34
    
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    35
    // build entry
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    36
    e.ino = e.attr.st_ino = ctx->ino;
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    37
    e.attr.st_mode = _dbfs_mode(ctx->type) | ctx->mode;
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    38
    e.attr.st_size = ctx->link ? strlen(ctx->link) : 0;
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    39
    e.attr.st_nlink = 1;
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    40
    e.attr_timeout = e.entry_timeout = CACHE_TIMEOUT;
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    41
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    42
    // reply
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    43
    if ((err = fuse_reply_entry(ctx_base->req, &e)))
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    44
        goto error;
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    45
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    46
    // req good
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    47
    ctx_base->req = NULL;
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    48
    
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    49
    // free
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    50
    dbfs_trans_free(ctx_base);
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    51
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    52
    // return
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    53
    return;
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    54
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    55
error:
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    56
    dbfs_trans_fail(ctx_base, err);
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    57
}
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    58
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    59
void dbfs_mk_filetree (const struct evsql_result_info *res, void *arg) {
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    60
    struct dbfs_mk_ctx *ctx = arg;
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    61
    int err = EIO;
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    62
    
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    63
    // check results
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    64
    if (_dbfs_check_res(res, 0, 0) < 0)
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    65
        goto error;
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    66
    
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    67
    // commit
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    68
    dbfs_trans_commit(&ctx->base);
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    69
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    70
    // fallthrough for result_free
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    71
    err = 0;
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    72
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    73
error:
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    74
    if (err)
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    75
        dbfs_trans_fail(&ctx->base, err);
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    76
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    77
    evsql_result_free(res);
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    78
}
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    79
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    80
void dbfs_mk_inode (const struct evsql_result_info *res, void *arg) {
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    81
    struct dbfs_mk_ctx *ctx = arg;
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    82
    struct dbfs *dbfs_ctx = fuse_req_userdata(ctx->base.req);
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    83
    int err = EIO;
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    84
    
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    85
    // check result
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    86
    if ((err = _dbfs_check_res(res, 1, 1)))
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    87
        SERROR(err = err > 0 ? ENOENT : EIO);
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    88
    
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    89
    // get ino
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    90
    if (evsql_result_uint32(res, 0, 0, &ctx->ino, 0))
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    91
        goto error;
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    92
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    93
    // insert file_tree entry
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    94
    const char *sql = 
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    95
        "INSERT"
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    96
        " INTO file_tree (name, parent, ino)"
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    97
        " VALUES ($1::varchar, $2::int4, $3::int4)";
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    98
    
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    99
    static struct evsql_query_params params = EVSQL_PARAMS(EVSQL_FMT_BINARY) {
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   100
        EVSQL_PARAM ( STRING ),
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   101
        EVSQL_PARAM ( UINT32 ),
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   102
        EVSQL_PARAM ( UINT32 ),
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   103
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   104
        EVSQL_PARAMS_END
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   105
    };
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   106
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   107
    if (0
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   108
        ||  evsql_param_string(&params, 0, ctx->name)
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   109
        ||  evsql_param_uint32(&params, 1, ctx->parent)
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   110
        ||  evsql_param_uint32(&params, 2, ctx->ino)
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   111
    )
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   112
        goto error;
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   113
    
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   114
    // query
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   115
    if (evsql_query_params(dbfs_ctx->db, ctx->base.trans, sql, &params, dbfs_mk_filetree, ctx))
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   116
        goto error;
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   117
    
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   118
    // fallthrough for result_free
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   119
    err = 0;
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   120
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   121
error:
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   122
    if (err)
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   123
        dbfs_trans_fail(&ctx->base, err);
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   124
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   125
    evsql_result_free(res);
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   126
}
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   127
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   128
void dbfs_mk_begin (struct dbfs_trans *ctx_base) {
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   129
    struct dbfs_mk_ctx *ctx = (struct dbfs_mk_ctx *) ctx_base;
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   130
    struct dbfs *dbfs_ctx = fuse_req_userdata(ctx_base->req);
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   131
    int ret;
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   132
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   133
    // insert inode
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   134
    char sql_buf[DBFS_MK_SQL_MAX];
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   135
    
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   136
    if ((ret = snprintf(sql_buf, DBFS_MK_SQL_MAX, 
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   137
        "INSERT"
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   138
        " INTO inodes (type, mode, data, link_path)"
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   139
        " VALUES ($1::char(3), $2::int2, %s, $3::varchar)"
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   140
        " RETURNING inodes.ino", ctx->data_expr ? ctx->data_expr : "NULL"
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   141
    )) >= DBFS_MK_SQL_MAX)
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   142
        ERROR("sql_buf is too small: %d", ret);
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   143
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   144
    static struct evsql_query_params params = EVSQL_PARAMS(EVSQL_FMT_BINARY) {
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   145
        EVSQL_PARAM ( STRING ),
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   146
        EVSQL_PARAM ( UINT16 ),
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   147
        EVSQL_PARAM ( STRING ),
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   148
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   149
        EVSQL_PARAMS_END
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   150
    };
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   151
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   152
    if (0
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   153
        || evsql_param_string(&params, 0, ctx->type)
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   154
        || evsql_param_uint16(&params, 1, ctx->mode)
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   155
        || evsql_param_string(&params, 2, ctx->link)
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   156
    )
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   157
        goto error;
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   158
    
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   159
    if (evsql_query_params(dbfs_ctx->db, ctx_base->trans, sql_buf, &params, dbfs_mk_inode, ctx) == NULL)
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   160
        goto error;
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   161
    
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   162
    return;
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   163
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   164
error:
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   165
    dbfs_trans_fail(ctx_base, EIO);
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   166
}
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   167
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   168
/*
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   169
 * It is assumed that name and link_path must be copied, but type remains useable
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   170
 */ 
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   171
void dbfs_mk (struct fuse_req *req, fuse_ino_t parent, const char *name, const char *type, uint16_t mode, const char *data_expr, const char *link) {
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   172
    struct dbfs_mk_ctx *ctx = NULL;
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   173
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   174
    // alloc
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   175
    if ((ctx = calloc(1, sizeof(*ctx))) == NULL)
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   176
        ERROR("calloc");
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   177
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   178
    // start trans
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   179
    if (dbfs_trans_init(&ctx->base, req))
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   180
        goto error;
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   181
 
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   182
    // callbacks
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   183
    ctx->base.free_fn = dbfs_mk_free;
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   184
    ctx->base.begin_fn = dbfs_mk_begin;
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   185
    ctx->base.commit_fn = dbfs_mk_commit;
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   186
   
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   187
    // state
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   188
    ctx->ino = 0;
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   189
    ctx->parent = parent;
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   190
    ctx->type = type;
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   191
    ctx->data_expr = data_expr;
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   192
    ctx->mode = mode;
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   193
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   194
    // copy volatile strings
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   195
    if (
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   196
            (link && (ctx->link = strdup(link)) == NULL)
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   197
        ||  (name && (ctx->name = strdup(name)) == NULL)
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   198
    )
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   199
        ERROR("strdup");
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   200
    
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   201
    // log
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   202
    INFO("[dbfs.mk %p:%p] parent=%lu, name=%s, type=%s, mode=%#04o data_expr=%s link=%s", ctx, req, parent, name, type, mode, data_expr, link);
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   203
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   204
    // wait
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   205
    return;
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   206
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   207
error:
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   208
    if (ctx)
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   209
        dbfs_trans_fail(&ctx->base, EIO);
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   210
}
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   211
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   212
/*
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   213
 * These are all just aliases to dbfs_mk
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   214
 */ 
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   215
void dbfs_mknod (struct fuse_req *req, fuse_ino_t parent, const char *name, mode_t mode, dev_t rdev) {
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   216
    int err;
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   217
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   218
    if ((mode & S_IFMT) != S_IFREG)
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   219
        EERROR(err = EINVAL, "mode is not REG: %#08o", mode);
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   220
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   221
    dbfs_mk(req, parent, name, "REG", mode & 07777, "lo_create(0)", NULL);
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   222
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   223
    return;
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   224
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   225
error:
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   226
    if ((err = fuse_reply_err(req, err)))
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   227
        EWARNING(err, "fuse_reply_error");
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   228
}
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   229
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   230
void dbfs_mkdir (struct fuse_req *req, fuse_ino_t parent, const char *name, mode_t mode) {
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   231
    dbfs_mk(req, parent, name, "DIR", mode, NULL, NULL);
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   232
}
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   233
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   234
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   235
void dbfs_symlink (struct fuse_req *req, const char *link, fuse_ino_t parent, const char *name) {
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   236
    dbfs_mk(req, parent, name, "LNK", DBFS_SYMLINK_MODE, NULL, link);
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   237
}
4f10421681d2 working mknod, mkdir, symlink
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   238