
/*
 * Maintained by Jeff Garzik <jgarzik@pobox.com>
 *
 * Copyright 2006-2007 Red Hat, Inc.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; see the file COPYING.  If not, write to
 * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 */

#define FUSE_USE_VERSION 26

#define _BSD_SOURCE

#include "dbfs-config.h"
#include <fuse_lowlevel.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <syslog.h>
#include <sys/vfs.h>
#include <glib.h>
#include <db.h>
#include "dbfs.h"

int debugging = 1;

static void dbfs_fill_attr(const struct dbfs_inode *ino, struct stat *st)
{
	memset(st, 0, sizeof(*st));
	st->st_dev	= 1;
	st->st_ino	= GUINT64_FROM_LE(ino->raw_inode->ino);
	st->st_mode	= GUINT32_FROM_LE(ino->raw_inode->mode);
	st->st_nlink	= GUINT32_FROM_LE(ino->raw_inode->nlink);
	st->st_uid	= GUINT32_FROM_LE(ino->raw_inode->uid);
	st->st_gid	= GUINT32_FROM_LE(ino->raw_inode->gid);
	st->st_rdev	= GUINT64_FROM_LE(ino->raw_inode->rdev);
	st->st_size	= GUINT64_FROM_LE(ino->raw_inode->size);
	st->st_blksize	= 512;
	st->st_blocks	= GUINT64_FROM_LE(ino->raw_inode->size) / 512ULL;
	st->st_atime	= GUINT64_FROM_LE(ino->raw_inode->atime);
	st->st_mtime	= GUINT64_FROM_LE(ino->raw_inode->mtime);
	st->st_ctime	= GUINT64_FROM_LE(ino->raw_inode->ctime);

	if (debugging)
		syslog(LOG_DEBUG, "fill_attr: ino %lu, mode %u, uid %u, "
			"gid %u, size %lu, mtime %lu",
		       st->st_ino,
		       st->st_mode,
		       st->st_uid,
		       st->st_gid,
		       st->st_size,
		       st->st_mtime);

}

static void dbfs_fill_ent(const struct dbfs_inode *ino,
			  struct fuse_entry_param *ent)
{
	memset(ent, 0, sizeof(*ent));

	ent->ino = GUINT64_FROM_LE(ino->raw_inode->ino);
	ent->generation = GUINT64_FROM_LE(ino->raw_inode->version);

	dbfs_fill_attr(ino, &ent->attr);

	/* these timeouts are just a guess */
	ent->attr_timeout = 2.0;
	ent->entry_timeout = 2.0;
}

static void dbfs_reply_ino(fuse_req_t req, struct dbfs_inode *ino)
{
	struct fuse_entry_param ent;

	dbfs_fill_ent(ino, &ent);

	fuse_reply_entry(req, &ent);

	dbfs_inode_free(ino);
}

static void dbfs_op_init(void *userdata, struct fuse_conn_info *conn)
{
	struct dbfs *fs;
	int rc;

	if (debugging)
		syslog(LOG_DEBUG, "ENTER dbfs_op_init");

	fs = dbfs_new();

	rc = dbfs_open(fs, DB_RECOVER | DB_CREATE, DB_CREATE, "dbfs", TRUE);
	if (rc) {
		syslog(LOG_ERR, "dbfs_open failed");
		abort();			/* TODO: improve */
	}

	gfs = fs;

	syslog(LOG_INFO, PACKAGE_STRING " initialized");
}

static void dbfs_op_destroy(void *userdata)
{
	struct dbfs *fs = gfs;

	if (debugging)
		syslog(LOG_DEBUG, "ENTER dbfs_op_destroy");

	dbfs_close(fs);
	dbfs_free(fs);

	gfs = NULL;

	if (debugging)
		syslog(LOG_DEBUG, "EXIT dbfs_op_destroy");
}

static void dbfs_op_lookup(fuse_req_t req, fuse_ino_t parent, const char *name)
{
	guint64 ino_n;
	struct dbfs_inode *ino;
	int rc;
	DB_TXN *txn;
	unsigned long long ino_pr;

	if (debugging)
		syslog(LOG_DEBUG, "ENTER dbfs_op_lookup, name=='%s'", name);

	rc = gfs->env->txn_begin(gfs->env, NULL, &txn, 0);
	if (rc) {
		fuse_reply_err(req, rc);
		return;
	}

	/* lookup inode in parent directory */
	rc = dbfs_dir_lookup(txn, parent, name, &ino_n);
	if (rc)
		goto err_out;

	rc = dbfs_inode_read(txn, ino_n, &ino);
	if (rc)
		goto err_out;

	rc = txn->commit(txn, 0);
	if (rc) {
		dbfs_inode_free(ino);
		fuse_reply_err(req, rc);
		return;
	}

	/* send reply */
	ino_pr = GUINT64_FROM_LE(ino->raw_inode->ino);
	dbfs_reply_ino(req, ino);
	if (debugging)
		syslog(LOG_DEBUG, "EXIT dbfs_op_lookup, ino==%Lu", ino_pr);
	return;

err_out:
	txn->abort(txn);
	fuse_reply_err(req, -rc);
	if (debugging)
		syslog(LOG_DEBUG, "EXIT dbfs_op_lookup, rc==%d", -rc);
}

