/* -*- mode: c; c-basic-offset: 8; -*-
 * vim: noexpandtab sw=8 ts=8 sts=0:
 *
 * inode.c
 *
 * vfs' aops, fops, dops and iops
 *
 * Copyright (C) 2002, 2004 Oracle.  All rights reserved.
 *
 * 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; either
 * version 2 of the License, or (at your option) any later version.
 *
 * 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; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 021110-1307, USA.
 */

#include <linux/fs.h>
#include <linux/types.h>
#include <linux/slab.h>
#include <linux/highmem.h>
#include <linux/pagemap.h>
#include <linux/smp_lock.h>

#include <asm/byteorder.h>

#define MLOG_MASK_PREFIX ML_INODE
#include <cluster/masklog.h>

#include "ocfs2.h"

#include "alloc.h"
#include "dlmglue.h"
#include "extent_map.h"
#include "file.h"
#include "inode.h"
#include "journal.h"
#include "namei.h"
#include "suballoc.h"
#include "super.h"
#include "symlink.h"
#include "sysfile.h"
#include "uptodate.h"
#include "vote.h"

#include "buffer_head_io.h"

#define OCFS2_FI_FLAG_NOWAIT	0x1
#define OCFS2_FI_FLAG_DELETE	0x2
struct ocfs2_find_inode_args
{
	u64		fi_blkno;
	unsigned long	fi_ino;
	unsigned int	fi_flags;
};

static int ocfs2_read_locked_inode(struct inode *inode,
				   struct ocfs2_find_inode_args *args);
static int ocfs2_init_locked_inode(struct inode *inode, void *opaque);
static int ocfs2_find_actor(struct inode *inode, void *opaque);
static int ocfs2_truncate_for_delete(struct ocfs2_super *osb,
				    struct inode *inode,
				    struct buffer_head *fe_bh);

struct inode *ocfs2_ilookup_for_vote(struct ocfs2_super *osb,
				     u64 blkno,
				     int delete_vote)
{
	struct ocfs2_find_inode_args args;

	/* ocfs2_ilookup_for_vote should *only* be called from the
	 * vote thread */
	BUG_ON(current != osb->vote_task);

	args.fi_blkno = blkno;
	args.fi_flags = OCFS2_FI_FLAG_NOWAIT;
	if (delete_vote)
		args.fi_flags |= OCFS2_FI_FLAG_DELETE;
	args.fi_ino = ino_from_blkno(osb->sb, blkno);
	return ilookup5(osb->sb, args.fi_ino, ocfs2_find_actor, &args);
}

struct inode *ocfs2_iget(struct ocfs2_super *osb, u64 blkno)
{
	struct inode *inode = NULL;
	struct super_block *sb = osb->sb;
	struct ocfs2_find_inode_args args;

	mlog_entry("(blkno = %"MLFu64")\n", blkno);

	/* Ok. By now we've either got the offsets passed to us by the
	 * caller, or we just pulled them off the bh. Lets do some
	 * sanity checks to make sure they're OK. */
	if (blkno == 0) {
		inode = ERR_PTR(-EINVAL);
		mlog_errno(PTR_ERR(inode));
		goto bail;
	}

	args.fi_blkno = blkno;
	args.fi_flags = 0;
	args.fi_ino = ino_from_blkno(sb, blkno);

	inode = iget5_locked(sb, args.fi_ino, ocfs2_find_actor,
			     ocfs2_init_locked_inode, &args);
	/* inode was *not* in the inode cache. 2.6.x requires
	 * us to do our own read_inode call and unlock it
	 * afterwards. */
	if (inode && inode->i_state & I_NEW) {
		mlog(0, "Inode was not in inode cache, reading it.\n");
		ocfs2_read_locked_inode(inode, &args);
		unlock_new_inode(inode);
	}
	if (inode == NULL) {
		inode = ERR_PTR(-ENOMEM);
		mlog_errno(PTR_ERR(inode));
		goto bail;
	}
	if (is_bad_inode(inode)) {
		iput(inode);
		inode = ERR_PTR(-ESTALE);
		mlog_errno(PTR_ERR(inode));
		goto bail;
	}

bail:
	if (!IS_ERR(inode)) {
		mlog(0, "returning inode with number %"MLFu64"\n",
		     OCFS2_I(inode)->ip_blkno);
		mlog_exit_ptr(inode);
	} else
		mlog_errno(PTR_ERR(inode));

	return inode;
}


/*
 * here's how inodes get read from disk:
 * iget5_locked -> find_actor -> OCFS2_FIND_ACTOR
 * found? : return the in-memory inode
 * not found? : get_new_inode -> OCFS2_INIT_LOCKED_INODE
 */

