/*
 * fs/logfs/dir.c	- directory-related code
 *
 * As should be obvious for Linux kernel code, license is GPLv2
 *
 * Copyright (c) 2005-2008 Joern Engel <joern@logfs.org>
 */
#include "logfs.h"


/*
 * Atomic dir operations
 *
 * Directory operations are by default not atomic.  Dentries and Inodes are
 * created/removed/altered in seperate operations.  Therefore we need to do
 * a small amount of journaling.
 *
 * Create, link, mkdir, mknod and symlink all share the same function to do
 * the work: __logfs_create.  This function works in two atomic steps:
 * 1. allocate inode (remember in journal)
 * 2. allocate dentry (clear journal)
 *
 * As we can only get interrupted between the two, when the inode we just
 * created is simply stored in the anchor.  On next mount, if we were
 * interrupted, we delete the inode.  From a users point of view the
 * operation never happened.
 *
 * Unlink and rmdir also share the same function: unlink.  Again, this
 * function works in two atomic steps
 * 1. remove dentry (remember inode in journal)
 * 2. unlink inode (clear journal)
 *
 * And again, on the next mount, if we were interrupted, we delete the inode.
 * From a users point of view the operation succeeded.
 *
 * Rename is the real pain to deal with, harder than all the other methods
 * combined.  Depending on the circumstances we can run into three cases.
 * A "target rename" where the target dentry already existed, a "local
 * rename" where both parent directories are identical or a "cross-directory
 * rename" in the remaining case.
 *
 * Local rename is atomic, as the old dentry is simply rewritten with a new
 * name.
 *
 * Cross-directory rename works in two steps, similar to __logfs_create and
 * logfs_unlink:
 * 1. Write new dentry (remember old dentry in journal)
 * 2. Remove old dentry (clear journal)
 *
 * Here we remember a dentry instead of an inode.  On next mount, if we were
 * interrupted, we delete the dentry.  From a users point of view, the
 * operation succeeded.
 *
 * Target rename works in three atomic steps:
 * 1. Attach old inode to new dentry (remember old dentry and new inode)
 * 2. Remove old dentry (still remember the new inode)
 * 3. Remove victim inode
 *
 * Here we remember both an inode an a dentry.  If we get interrupted
 * between steps 1 and 2, we delete both the dentry and the inode.  If
 * we get interrupted between steps 2 and 3, we delete just the inode.
 * In either case, the remaining objects are deleted on next mount.  From
 * a users point of view, the operation succeeded.
 */

static int write_dir(struct inode *dir, struct logfs_disk_dentry *dd,
		loff_t pos)
{
	return logfs_inode_write(dir, dd, sizeof(*dd), pos, WF_LOCK, NULL);
}

static int write_inode(struct inode *inode)
{
	return __logfs_write_inode(inode, WF_LOCK);
}

static s64 dir_seek_data(struct inode *inode, s64 pos)
{
	s64 new_pos = logfs_seek_data(inode, pos);

	return max(pos, new_pos - 1);
}

static int beyond_eof(struct inode *inode, loff_t bix)
{
	loff_t pos = bix << inode->i_sb->s_blocksize_bits;
	return pos >= i_size_read(inode);
}

/*
 * Prime value was chosen to be roughly 256 + 26.  r5 hash uses 11,
 * so short names (len <= 9) don't even occupy the complete 32bit name
 * space.  A prime >256 ensures short names quickly spread the 32bit
 * name space.  Add about 26 for the estimated amount of information
 * of each character and pick a prime nearby, preferrably a bit-sparse
 * one.
 */
static u32 hash_32(const char *s, int len, u32 seed)
{
	u32 hash = seed;
	int i;

	for (i = 0; i < len; i++)
		hash = hash * 293 + s[i];
	return hash;
}

/*
 * We have to satisfy several conflicting requirements here.  Small
 * directories should stay fairly compact and not require too many
 * indirect blocks.  The number of possible locations for a given hash
 * should be small to make lookup() fast.  And we should try hard not
 * to overflow the 32bit name space or nfs and 32bit host systems will
 * be unhappy.
 *
 * So we use the following scheme.  First we reduce the hash to 0..15
 * and try a direct block.  If that is occupied we reduce the hash to
 * 16..255 and try an indirect block.  Same for 2x and 3x indirect
 * blocks.  Lastly we reduce the hash to 0x800_0000 .. 0xffff_ffff,
 * but use buckets containing eight entries instead of a single one.
 *
 * Using 16 entries should allow for a reasonable amount of hash
 * collisions, so the 32bit name space can be packed fairly tight
 * before overflowing.  Oh and currently we don't overflow but return
 * and error.
 *
 * How likely are collisions?  Doing the appropriate math is beyond me
 * and the Bronstein textbook.  But running a test program to brute
 * force collisions for a couple of days showed that on average the
 * first collision occurs after 598M entries, with 290M being the
 * smallest result.  Obviously 21 entries could already cause a
 * collision if all entries are carefully chosen.
 */