static void dbfs_op_getattr(fuse_req_t req, fuse_ino_t ino_n,
			     struct fuse_file_info *fi)
{
	struct dbfs_inode *ino;
	struct stat st;
	int rc;
	DB_TXN *txn;

	if (debugging)
		syslog(LOG_DEBUG, "ENTER dbfs_op_getattr, ino==%lu", ino_n);

	rc = gfs->env->txn_begin(gfs->env, NULL, &txn, 0);
	if (rc) {
		fuse_reply_err(req, rc);
		return;
	}

	/* read inode from database */
	rc = dbfs_inode_read(txn, ino_n, &ino);
	if (rc) {
		rc = ENOENT;
		goto err_out_txn;
	}

	rc = txn->commit(txn, 0);
	if (rc) {
		rc = -rc;
		goto err_out;
	}

	/* fill in stat buf, taking care to convert from
	 * little endian to native endian
	 */
	dbfs_fill_attr(ino, &st);

	/* send result back to FUSE */
	fuse_reply_attr(req, &st, 2.0);

	dbfs_inode_free(ino);
	if (debugging)
		syslog(LOG_DEBUG, "EXIT dbfs_op_getattr, ino==%Lu",
			(unsigned long long) st.st_ino);
	return;

err_out_txn:
	txn->abort(txn);
err_out:
	fuse_reply_err(req, rc);
	if (debugging)
		syslog(LOG_DEBUG, "EXIT dbfs_op_getattr, rc==%d", rc);
}

static void dbfs_op_setattr(fuse_req_t req, fuse_ino_t ino_n,
			    struct stat *attr, int to_set,
			    struct fuse_file_info *fi)
{
	struct dbfs_inode *ino;
	struct stat st;
	int rc, dirty = 0;
	DB_TXN *txn;

	if (debugging)
		syslog(LOG_DEBUG, "ENTER dbfs_op_setattr, ino==%lu", ino_n);

	rc = gfs->env->txn_begin(gfs->env, NULL, &txn, 0);
	if (rc) {
		rc = -rc;
		goto err_out;
	}

	/* read inode from database */
	rc = dbfs_inode_read(txn, ino_n, &ino);
	if (rc)
		goto err_out_txn;

	if (to_set & FUSE_SET_ATTR_MODE) {
		ino->raw_inode->mode = GUINT32_TO_LE(attr->st_mode);
		dirty = 1;
	}
	if (to_set & FUSE_SET_ATTR_UID) {
		ino->raw_inode->uid = GUINT32_TO_LE(attr->st_uid);
		dirty = 1;
	}
	if (to_set & FUSE_SET_ATTR_GID) {
		ino->raw_inode->gid = GUINT32_TO_LE(attr->st_gid);
		dirty = 1;
	}
	if (to_set & FUSE_SET_ATTR_SIZE) {
		rc = dbfs_inode_resize(txn, ino, attr->st_size);
		if (rc)
			goto err_out_free;
		ino->raw_inode->size = GUINT64_TO_LE(attr->st_size);
		dirty = 1;
	}
	if (to_set & FUSE_SET_ATTR_ATIME) {
		ino->raw_inode->atime = GUINT64_TO_LE(attr->st_atime);
		dirty = 1;
	}
	if (to_set & FUSE_SET_ATTR_MTIME) {
		ino->raw_inode->mtime = GUINT64_TO_LE(attr->st_mtime);
		dirty = 1;
	}

	if (dirty) {
		rc = dbfs_inode_write(txn, ino);
		if (rc)
			goto err_out_free;
	}

	rc = txn->commit(txn, 0);
	if (rc) {
		rc = -rc;
		txn = NULL;
		goto err_out_free;
	}

	dbfs_fill_attr(ino, &st);
	dbfs_inode_free(ino);
	fuse_reply_attr(req, &st, 2.0);
	if (debugging)
		syslog(LOG_DEBUG, "EXIT dbfs_op_setattr, ino==%Lu",
			(unsigned long long) st.st_ino);
	return;

err_out_free:
	dbfs_inode_free(ino);
err_out_txn:
	if (txn)
		txn->abort(txn);
err_out:
	fuse_reply_err(req, -rc);
	if (debugging)
		syslog(LOG_DEBUG, "EXIT dbfs_op_setattr, rc==%d", -rc);
}