static int ocfs2_find_actor(struct inode *inode, void *opaque)
{
	struct ocfs2_find_inode_args *args = NULL;
	struct ocfs2_inode_info *oi = OCFS2_I(inode);
	int ret = 0;

	mlog_entry("(0x%p, %lu, 0x%p)\n", inode, inode->i_ino, opaque);

	args = opaque;

	mlog_bug_on_msg(!inode, "No inode in find actor!\n");

	if (oi->ip_blkno != args->fi_blkno)
		goto bail;

	/* OCFS2_FI_FLAG_NOWAIT is *only* set from
	 * ocfs2_ilookup_for_vote which won't create an inode for one
	 * that isn't found. The vote thread which doesn't want to get
	 * an inode which is in the process of going away - otherwise
	 * the call to __wait_on_freeing_inode in find_inode_fast will
	 * cause it to deadlock on an inode which may be waiting on a
	 * vote (or lock release) in delete_inode */
	if ((args->fi_flags & OCFS2_FI_FLAG_NOWAIT) &&
	    (inode->i_state & (I_FREEING|I_CLEAR))) {
		/* As stated above, we're not going to return an
		 * inode.  In the case of a delete vote, the voting
		 * code is going to signal the other node to go
		 * ahead. Mark that state here, so this freeing inode
		 * has the state when it gets to delete_inode. */
		if (args->fi_flags & OCFS2_FI_FLAG_DELETE) {
			spin_lock(&oi->ip_lock);
			ocfs2_mark_inode_remotely_deleted(inode);
			spin_unlock(&oi->ip_lock);
		}
		goto bail;
	}

	ret = 1;
bail:
	mlog_exit(ret);
	return ret;
}

/*
 * initialize the new inode, but don't do anything that would cause
 * us to sleep.
 * return 0 on success, 1 on failure
 */
static int ocfs2_init_locked_inode(struct inode *inode, void *opaque)
{
	struct ocfs2_find_inode_args *args = opaque;

	mlog_entry("inode = %p, opaque = %p\n", inode, opaque);

	inode->i_ino = args->fi_ino;
	OCFS2_I(inode)->ip_blkno = args->fi_blkno;

	mlog_exit(0);
	return 0;
}

int ocfs2_populate_inode(struct inode *inode, struct ocfs2_dinode *fe,
		     	 int create_ino)
{
	struct super_block *sb;
	struct ocfs2_super *osb;
	int status = -EINVAL;

	mlog_entry("(0x%p, size:%"MLFu64")\n", inode, fe->i_size);

	sb = inode->i_sb;
	osb = OCFS2_SB(sb);

	/* this means that read_inode cannot create a superblock inode
	 * today.  change if needed. */
	if (!OCFS2_IS_VALID_DINODE(fe) ||
	    !(fe->i_flags & cpu_to_le32(OCFS2_VALID_FL))) {
		mlog(ML_ERROR, "Invalid dinode: i_ino=%lu, i_blkno=%"MLFu64", "
		     "signature = %.*s, flags = 0x%x\n",
		     inode->i_ino, le64_to_cpu(fe->i_blkno), 7,
		     fe->i_signature, le32_to_cpu(fe->i_flags));
		goto bail;
	}

	if (le32_to_cpu(fe->i_fs_generation) != osb->fs_generation) {
		mlog(ML_ERROR, "file entry generation does not match "
		     "superblock! osb->fs_generation=%x, "
		     "fe->i_fs_generation=%x\n",
		     osb->fs_generation, le32_to_cpu(fe->i_fs_generation));
		goto bail;
	}

	inode->i_version = 1;
	inode->i_generation = le32_to_cpu(fe->i_generation);
	inode->i_rdev = huge_decode_dev(le64_to_cpu(fe->id1.dev1.i_rdev));
	inode->i_mode = le16_to_cpu(fe->i_mode);
	inode->i_uid = le32_to_cpu(fe->i_uid);
	inode->i_gid = le32_to_cpu(fe->i_gid);
	inode->i_blksize = (u32)osb->s_clustersize;

	/* Fast symlinks will have i_size but no allocated clusters. */
	if (S_ISLNK(inode->i_mode) && !fe->i_clusters)
		inode->i_blocks = 0;
	else
		inode->i_blocks =
			ocfs2_align_bytes_to_sectors(le64_to_cpu(fe->i_size));
	inode->i_mapping->a_ops = &ocfs2_aops;
	inode->i_flags |= S_NOATIME;
	inode->i_atime.tv_sec = le64_to_cpu(fe->i_atime);
	inode->i_atime.tv_nsec = le32_to_cpu(fe->i_atime_nsec);
	inode->i_mtime.tv_sec = le64_to_cpu(fe->i_mtime);
	inode->i_mtime.tv_nsec = le32_to_cpu(fe->i_mtime_nsec);
	inode->i_ctime.tv_sec = le64_to_cpu(fe->i_ctime);
	inode->i_ctime.tv_nsec = le32_to_cpu(fe->i_ctime_nsec);

	if (OCFS2_I(inode)->ip_blkno != le64_to_cpu(fe->i_blkno))
		mlog(ML_ERROR,
		     "ip_blkno %"MLFu64" != i_blkno %"MLFu64"!\n",
		     OCFS2_I(inode)->ip_blkno, fe->i_blkno);

	OCFS2_I(inode)->ip_clusters = le32_to_cpu(fe->i_clusters);
	OCFS2_I(inode)->ip_orphaned_slot = OCFS2_INVALID_SLOT;

	if (create_ino)
		inode->i_ino = ino_from_blkno(inode->i_sb,
			       le64_to_cpu(fe->i_blkno));

	mlog(0, "blkno = %"MLFu64", ino = %lu, create_ino = %s\n",
	     fe->i_blkno, inode->i_ino, create_ino ? "true" : "false");

	inode->i_nlink = le16_to_cpu(fe->i_links_count);

	if (fe->i_flags & cpu_to_le32(OCFS2_LOCAL_ALLOC_FL)) {
		OCFS2_I(inode)->ip_flags |= OCFS2_INODE_BITMAP;
		mlog(0, "local alloc inode: i_ino=%lu\n", inode->i_ino);
	} else if (fe->i_flags & cpu_to_le32(OCFS2_BITMAP_FL)) {
		OCFS2_I(inode)->ip_flags |= OCFS2_INODE_BITMAP;
	} else if (fe->i_flags & cpu_to_le32(OCFS2_SUPER_BLOCK_FL)) {
		mlog(0, "superblock inode: i_ino=%lu\n", inode->i_ino);
		/* we can't actually hit this as read_inode can't
		 * handle superblocks today ;-) */
		BUG();
	}

	switch (inode->i_mode & S_IFMT) {
	    case S_IFREG:
		    inode->i_fop = &ocfs2_fops;
		    inode->i_op = &ocfs2_file_iops;
		    i_size_write(inode, le64_to_cpu(fe->i_size));
		    break;
	    case S_IFDIR:
		    inode->i_op = &ocfs2_dir_iops;
		    inode->i_fop = &ocfs2_dops;
		    i_size_write(inode, le64_to_cpu(fe->i_size));
		    break;
	    case S_IFLNK:
		    if (ocfs2_inode_is_fast_symlink(inode))
			inode->i_op = &ocfs2_fast_symlink_inode_operations;
		    else
			inode->i_op = &ocfs2_symlink_inode_operations;
		    i_size_write(inode, le64_to_cpu(fe->i_size));
		    break;
	    default:
		    inode->i_op = &ocfs2_special_file_iops;
		    init_special_inode(inode, inode->i_mode,
				       inode->i_rdev);
		    break;
	}

	ocfs2_inode_lock_res_init(&OCFS2_I(inode)->ip_rw_lockres,
				  OCFS2_LOCK_TYPE_RW, inode);
	ocfs2_inode_lock_res_init(&OCFS2_I(inode)->ip_meta_lockres,
				  OCFS2_LOCK_TYPE_META, inode);
	ocfs2_inode_lock_res_init(&OCFS2_I(inode)->ip_data_lockres,
				  OCFS2_LOCK_TYPE_DATA, inode);

	status = 0;
bail:
	mlog_exit(status);
	return status;
}