static pgoff_t hash_index(u32 hash, int round)
{
	u32 i0_blocks = I0_BLOCKS;
	u32 i1_blocks = I1_BLOCKS;
	u32 i2_blocks = I2_BLOCKS;
	u32 i3_blocks = I3_BLOCKS;

	switch (round) {
	case 0:
		return hash % i0_blocks;
	case 1:
		return i0_blocks + hash % (i1_blocks - i0_blocks);
	case 2:
		return i1_blocks + hash % (i2_blocks - i1_blocks);
	case 3:
		return i2_blocks + hash % (i3_blocks - i2_blocks);
	case 4 ... 19:
		return i3_blocks + 16 * (hash % (((1<<31) - i3_blocks) / 16))
			+ round - 4;
	}
	BUG();
}

static struct page *logfs_get_dd_page(struct inode *dir, struct dentry *dentry)
{
	struct qstr *name = &dentry->d_name;
	struct page *page;
	struct logfs_disk_dentry *dd;
	u32 hash = hash_32(name->name, name->len, 0);
	pgoff_t index;
	int round;

	if (name->len > LOGFS_MAX_NAMELEN)
		return ERR_PTR(-ENAMETOOLONG);

	for (round = 0; round < 20; round++) {
		index = hash_index(hash, round);

		if (beyond_eof(dir, index))
			return NULL;
		if (!logfs_exist_block(dir, index))
			continue;
		page = read_cache_page(dir->i_mapping, index,
				(filler_t *)logfs_readpage, NULL);
		if (IS_ERR(page))
			return page;
		dd = kmap_atomic(page, KM_USER0);
		BUG_ON(dd->namelen == 0);

		if (name->len != be16_to_cpu(dd->namelen) ||
				memcmp(name->name, dd->name, name->len)) {
			kunmap_atomic(dd, KM_USER0);
			page_cache_release(page);
			continue;
		}

		kunmap_atomic(dd, KM_USER0);
		return page;
	}
	return NULL;
}

static int logfs_remove_inode(struct inode *inode)
{
	int ret;

	inode->i_nlink--;
	ret = write_inode(inode);
	LOGFS_BUG_ON(ret, inode->i_sb);
	return ret;
}

static void abort_transaction(struct inode *inode, struct logfs_transaction *ta)
{
	if (logfs_inode(inode)->li_block)
		logfs_inode(inode)->li_block->ta = NULL;
	kfree(ta);
}

static int logfs_unlink(struct inode *dir, struct dentry *dentry)
{
	struct logfs_super *super = logfs_super(dir->i_sb);
	struct inode *inode = dentry->d_inode;
	struct logfs_transaction *ta;
	struct page *page;
	pgoff_t index;
	int ret;

	ta = kzalloc(sizeof(*ta), GFP_KERNEL);
	if (!ta)
		return -ENOMEM;

	ta->state = UNLINK_1;
	ta->ino = inode->i_ino;

	inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME;

	page = logfs_get_dd_page(dir, dentry);
	if (!page) {
		kfree(ta);
		return -ENOENT;
	}
	if (IS_ERR(page)) {
		kfree(ta);
		return PTR_ERR(page);
	}
	index = page->index;
	page_cache_release(page);

	mutex_lock(&super->s_dirop_mutex);
	logfs_add_transaction(dir, ta);

	ret = logfs_delete(dir, index, NULL);
	if (!ret)
		ret = write_inode(dir);

	if (ret) {
		abort_transaction(dir, ta);
		printk(KERN_ERR"LOGFS: unable to delete inode\n");
		goto out;
	}

	ta->state = UNLINK_2;
	logfs_add_transaction(inode, ta);
	ret = logfs_remove_inode(inode);
out:
	mutex_unlock(&super->s_dirop_mutex);
	return ret;
}

static inline int logfs_empty_dir(struct inode *dir)
{
	u64 data;

	data = logfs_seek_data(dir, 0) << dir->i_sb->s_blocksize_bits;
	return data >= i_size_read(dir);
}

