view src/objstore/posix/posix.h @ 1263:8d3171c87786

objstore/posix: remove hack to fill newly created dirs In the past we needed to automatically fill the contents of a newly created directory with entries referring to '.' and '..'. This is now handled automatically later in the same transaction. Unfortunately, a simplified version of the code still exists for root-object creation. Signed-off-by: Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
author Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
date Sat, 17 Dec 2022 15:40:26 -0500
parents facc1b5299a8
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.
 */

#ifndef __NOMAD_OBJSTORE_POSIX_H
#define __NOMAD_OBJSTORE_POSIX_H

#include <dirent.h>

#include <jeffpc/time.h>
#include <jeffpc/io.h>

#include <nomad/types.h>

#include <nomad/objstore.h>
#include <nomad/objstore_backend.h>

/*
 * This is an objstore backend that uses a POSIX file system for storage of
 * objects.
 *
 * The layout is relatively simple:
 *
 * .../                       - the data dir
 * .../nomad-vdev             - vdev info (uuid)
 * .../<volid>                - volume
 * .../<volid>/vol-info       - volume info (root OID, uuid, etc.)
 * .../<volid>/txn-log        - transaction log
 * .../<volid>/new            - new object dir
 * .../<volid>/<uniq>         - everything related to the object
 * .../<volid>/<uniq>/<clock> - one version of the object
 *
 * Each .../<volid>/<uniq>/<clock> file contains a header (containing
 * attributes, etc.) followed by the object contents.
 */

/*
 * In-memory structures
 */
#define POSIX_FIRST_VALID_UNIQ	1

struct posix_vdev {
	struct objstore_vdev *vdev;

	int rootfd;
};

struct posix_vol {
	struct objstore_clone *clone;
	uint64_t created_at;

	/* the root object's id */
	uint64_t root_host;
	uint64_t root_uniq;

	uint64_t next_uniq;	/* next free object id on *this* host */

	int rootfd;	/* this volume's root */
	int txnfd;	/* the transaction log */
};

struct posix_obj {
	struct obj *obj;

	char objname[34];
};

/*
 * On-disk structures
 *
 * Note: An object id (struct noid) consists of a volume id (a uuid) and a
 * volume-local uniquifier (integer).  This backend tends to call the unique
 * part the object id.  This is ok since the structures that do that belong
 * to a volume and therefore the uuid part is implied.
 */
#define POSIX_VDEV_FNAME	"nomad-vdev"
#define POSIX_VOL_FNAME		"vol-info"
#define POSIX_NEW_FNAME		"new"
#define POSIX_TXN_FNAME		"txn-log"

#define POSIX_VDEV_MAGIC	0x504f533158444556ull	/* "POS1XDEV" */
#define POSIX_VOL_MAGIC		0x504f533158564f4cull	/* "POS1XVOL" */
#define POSIX_TXN_MAGIC		0x504f53315854584eull	/* "POS1XTXN" */
#define POSIX_VER_MAGIC		0x504f533158564552ull	/* "POS1XVER" */

#define BLOCK_SIZE		4096

struct posix_vdev_header {
	uint64_t magic;		/* POSIX_VDEV_MAGIC */
	uint64_t created;	/* time created */
	struct xuuid uuid;	/* our uuid */

	uint8_t _pad1[4064];
} __attribute__((packed,aligned(8)));

struct posix_vol_header {
	uint64_t magic;		/* POSIX_VOL_MAGIC */
	uint64_t _pad0;
	struct xuuid uuid;	/* our uuid */
	uint64_t created_at;	/* time created */
	uint64_t root_host;	/* the root directory's object id (host) */
	uint64_t root_uniq;	/* the root directory's object id (uniq) */
	uint64_t next_uniq;	/* the next available object id to allocate */

	uint8_t _pad1[4032];
} __attribute__((packed,aligned(8)));

struct posix_txn_header {
	uint64_t magic;		/* POSIX_TXN_MAGIC */

	uint8_t _pad[4088];
} __attribute__((packed,aligned(8)));

struct posix_ver_header {
	uint64_t magic;		/* POSIX_VER_MAGIC */

	/* attributes */
	uint16_t _pad0;
	uint16_t mode;
	uint32_t nlink;
	uint64_t size;
	uint64_t atime; /* access time */
	uint64_t btime; /* birth time */
	uint64_t ctime; /* change time */
	uint64_t mtime; /* modify time */
	uint32_t owner;
	uint32_t group;

	uint8_t _pad1[4032];
} __attribute__((packed,aligned(8)));

/* sanity check on-disk struct sizes */
STATIC_ASSERT(sizeof(struct posix_vdev_header) == BLOCK_SIZE);
STATIC_ASSERT(sizeof(struct posix_vol_header) == BLOCK_SIZE);
STATIC_ASSERT(sizeof(struct posix_txn_header) == BLOCK_SIZE);
STATIC_ASSERT(sizeof(struct posix_ver_header) == BLOCK_SIZE);

/*
 * Various prototypes
 */

extern const struct obj_ops posix_obj_ops;
extern const struct clone_ops posix_clone_ops;

extern int create_obj(int rootfd, uint64_t host, uint64_t uniq,
		      const struct nvclock *clock, const struct nattr *attrs,
		      struct buffer *contents);
extern int create_rootdir(int rootfd, uint64_t host, uint64_t uniq);

extern int write_ver_header(struct objver *ver, int fd,
			    const struct posix_ver_header *_hdr);
extern ssize_t write_ver_data(struct objver *ver, int fd, const void *buf,
			      size_t len, uint64_t offset);

extern int txnlog_create(int rootfd);
extern void txnlog_destroy(int rootfd);

extern int posix_txn_begin(struct txn *txn);
extern int posix_txn_log_entry(struct txn *txn, struct txn_entry *entry);
extern int posix_txn_commit(struct txn *txn);
extern int posix_txn_complete(struct txn *txn);
extern void posix_txn_abort(struct txn *txn);

extern int walk_object_versions(struct posix_obj *pobj, int fd,
				int (*fxn)(struct posix_obj *, void *,
					   struct dirent *),
				void *private);

#endif