static int ocfs2_read_locked_inode(struct inode *inode,
				   struct ocfs2_find_inode_args *args)
{
	struct super_block *sb;
	struct ocfs2_super *osb;
	struct ocfs2_dinode *fe;
	struct buffer_head *bh = NULL;
	int status;
	int sysfile = 0;

	mlog_entry("(0x%p, 0x%p)\n", inode, args);

	status = -EINVAL;
	if (inode == NULL || inode->i_sb == NULL) {
		mlog(ML_ERROR, "bad inode\n");
		goto bail;
	}
	sb = inode->i_sb;
	osb = OCFS2_SB(sb);

	if (!args) {
		mlog(ML_ERROR, "bad inode args\n");
		make_bad_inode(inode);
		goto bail;
	}

	/* Read the FE off disk. This is safe because the kernel only
	 * does one read_inode2 for a new inode, and if it doesn't
	 * exist yet then nobody can be working on it! */
	status = ocfs2_read_block(osb, args->fi_blkno, &bh, 0, NULL);
	if (status < 0) {
		mlog_errno(status);
		make_bad_inode(inode);
		goto bail;
	}

	fe = (struct ocfs2_dinode *) bh->b_data;
	if (!OCFS2_IS_VALID_DINODE(fe)) {
		mlog(ML_ERROR, "Invalid dinode #%"MLFu64": signature = %.*s\n",
		     fe->i_blkno, 7, fe->i_signature);
		make_bad_inode(inode);
		goto bail;
	}

	if (fe->i_flags & cpu_to_le32(OCFS2_SYSTEM_FL))
		sysfile = 1;

	if (S_ISCHR(le16_to_cpu(fe->i_mode)) ||
	    S_ISBLK(le16_to_cpu(fe->i_mode)))
    		inode->i_rdev = huge_decode_dev(le64_to_cpu(fe->id1.dev1.i_rdev));

	status = -EINVAL;
	if (ocfs2_populate_inode(inode, fe, 0) < 0) {
		mlog(ML_ERROR, "populate inode failed! i_blkno=%"MLFu64", "
		     "i_ino=%lu\n", fe->i_blkno, inode->i_ino);
		make_bad_inode(inode);
		goto bail;
	}

	BUG_ON(args->fi_blkno != le64_to_cpu(fe->i_blkno));

	if (sysfile)
	       OCFS2_I(inode)->ip_flags |= OCFS2_INODE_SYSTEM_FILE;

	status = 0;

bail:
	if (args && bh)
		brelse(bh);

	mlog_exit(status);
	return status;
}

void ocfs2_sync_blockdev(struct super_block *sb)
{
	sync_blockdev(sb->s_bdev);
}