static int logfs_rmdir(struct inode *dir, struct dentry *dentry)
{
	struct inode *inode = dentry->d_inode;

	if (!logfs_empty_dir(inode))
		return -ENOTEMPTY;

	return logfs_unlink(dir, dentry);
}

/* FIXME: readdir currently has it's own dir_walk code.  I don't see a good
 * way to combine the two copies */
#define IMPLICIT_NODES 2
static int __logfs_readdir(struct file *file, void *buf, filldir_t filldir)
{
	struct inode *dir = file->f_dentry->d_inode;
	loff_t pos = file->f_pos - IMPLICIT_NODES;
	struct page *page;
	struct logfs_disk_dentry *dd;
	int full;

	BUG_ON(pos < 0);
	for (;; pos++) {
		if (beyond_eof(dir, pos))
			break;
		if (!logfs_exist_block(dir, pos)) {
			/* deleted dentry */
			pos = dir_seek_data(dir, pos);
			continue;
		}
		page = read_cache_page(dir->i_mapping, pos,
				(filler_t *)logfs_readpage, NULL);
		if (IS_ERR(page))
			return PTR_ERR(page);
		dd = kmap_atomic(page, KM_USER0);
		BUG_ON(dd->namelen == 0);

		full = filldir(buf, (char *)dd->name, be16_to_cpu(dd->namelen),
				pos, be64_to_cpu(dd->ino), dd->type);
		kunmap_atomic(dd, KM_USER0);
		page_cache_release(page);
		if (full)
			break;
	}

	file->f_pos = pos + IMPLICIT_NODES;
	return 0;
}

static int logfs_readdir(struct file *file, void *buf, filldir_t filldir)
{
	struct inode *inode = file->f_dentry->d_inode;
	ino_t pino = parent_ino(file->f_dentry);
	int err;

	if (file->f_pos < 0)
		return -EINVAL;

	if (file->f_pos == 0) {
		if (filldir(buf, ".", 1, 1, inode->i_ino, DT_DIR) < 0)
			return 0;
		file->f_pos++;
	}
	if (file->f_pos == 1) {
		if (filldir(buf, "..", 2, 2, pino, DT_DIR) < 0)
			return 0;
		file->f_pos++;
	}

	err = __logfs_readdir(file, buf, filldir);
	return err;
}

static void logfs_set_name(struct logfs_disk_dentry *dd, struct qstr *name)
{
	dd->namelen = cpu_to_be16(name->len);
	memcpy(dd->name, name->name, name->len);
}

static struct dentry *logfs_lookup(struct inode *dir, struct dentry *dentry,
		struct nameidata *nd)
{
	struct page *page;
	struct logfs_disk_dentry *dd;
	pgoff_t index;
	u64 ino = 0;
	struct inode *inode;

	page = logfs_get_dd_page(dir, dentry);
	if (IS_ERR(page))
		return ERR_CAST(page);
	if (!page) {
		d_add(dentry, NULL);
		return NULL;
	}
	index = page->index;
	dd = kmap_atomic(page, KM_USER0);
	ino = be64_to_cpu(dd->ino);
	kunmap_atomic(dd, KM_USER0);
	page_cache_release(page);

	inode = logfs_iget(dir->i_sb, ino);
	if (IS_ERR(inode)) {
		printk(KERN_ERR"LogFS: Cannot read inode #%llx for dentry (%lx, %lx)n",
				ino, dir->i_ino, index);
		return ERR_CAST(inode);
	}
	return d_splice_alias(inode, dentry);
}

static void grow_dir(struct inode *dir, loff_t index)
{
	index = (index + 1) << dir->i_sb->s_blocksize_bits;
	if (i_size_read(dir) < index)
		i_size_write(dir, index);
}

static int logfs_write_dir(struct inode *dir, struct dentry *dentry,
		struct inode *inode)
{
	struct page *page;
	struct logfs_disk_dentry *dd;
	u32 hash = hash_32(dentry->d_name.name, dentry->d_name.len, 0);
	pgoff_t index;
	int round, err;

