Mercurial > nomad
changeset 570:d57bc9242936
client: implement an inode number mapping layer
Signed-off-by: Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
author | Josef 'Jeff' Sipek <jeffpc@josefsipek.net> |
---|---|
date | Fri, 15 Feb 2019 07:58:15 -0500 |
parents | 0df06bfe7165 |
children | 3e4666a456de |
files | src/client/CMakeLists.txt src/client/cmds.h src/client/inode_map.c src/client/inode_map.h src/client/main.c |
diffstat | 5 files changed, 209 insertions(+), 3 deletions(-) [+] |
line wrap: on
line diff
--- a/src/client/CMakeLists.txt Thu Feb 21 18:54:05 2019 -0500 +++ b/src/client/CMakeLists.txt Fri Feb 15 07:58:15 2019 -0500 @@ -1,5 +1,5 @@ # -# Copyright (c) 2015-2018 Josef 'Jeff' Sipek <jeffpc@josefsipek.net> +# Copyright (c) 2015-2019 Josef 'Jeff' Sipek <jeffpc@josefsipek.net> # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal @@ -23,6 +23,7 @@ add_executable(nomad-client main.c cmds.c + inode_map.c ohandle.c # assorted RPC handlers
--- a/src/client/cmds.h Thu Feb 21 18:54:05 2019 -0500 +++ b/src/client/cmds.h Fri Feb 15 07:58:15 2019 -0500 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2018 Josef 'Jeff' Sipek <jeffpc@josefsipek.net> + * Copyright (c) 2015-2019 Josef 'Jeff' Sipek <jeffpc@josefsipek.net> * Copyright (c) 2015 Holly Sipek * Copyright (c) 2016 Steve Dougherty * @@ -30,6 +30,8 @@ #include <nomad/rpc_fs.h> #include <nomad/objstore.h> +#include "inode_map.h" + union cmd { /* close */ struct { @@ -125,6 +127,7 @@ struct objstore *vol; struct rb_tree open_handles; + struct inode_map inode_map; }; extern bool process_handshake(struct fsconn *conn);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/client/inode_map.c Fri Feb 15 07:58:15 2019 -0500 @@ -0,0 +1,143 @@ +/* + * Copyright (c) 2019 Josef 'Jeff' Sipek <jeffpc@josefsipek.net> + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include <jeffpc/mem.h> +#include <jeffpc/error.h> + +#include "inode_map.h" + +struct inode_map_entry { + struct rb_node fwd; + struct rb_node rev; + struct noid oid; + uint64_t ino; +}; + +static struct mem_cache *inode_map_entry_cache; + +int inode_map_init(void) +{ + inode_map_entry_cache = mem_cache_create("inode-map-entry", + sizeof(struct inode_map_entry), + 0); + if (IS_ERR(inode_map_entry_cache)) + return PTR_ERR(inode_map_entry_cache); + + return 0; +} + +static int inode_map_entry_cmp_oid(const void *va, const void *vb) +{ + const struct inode_map_entry *a = va; + const struct inode_map_entry *b = vb; + + return noid_cmp(&a->oid, &b->oid); +} + +static int inode_map_entry_cmp_ino(const void *va, const void *vb) +{ + const struct inode_map_entry *a = va; + const struct inode_map_entry *b = vb; + + if (a->ino < b->ino) + return -1; + if (a->ino > b->ino) + return 1; + return 0; +} + +void inode_map_alloc(struct inode_map *map) +{ + rb_create(&map->fwd, inode_map_entry_cmp_oid, + sizeof(struct inode_map_entry), + offsetof(struct inode_map_entry, fwd)); + rb_create(&map->rev, inode_map_entry_cmp_ino, + sizeof(struct inode_map_entry), + offsetof(struct inode_map_entry, rev)); + + map->next_ino = 1; /* the first inode number to use */ +} + +void inode_map_free(struct inode_map *map) +{ + struct inode_map_entry *entry; + struct rb_cookie cookie; + + memset(&cookie, 0, sizeof(struct rb_cookie)); + while ((entry = rb_destroy_nodes(&map->rev, &cookie))) + ; /* nothing to do */ + + memset(&cookie, 0, sizeof(struct rb_cookie)); + while ((entry = rb_destroy_nodes(&map->fwd, &cookie))) + mem_cache_free(inode_map_entry_cache, entry); + + rb_destroy(&map->fwd); + rb_destroy(&map->rev); +} + +int inode_map_find_by_oid(struct inode_map *map, const struct noid *oid, + uint64_t *ino_r) +{ + const struct inode_map_entry key = { + .oid = *oid, + }; + struct inode_map_entry *entry; + struct rb_cookie where; + + /* check if we already have a oid -> ino mapped */ + entry = rb_find(&map->fwd, &key, &where); + if (entry) { + *ino_r = entry->ino; + return 0; + } + + entry = mem_cache_alloc(inode_map_entry_cache); + if (!entry) + return -ENOMEM; + + entry->oid = *oid; + entry->ino = map->next_ino++; + + rb_insert_here(&map->fwd, entry, &where); + rb_add(&map->rev, entry); + + *ino_r = entry->ino; + + return 0; +} + +int inode_map_find_by_ino(struct inode_map *map, uint64_t ino, + struct noid *oid_r) +{ + const struct inode_map_entry key = { + .ino = ino, + }; + struct inode_map_entry *entry; + + entry = rb_find(&map->rev, &key, NULL); + if (!entry) + return -ENOENT; + + *oid_r = entry->oid; + + return 0; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/client/inode_map.h Fri Feb 15 07:58:15 2019 -0500 @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2019 Josef 'Jeff' Sipek <jeffpc@josefsipek.net> + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef __NOMAD_CLIENT_INODE_MAP_H +#define __NOMAD_CLIENT_INODE_MAP_H + +#include <jeffpc/rbtree.h> + +#include <nomad/types.h> + +struct inode_map { + struct rb_tree fwd; /* oid -> ino */ + struct rb_tree rev; /* ino -> oid */ + + uint64_t next_ino; /* next inode number to allocate */ +}; + +extern int inode_map_init(void); +extern void inode_map_alloc(struct inode_map *map); +extern void inode_map_free(struct inode_map *map); + +/* look up ino by oid; allocates & returns a new ino if not found */ +extern int inode_map_find_by_oid(struct inode_map *map, const struct noid *oid, + uint64_t *ino_r); +/* look up oid by ino; returns -ENOENT if not found */ +extern int inode_map_find_by_ino(struct inode_map *map, uint64_t ino, + struct noid *oid_r); + +#endif
--- a/src/client/main.c Thu Feb 21 18:54:05 2019 -0500 +++ b/src/client/main.c Fri Feb 15 07:58:15 2019 -0500 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2018 Josef 'Jeff' Sipek <jeffpc@josefsipek.net> + * Copyright (c) 2015-2019 Josef 'Jeff' Sipek <jeffpc@josefsipek.net> * Copyright (c) 2015 Holly Sipek * Copyright (c) 2016 Steve Dougherty * @@ -46,6 +46,8 @@ conn.fd = fd; conn.vol = NULL; + inode_map_alloc(&conn.inode_map); + rb_create(&conn.open_handles, ohandle_cmp, sizeof(struct ohandle), offsetof(struct ohandle, node)); @@ -57,6 +59,8 @@ ohandle_close_all(&conn); + inode_map_free(&conn.inode_map); + rb_destroy(&conn.open_handles); } @@ -64,6 +68,13 @@ { int ret; + ret = inode_map_init(); + if (ret) { + cmn_err(CE_CRIT, "failed to initialize inode-map subsystem: %s", + xstrerror(ret)); + goto err; + } + ret = ohandle_init(); if (ret) { cmn_err(CE_CRIT, "failed to initialize ohandle subsystem: %s",