static int ocfs2_truncate_for_delete(struct ocfs2_super *osb,
				     struct inode *inode,
				     struct buffer_head *fe_bh)
{
	int status = 0;
	struct ocfs2_journal_handle *handle = NULL;
	struct ocfs2_truncate_context *tc = NULL;
	struct ocfs2_dinode *fe;

	mlog_entry_void();

	fe = (struct ocfs2_dinode *) fe_bh->b_data;

	/* zero allocation, zero truncate :) */
	if (!fe->i_clusters)
		goto bail;

	handle = ocfs2_start_trans(osb, handle, OCFS2_INODE_UPDATE_CREDITS);
	if (IS_ERR(handle)) {
		status = PTR_ERR(handle);
		handle = NULL;
		mlog_errno(status);
		goto bail;
	}

	status = ocfs2_set_inode_size(handle, inode, fe_bh, 0ULL);
	if (status < 0) {
		mlog_errno(status);
		goto bail;
	}

	ocfs2_commit_trans(handle);
	handle = NULL;

	status = ocfs2_prepare_truncate(osb, inode, fe_bh, &tc);
	if (status < 0) {
		mlog_errno(status);
		goto bail;
	}

	status = ocfs2_commit_truncate(osb, inode, fe_bh, tc);
	if (status < 0) {
		mlog_errno(status);
		goto bail;
	}
bail:
	if (handle)
		ocfs2_commit_trans(handle);

	mlog_exit(status);
	return status;
}

static int ocfs2_remove_inode(struct inode *inode,
			      struct buffer_head *di_bh,
			      struct inode *orphan_dir_inode,
			      struct buffer_head *orphan_dir_bh)
{
	int status;
	struct inode *inode_alloc_inode = NULL;
	struct buffer_head *inode_alloc_bh = NULL;
	struct ocfs2_journal_handle *handle;
	struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
	struct ocfs2_dinode *di = (struct ocfs2_dinode *) di_bh->b_data;

	inode_alloc_inode =
		ocfs2_get_system_file_inode(osb, INODE_ALLOC_SYSTEM_INODE,
					    le16_to_cpu(di->i_suballoc_slot));
	if (!inode_alloc_inode) {
		status = -EEXIST;
		mlog_errno(status);
		goto bail;
	}

	mutex_lock(&inode_alloc_inode->i_mutex);
	status = ocfs2_meta_lock(inode_alloc_inode, NULL, &inode_alloc_bh, 1);
	if (status < 0) {
		mutex_unlock(&inode_alloc_inode->i_mutex);

		mlog_errno(status);
		goto bail;
	}

	handle = ocfs2_start_trans(osb, NULL, OCFS2_DELETE_INODE_CREDITS);
	if (IS_ERR(handle)) {
		status = PTR_ERR(handle);
		mlog_errno(status);
		goto bail_unlock;
	}

	status = ocfs2_orphan_del(osb, handle, orphan_dir_inode, inode,
				  orphan_dir_bh);
	if (status < 0) {
		mlog_errno(status);
		goto bail_commit;
	}

	/* set the inodes dtime */
	status = ocfs2_journal_access(handle, inode, di_bh,
				      OCFS2_JOURNAL_ACCESS_WRITE);
	if (status < 0) {
		mlog_errno(status);
		goto bail_commit;
	}

	di->i_dtime = cpu_to_le64(CURRENT_TIME.tv_sec);
	le32_and_cpu(&di->i_flags, ~(OCFS2_VALID_FL | OCFS2_ORPHANED_FL));

	status = ocfs2_journal_dirty(handle, di_bh);
	if (status < 0) {
		mlog_errno(status);
		goto bail_commit;
	}

	ocfs2_remove_from_cache(inode, di_bh);

	status = ocfs2_free_dinode(handle, inode_alloc_inode,
				   inode_alloc_bh, di);
	if (status < 0)
		mlog_errno(status);

bail_commit:
	ocfs2_commit_trans(handle);
bail_unlock:
	ocfs2_meta_unlock(inode_alloc_inode, 1);
	mutex_unlock(&inode_alloc_inode->i_mutex);
	brelse(inode_alloc_bh);
bail:
	iput(inode_alloc_inode);

	return status;
}

static int ocfs2_wipe_inode(struct inode *inode,
			    struct buffer_head *di_bh)
{
	int status, orphaned_slot;
	struct inode *orphan_dir_inode = NULL;
	struct buffer_head *orphan_dir_bh = NULL;
	struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);

	/* We've already voted on this so it should be readonly - no
	 * spinlock needed. */
	orphaned_slot = OCFS2_I(inode)->ip_orphaned_slot;
	orphan_dir_inode = ocfs2_get_system_file_inode(osb,
						       ORPHAN_DIR_SYSTEM_INODE,
						       orphaned_slot);
	if (!orphan_dir_inode) {
		status = -EEXIST;
		mlog_errno(status);
		goto bail;
	}

	/* Lock the orphan dir. The lock will be held for the entire
	 * delete_inode operation. We do this now to avoid races with
	 * recovery completion on other nodes. */
	mutex_lock(&orphan_dir_inode->i_mutex);
	status = ocfs2_meta_lock(orphan_dir_inode, NULL, &orphan_dir_bh, 1);
	if (status < 0) {
		mutex_unlock(&orphan_dir_inode->i_mutex);

		mlog_errno(status);
		goto bail;
	}

	/* we do this while holding the orphan dir lock because we
	 * don't want recovery being run from another node to vote for
	 * an inode delete on us -- this will result in two nodes
	 * truncating the same file! */
	status = ocfs2_truncate_for_delete(osb, inode, di_bh);
	if (status < 0) {
		mlog_errno(status);
		goto bail_unlock_dir;
	}

	status = ocfs2_remove_inode(inode, di_bh, orphan_dir_inode,
				    orphan_dir_bh);
	if (status < 0)
		mlog_errno(status);