	for (round = 0; round < 20; round++) {
		index = hash_index(hash, round);

		if (logfs_exist_block(dir, index))
			continue;
		page = find_or_create_page(dir->i_mapping, index, GFP_KERNEL);
		if (!page)
			return -ENOMEM;

		dd = kmap_atomic(page, KM_USER0);
		memset(dd, 0, sizeof(*dd));
		dd->ino = cpu_to_be64(inode->i_ino);
		dd->type = logfs_type(inode);
		logfs_set_name(dd, &dentry->d_name);
		kunmap_atomic(dd, KM_USER0);

		err = logfs_write_buf(dir, page, WF_LOCK);
		unlock_page(page);
		page_cache_release(page);
		if (!err)
			grow_dir(dir, index);
		return err;
	}
	/* FIXME: Is there a better return value?  In most cases neither
	 * the filesystem nor the directory are full.  But we have had
	 * too many collisions for this particular hash and no fallback.
	 */
	return -ENOSPC;
}

static int __logfs_create(struct inode *dir, struct dentry *dentry,
		struct inode *inode, const char *dest, long destlen)
{
	struct logfs_super *super = logfs_super(dir->i_sb);
	struct logfs_inode *li = logfs_inode(inode);
	struct logfs_transaction *ta;
	int ret;

	ta = kzalloc(sizeof(*ta), GFP_KERNEL);
	if (!ta)
		return -ENOMEM;

	ta->state = CREATE_1;
	ta->ino = inode->i_ino;
	mutex_lock(&super->s_dirop_mutex);
	logfs_add_transaction(inode, ta);

	if (dest) {
		/* symlink */
		ret = logfs_inode_write(inode, dest, destlen, 0, WF_LOCK, NULL);
		if (!ret)
			ret = write_inode(inode);
	} else {
		/* creat/mkdir/mknod */
		ret = write_inode(inode);
	}
	if (ret) {
		abort_transaction(inode, ta);
		li->li_flags |= LOGFS_IF_STILLBORN;
		/* FIXME: truncate symlink */
		inode->i_nlink--;
		iput(inode);
		goto out;
	}

	ta->state = CREATE_2;
	logfs_add_transaction(dir, ta);
	ret = logfs_write_dir(dir, dentry, inode);
	/* sync directory */
	if (!ret)
		ret = write_inode(dir);

	if (ret) {
		logfs_del_transaction(dir, ta);
		ta->state = CREATE_2;
		logfs_add_transaction(inode, ta);
		logfs_remove_inode(inode);
		iput(inode);
		goto out;
	}
	d_instantiate(dentry, inode);
out:
	mutex_unlock(&super->s_dirop_mutex);
	return ret;
}

static int logfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
{
	struct inode *inode;

	/*
	 * FIXME: why do we have to fill in S_IFDIR, while the mode is
	 * correct for mknod, creat, etc.?  Smells like the vfs *should*
	 * do it for us but for some reason fails to do so.
	 */
	inode = logfs_new_inode(dir, S_IFDIR | mode);
	if (IS_ERR(inode))
		return PTR_ERR(inode);

	inode->i_op = &logfs_dir_iops;
	inode->i_fop = &logfs_dir_fops;

	return __logfs_create(dir, dentry, inode, NULL, 0);
}

static int logfs_create(struct inode *dir, struct dentry *dentry, int mode,
		struct nameidata *nd)
{
	struct inode *inode;

	inode = logfs_new_inode(dir, mode);
	if (IS_ERR(inode))
		return PTR_ERR(inode);

	inode->i_op = &logfs_reg_iops;
	inode->i_fop = &logfs_reg_fops;
	inode->i_mapping->a_ops = &logfs_reg_aops;

	return __logfs_create(dir, dentry, inode, NULL, 0);
}

static int logfs_mknod(struct inode *dir, struct dentry *dentry, int mode,
		dev_t rdev)
{
	struct inode *inode;

	if (dentry->d_name.len > LOGFS_MAX_NAMELEN)
		return -ENAMETOOLONG;

	inode = logfs_new_inode(dir, mode);
	if (IS_ERR(inode))
		return PTR_ERR(inode);

	init_special_inode(inode, mode, rdev);

	return __logfs_create(dir, dentry, inode, NULL, 0);
}

static int logfs_symlink(struct inode *dir, struct dentry *dentry,
		const char *target)
{
	struct inode *inode;
	size_t destlen = strlen(target) + 1;

	if (destlen > dir->i_sb->s_blocksize)
		return -ENAMETOOLONG;

	inode = logfs_new_inode(dir, S_IFLNK | 0777);
	if (IS_ERR(inode))
		return PTR_ERR(inode);

	inode->i_op = &logfs_symlink_iops;
	inode->i_mapping->a_ops = &logfs_reg_aops;

	return __logfs_create(dir, dentry, inode, target, destlen);
}