static void dbfs_op_readlink(fuse_req_t req, fuse_ino_t ino)
{
	int rc;
	DBT val;
	char *s;
	DB_TXN *txn;

	if (debugging)
		syslog(LOG_DEBUG, "ENTER dbfs_op_readlink, ino==%lu", ino);

	rc = gfs->env->txn_begin(gfs->env, NULL, &txn, 0);
	if (rc) {
		rc = -rc;
		goto err_out;
	}

	/* read link from database */
	rc = dbfs_symlink_read(txn, ino, &val);
	if (rc)
		goto err_out_txn;

	rc = txn->commit(txn, 0);
	if (rc) {
		rc = -rc;
		free(val.data);
		goto err_out;
	}

	/* send reply; use g_strndup to append a trailing null */
	s = g_strndup(val.data, val.size);
	fuse_reply_readlink(req, s);

	free(val.data);
	if (debugging)
		syslog(LOG_DEBUG, "EXIT dbfs_op_readlink, linktext=='%s'", s);
	g_free(s);
	return;

err_out_txn:
	txn->abort(txn);
err_out:
	fuse_reply_err(req, -rc);
	if (debugging)
		syslog(LOG_DEBUG, "EXIT dbfs_op_readlink, rc==%d", -rc);
}

static int dbfs_mode_validate(mode_t mode)
{
	unsigned int ifmt = mode & S_IFMT;
	int rc = 0;

	if (S_ISREG(mode)) {
		if (ifmt & ~S_IFREG)
			rc = -EINVAL;
	}
	else if (S_ISDIR(mode)) {
		if (ifmt & ~S_IFDIR)
			rc = -EINVAL;
	}
	else if (S_ISCHR(mode)) {
		if (ifmt & ~S_IFCHR)
			rc = -EINVAL;
	}
	else if (S_ISBLK(mode)) {
		if (ifmt & ~S_IFBLK)
			rc = -EINVAL;
	}
	else if (S_ISFIFO(mode)) {
		if (ifmt & ~S_IFIFO)
			rc = -EINVAL;
	}
	else if (S_ISLNK(mode))
		rc = -EINVAL;
	else if (S_ISSOCK(mode)) {
		if (ifmt & ~S_IFSOCK)
			rc = -EINVAL;
	}
	else
		rc = -EINVAL;

	return rc;
}

static void dbfs_op_mknod(fuse_req_t req, fuse_ino_t parent, const char *name,
			  mode_t mode, dev_t rdev)
{
	struct dbfs_inode *ino;
	int rc;
	DB_TXN *txn;
	unsigned long long ino_pr;

	if (debugging)
		syslog(LOG_DEBUG, "ENTER dbfs_op_mknod, name='%s'", name);

	rc = gfs->env->txn_begin(gfs->env, NULL, &txn, 0);
	if (rc) {
		rc = -rc;
		goto err_out;
	}

	rc = dbfs_mode_validate(mode);
	if (rc)
		goto err_out_txn;

	/* these have separate inode-creation hooks */
	if (S_ISDIR(mode) || S_ISLNK(mode)) {
		rc = -EINVAL;
		goto err_out_txn;
	}

	rc = dbfs_mknod(txn, parent, name, mode, rdev, &ino);
	if (rc)
		goto err_out_txn;

	rc = txn->commit(txn, 0);
	if (rc) {
		dbfs_inode_free(ino);
		rc = -rc;
		goto err_out;
	}

	ino_pr = GUINT64_FROM_LE(ino->raw_inode->ino);
	dbfs_reply_ino(req, ino);
	if (debugging)
		syslog(LOG_DEBUG, "EXIT dbfs_op_mknod, ino==%Lu", ino_pr);
	return;

err_out_txn:
	txn->abort(txn);
err_out:
	fuse_reply_err(req, -rc);
	if (debugging)
		syslog(LOG_DEBUG, "EXIT dbfs_op_mknod, rc==%d", -rc);
}

static void dbfs_op_mkdir(fuse_req_t req, fuse_ino_t parent, const char *name,
			  mode_t mode)
{
	struct dbfs_inode *ino;
	int rc;
	DB_TXN *txn;
	unsigned long long ino_pr;

	if (debugging)
		syslog(LOG_DEBUG, "ENTER dbfs_op_mkdir, name=='%s'", name);

	rc = gfs->env->txn_begin(gfs->env, NULL, &txn, 0);
	if (rc) {
		rc = -rc;
		goto err_out;
	}

	mode &= ALLPERMS;
	mode |= S_IFDIR;

	rc = dbfs_mknod(txn, parent, name, mode, 0, &ino);
	if (rc)
		goto err_out_txn;

	rc = txn->commit(txn, 0);
	if (rc) {
		dbfs_inode_free(ino);
		rc = -rc;
		goto err_out;
	}

	ino_pr = GUINT64_FROM_LE(ino->raw_inode->ino);
	dbfs_reply_ino(req, ino);
	if (debugging)
		syslog(LOG_DEBUG, "EXIT dbfs_op_mkdir, ino==%Lu", ino_pr);
	return;

err_out_txn:
	txn->abort(txn);
err_out:
	fuse_reply_err(req, -rc);
	if (debugging)
		syslog(LOG_DEBUG, "EXIT dbfs_op_mkdir, rc==%d", -rc);
}

