Mercurial > nomad
view src/objstore/posix/obj_create.c @ 891:77a35abc6a24
objstore: move dir buffer making helper to dir.c
This is where it belongs since it doesn't do anything directly with objects.
Signed-off-by: Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
author | Josef 'Jeff' Sipek <jeffpc@josefsipek.net> |
---|---|
date | Mon, 19 Dec 2022 19:44:45 -0500 |
parents | 8d3171c87786 |
children |
line wrap: on
line source
/* * Copyright (c) 2018-2020,2022 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 "posix.h" /* * Low-level new object creation */ static int create_objver(int objfd, const struct nvclock *clock, const struct nattr *attrs, struct buffer *contents) { struct posix_ver_header hdr; char vername[PATH_MAX]; int ret; int fd; ret = nvclock_to_str(clock, vername, sizeof(vername)); if (ret) return ret; fd = xopenat(objfd, vername, O_RDWR | O_CREAT | O_EXCL, 0600); if (fd < 0) return fd; hdr.mode = attrs->mode; hdr.nlink = attrs->nlink; hdr.size = attrs->size; hdr.atime = attrs->atime; hdr.btime = attrs->btime; hdr.ctime = attrs->ctime; hdr.mtime = attrs->mtime; hdr.owner = attrs->owner; hdr.group = attrs->group; ret = write_ver_header(NULL, fd, &hdr); if (ret) goto err; /* truncate the file to match the size in attrs */ ret = xftruncate(fd, sizeof(struct posix_ver_header) + p2roundup(attrs->size, BLOCK_SIZE)); if (ret) goto err; /* write out the dir contents if we got them */ if (contents) { VERIFY(NATTR_ISDIR(attrs->mode)); VERIFY3U(attrs->size, ==, buffer_size(contents)); ret = write_ver_data(NULL, fd, buffer_data(contents), buffer_size(contents), 0); if (ret < 0) goto err; if (ret != buffer_size(contents)) { ret = -EPIPE; goto err; } } xclose(fd); return 0; err: xclose(fd); xunlinkat(objfd, vername, 0); return ret; } int create_obj(int rootfd, uint64_t this_host, uint64_t this_uniq, const struct nvclock *clock, const struct nattr *_attrs, struct buffer *contents) { struct nattr attrs; char objname[34]; int ret; int fd; attrs = *_attrs; snprintf(objname, sizeof(objname), "%016"PRIx64"-%016"PRIx64, this_host, this_uniq); /* create the object directory */ ret = xmkdirat(rootfd, objname, 0700); if (ret) return ret; /* open the object directory */ fd = xopenat(rootfd, objname, O_RDONLY, 0); if (fd < 0) { ret = fd; goto err; } /* create the object version file */ ret = create_objver(fd, clock, &attrs, contents); if (ret) goto err_close; xclose(fd); return ret; err_close: xclose(fd); err: xunlinkat(rootfd, objname, 0); return ret; } /* create a root directory */ int create_rootdir(int rootfd, uint64_t host, uint64_t uniq) { const uint64_t now = gettime(); struct nattr attrs = { .mode = NATTR_DIR | 0700, .nlink = 1, /* even new dirs have a link count of 1 */ .size = 0, /* overwritten below */ .atime = now, .btime = now, .ctime = now, .mtime = now, .owner = 0, .group = 0, }; struct nvclock clock; struct buffer contents; int ret; nvclock_reset(&clock); VERIFY0(nvclock_inc(&clock)); /* * construct an empty directory */ ret = buffer_init_heap(&contents, BLOCK_SIZE); /* size guess */ if (ret) return ret; ret = dir_make_buffer(host, uniq, host, uniq, &contents); if (ret) goto err; /* overwrite the requested size */ attrs.size = buffer_size(&contents); ret = create_obj(rootfd, host, uniq, &clock, &attrs, &contents); err: buffer_free(&contents); return ret; }