bail_unlock_dir:
	ocfs2_meta_unlock(orphan_dir_inode, 1);
	mutex_unlock(&orphan_dir_inode->i_mutex);
	brelse(orphan_dir_bh);
bail:
	iput(orphan_dir_inode);

	return status;
}

/* There is a series of simple checks that should be done before a
 * vote is even considered. Encapsulate those in this function. */
static int ocfs2_inode_is_valid_to_delete(struct inode *inode)
{
	int ret = 0;
	struct ocfs2_inode_info *oi = OCFS2_I(inode);
	struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);

	/* We shouldn't be getting here for the root directory
	 * inode.. */
	if (inode == osb->root_inode) {
		mlog(ML_ERROR, "Skipping delete of root inode.\n");
		goto bail;
	}

	/* If we're coming from process_vote we can't go into our own
	 * voting [hello, deadlock city!], so unforuntately we just
	 * have to skip deleting this guy. That's OK though because
	 * the node who's doing the actual deleting should handle it
	 * anyway. */
	if (current == osb->vote_task) {
		mlog(0, "Skipping delete of %lu because we're currently "
		     "in process_vote\n", inode->i_ino);
		goto bail;
	}

	spin_lock(&oi->ip_lock);
	/* OCFS2 *never* deletes system files. This should technically
	 * never get here as system file inodes should always have a
	 * positive link count. */
	if (oi->ip_flags & OCFS2_INODE_SYSTEM_FILE) {
		mlog(ML_ERROR, "Skipping delete of system file %"MLFu64".\n",
		     oi->ip_blkno);
		goto bail_unlock;
	}

	/* If we have voted "yes" on the wipe of this inode for
	 * another node, it will be marked here so we can safely skip
	 * it. Recovery will cleanup any inodes we might inadvertantly
	 * skip here. */
	if (oi->ip_flags & OCFS2_INODE_SKIP_DELETE) {
		mlog(0, "Skipping delete of %lu because another node "
		     "has done this for us.\n", inode->i_ino);
		goto bail_unlock;
	}

	ret = 1;
bail_unlock:
	spin_unlock(&oi->ip_lock);
bail:
	return ret;
}

/* Query the cluster to determine whether we should wipe an inode from
 * disk or not.
 *
 * Requires the inode to have the cluster lock. */
static int ocfs2_query_inode_wipe(struct inode *inode,
				  struct buffer_head *di_bh,
				  int *wipe)
{
	int status = 0;
	struct ocfs2_inode_info *oi = OCFS2_I(inode);
	struct ocfs2_dinode *di;

	*wipe = 0;

	/* While we were waiting for the cluster lock in
	 * ocfs2_delete_inode, another node might have asked to delete
	 * the inode. Recheck our flags to catch this. */
	if (!ocfs2_inode_is_valid_to_delete(inode)) {
		mlog(0, "Skipping delete of %"MLFu64" because flags changed\n",
		     oi->ip_blkno);
		goto bail;
	}

	/* Now that we have an up to date inode, we can double check
	 * the link count. */
	if (inode->i_nlink) {
		mlog(0, "Skipping delete of %"MLFu64" because nlink = %u\n",
		     oi->ip_blkno, inode->i_nlink);
		goto bail;
	}

	/* Do some basic inode verification... */
	di = (struct ocfs2_dinode *) di_bh->b_data;
	if (!(di->i_flags & cpu_to_le32(OCFS2_ORPHANED_FL))) {
		/* for lack of a better error? */
		status = -EEXIST;
		mlog(ML_ERROR,
		     "Inode %"MLFu64" (on-disk %"MLFu64") not orphaned! "
		     "Disk flags  0x%x, inode flags 0x%x\n",
		     oi->ip_blkno, di->i_blkno, di->i_flags, oi->ip_flags);
		goto bail;
	}

	/* has someone already deleted us?! baaad... */
	if (di->i_dtime) {
		status = -EEXIST;
		mlog_errno(status);
		goto bail;
	}

	status = ocfs2_request_delete_vote(inode);
	/* -EBUSY means that other nodes are still using the
	 * inode. We're done here though, so avoid doing anything on
	 * disk and let them worry about deleting it. */
	if (status == -EBUSY) {
		status = 0;
		mlog(0, "Skipping delete of %"MLFu64" because it is in use on"
		     "other nodes\n", oi->ip_blkno);
		goto bail;
	}
	if (status < 0) {
		mlog_errno(status);
		goto bail;
	}

	spin_lock(&oi->ip_lock);
	if (oi->ip_orphaned_slot == OCFS2_INVALID_SLOT) {
		/* Nobody knew which slot this inode was orphaned
		 * into. This may happen during node death and
		 * recovery knows how to clean it up so we can safely
		 * ignore this inode for now on. */
		mlog(0, "Nobody knew where inode %"MLFu64" was orphaned!\n",
		     oi->ip_blkno);
	} else {
		*wipe = 1;

		mlog(0, "Inode %"MLFu64" is ok to wipe from orphan dir %d\n",
		     oi->ip_blkno, oi->ip_orphaned_slot);
	}
	spin_unlock(&oi->ip_lock);

bail:
	return status;
}