static void dbfs_op_unlink(fuse_req_t req, fuse_ino_t parent, const char *name)
{
	int rc;
	DB_TXN *txn;

	if (debugging)
		syslog(LOG_DEBUG, "ENTER dbfs_op_unlink, name=='%s'", name);

	rc = gfs->env->txn_begin(gfs->env, NULL, &txn, 0);
	if (rc) {
		rc = -rc;
		goto out;
	}

	rc = dbfs_unlink(txn, parent, name, 0);
	if (rc)
		goto err_out;

	rc = txn->commit(txn, 0);
	if (rc) {
		rc = -rc;
		goto out;
	}

out:
	fuse_reply_err(req, -rc);
	if (debugging)
		syslog(LOG_DEBUG, "EXIT dbfs_op_unlink, rc==%d", -rc);
	return;

err_out:
	txn->abort(txn);
	goto out;
}

static void dbfs_op_link(fuse_req_t req, fuse_ino_t ino_n, fuse_ino_t parent,
			 const char *newname)
{
	struct dbfs_inode *ino;
	int rc;
	DB_TXN *txn;
	unsigned long long ino_pr;

	if (debugging)
		syslog(LOG_DEBUG, "ENTER dbfs_op_link, ino==%lu, newname=='%s'",
			ino_n, newname);

	rc = gfs->env->txn_begin(gfs->env, NULL, &txn, 0);
	if (rc) {
		rc = -rc;
		goto err_out;
	}

	/* read inode from database */
	rc = dbfs_inode_read(txn, ino_n, &ino);
	if (rc) {
		rc = -ENOENT;
		goto err_out_txn;
	}

	/* attempt to create hard link */
	rc = dbfs_link(txn, ino, ino_n, parent, newname);
	if (rc)
		goto err_out_ino;

	rc = txn->commit(txn, 0);
	if (rc) {
		dbfs_inode_free(ino);
		rc = -rc;
		goto err_out;
	}

	ino_pr = GUINT64_FROM_LE(ino->raw_inode->ino);
	dbfs_reply_ino(req, ino);
	if (debugging)
		syslog(LOG_DEBUG, "EXIT dbfs_op_link, ino==%Lu", ino_pr);
	return;

err_out_ino:
	dbfs_inode_free(ino);
err_out_txn:
	txn->abort(txn);
err_out:
	fuse_reply_err(req, -rc);
	if (debugging)
		syslog(LOG_DEBUG, "EXIT dbfs_op_link, rc==%d", -rc);
}

static void dbfs_op_open(fuse_req_t req, fuse_ino_t ino,
			 struct fuse_file_info *fi)
{
	if (debugging)
		syslog(LOG_DEBUG, "ENTER dbfs_op_open, ino==%lu", ino);

	fi->direct_io = 0;
	fi->keep_cache = 1;
	fuse_reply_open(req, fi);
}

static void dbfs_op_read(fuse_req_t req, fuse_ino_t ino, size_t size,
			 off_t off, struct fuse_file_info *fi)
{
	void *buf = NULL;
	int rc, rc2;
	DB_TXN *txn;

	if (debugging)
		syslog(LOG_DEBUG, "ENTER dbfs_op_read, ino==%lu", ino);

	rc = gfs->env->txn_begin(gfs->env, NULL, &txn, 0);
	if (rc) {
		rc = -rc;
		goto err_out;
	}

	rc = dbfs_read(txn, ino, off, size, &buf);
	if (rc < 0)
		goto err_out_txn;

	rc2 = txn->commit(txn, 0);
	if (rc2) {
		rc = -rc2;
		goto err_out;
	}

	fuse_reply_buf(req, buf, rc);
	free(buf);
	if (debugging)
		syslog(LOG_DEBUG, "EXIT dbfs_op_read, rc==%d", rc);
	return;

err_out_txn:
	txn->abort(txn);
err_out:
	fuse_reply_err(req, -rc);
	if (debugging)
		syslog(LOG_DEBUG, "EXIT dbfs_op_read, rc==%d", -rc);
}

static void dbfs_op_write(fuse_req_t req, fuse_ino_t ino, const char *buf,
			  size_t size, off_t off, struct fuse_file_info *fi)
{
	int rc, rc2;
	DB_TXN *txn;

	if (debugging)
		syslog(LOG_DEBUG, "ENTER dbfs_op_write, ino==%lu", ino);

	rc = gfs->env->txn_begin(gfs->env, NULL, &txn, 0);
	if (rc) {
		rc = -rc;
		goto err_out;
	}

	rc = dbfs_write(txn, ino, off, buf, size);
	if (rc < 0)
		goto err_out_txn;

	rc2 = txn->commit(txn, 0);
	if (rc2) {
		rc = -rc2;
		goto err_out;
	}

	fuse_reply_write(req, rc);
	if (debugging)
		syslog(LOG_DEBUG, "EXIT dbfs_op_write, rc==%d", rc);
	return;

err_out_txn:
	txn->abort(txn);
err_out:
	fuse_reply_err(req, -rc);
	if (debugging)
		syslog(LOG_DEBUG, "EXIT dbfs_op_write, error, rc==%d", -rc);
}

