# HG changeset patch # User Olaf Wintermann # Date 1643381070 -3600 # Node ID 0cb4eda146c4564a17f01cb9e9c7b110ba78c548 # Parent 535004faa1a5e911daf759ab8a868e8a3cb960fa add function to create a postgresql-based VFS diff -r 535004faa1a5 -r 0cb4eda146c4 src/server/daemon/vfs.c --- a/src/server/daemon/vfs.c Thu Jan 27 21:24:27 2022 +0100 +++ b/src/server/daemon/vfs.c Fri Jan 28 15:44:30 2022 +0100 @@ -45,7 +45,7 @@ #define VFS_MALLOC(pool, size) pool ? pool_malloc(pool, size) : malloc(size) #define VFS_FREE(pool, ptr) pool ? pool_free(pool, ptr) : free(ptr) -static UcxMap *vfs_map; +static UcxMap *vfs_type_map; static VFS sys_vfs = { sys_vfs_open, @@ -79,20 +79,22 @@ }; int vfs_init() { - vfs_map = ucx_map_new(16); - if(!vfs_map) { + vfs_type_map = ucx_map_new(16); + if(!vfs_type_map) { return -1; } return 0; } -void vfs_add(char *name, VFS *vfs) { +int vfs_register_type(const char *name, vfs_create_func vfsCreate) { WS_ASSERT(name); - if(!vfs_map) { - vfs_init(); + if(!vfs_type_map) { + if(vfs_init()) { + return 1; + } } - ucx_map_cstr_put(vfs_map, name, vfs); + return ucx_map_cstr_put(vfs_type_map, name, vfsCreate); } VFSContext* vfs_request_context(Session *sn, Request *rq) { diff -r 535004faa1a5 -r 0cb4eda146c4 src/server/plugins/postgresql/init.c --- a/src/server/plugins/postgresql/init.c Thu Jan 27 21:24:27 2022 +0100 +++ b/src/server/plugins/postgresql/init.c Fri Jan 28 15:44:30 2022 +0100 @@ -29,6 +29,7 @@ #include "init.h" #include "resource.h" +#include "vfs.h" int pg_init(pblock *pb, Session *sn, Request *Rq) { if(resourcepool_register_type("postgresql", pg_get_resource_type())) { @@ -36,5 +37,14 @@ return REQ_ABORTED; } + if(pg_register_vfs(pb)) { + log_ereport(LOG_FAILURE, "pg-init: Cannot register vfs type"); + return REQ_ABORTED; + } + return REQ_PROCEED; } + +int pg_register_vfs(pblock *pb) { + return vfs_register_type("postgresql", pg_vfs_create); +} diff -r 535004faa1a5 -r 0cb4eda146c4 src/server/plugins/postgresql/init.h --- a/src/server/plugins/postgresql/init.h Thu Jan 27 21:24:27 2022 +0100 +++ b/src/server/plugins/postgresql/init.h Fri Jan 28 15:44:30 2022 +0100 @@ -39,6 +39,8 @@ int pg_init(pblock *pb, Session *sn, Request *Rq); +int pg_register_vfs(pblock *pb); + #ifdef __cplusplus } diff -r 535004faa1a5 -r 0cb4eda146c4 src/server/plugins/postgresql/vfs.c --- a/src/server/plugins/postgresql/vfs.c Thu Jan 27 21:24:27 2022 +0100 +++ b/src/server/plugins/postgresql/vfs.c Fri Jan 28 15:44:30 2022 +0100 @@ -55,6 +55,46 @@ pg_vfs_dirio_close }; + + +VFS* pg_vfs_create(Session *sn, Request *rq, pblock *pb) { + // resourcepool is required + char *resource_pool = pblock_find("resourcepool", pb); + if(!resource_pool) { + log_ereport(LOG_MISCONFIG, "pg_vfs_create: missing resourcepool parameter"); + return NULL; + } + + // get the resource first (most likely to fail due to misconfig) + ResourceData *resdata = resourcepool_lookup(sn, rq, resource_pool, 0); + if(!resdata) { + log_ereport(LOG_MISCONFIG, "postgresql vfs: resource pool %s not found", resource_pool); + return NULL; + } + // resdata will be freed automatically when the request is finished + + // Create a new VFS object and a separate instance object + // VFS contains fptrs that can be copied from pg_vfs_class + // instance contains request specific data (PGconn) + VFS *vfs = pool_malloc(sn->pool, sizeof(VFS)); + if(!vfs) { + return NULL; + } + + PgVFS *vfs_priv = pool_malloc(sn->pool, sizeof(PgVFS)); + if(!vfs_priv) { + pool_free(sn->pool, vfs); + return NULL; + } + + memcpy(vfs, &pg_vfs_class, sizeof(VFS)); + vfs->flags = 0; + vfs->instance = vfs_priv; + + return vfs; +} + + /* -------------------------- VFS functions -------------------------- */ SYS_FILE pg_vfs_open(VFSContext *ctx, const char *path, int oflags) { diff -r 535004faa1a5 -r 0cb4eda146c4 src/server/plugins/postgresql/vfs.h --- a/src/server/plugins/postgresql/vfs.h Thu Jan 27 21:24:27 2022 +0100 +++ b/src/server/plugins/postgresql/vfs.h Fri Jan 28 15:44:30 2022 +0100 @@ -32,10 +32,18 @@ #include "../../public/nsapi.h" #include "../../public/vfs.h" +#include + #ifdef __cplusplus extern "C" { #endif +typedef struct PgVFS { + ResourceData *pg_resource; + PGconn *connection; +} PgVFS; + +VFS* pg_vfs_create(Session *sn, Request *rq, pblock *pb); SYS_FILE pg_vfs_open(VFSContext *ctx, const char *path, int oflags); int pg_vfs_stat(VFSContext *ctx, const char *path, struct stat *buf); diff -r 535004faa1a5 -r 0cb4eda146c4 src/server/public/vfs.h --- a/src/server/public/vfs.h Thu Jan 27 21:24:27 2022 +0100 +++ b/src/server/public/vfs.h Fri Jan 28 15:44:30 2022 +0100 @@ -108,10 +108,12 @@ void (*close)(VFS_DIR dir); }; +typedef VFS*(*vfs_create_func)(Session *sn, Request *rq, pblock *pb); + /* * registers a new VFS */ -void vfs_add(char *name, VFS *vfs); +int vfs_register_type(const char *name, vfs_create_func vfsCreate); /* * creates a VFSContext for a Request