/* Support function for ocfs2_delete_inode. Will help us keep the
 * inode data in a consistent state for clear_inode. Always truncates
 * pages, optionally sync's them first. */
static void ocfs2_cleanup_delete_inode(struct inode *inode,
				       int sync_data)
{
	mlog(0, "Cleanup inode %"MLFu64", sync = %d\n",
	     OCFS2_I(inode)->ip_blkno, sync_data);
	if (sync_data)
		write_inode_now(inode, 1);
	truncate_inode_pages(&inode->i_data, 0);
}

void ocfs2_delete_inode(struct inode *inode)
{
	int wipe, status;
	sigset_t blocked, oldset;
	struct buffer_head *di_bh = NULL;

	mlog_entry("(inode->i_ino = %lu)\n", inode->i_ino);

	if (is_bad_inode(inode)) {
		mlog(0, "Skipping delete of bad inode\n");
		goto bail;
	}

	if (!ocfs2_inode_is_valid_to_delete(inode)) {
		/* It's probably not necessary to truncate_inode_pages
		 * here but we do it for safety anyway (it will most
		 * likely be a no-op anyway) */
		ocfs2_cleanup_delete_inode(inode, 0);
		goto bail;
	}

	/* We want to block signals in delete_inode as the lock and
	 * messaging paths may return us -ERESTARTSYS. Which would
	 * cause us to exit early, resulting in inodes being orphaned
	 * forever. */
	sigfillset(&blocked);
	status = sigprocmask(SIG_BLOCK, &blocked, &oldset);
	if (status < 0) {
		mlog_errno(status);
		ocfs2_cleanup_delete_inode(inode, 1);
		goto bail;
	}

	/* Lock down the inode. This gives us an up to date view of
	 * it's metadata (for verification), and allows us to
	 * serialize delete_inode votes. 
	 *
	 * Even though we might be doing a truncate, we don't take the
	 * allocation lock here as it won't be needed - nobody will
	 * have the file open.
	 */
	status = ocfs2_meta_lock(inode, NULL, &di_bh, 1);
	if (status < 0) {
		if (status != -ENOENT)
			mlog_errno(status);
		ocfs2_cleanup_delete_inode(inode, 0);
		goto bail_unblock;
	}

	/* Query the cluster. This will be the final decision made
	 * before we go ahead and wipe the inode. */
	status = ocfs2_query_inode_wipe(inode, di_bh, &wipe);
	if (!wipe || status < 0) {
		/* Error and inode busy vote both mean we won't be
		 * removing the inode, so they take almost the same
		 * path. */
		if (status < 0)
			mlog_errno(status);

		/* Someone in the cluster has voted to not wipe this
		 * inode, or it was never completely orphaned. Write
		 * out the pages and exit now. */
		ocfs2_cleanup_delete_inode(inode, 1);
		goto bail_unlock_inode;
	}

	ocfs2_cleanup_delete_inode(inode, 0);

	status = ocfs2_wipe_inode(inode, di_bh);
	if (status < 0) {
		mlog_errno(status);
		goto bail_unlock_inode;
	}

	/* Mark the inode as successfully deleted. This is important
	 * for ocfs2_clear_inode as it will check this flag and skip
	 * any checkpointing work */
	OCFS2_I(inode)->ip_flags |= OCFS2_INODE_DELETED;

bail_unlock_inode:
	ocfs2_meta_unlock(inode, 1);
	brelse(di_bh);
bail_unblock:
	status = sigprocmask(SIG_SETMASK, &oldset, NULL);
	if (status < 0)
		mlog_errno(status);
bail:
	clear_inode(inode);
	mlog_exit_void();
}