static int dbfs_chk_empty(struct dbfs_dirent *de, void *userdata)
{
	if ((GUINT16_FROM_LE(de->namelen) == 1) && (!memcmp(de->name, ".", 1)))
		return 0;
	if ((GUINT16_FROM_LE(de->namelen) == 2) && (!memcmp(de->name, "..", 2)))
		return 0;
	return ENOTEMPTY;
}

static void dbfs_op_rmdir(fuse_req_t req, fuse_ino_t parent, const char *name)
{
	guint64 ino_n;
	int rc;
	DBT val;
	DB_TXN *txn;

	if (debugging)
		syslog(LOG_DEBUG, "ENTER dbfs_op_rmdir, name=='%s'", name);

	rc = gfs->env->txn_begin(gfs->env, NULL, &txn, 0);
	if (rc) {
		rc = -rc;
		goto out;
	}

	/* get inode number associated with name */
	rc = dbfs_dir_lookup(txn, parent, name, &ino_n);
	if (rc)
		goto out_txn;

	/* read dir associated with name */
	rc = dbfs_dir_read(txn, ino_n, &val);
	if (rc)
		goto out_txn;

	/* make sure dir only contains "." and ".." */
	rc = dbfs_dir_foreach(val.data, dbfs_chk_empty, NULL);
	free(val.data);

	/* if dbfs_chk_empty() returns non-zero, dir is not empty */
	if (rc)
		goto out_txn;

	/* dir is empty, go ahead and unlink */
	rc = dbfs_unlink(txn, parent, name, DBFS_UNLINK_DIR);
	if (rc)
		goto out_txn;

	rc = txn->commit(txn, 0);
	if (rc) {
		rc = -rc;
		goto out;
	}

	fuse_reply_err(req, 0);
	if (debugging)
		syslog(LOG_DEBUG, "EXIT dbfs_op_rmdir, rc==0");
	return;

out_txn:
	txn->abort(txn);
out:
	fuse_reply_err(req, -rc);
	if (debugging)
		syslog(LOG_DEBUG, "EXIT dbfs_op_rmdir, rc==%d", -rc);
}

static void dbfs_op_symlink(fuse_req_t req, const char *link,
			    fuse_ino_t parent, const char *name)
{
	struct dbfs_inode *ino;
	int rc;
	DB_TXN *txn;
	unsigned long long ino_pr;

	if (debugging)
		syslog(LOG_DEBUG, "ENTER dbfs_op_symlink, name=='%s'", name);

	if (!g_utf8_validate(link, -1, NULL)) {
		rc = -EINVAL;
		goto err_out;
	}

	rc = gfs->env->txn_begin(gfs->env, NULL, &txn, 0);
	if (rc) {
		rc = -rc;
		goto err_out;
	}

	rc = dbfs_mknod(txn, parent, name,
			S_IFLNK | S_IRWXU | S_IRWXG | S_IRWXO, 0, &ino);
	if (rc)
		goto err_out_txn;

	rc = dbfs_symlink_write(txn, GUINT64_FROM_LE(ino->raw_inode->ino), link);
	if (rc)
		goto err_out_ino;

	rc = txn->commit(txn, 0);
	if (rc) {
		dbfs_inode_free(ino);
		rc = -rc;
		goto err_out;
	}

	ino_pr = GUINT64_FROM_LE(ino->raw_inode->ino);
	dbfs_reply_ino(req, ino);
	if (debugging)
		syslog(LOG_DEBUG, "EXIT dbfs_op_symlink, ino==%Lu", ino_pr);
	return;

err_out_ino:
	dbfs_inode_free(ino);
err_out_txn:
	txn->abort(txn);
err_out:
	fuse_reply_err(req, -rc);
	if (debugging)
		syslog(LOG_DEBUG, "EXIT dbfs_op_symlink, rc==%d", -rc);
}

static void dbfs_op_rename(fuse_req_t req, fuse_ino_t parent,
			   const char *name, fuse_ino_t newparent,
			   const char *newname)
{
	int rc;
	DB_TXN *txn;

	if (debugging)
		syslog(LOG_DEBUG, "ENTER dbfs_op_rename, name=='%s', newname=='%s'",
			name, newname);

	rc = gfs->env->txn_begin(gfs->env, NULL, &txn, 0);
	if (rc) {
		rc = -rc;
		goto out;
	}

	rc = dbfs_rename(txn, parent, name, newparent, newname);
	if (rc)
		goto out_txn;

	rc = txn->commit(txn, 0);
	if (rc) {
		rc = -rc;
		goto out;
	}

	fuse_reply_err(req, 0);
	return;

out_txn:
	txn->abort(txn);
out:
	fuse_reply_err(req, -rc);
	if (debugging)
		syslog(LOG_DEBUG, "EXIT dbfs_op_rename, rc==%d", -rc);
}

