view src/objstore/obj_attr.c @ 887:796345005f9f

objstore: move obj_setattr into a separate file Signed-off-by: Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
author Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
date Mon, 19 Dec 2022 19:33:52 -0500
parents
children 45a236e09b43
line wrap: on
line source

/*
 * Copyright (c) 2015-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 <jeffpc/error.h>

#include "objstore_impl.h"

static int __obj_setattr_perform(struct txn *txn, struct txn_entry *entry)
{
	struct objver *ver = entry->setattr.ver;

	return ver->obj->ops->setattr(ver,
				      &ver->attrs,
				      entry->setattr.changed);
}

static void __obj_setattr_rollback(struct txn *txn, struct txn_entry *entry)
{
	entry->setattr.ver->attrs = entry->setattr.old_attrs;
}

static void __obj_setattr_cleanup(struct txn *txn, struct txn_entry *entry)
{
	txn_detach_objver(txn, entry->setattr.ver);
}

void obj_setattr(struct txn *txn, struct objver *ver, const struct nattr *attrs,
		 unsigned valid)
{
	struct txn_entry *entry;

	txn_attach_objver(txn, ver);

	if (valid & OBJ_ATTR_SIZE) {
		const uint64_t old = p2roundup(ver->attrs.size, PAGE_SIZE);
		const uint64_t new = p2roundup(attrs->size, PAGE_SIZE);

		/* invalidate all pages beyond the new EOF */
		if (old > new)
			page_inval_range(ver, new / PAGE_SIZE,
					 (old - new) / PAGE_SIZE);

		/* keep track of the shortest truncation so far */
		ver->txn.min_data_size = MIN(ver->txn.min_data_size,
					     attrs->size);
	}

	entry = txn_alloc_entry(txn);
	entry->op = OP_SETATTR;
	entry->perform = __obj_setattr_perform;
	entry->rollback = __obj_setattr_rollback;
	entry->cleanup = __obj_setattr_cleanup;
	entry->setattr.ver = ver;
	entry->setattr.old_attrs = ver->attrs;
	entry->setattr.changed = valid;

	if (valid & OBJ_ATTR_MODE)
		ver->attrs.mode = attrs->mode;
	if (valid & _OBJ_ATTR_NLINK)
		ver->attrs.nlink = attrs->nlink;
	if (valid & OBJ_ATTR_SIZE)
		ver->attrs.size = attrs->size;
	if (valid & OBJ_ATTR_ATIME)
		ver->attrs.atime = attrs->atime;
	if (valid & OBJ_ATTR_BTIME)
		ver->attrs.btime = attrs->btime;
	if (valid & OBJ_ATTR_CTIME)
		ver->attrs.ctime = attrs->ctime;
	if (valid & OBJ_ATTR_MTIME)
		ver->attrs.mtime = attrs->mtime;
	if (valid & OBJ_ATTR_OWNER)
		ver->attrs.owner = attrs->owner;
	if (valid & OBJ_ATTR_GROUP)
		ver->attrs.group = attrs->group;

	txn_log_entry(txn, entry);
}