void ocfs2_clear_inode(struct inode *inode)
{
	int status;
	struct ocfs2_inode_info *oi = OCFS2_I(inode);

	mlog_entry_void();

	if (!inode)
		goto bail;

	mlog(0, "Clearing inode: %"MLFu64", nlink = %u\n",
	     OCFS2_I(inode)->ip_blkno, inode->i_nlink);

	mlog_bug_on_msg(OCFS2_SB(inode->i_sb) == NULL,
			"Inode=%lu\n", inode->i_ino);

	/* Do these before all the other work so that we don't bounce
	 * the vote thread while waiting to destroy the locks. */
	ocfs2_mark_lockres_freeing(&oi->ip_rw_lockres);
	ocfs2_mark_lockres_freeing(&oi->ip_meta_lockres);
	ocfs2_mark_lockres_freeing(&oi->ip_data_lockres);

	/* We very well may get a clear_inode before all an inodes
	 * metadata has hit disk. Of course, we can't drop any cluster
	 * locks until the journal has finished with it. The only
	 * exception here are successfully wiped inodes - their
	 * metadata can now be considered to be part of the system
	 * inodes from which it came. */
	if (!(OCFS2_I(inode)->ip_flags & OCFS2_INODE_DELETED))
		ocfs2_checkpoint_inode(inode);

	mlog_bug_on_msg(!list_empty(&oi->ip_io_markers),
			"Clear inode of %"MLFu64", inode has io markers\n",
			oi->ip_blkno);

	ocfs2_extent_map_drop(inode, 0);
	ocfs2_extent_map_init(inode);

	status = ocfs2_drop_inode_locks(inode);
	if (status < 0)
		mlog_errno(status);

	ocfs2_lock_res_free(&oi->ip_rw_lockres);
	ocfs2_lock_res_free(&oi->ip_meta_lockres);
	ocfs2_lock_res_free(&oi->ip_data_lockres);

	ocfs2_metadata_cache_purge(inode);

	mlog_bug_on_msg(oi->ip_metadata_cache.ci_num_cached,
			"Clear inode of %"MLFu64", inode has %u cache items\n",
			oi->ip_blkno, oi->ip_metadata_cache.ci_num_cached);

	mlog_bug_on_msg(!(oi->ip_flags & OCFS2_INODE_CACHE_INLINE),
			"Clear inode of %"MLFu64", inode has a bad flag\n",
			oi->ip_blkno);

	mlog_bug_on_msg(spin_is_locked(&oi->ip_lock),
			"Clear inode of %"MLFu64", inode is locked\n",
			oi->ip_blkno);

	mlog_bug_on_msg(!mutex_trylock(&oi->ip_io_mutex),
			"Clear inode of %"MLFu64", io_mutex is locked\n",
			oi->ip_blkno);
	mutex_unlock(&oi->ip_io_mutex);

	/*
	 * down_trylock() returns 0, down_write_trylock() returns 1
	 * kernel 1, world 0
	 */
	mlog_bug_on_msg(!down_write_trylock(&oi->ip_alloc_sem),
			"Clear inode of %"MLFu64", alloc_sem is locked\n",
			oi->ip_blkno);
	up_write(&oi->ip_alloc_sem);

	mlog_bug_on_msg(oi->ip_open_count,
			"Clear inode of %"MLFu64" has open count %d\n",
			oi->ip_blkno, oi->ip_open_count);
	mlog_bug_on_msg(!list_empty(&oi->ip_handle_list),
			"Clear inode of %"MLFu64" has non empty handle list\n",
			oi->ip_blkno);
	mlog_bug_on_msg(oi->ip_handle,
			"Clear inode of %"MLFu64" has non empty handle pointer\n",
			oi->ip_blkno);

	/* Clear all other flags. */
	oi->ip_flags = OCFS2_INODE_CACHE_INLINE;
	oi->ip_created_trans = 0;
	oi->ip_last_trans = 0;
	oi->ip_dir_start_lookup = 0;
	oi->ip_blkno = 0ULL;

bail:
	mlog_exit_void();
}

/* Called under inode_lock, with no more references on the
 * struct inode, so it's safe here to check the flags field
 * and to manipulate i_nlink without any other locks. */
void ocfs2_drop_inode(struct inode *inode)
{
	struct ocfs2_inode_info *oi = OCFS2_I(inode);

	mlog_entry_void();

	mlog(0, "Drop inode %"MLFu64", nlink = %u, ip_flags = 0x%x\n",
	     oi->ip_blkno, inode->i_nlink, oi->ip_flags);

	/* Testing ip_orphaned_slot here wouldn't work because we may
	 * not have gotten a delete_inode vote from any other nodes
	 * yet. */
	if (oi->ip_flags & OCFS2_INODE_MAYBE_ORPHANED) {
		mlog(0, "Inode was orphaned on another node, clearing nlink.\n");
		inode->i_nlink = 0;
	}

	generic_drop_inode(inode);

	mlog_exit_void();
}

/*
 * TODO: this should probably be merged into ocfs2_get_block
 *
 * However, you now need to pay attention to the cont_prepare_write()
 * stuff in ocfs2_get_block (that is, ocfs2_get_block pretty much
 * expects never to extend).
 */
struct buffer_head *ocfs2_bread(struct inode *inode,
				int block, int *err, int reada)
{
	struct buffer_head *bh = NULL;
	int tmperr;
	u64 p_blkno;
	int readflags = OCFS2_BH_CACHED;

#if 0
	/* only turn this on if we know we can deal with read_block
	 * returning nothing */
	if (reada)
		readflags |= OCFS2_BH_READAHEAD;
#endif

	if (((u64)block << inode->i_sb->s_blocksize_bits) >=
	    i_size_read(inode)) {
		BUG_ON(!reada);
		return NULL;
	}

	tmperr = ocfs2_extent_map_get_blocks(inode, block, 1,
					     &p_blkno, NULL);
	if (tmperr < 0) {
		mlog_errno(tmperr);
		goto fail;
	}

	tmperr = ocfs2_read_block(OCFS2_SB(inode->i_sb), p_blkno, &bh,
				  readflags, inode);
	if (tmperr < 0)
		goto fail;

	tmperr = 0;

	*err = 0;
	return bh;

fail:
	if (bh) {
		brelse(bh);
		bh = NULL;
	}
	*err = -EIO;
	return NULL;
}