static void dbfs_op_fsync (fuse_req_t req, fuse_ino_t ino,
			   int datasync, struct fuse_file_info *fi)
{
	if (debugging)
		syslog(LOG_DEBUG, "ENTER dbfs_op_fsync, ino==%lu", ino);

	/* DB should have already sync'd our data for us */
	fuse_reply_err(req, 0);
}

static void dbfs_op_opendir(fuse_req_t req, fuse_ino_t ino,
			    struct fuse_file_info *fi)
{
	DBT val;
	int rc;
	DB_TXN *txn;

	if (debugging)
		syslog(LOG_DEBUG, "ENTER dbfs_op_opendir, ino==%lu", ino);

	rc = gfs->env->txn_begin(gfs->env, NULL, &txn, 0);
	if (rc) {
		rc = -rc;
		goto err_out;
	}

	/* read directory from database */
	rc = dbfs_dir_read(txn, ino, &val);
	if (rc)
		goto err_out_txn;

	rc = txn->commit(txn, 0);
	if (rc) {
		rc = -rc;
		goto err_out;
	}

	/* save for later use */
	fi->fh = (uint64_t) (unsigned long) val.data;

	/* send reply */
	fuse_reply_open(req, fi);
	if (debugging)
		syslog(LOG_DEBUG, "EXIT dbfs_op_opendir");
	return;

err_out_txn:
	txn->abort(txn);
err_out:
	fuse_reply_err(req, -rc);
	if (debugging)
		syslog(LOG_DEBUG, "EXIT dbfs_op_opendir, rc==%d", -rc);
}

struct dirbuf {
	char		*p;
	size_t		size;
};

struct dirbuf_iter {
	struct dirbuf	db;
	fuse_req_t	req;
};

/* stock function copied from FUSE template (hello_ll.c) */
static void dirbuf_add(fuse_req_t req, struct dirbuf *b, const char *name,
		       fuse_ino_t ino)
{
	struct stat stbuf;
	size_t oldsize = b->size;
	b->size += fuse_add_direntry(req, NULL, 0, name, NULL, 0);
	b->p = (char *) realloc(b->p, b->size);
	memset(&stbuf, 0, sizeof(stbuf));
	stbuf.st_ino = ino;
	fuse_add_direntry(req, b->p + oldsize, b->size - oldsize, name, &stbuf,
			  b->size);
}

#ifndef min
#define min(x, y) ((x) < (y) ? (x) : (y))
#endif

/* stock function copied from FUSE template */
static int reply_buf_limited(fuse_req_t req, const void *buf, size_t bufsize,
			     off_t off, size_t maxsize)
{
	if (off < bufsize)
		return fuse_reply_buf(req, buf + off,
				      min(bufsize - off, maxsize));
	else
		return fuse_reply_buf(req, NULL, 0);
}

static int dbfs_fill_dirbuf(struct dbfs_dirent *de, void *userdata)
{
	struct dirbuf_iter *di = userdata;
	struct dirbuf *b = &di->db;
	char *s;

	/* add dirent to buffer; use g_strndup solely to append nul */
	s = g_strndup(de->name, GUINT16_FROM_LE(de->namelen));
	dirbuf_add(di->req, b, s, GUINT64_FROM_LE(de->ino));
	free(s);
	return 0;
}

static void dbfs_op_readdir(fuse_req_t req, fuse_ino_t ino, size_t size,
			     off_t off, struct fuse_file_info *fi)
{
	struct dirbuf_iter di;
	void *p;

	if (debugging)
		syslog(LOG_DEBUG, "ENTER dbfs_op_readdir, ino==%lu", ino);

	/* grab directory contents stored by opendir */
	p = (void *) (unsigned long) fi->fh;

	/* iterate through each dirent, filling dirbuf */
	memset(&di, 0, sizeof(di));
	dbfs_dir_foreach(p, dbfs_fill_dirbuf, &di);

	/* send reply */
	reply_buf_limited(req, di.db.p, di.db.size, off, size);
	free(di.db.p);

	if (debugging)
		syslog(LOG_DEBUG, "EXIT dbfs_op_readdir");
}

static void dbfs_op_releasedir(fuse_req_t req, fuse_ino_t ino,
			       struct fuse_file_info *fi)
{
	void *p = (void *) (unsigned long) fi->fh;

	if (debugging)
		syslog(LOG_DEBUG, "ENTER dbfs_op_releasedir, ino==%lu", ino);

	/* release directory contents */
	free(p);

	fuse_reply_err(req, 0);
}

static void dbfs_op_fsyncdir (fuse_req_t req, fuse_ino_t ino,
			      int datasync, struct fuse_file_info *fi)
{
	if (debugging)
		syslog(LOG_DEBUG, "ENTER dbfs_op_fsyncdir, ino==%lu", ino);

	/* DB should have already sync'd our data for us */
	fuse_reply_err(req, 0);
}