static int logfs_permission(struct inode *inode, int mask)
{
	return generic_permission(inode, mask, NULL);
}

static int logfs_link(struct dentry *old_dentry, struct inode *dir,
		struct dentry *dentry)
{
	struct inode *inode = old_dentry->d_inode;

	if (inode->i_nlink >= LOGFS_LINK_MAX)
		return -EMLINK;

	inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME;
	atomic_inc(&inode->i_count);
	inode->i_nlink++;
	mark_inode_dirty_sync(inode);

	return __logfs_create(dir, dentry, inode, NULL, 0);
}

static int logfs_get_dd(struct inode *dir, struct dentry *dentry,
		struct logfs_disk_dentry *dd, loff_t *pos)
{
	struct page *page;
	void *map;

	page = logfs_get_dd_page(dir, dentry);
	if (IS_ERR(page))
		return PTR_ERR(page);
	*pos = page->index;
	map = kmap_atomic(page, KM_USER0);
	memcpy(dd, map, sizeof(*dd));
	kunmap_atomic(map, KM_USER0);
	page_cache_release(page);
	return 0;
}

static int logfs_delete_dd(struct inode *dir, loff_t pos)
{
	/*
	 * Getting called with pos somewhere beyond eof is either a goofup
	 * within this file or means someone maliciously edited the
	 * (crc-protected) journal.
	 */
	BUG_ON(beyond_eof(dir, pos));
	dir->i_ctime = dir->i_mtime = CURRENT_TIME;
	log_dir(" Delete dentry (%lx, %llx)\n", dir->i_ino, pos);
	return logfs_delete(dir, pos, NULL);
}

/*
 * Cross-directory rename, target does not exist.  Just a little nasty.
 * Create a new dentry in the target dir, then remove the old dentry,
 * all the while taking care to remember our operation in the journal.
 */
static int logfs_rename_cross(struct inode *old_dir, struct dentry *old_dentry,
			      struct inode *new_dir, struct dentry *new_dentry)
{
	struct logfs_super *super = logfs_super(old_dir->i_sb);
	struct logfs_disk_dentry dd;
	struct logfs_transaction *ta;
	loff_t pos;
	int err;

	/* 1. locate source dd */
	err = logfs_get_dd(old_dir, old_dentry, &dd, &pos);
	if (err)
		return err;

	ta = kzalloc(sizeof(*ta), GFP_KERNEL);
	if (!ta)
		return -ENOMEM;

	ta->state = CROSS_RENAME_1;
	ta->dir = old_dir->i_ino;
	ta->pos = pos;

	/* 2. write target dd */
	mutex_lock(&super->s_dirop_mutex);
	logfs_add_transaction(new_dir, ta);
	err = logfs_write_dir(new_dir, new_dentry, old_dentry->d_inode);
	if (!err)
		err = write_inode(new_dir);

	if (err) {
		super->s_rename_dir = 0;
		super->s_rename_pos = 0;
		abort_transaction(new_dir, ta);
		goto out;
	}

	/* 3. remove source dd */
	ta->state = CROSS_RENAME_2;
	logfs_add_transaction(old_dir, ta);
	err = logfs_delete_dd(old_dir, pos);
	if (!err)
		err = write_inode(old_dir);
	LOGFS_BUG_ON(err, old_dir->i_sb);
out:
	mutex_unlock(&super->s_dirop_mutex);
	return err;
}

static int logfs_replace_inode(struct inode *dir, struct dentry *dentry,
		struct logfs_disk_dentry *dd, struct inode *inode)
{
	loff_t pos;
	int err;

	err = logfs_get_dd(dir, dentry, dd, &pos);
	if (err)
		return err;
	dd->ino = cpu_to_be64(inode->i_ino);
	dd->type = logfs_type(inode);

	err = write_dir(dir, dd, pos);
	if (err)
		return err;
	log_dir("Replace dentry (%lx, %llx) %s -> %llx\n", dir->i_ino, pos,
			dd->name, be64_to_cpu(dd->ino));
	return write_inode(dir);
}

/* Target dentry exists - the worst case.  We need to attach the source
 * inode to the target dentry, then remove the orphaned target inode and
 * source dentry.
 */
static int logfs_rename_target(struct inode *old_dir, struct dentry *old_dentry,
			       struct inode *new_dir, struct dentry *new_dentry)
{
	struct logfs_super *super = logfs_super(old_dir->i_sb);
	struct inode *old_inode = old_dentry->d_inode;
	struct inode *new_inode = new_dentry->d_inode;
	int isdir = S_ISDIR(old_inode->i_mode);
	struct logfs_disk_dentry dd;
	struct logfs_transaction *ta;
	loff_t pos;
	int err;