/*
 * This is called from our getattr.
 */
int ocfs2_inode_revalidate(struct dentry *dentry)
{
	struct inode *inode = dentry->d_inode;
	int status = 0;

	mlog_entry("(inode = 0x%p, ino = %"MLFu64")\n", inode,
		   inode ? OCFS2_I(inode)->ip_blkno : 0ULL);

	if (!inode) {
		mlog(0, "eep, no inode!\n");
		status = -ENOENT;
		goto bail;
	}

	spin_lock(&OCFS2_I(inode)->ip_lock);
	if (OCFS2_I(inode)->ip_flags & OCFS2_INODE_DELETED) {
		spin_unlock(&OCFS2_I(inode)->ip_lock);
		mlog(0, "inode deleted!\n");
		status = -ENOENT;
		goto bail;
	}
	spin_unlock(&OCFS2_I(inode)->ip_lock);

	/* Let ocfs2_meta_lock do the work of updating our struct
	 * inode for us. */
	status = ocfs2_meta_lock(inode, NULL, NULL, 0);
	if (status < 0) {
		if (status != -ENOENT)
			mlog_errno(status);
		goto bail;
	}
	ocfs2_meta_unlock(inode, 0);
bail:
	mlog_exit(status);

	return status;
}

/*
 * Updates a disk inode from a
 * struct inode.
 * Only takes ip_lock.
 */
int ocfs2_mark_inode_dirty(struct ocfs2_journal_handle *handle,
			   struct inode *inode,
			   struct buffer_head *bh)
{
	int status;
	struct ocfs2_dinode *fe = (struct ocfs2_dinode *) bh->b_data;

	mlog_entry("(inode %"MLFu64")\n", OCFS2_I(inode)->ip_blkno);

	status = ocfs2_journal_access(handle, inode, bh,
				      OCFS2_JOURNAL_ACCESS_WRITE);
	if (status < 0) {
		mlog_errno(status);
		goto leave;
	}

	spin_lock(&OCFS2_I(inode)->ip_lock);
	fe->i_clusters = cpu_to_le32(OCFS2_I(inode)->ip_clusters);
	spin_unlock(&OCFS2_I(inode)->ip_lock);

	fe->i_size = cpu_to_le64(i_size_read(inode));
	fe->i_links_count = cpu_to_le16(inode->i_nlink);
	fe->i_uid = cpu_to_le32(inode->i_uid);
	fe->i_gid = cpu_to_le32(inode->i_gid);
	fe->i_mode = cpu_to_le16(inode->i_mode);
	fe->i_atime = cpu_to_le64(inode->i_atime.tv_sec);
	fe->i_atime_nsec = cpu_to_le32(inode->i_atime.tv_nsec);
	fe->i_ctime = cpu_to_le64(inode->i_ctime.tv_sec);
	fe->i_ctime_nsec = cpu_to_le32(inode->i_ctime.tv_nsec);
	fe->i_mtime = cpu_to_le64(inode->i_mtime.tv_sec);
	fe->i_mtime_nsec = cpu_to_le32(inode->i_mtime.tv_nsec);

	status = ocfs2_journal_dirty(handle, bh);
	if (status < 0)
		mlog_errno(status);

	status = 0;
leave:

	mlog_exit(status);
	return status;
}

/*
 *
 * Updates a struct inode from a disk inode.
 * does no i/o, only takes ip_lock.
 */
void ocfs2_refresh_inode(struct inode *inode,
			 struct ocfs2_dinode *fe)
{
	struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);

	spin_lock(&OCFS2_I(inode)->ip_lock);

	OCFS2_I(inode)->ip_clusters = le32_to_cpu(fe->i_clusters);
	i_size_write(inode, le64_to_cpu(fe->i_size));
	inode->i_nlink = le16_to_cpu(fe->i_links_count);
	inode->i_uid = le32_to_cpu(fe->i_uid);
	inode->i_gid = le32_to_cpu(fe->i_gid);
	inode->i_mode = le16_to_cpu(fe->i_mode);
	inode->i_blksize = (u32) osb->s_clustersize;
	if (S_ISLNK(inode->i_mode) && le32_to_cpu(fe->i_clusters) == 0)
		inode->i_blocks = 0;
	else
		inode->i_blocks = ocfs2_align_bytes_to_sectors(i_size_read(inode));
	inode->i_atime.tv_sec = le64_to_cpu(fe->i_atime);
	inode->i_atime.tv_nsec = le32_to_cpu(fe->i_atime_nsec);
	inode->i_mtime.tv_sec = le64_to_cpu(fe->i_mtime);
	inode->i_mtime.tv_nsec = le32_to_cpu(fe->i_mtime_nsec);
	inode->i_ctime.tv_sec = le64_to_cpu(fe->i_ctime);
	inode->i_ctime.tv_nsec = le32_to_cpu(fe->i_ctime_nsec);

	spin_unlock(&OCFS2_I(inode)->ip_lock);
}