#define COPY(x) f.f_##x = st.f_##x
static void dbfs_op_statfs(fuse_req_t req, fuse_ino_t ino)
{
	struct statvfs f;
	struct statfs st;

	if (debugging)
		syslog(LOG_DEBUG, "ENTER dbfs_op_statfs");

	if (statfs(gfs->home, &st) < 0) {
		fuse_reply_err(req, errno);
		return;
	}

	memset(&f, 0, sizeof(f));
	COPY(bsize);
	f.f_frsize = 512;
	COPY(blocks);
	COPY(bfree);
	COPY(bavail);
	f.f_files = 0xfffffff;
	f.f_ffree = 0xffffff;
	f.f_favail = 0xffffff;
	f.f_fsid = 0xdeadbeef;
	f.f_flag = 0;
	f.f_namemax = DBFS_FILENAME_MAX;

	fuse_reply_statfs(req, &f);
}
#undef COPY

static void dbfs_op_setxattr(fuse_req_t req, fuse_ino_t ino,
			     const char *name, const char *value,
			     size_t size, int flags)
{
	int rc;
	DB_TXN *txn;

	if (debugging)
		syslog(LOG_DEBUG, "ENTER dbfs_op_setxattr, name=='%s'", name);

	rc = gfs->env->txn_begin(gfs->env, NULL, &txn, 0);
	if (rc) {
		rc = -rc;
		goto err_out;
	}

	rc = dbfs_xattr_set(txn, ino, name, value, size, flags);
	if (rc)
		goto err_out_txn;

	rc = txn->commit(txn, 0);
	if (rc) {
		rc = -rc;
		goto err_out;
	}

	fuse_reply_err(req, 0);
	return;

err_out_txn:
	txn->abort(txn);
err_out:
	fuse_reply_err(req, -rc);
	if (debugging)
		syslog(LOG_DEBUG, "EXIT dbfs_op_setxattr, rc==%d", -rc);
}

static void dbfs_op_getxattr(fuse_req_t req, fuse_ino_t ino,
			     const char *name, size_t size)
{
	void *buf = NULL;
	size_t buflen = 0;
	int rc;
	DB_TXN *txn;

	if (debugging)
		syslog(LOG_DEBUG, "ENTER dbfs_op_getxattr, name=='%s'", name);

	rc = gfs->env->txn_begin(gfs->env, NULL, &txn, 0);
	if (rc) {
		rc = -rc;
		goto err_out;
	}

	rc = dbfs_xattr_get(txn, ino, name, &buf, &buflen);
	if (rc)
		goto err_out_txn;

	rc = txn->commit(txn, 0);
	if (rc) {
		rc = -rc;
		goto err_out;
	}

	if (size == 0)
		fuse_reply_xattr(req, buflen);
	else if (buflen <= size)
		fuse_reply_buf(req, buf, buflen);
	else {
		rc = -ERANGE;
		goto err_out;
	}

	free(buf);
	return;

err_out_txn:
	txn->abort(txn);
err_out:
	fuse_reply_err(req, -rc);
	if (debugging)
		syslog(LOG_DEBUG, "EXIT dbfs_op_getxattr, rc==%d", -rc);
}

static void dbfs_op_listxattr(fuse_req_t req, fuse_ino_t ino, size_t size)
{
	int rc;
	void *buf;
	size_t buflen;
	DB_TXN *txn;

	if (debugging)
		syslog(LOG_DEBUG, "ENTER dbfs_op_listxattr, ino==%lu", ino);

	rc = gfs->env->txn_begin(gfs->env, NULL, &txn, 0);
	if (rc) {
		rc = -rc;
		goto err_out;
	}

	rc = dbfs_xattr_list(txn, ino, &buf, &buflen);
	if (rc < 0)
		goto err_out_txn;

	rc = txn->commit(txn, 0);
	if (rc) {
		rc = -rc;
		goto err_out;
	}

	if (size == 0)
		fuse_reply_xattr(req, buflen);
	else if (size < buflen)
		fuse_reply_err(req, ERANGE);
	else
		fuse_reply_buf(req, buf, buflen);

	free(buf);
	return;

err_out_txn:
	txn->abort(txn);
err_out:
	fuse_reply_err(req, -rc);
	if (debugging)
		syslog(LOG_DEBUG, "EXIT dbfs_op_listxattr, rc==%d", -rc);
}