	BUG_ON(isdir != S_ISDIR(new_inode->i_mode));
	if (isdir) {
		if (!logfs_empty_dir(new_inode))
			return -ENOTEMPTY;
	}

	/* 1. locate source dd */
	err = logfs_get_dd(old_dir, old_dentry, &dd, &pos);
	if (err)
		return err;

	ta = kzalloc(sizeof(*ta), GFP_KERNEL);
	if (!ta)
		return -ENOMEM;

	ta->state = TARGET_RENAME_1;
	ta->dir = old_dir->i_ino;
	ta->pos = pos;
	ta->ino = new_inode->i_ino;

	/* 2. attach source inode to target dd */
	mutex_lock(&super->s_dirop_mutex);
	logfs_add_transaction(new_dir, ta);
	err = logfs_replace_inode(new_dir, new_dentry, &dd, old_inode);
	if (err) {
		super->s_rename_dir = 0;
		super->s_rename_pos = 0;
		super->s_victim_ino = 0;
		abort_transaction(new_dir, ta);
		goto out;
	}

	/* 3. remove source dd */
	ta->state = TARGET_RENAME_2;
	logfs_add_transaction(old_dir, ta);
	err = logfs_delete_dd(old_dir, pos);
	if (!err)
		err = write_inode(old_dir);
	LOGFS_BUG_ON(err, old_dir->i_sb);

	/* 4. remove target inode */
	ta->state = TARGET_RENAME_3;
	logfs_add_transaction(new_inode, ta);
	err = logfs_remove_inode(new_inode);

out:
	mutex_unlock(&super->s_dirop_mutex);
	return err;
}

static int logfs_rename(struct inode *old_dir, struct dentry *old_dentry,
			struct inode *new_dir, struct dentry *new_dentry)
{
	if (new_dentry->d_inode)
		return logfs_rename_target(old_dir, old_dentry,
					   new_dir, new_dentry);
	return logfs_rename_cross(old_dir, old_dentry, new_dir, new_dentry);
}

/* No locking done here, as this is called before .get_sb() returns. */
int logfs_replay_journal(struct super_block *sb)
{
	struct logfs_super *super = logfs_super(sb);
	struct inode *inode;
	u64 ino, pos;
	int err;

	if (super->s_victim_ino) {
		/* delete victim inode */
		ino = super->s_victim_ino;
		printk(KERN_INFO"LogFS: delete unmapped inode #%llx\n", ino);
		inode = logfs_iget(sb, ino);
		if (IS_ERR(inode))
			goto fail;

		LOGFS_BUG_ON(i_size_read(inode) > 0, sb);
		super->s_victim_ino = 0;
		err = logfs_remove_inode(inode);
		iput(inode);
		if (err) {
			super->s_victim_ino = ino;
			goto fail;
		}
	}
	if (super->s_rename_dir) {
		/* delete old dd from rename */
		ino = super->s_rename_dir;
		pos = super->s_rename_pos;
		printk(KERN_INFO"LogFS: delete unbacked dentry (%llx, %llx)\n",
				ino, pos);
		inode = logfs_iget(sb, ino);
		if (IS_ERR(inode))
			goto fail;

		super->s_rename_dir = 0;
		super->s_rename_pos = 0;
		err = logfs_delete_dd(inode, pos);
		iput(inode);
		if (err) {
			super->s_rename_dir = ino;
			super->s_rename_pos = pos;
			goto fail;
		}
	}
	return 0;
fail:
	LOGFS_BUG(sb);
	return -EIO;
}

const struct inode_operations logfs_symlink_iops = {
	.readlink	= generic_readlink,
	.follow_link	= page_follow_link_light,
};

const struct inode_operations logfs_dir_iops = {
	.create		= logfs_create,
	.link		= logfs_link,
	.lookup		= logfs_lookup,
	.mkdir		= logfs_mkdir,
	.mknod		= logfs_mknod,
	.rename		= logfs_rename,
	.rmdir		= logfs_rmdir,
	.permission	= logfs_permission,
	.symlink	= logfs_symlink,
	.unlink		= logfs_unlink,
};
const struct file_operations logfs_dir_fops = {
	.fsync		= logfs_fsync,
	.ioctl		= logfs_ioctl,
	.readdir	= logfs_readdir,
	.read		= generic_read_dir,
};