static void dbfs_op_removexattr(fuse_req_t req, fuse_ino_t ino,
				const char *name)
{
	int rc;
	DB_TXN *txn;

	if (debugging)
		syslog(LOG_DEBUG, "ENTER dbfs_op_removexattr, ino==%lu, name=='%s'",
			ino, name);

	rc = gfs->env->txn_begin(gfs->env, NULL, &txn, 0);
	if (rc) {
		rc = -rc;
		goto err_out;
	}

	rc = dbfs_xattr_remove(txn, ino, name, TRUE);
	if (rc)
		goto err_out_txn;

	rc = txn->commit(txn, 0);
	if (rc) {
		rc = -rc;
		goto err_out;
	}

	fuse_reply_err(req, 0);
	return;

err_out_txn:
	txn->abort(txn);
err_out:
	fuse_reply_err(req, -rc);
	if (debugging)
		syslog(LOG_DEBUG, "EXIT dbfs_op_removexattr, rc==%d", -rc);
}

static void dbfs_op_access(fuse_req_t req, fuse_ino_t ino_n, int mask)
{
	struct dbfs_inode *ino;
	const struct fuse_ctx *ctx;
	int rc;
	guint32 mode, uid, gid;
	DB_TXN *txn;

	if (debugging)
		syslog(LOG_DEBUG, "ENTER dbfs_op_access, ino==%lu", ino_n);

	ctx = fuse_req_ctx(req);
	g_assert(ctx != NULL);

	rc = gfs->env->txn_begin(gfs->env, NULL, &txn, 0);
	if (rc) {
		rc = -rc;
		goto out;
	}

	rc = dbfs_inode_read(txn, ino_n, &ino);
	if (rc)
		goto out_txn;

	rc = txn->commit(txn, 0);
	if (rc) {
		dbfs_inode_free(ino);
		rc = -rc;
		goto out;
	}

	mode = GUINT32_FROM_LE(ino->raw_inode->mode);
	uid = GUINT32_FROM_LE(ino->raw_inode->uid);
	gid = GUINT32_FROM_LE(ino->raw_inode->gid);

	if (uid == ctx->uid)
		mode >>= 8;
	else if (gid == ctx->gid)
		mode >>= 4;

	rc = 0;
	if ((mask & R_OK) && (!(mode & S_IROTH)))
		rc = -EACCES;
	if ((mask & W_OK) && (!(mode & S_IWOTH)))
		rc = -EACCES;
	if ((mask & X_OK) && (!(mode & S_IXOTH)))
		rc = -EACCES;

	dbfs_inode_free(ino);

out:
	fuse_reply_err(req, -rc);
	if (debugging)
		syslog(LOG_DEBUG, "EXIT dbfs_op_access, rc==%d", -rc);
	return;

out_txn:
	txn->abort(txn);
	goto out;
}

static struct fuse_lowlevel_ops dbfs_ops = {
	.init		= dbfs_op_init,
	.destroy	= dbfs_op_destroy,
	.lookup		= dbfs_op_lookup,
	.forget		= NULL,
	.getattr	= dbfs_op_getattr,
	.setattr	= dbfs_op_setattr,
	.readlink	= dbfs_op_readlink,
	.mknod		= dbfs_op_mknod,
	.mkdir		= dbfs_op_mkdir,
	.unlink		= dbfs_op_unlink,
	.rmdir		= dbfs_op_rmdir,
	.symlink	= dbfs_op_symlink,
	.rename		= dbfs_op_rename,
	.link		= dbfs_op_link,
	.open		= dbfs_op_open,
	.read		= dbfs_op_read,
	.write		= dbfs_op_write,
	.flush		= NULL,
	.release	= NULL,
	.fsync		= dbfs_op_fsync,
	.opendir	= dbfs_op_opendir,
	.readdir	= dbfs_op_readdir,
	.releasedir	= dbfs_op_releasedir,
	.fsyncdir	= dbfs_op_fsyncdir,
	.statfs		= dbfs_op_statfs,
	.setxattr	= dbfs_op_setxattr,
	.getxattr	= dbfs_op_getxattr,
	.listxattr	= dbfs_op_listxattr,
	.removexattr	= dbfs_op_removexattr,
	.access		= dbfs_op_access,
	.create		= NULL,
};

/* stock main() from FUSE example */
int main(int argc, char *argv[])
{
	struct fuse_args args = FUSE_ARGS_INIT(argc, argv);
	struct fuse_chan *ch;
	char *mountpoint;
	int err = -1;

	openlog("dbfs", LOG_PID, LOG_LOCAL4);

	if (fuse_parse_cmdline(&args, &mountpoint, NULL, NULL) != -1 &&
	    (ch = fuse_mount(mountpoint, &args)) != NULL) {
		struct fuse_session *se;

		se = fuse_lowlevel_new(&args, &dbfs_ops,
				       sizeof(dbfs_ops), NULL);
		if (se != NULL) {
			if (fuse_set_signal_handlers(se) != -1) {
				fuse_session_add_chan(se, ch);
				err = fuse_session_loop(se);
				fuse_remove_signal_handlers(se);
				fuse_session_remove_chan(ch);
			}
			fuse_session_destroy(se);
		}
		fuse_unmount(mountpoint, ch);
	}
	fuse_opt_free_args(&args);

	return err ? 1 : 0;
}

