/*
 * Copyright (C) Sistina Software, Inc.  1997-2003 All rights reserved.
 * Copyright (C) 2004-2005 Red Hat, Inc.  All rights reserved.
 *
 * This copyrighted material is made available to anyone wishing to use,
 * modify, copy, or redistribute it subject to the terms and conditions
 * of the GNU General Public License v.2.
 */

#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/completion.h>
#include <linux/buffer_head.h>
#include <linux/posix_acl.h>
#include <linux/sort.h>
#include <asm/semaphore.h>

#include "gfs2.h"
#include "acl.h"
#include "bmap.h"
#include "dir.h"
#include "eattr.h"
#include "glock.h"
#include "glops.h"
#include "inode.h"
#include "log.h"
#include "meta_io.h"
#include "ops_address.h"
#include "ops_file.h"
#include "ops_inode.h"
#include "quota.h"
#include "rgrp.h"
#include "trans.h"
#include "unlinked.h"

/**
 * inode_attr_in - Copy attributes from the dinode into the VFS inode
 * @ip: The GFS2 inode (with embedded disk inode data)
 * @inode:  The Linux VFS inode
 *
 */

static void inode_attr_in(struct gfs2_inode *ip, struct inode *inode)
{
	inode->i_ino = ip->i_num.no_formal_ino;

	switch (ip->i_di.di_mode & S_IFMT) {
	case S_IFBLK:
	case S_IFCHR:
		inode->i_rdev = MKDEV(ip->i_di.di_major, ip->i_di.di_minor);
		break;
	default:
		inode->i_rdev = 0;
		break;
	};

	inode->i_mode = ip->i_di.di_mode;
	inode->i_nlink = ip->i_di.di_nlink;
	inode->i_uid = ip->i_di.di_uid;
	inode->i_gid = ip->i_di.di_gid;
	i_size_write(inode, ip->i_di.di_size);
	inode->i_atime.tv_sec = ip->i_di.di_atime;
	inode->i_mtime.tv_sec = ip->i_di.di_mtime;
	inode->i_ctime.tv_sec = ip->i_di.di_ctime;
	inode->i_atime.tv_nsec = 0;
	inode->i_mtime.tv_nsec = 0;
	inode->i_ctime.tv_nsec = 0;
	inode->i_blksize = PAGE_SIZE;
	inode->i_blocks = ip->i_di.di_blocks <<
		(ip->i_sbd->sd_sb.sb_bsize_shift - GFS2_BASIC_BLOCK_SHIFT);

	if (ip->i_di.di_flags & GFS2_DIF_IMMUTABLE)
		inode->i_flags |= S_IMMUTABLE;
	else
		inode->i_flags &= ~S_IMMUTABLE;

	if (ip->i_di.di_flags & GFS2_DIF_APPENDONLY)
		inode->i_flags |= S_APPEND;
	else
		inode->i_flags &= ~S_APPEND;
}

/**
 * gfs2_inode_attr_in - Copy attributes from the dinode into the VFS inode
 * @ip: The GFS2 inode (with embedded disk inode data)
 *
 */

void gfs2_inode_attr_in(struct gfs2_inode *ip)
{
	struct inode *inode;

	inode = gfs2_ip2v_lookup(ip);
	if (inode) {
		inode_attr_in(ip, inode);
		iput(inode);
	}
}

/**
 * gfs2_inode_attr_out - Copy attributes from VFS inode into the dinode
 * @ip: The GFS2 inode
 *
 * Only copy out the attributes that we want the VFS layer
 * to be able to modify.
 */

void gfs2_inode_attr_out(struct gfs2_inode *ip)
{
	struct inode *inode = ip->i_vnode;

	gfs2_assert_withdraw(ip->i_sbd,
		(ip->i_di.di_mode & S_IFMT) == (inode->i_mode & S_IFMT));
	ip->i_di.di_mode = inode->i_mode;
	ip->i_di.di_uid = inode->i_uid;
	ip->i_di.di_gid = inode->i_gid;
	ip->i_di.di_atime = inode->i_atime.tv_sec;
	ip->i_di.di_mtime = inode->i_mtime.tv_sec;
	ip->i_di.di_ctime = inode->i_ctime.tv_sec;
}

/**
 * gfs2_ip2v_lookup - Get the struct inode for a struct gfs2_inode
 * @ip: the struct gfs2_inode to get the struct inode for
 *
 * Returns: A VFS inode, or NULL if none
 */

struct inode *gfs2_ip2v_lookup(struct gfs2_inode *ip)
{
	struct inode *inode = NULL;

	gfs2_assert_warn(ip->i_sbd, test_bit(GIF_MIN_INIT, &ip->i_flags));

	spin_lock(&ip->i_spin);
	if (ip->i_vnode)
		inode = igrab(ip->i_vnode);
	spin_unlock(&ip->i_spin);

	return inode;
}

/**
 * gfs2_ip2v - Get/Create a struct inode for a struct gfs2_inode
 * @ip: the struct gfs2_inode to get the struct inode for
 *
 * Returns: A VFS inode, or NULL if no mem
 */

struct inode *gfs2_ip2v(struct gfs2_inode *ip)
{
	struct inode *inode, *tmp;

	inode = gfs2_ip2v_lookup(ip);
	if (inode)
		return inode;

	tmp = new_inode(ip->i_sbd->sd_vfs);
	if (!tmp)
		return NULL;

	inode_attr_in(ip, tmp);

	if (S_ISREG(ip->i_di.di_mode)) {
		tmp->i_op = &gfs2_file_iops;
		tmp->i_fop = &gfs2_file_fops;
		tmp->i_mapping->a_ops = &gfs2_file_aops;
	} else if (S_ISDIR(ip->i_di.di_mode)) {
		tmp->i_op = &gfs2_dir_iops;
		tmp->i_fop = &gfs2_dir_fops;
	} else if (S_ISLNK(ip->i_di.di_mode)) {
		tmp->i_op = &gfs2_symlink_iops;
	} else {
		tmp->i_op = &gfs2_dev_iops;
		init_special_inode(tmp, tmp->i_mode, tmp->i_rdev);
	}

	set_v2ip(tmp, NULL);

	for (;;) {
		spin_lock(&ip->i_spin);
		if (!ip->i_vnode)
			break;
		inode = igrab(ip->i_vnode);
		spin_unlock(&ip->i_spin);

		if (inode) {
			iput(tmp);
			return inode;
		}
		yield();
	}

	inode = tmp;

	gfs2_inode_hold(ip);
	ip->i_vnode = inode;
	set_v2ip(inode, ip);

	spin_unlock(&ip->i_spin);

	insert_inode_hash(inode);

	return inode;
}

static int iget_test(struct inode *inode, void *opaque)
{
	struct gfs2_inode *ip = get_v2ip(inode);
	struct gfs2_inum *inum = (struct gfs2_inum *)opaque;

	if (ip && ip->i_num.no_addr == inum->no_addr)
		return 1;

	return 0;
}

struct inode *gfs2_iget(struct super_block *sb, struct gfs2_inum *inum)
{
	return ilookup5(sb, (unsigned long)inum->no_formal_ino,
			iget_test, inum);
}

void gfs2_inode_min_init(struct gfs2_inode *ip, unsigned int type)
{
	spin_lock(&ip->i_spin);
	if (!test_and_set_bit(GIF_MIN_INIT, &ip->i_flags)) {
		ip->i_di.di_nlink = 1;
		ip->i_di.di_mode = DT2IF(type);
	}
	spin_unlock(&ip->i_spin);
}

/**
 * gfs2_inode_refresh - Refresh the incore copy of the dinode
 * @ip: The GFS2 inode
 *
 * Returns: errno
 */

int gfs2_inode_refresh(struct gfs2_inode *ip)
{
	struct buffer_head *dibh;
	int error;

	error = gfs2_meta_inode_buffer(ip, &dibh);
	if (error)
		return error;

	if (gfs2_metatype_check(ip->i_sbd, dibh, GFS2_METATYPE_DI)) {
		brelse(dibh);
		return -EIO;
	}

	spin_lock(&ip->i_spin);
	gfs2_dinode_in(&ip->i_di, dibh->b_data);
	set_bit(GIF_MIN_INIT, &ip->i_flags);
	spin_unlock(&ip->i_spin);

	brelse(dibh);

	if (ip->i_num.no_addr != ip->i_di.di_num.no_addr) {
		if (gfs2_consist_inode(ip))
			gfs2_dinode_print(&ip->i_di);
		return -EIO;
	}
	if (ip->i_num.no_formal_ino != ip->i_di.di_num.no_formal_ino)
		return -ESTALE;

	ip->i_vn = ip->i_gl->gl_vn;

	return 0;
}

/**
 * inode_create - create a struct gfs2_inode
 * @i_gl: The glock covering the inode
 * @inum: The inode number
 * @io_gl: the iopen glock to acquire/hold (using holder in new gfs2_inode)
 * @io_state: the state the iopen glock should be acquired in
 * @ipp: pointer to put the returned inode in
 *
 * Returns: errno
 */

static int inode_create(struct gfs2_glock *i_gl, struct gfs2_inum *inum,
			struct gfs2_glock *io_gl, unsigned int io_state,
			struct gfs2_inode **ipp)
{
	struct gfs2_sbd *sdp = i_gl->gl_sbd;
	struct gfs2_inode *ip;
	int error = 0;

	ip = kmem_cache_alloc(gfs2_inode_cachep, GFP_KERNEL);
	if (!ip)
		return -ENOMEM;
	memset(ip, 0, sizeof(struct gfs2_inode));

	ip->i_num = *inum;

	atomic_set(&ip->i_count, 1);

	ip->i_vn = i_gl->gl_vn - 1;

	ip->i_gl = i_gl;
	ip->i_sbd = sdp;

	spin_lock_init(&ip->i_spin);
	init_rwsem(&ip->i_rw_mutex);

	ip->i_greedy = gfs2_tune_get(sdp, gt_greedy_default);

	error = gfs2_glock_nq_init(io_gl,
				   io_state, GL_LOCAL_EXCL | GL_EXACT,
				   &ip->i_iopen_gh);
	if (error)
		goto fail;
	ip->i_iopen_gh.gh_owner = NULL;

	spin_lock(&io_gl->gl_spin);
	gfs2_glock_hold(i_gl);
	set_gl2gl(io_gl, i_gl);
	spin_unlock(&io_gl->gl_spin);

	gfs2_glock_hold(i_gl);
	set_gl2ip(i_gl, ip);

	atomic_inc(&sdp->sd_inode_count);

	*ipp = ip;

	return 0;

 fail:
	gfs2_meta_cache_flush(ip);
	kmem_cache_free(gfs2_inode_cachep, ip);
	*ipp = NULL;

	return error;
}

/**
 * gfs2_inode_get - Create or get a reference on an inode
 * @i_gl: The glock covering the inode
 * @inum: The inode number
 * @create:
 * @ipp: pointer to put the returned inode in
 *
 * Returns: errno
 */

int gfs2_inode_get(struct gfs2_glock *i_gl, struct gfs2_inum *inum, int create,
		   struct gfs2_inode **ipp)
{
	struct gfs2_sbd *sdp = i_gl->gl_sbd;
	struct gfs2_glock *io_gl;
	int error = 0;

	gfs2_glmutex_lock(i_gl);

	*ipp = get_gl2ip(i_gl);
	if (*ipp) {
		error = -ESTALE;
		if ((*ipp)->i_num.no_formal_ino != inum->no_formal_ino)
			goto out;
		atomic_inc(&(*ipp)->i_count);
		error = 0;
		goto out;
	}

	if (!create)
		goto out;

	error = gfs2_glock_get(sdp, inum->no_addr, &gfs2_iopen_glops,
			       CREATE, &io_gl);
	if (!error) {
		error = inode_create(i_gl, inum, io_gl, LM_ST_SHARED, ipp);
		gfs2_glock_put(io_gl);
	}

 out:
	gfs2_glmutex_unlock(i_gl);

	return error;
}

void gfs2_inode_hold(struct gfs2_inode *ip)
{
	gfs2_assert(ip->i_sbd, atomic_read(&ip->i_count) > 0);
	atomic_inc(&ip->i_count);
}

void gfs2_inode_put(struct gfs2_inode *ip)
{
	gfs2_assert(ip->i_sbd, atomic_read(&ip->i_count) > 0);
	atomic_dec(&ip->i_count);
}

void gfs2_inode_destroy(struct gfs2_inode *ip)
{
	struct gfs2_sbd *sdp = ip->i_sbd;
	struct gfs2_glock *io_gl = ip->i_iopen_gh.gh_gl;
	struct gfs2_glock *i_gl = ip->i_gl;

	gfs2_assert_warn(sdp, !atomic_read(&ip->i_count));
	gfs2_assert(sdp, get_gl2gl(io_gl) == i_gl);

	spin_lock(&io_gl->gl_spin);
	set_gl2gl(io_gl, NULL);
	gfs2_glock_put(i_gl);
	spin_unlock(&io_gl->gl_spin);

	gfs2_glock_dq_uninit(&ip->i_iopen_gh);

	gfs2_meta_cache_flush(ip);
	kmem_cache_free(gfs2_inode_cachep, ip);

	set_gl2ip(i_gl, NULL);
	gfs2_glock_put(i_gl);

	atomic_dec(&sdp->sd_inode_count);
}

static int dinode_dealloc(struct gfs2_inode *ip, struct gfs2_unlinked *ul)
{
	struct gfs2_sbd *sdp = ip->i_sbd;
	struct gfs2_alloc *al;
	struct gfs2_rgrpd *rgd;
	int error;

	if (ip->i_di.di_blocks != 1) {
		if (gfs2_consist_inode(ip))
			gfs2_dinode_print(&ip->i_di);
		return -EIO;
	}

	al = gfs2_alloc_get(ip);

	error = gfs2_quota_hold(ip, NO_QUOTA_CHANGE, NO_QUOTA_CHANGE);
	if (error)
		goto out;

	error = gfs2_rindex_hold(sdp, &al->al_ri_gh);
	if (error)
		goto out_qs;

	rgd = gfs2_blk2rgrpd(sdp, ip->i_num.no_addr);
	if (!rgd) {
		gfs2_consist_inode(ip);
		error = -EIO;
		goto out_rindex_relse;
	}

	error = gfs2_glock_nq_init(rgd->rd_gl, LM_ST_EXCLUSIVE, 0,
				   &al->al_rgd_gh);
	if (error)
		goto out_rindex_relse;

	error = gfs2_trans_begin(sdp, RES_RG_BIT + RES_UNLINKED +
				 RES_STATFS + RES_QUOTA, 1);
	if (error)
		goto out_rg_gunlock;

	gfs2_trans_add_gl(ip->i_gl);

	gfs2_free_di(rgd, ip);

	error = gfs2_unlinked_ondisk_rm(sdp, ul);

	gfs2_trans_end(sdp);
	clear_bit(GLF_STICKY, &ip->i_gl->gl_flags);

 out_rg_gunlock:
	gfs2_glock_dq_uninit(&al->al_rgd_gh);

 out_rindex_relse:
	gfs2_glock_dq_uninit(&al->al_ri_gh);

 out_qs:
	gfs2_quota_unhold(ip);

 out:
	gfs2_alloc_put(ip);

	return error;
}

/**
 * inode_dealloc - Deallocate all on-disk blocks for an inode (dinode)
 * @sdp: the filesystem
 * @inum: the inode number to deallocate
 * @io_gh: a holder for the iopen glock for this inode
 *
 * Returns: errno
 */

static int inode_dealloc(struct gfs2_sbd *sdp, struct gfs2_unlinked *ul,
			 struct gfs2_holder *io_gh)
{
	struct gfs2_inode *ip;
	struct gfs2_holder i_gh;
	int error;

	error = gfs2_glock_nq_num(sdp,
				  ul->ul_ut.ut_inum.no_addr, &gfs2_inode_glops,
				  LM_ST_EXCLUSIVE, 0, &i_gh);
	if (error)
		return error;

	/* We reacquire the iopen lock here to avoid a race with the NFS server
	   calling gfs2_read_inode() with the inode number of a inode we're in
	   the process of deallocating.  And we can't keep our hold on the lock
	   from inode_dealloc_init() for deadlock reasons. */

	gfs2_holder_reinit(LM_ST_EXCLUSIVE, LM_FLAG_TRY, io_gh);
	error = gfs2_glock_nq(io_gh);
	switch (error) {
	case 0:
		break;
	case GLR_TRYFAILED:
		error = 1;
	default:
		goto out;
	}

	gfs2_assert_warn(sdp, !get_gl2ip(i_gh.gh_gl));
	error = inode_create(i_gh.gh_gl, &ul->ul_ut.ut_inum, io_gh->gh_gl,
			     LM_ST_EXCLUSIVE, &ip);

	gfs2_glock_dq(io_gh);

	if (error)
		goto out;

	error = gfs2_inode_refresh(ip);
	if (error)
		goto out_iput;

	if (ip->i_di.di_nlink) {
		if (gfs2_consist_inode(ip))
			gfs2_dinode_print(&ip->i_di);
		error = -EIO;
		goto out_iput;
	}

	if (S_ISDIR(ip->i_di.di_mode) &&
	    (ip->i_di.di_flags & GFS2_DIF_EXHASH)) {
		error = gfs2_dir_exhash_dealloc(ip);
		if (error)
			goto out_iput;
	}

	if (ip->i_di.di_eattr) {
		error = gfs2_ea_dealloc(ip);
		if (error)
			goto out_iput;
	}

	if (!gfs2_is_stuffed(ip)) {
		error = gfs2_file_dealloc(ip);
		if (error)
			goto out_iput;
	}

	error = dinode_dealloc(ip, ul);
	if (error)
		goto out_iput;

 out_iput:
	gfs2_glmutex_lock(i_gh.gh_gl);
	gfs2_inode_put(ip);
	gfs2_inode_destroy(ip);
	gfs2_glmutex_unlock(i_gh.gh_gl);

 out:
	gfs2_glock_dq_uninit(&i_gh);

	return error;
}

/**
 * try_inode_dealloc - Try to deallocate an inode and all its blocks
 * @sdp: the filesystem
 *
 * Returns: 0 on success, -errno on error, 1 on busy (inode open)
 */

static int try_inode_dealloc(struct gfs2_sbd *sdp, struct gfs2_unlinked *ul)
{
	struct gfs2_holder io_gh;
	int error = 0;

	gfs2_try_toss_inode(sdp, &ul->ul_ut.ut_inum);

	error = gfs2_glock_nq_num(sdp,
				  ul->ul_ut.ut_inum.no_addr, &gfs2_iopen_glops,
				  LM_ST_EXCLUSIVE, LM_FLAG_TRY_1CB, &io_gh);
	switch (error) {
	case 0:
		break;
	case GLR_TRYFAILED:
		return 1;
	default:
		return error;
	}

	gfs2_glock_dq(&io_gh);
	error = inode_dealloc(sdp, ul, &io_gh);
	gfs2_holder_uninit(&io_gh);

	return error;
}

static int inode_dealloc_uninit(struct gfs2_sbd *sdp, struct gfs2_unlinked *ul)
{
	struct gfs2_rgrpd *rgd;
	struct gfs2_holder ri_gh, rgd_gh;
	int error;

	error = gfs2_rindex_hold(sdp, &ri_gh);
	if (error)
		return error;

	rgd = gfs2_blk2rgrpd(sdp, ul->ul_ut.ut_inum.no_addr);
	if (!rgd) {
		gfs2_consist(sdp);
		error = -EIO;
		goto out;
	}

	error = gfs2_glock_nq_init(rgd->rd_gl, LM_ST_EXCLUSIVE, 0, &rgd_gh);
	if (error)
		goto out;

	error = gfs2_trans_begin(sdp,
				 RES_RG_BIT + RES_UNLINKED + RES_STATFS,
				 0);
	if (error)
		goto out_gunlock;

	gfs2_free_uninit_di(rgd, ul->ul_ut.ut_inum.no_addr);
	gfs2_unlinked_ondisk_rm(sdp, ul);

	gfs2_trans_end(sdp);

 out_gunlock:
	gfs2_glock_dq_uninit(&rgd_gh);
 out:
	gfs2_glock_dq_uninit(&ri_gh);

	return error;
}

int gfs2_inode_dealloc(struct gfs2_sbd *sdp, struct gfs2_unlinked *ul)
{
	if (ul->ul_ut.ut_flags & GFS2_UTF_UNINIT)
		return inode_dealloc_uninit(sdp, ul);
	else
		return try_inode_dealloc(sdp, ul);
}

/**
 * gfs2_change_nlink - Change nlink count on inode
 * @ip: The GFS2 inode
 * @diff: The change in the nlink count required
 *
 * Returns: errno
 */

int gfs2_change_nlink(struct gfs2_inode *ip, int diff)
{
	struct buffer_head *dibh;
	uint32_t nlink;
	int error;

	nlink = ip->i_di.di_nlink + diff;

	/* If we are reducing the nlink count, but the new value ends up being
	   bigger than the old one, we must have underflowed. */
	if (diff < 0 && nlink > ip->i_di.di_nlink) {
		if (gfs2_consist_inode(ip))
			gfs2_dinode_print(&ip->i_di);
		return -EIO;
	}

	error = gfs2_meta_inode_buffer(ip, &dibh);
	if (error)
		return error;

	ip->i_di.di_nlink = nlink;
	ip->i_di.di_ctime = get_seconds();

	gfs2_trans_add_bh(ip->i_gl, dibh, 1);
	gfs2_dinode_out(&ip->i_di, dibh->b_data);
	brelse(dibh);

	return 0;
}

/**
 * gfs2_lookupi - Look up a filename in a directory and return its inode
 * @d_gh: An initialized holder for the directory glock
 * @name: The name of the inode to look for
 * @is_root: If 1, ignore the caller's permissions
 * @i_gh: An uninitialized holder for the new inode glock
 *
 * There will always be a vnode (Linux VFS inode) for the d_gh inode unless
 * @is_root is true.
 *
 * Returns: errno
 */

int gfs2_lookupi(struct inode *dir, struct qstr *name, int is_root,
		 struct inode **inodep)
{
	struct gfs2_inode *ipp;
	struct gfs2_inode *dip = get_v2ip(dir);
	struct gfs2_sbd *sdp = dip->i_sbd;
	struct gfs2_holder d_gh;
	struct gfs2_inum inum;
	unsigned int type;
	struct gfs2_glock *gl;
	int error = 0;

	*inodep = NULL;

	if (!name->len || name->len > GFS2_FNAMESIZE)
		return -ENAMETOOLONG;

	if (gfs2_filecmp(name, ".", 1) ||
	    (gfs2_filecmp(name, "..", 2) && dir == sdp->sd_root_dir)) {
		gfs2_inode_hold(dip);
		ipp = dip;
		goto done;
	}

	error = gfs2_glock_nq_init(dip->i_gl, LM_ST_SHARED, 0, &d_gh);
	if (error)
		return error;

	if (!is_root) {
		error = gfs2_repermission(dip->i_vnode, MAY_EXEC, NULL);
		if (error)
			goto out;
	}

	error = gfs2_dir_search(dip, name, &inum, &type);
	if (error)
		goto out;

	error = gfs2_glock_get(sdp, inum.no_addr, &gfs2_inode_glops,
			       CREATE, &gl);
	if (error)
		goto out;

	error = gfs2_inode_get(gl, &inum, CREATE, &ipp);
	if (!error)
		gfs2_inode_min_init(ipp, type);

	gfs2_glock_put(gl);

out:
	gfs2_glock_dq_uninit(&d_gh);
done:
	if (error == 0) {
		*inodep = gfs2_ip2v(ipp);
		if (!*inodep)
			error = -ENOMEM;
		gfs2_inode_put(ipp);
	}
	return error;
}

static int pick_formal_ino_1(struct gfs2_sbd *sdp, uint64_t *formal_ino)
{
	struct gfs2_inode *ip = get_v2ip(sdp->sd_ir_inode);
	struct buffer_head *bh;
	struct gfs2_inum_range ir;
	int error;

	error = gfs2_trans_begin(sdp, RES_DINODE, 0);
	if (error)
		return error;
	mutex_lock(&sdp->sd_inum_mutex);

	error = gfs2_meta_inode_buffer(ip, &bh);
	if (error) {
		mutex_unlock(&sdp->sd_inum_mutex);
		gfs2_trans_end(sdp);
		return error;
	}

	gfs2_inum_range_in(&ir, bh->b_data + sizeof(struct gfs2_dinode));

	if (ir.ir_length) {
		*formal_ino = ir.ir_start++;
		ir.ir_length--;
		gfs2_trans_add_bh(ip->i_gl, bh, 1);
		gfs2_inum_range_out(&ir,
				    bh->b_data + sizeof(struct gfs2_dinode));
		brelse(bh);
		mutex_unlock(&sdp->sd_inum_mutex);
		gfs2_trans_end(sdp);
		return 0;
	}

	brelse(bh);

	mutex_unlock(&sdp->sd_inum_mutex);
	gfs2_trans_end(sdp);

	return 1;
}

static int pick_formal_ino_2(struct gfs2_sbd *sdp, uint64_t *formal_ino)
{
	struct gfs2_inode *ip = get_v2ip(sdp->sd_ir_inode);
	struct gfs2_inode *m_ip = get_v2ip(sdp->sd_inum_inode);
	struct gfs2_holder gh;
	struct buffer_head *bh;
	struct gfs2_inum_range ir;
	int error;

	error = gfs2_glock_nq_init(m_ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh);
	if (error)
		return error;

	error = gfs2_trans_begin(sdp, 2 * RES_DINODE, 0);
	if (error)
		goto out;
	mutex_lock(&sdp->sd_inum_mutex);

	error = gfs2_meta_inode_buffer(ip, &bh);
	if (error)
		goto out_end_trans;
	
	gfs2_inum_range_in(&ir, bh->b_data + sizeof(struct gfs2_dinode));

	if (!ir.ir_length) {
		struct buffer_head *m_bh;
		uint64_t x, y;

		error = gfs2_meta_inode_buffer(m_ip, &m_bh);
		if (error)
			goto out_brelse;

		x = *(uint64_t *)(m_bh->b_data + sizeof(struct gfs2_dinode));
		x = y = be64_to_cpu(x);
		ir.ir_start = x;
		ir.ir_length = GFS2_INUM_QUANTUM;
		x += GFS2_INUM_QUANTUM;
		if (x < y)
			gfs2_consist_inode(m_ip);
		x = cpu_to_be64(x);
		gfs2_trans_add_bh(m_ip->i_gl, m_bh, 1);
		*(uint64_t *)(m_bh->b_data + sizeof(struct gfs2_dinode)) = x;

		brelse(m_bh);
	}

	*formal_ino = ir.ir_start++;
	ir.ir_length--;

	gfs2_trans_add_bh(ip->i_gl, bh, 1);
	gfs2_inum_range_out(&ir, bh->b_data + sizeof(struct gfs2_dinode));

 out_brelse:
	brelse(bh);

 out_end_trans:
	mutex_unlock(&sdp->sd_inum_mutex);
	gfs2_trans_end(sdp);

 out:
	gfs2_glock_dq_uninit(&gh);

	return error;
}

static int pick_formal_ino(struct gfs2_sbd *sdp, uint64_t *inum)
{
	int error;

	error = pick_formal_ino_1(sdp, inum);
	if (error <= 0)
		return error;

	error = pick_formal_ino_2(sdp, inum);

	return error;
}

/**
 * create_ok - OK to create a new on-disk inode here?
 * @dip:  Directory in which dinode is to be created
 * @name:  Name of new dinode
 * @mode:
 *
 * Returns: errno
 */

static int create_ok(struct gfs2_inode *dip, struct qstr *name,
		     unsigned int mode)
{
	int error;

	error = gfs2_repermission(dip->i_vnode, MAY_WRITE | MAY_EXEC, NULL);
	if (error)
		return error;

	/*  Don't create entries in an unlinked directory  */
	if (!dip->i_di.di_nlink)
		return -EPERM;

	error = gfs2_dir_search(dip, name, NULL, NULL);
	switch (error) {
	case -ENOENT:
		error = 0;
		break;
	case 0:
		return -EEXIST;
	default:
		return error;
	}

	if (dip->i_di.di_entries == (uint32_t)-1)
		return -EFBIG;
	if (S_ISDIR(mode) && dip->i_di.di_nlink == (uint32_t)-1)
		return -EMLINK;

	return 0;
}

static void munge_mode_uid_gid(struct gfs2_inode *dip, unsigned int *mode,
			       unsigned int *uid, unsigned int *gid)
{
	if (dip->i_sbd->sd_args.ar_suiddir &&
	    (dip->i_di.di_mode & S_ISUID) &&
	    dip->i_di.di_uid) {
		if (S_ISDIR(*mode))
			*mode |= S_ISUID;
		else if (dip->i_di.di_uid != current->fsuid)
			*mode &= ~07111;
		*uid = dip->i_di.di_uid;
	} else
		*uid = current->fsuid;

	if (dip->i_di.di_mode & S_ISGID) {
		if (S_ISDIR(*mode))
			*mode |= S_ISGID;
		*gid = dip->i_di.di_gid;
	} else
		*gid = current->fsgid;
}

static int alloc_dinode(struct gfs2_inode *dip, struct gfs2_unlinked *ul)
{
	struct gfs2_sbd *sdp = dip->i_sbd;
	int error;

	gfs2_alloc_get(dip);

	dip->i_alloc.al_requested = RES_DINODE;
	error = gfs2_inplace_reserve(dip);
	if (error)
		goto out;

	error = gfs2_trans_begin(sdp, RES_RG_BIT + RES_UNLINKED +
				 RES_STATFS, 0);
	if (error)
		goto out_ipreserv;

	ul->ul_ut.ut_inum.no_addr = gfs2_alloc_di(dip);

	ul->ul_ut.ut_flags = GFS2_UTF_UNINIT;
	error = gfs2_unlinked_ondisk_add(sdp, ul);

	gfs2_trans_end(sdp);

 out_ipreserv:
	gfs2_inplace_release(dip);

 out:
	gfs2_alloc_put(dip);

	return error;
}

/**
 * init_dinode - Fill in a new dinode structure
 * @dip: the directory this inode is being created in
 * @gl: The glock covering the new inode
 * @inum: the inode number
 * @mode: the file permissions
 * @uid:
 * @gid:
 *
 */

static void init_dinode(struct gfs2_inode *dip, struct gfs2_glock *gl,
			struct gfs2_inum *inum, unsigned int mode,
			unsigned int uid, unsigned int gid)
{
	struct gfs2_sbd *sdp = dip->i_sbd;
	struct gfs2_dinode *di;
	struct buffer_head *dibh;

	dibh = gfs2_meta_new(gl, inum->no_addr);
	gfs2_trans_add_bh(gl, dibh, 1);
	gfs2_metatype_set(dibh, GFS2_METATYPE_DI, GFS2_FORMAT_DI);
	gfs2_buffer_clear_tail(dibh, sizeof(struct gfs2_dinode));
	di = (struct gfs2_dinode *)dibh->b_data;

	di->di_num.no_formal_ino = cpu_to_be64(inum->no_formal_ino);
	di->di_num.no_addr = cpu_to_be64(inum->no_addr);
	di->di_mode = cpu_to_be32(mode);
	di->di_uid = cpu_to_be32(uid);
	di->di_gid = cpu_to_be32(gid);
	di->di_nlink = cpu_to_be32(0);
	di->di_size = cpu_to_be64(0);
	di->di_blocks = cpu_to_be64(1);
	di->di_atime = di->di_mtime = di->di_ctime = cpu_to_be64(get_seconds());
	di->di_major = di->di_minor = cpu_to_be32(0);
	di->di_goal_meta = di->di_goal_data = cpu_to_be64(inum->no_addr);
	di->__pad[0] = di->__pad[1] = 0;
	di->di_flags = cpu_to_be32(0);

	if (S_ISREG(mode)) {
		if ((dip->i_di.di_flags & GFS2_DIF_INHERIT_JDATA) ||
		    gfs2_tune_get(sdp, gt_new_files_jdata))
			di->di_flags |= cpu_to_be32(GFS2_DIF_JDATA);
		if ((dip->i_di.di_flags & GFS2_DIF_INHERIT_DIRECTIO) ||
		    gfs2_tune_get(sdp, gt_new_files_directio))
			di->di_flags |= cpu_to_be32(GFS2_DIF_DIRECTIO);
	} else if (S_ISDIR(mode)) {
		di->di_flags |= cpu_to_be32(dip->i_di.di_flags & GFS2_DIF_INHERIT_DIRECTIO);
		di->di_flags |= cpu_to_be32(dip->i_di.di_flags & GFS2_DIF_INHERIT_JDATA);
	}

	di->__pad1 = 0;
	di->di_height = cpu_to_be32(0);
	di->__pad2 = 0;
	di->__pad3 = 0;
	di->di_depth = cpu_to_be16(0);
	di->di_entries = cpu_to_be32(0);
	memset(&di->__pad4, 0, sizeof(di->__pad4));
	di->di_eattr = cpu_to_be64(0);
	memset(&di->di_reserved, 0, sizeof(di->di_reserved));

	brelse(dibh);
}

static int make_dinode(struct gfs2_inode *dip, struct gfs2_glock *gl,
		       unsigned int mode, struct gfs2_unlinked *ul)
{
	struct gfs2_sbd *sdp = dip->i_sbd;
	unsigned int uid, gid;
	int error;

	munge_mode_uid_gid(dip, &mode, &uid, &gid);

	gfs2_alloc_get(dip);

	error = gfs2_quota_lock(dip, uid, gid);
	if (error)
		goto out;

	error = gfs2_quota_check(dip, uid, gid);
	if (error)
		goto out_quota;

	error = gfs2_trans_begin(sdp, RES_DINODE + RES_UNLINKED +
				 RES_QUOTA, 0);
	if (error)
		goto out_quota;

	ul->ul_ut.ut_flags = 0;
	error = gfs2_unlinked_ondisk_munge(sdp, ul);

	init_dinode(dip, gl, &ul->ul_ut.ut_inum,
		     mode, uid, gid);

	gfs2_quota_change(dip, +1, uid, gid);

	gfs2_trans_end(sdp);

 out_quota:
	gfs2_quota_unlock(dip);

 out:
	gfs2_alloc_put(dip);

	return error;
}

static int link_dinode(struct gfs2_inode *dip, struct qstr *name,
		       struct gfs2_inode *ip, struct gfs2_unlinked *ul)
{
	struct gfs2_sbd *sdp = dip->i_sbd;
	struct gfs2_alloc *al;
	int alloc_required;
	struct buffer_head *dibh;
	int error;

	al = gfs2_alloc_get(dip);

	error = gfs2_quota_lock(dip, NO_QUOTA_CHANGE, NO_QUOTA_CHANGE);
	if (error)
		goto fail;

	error = gfs2_diradd_alloc_required(dip, name, &alloc_required);
	if (alloc_required) {
		error = gfs2_quota_check(dip, dip->i_di.di_uid,
					 dip->i_di.di_gid);
		if (error)
			goto fail_quota_locks;

		al->al_requested = sdp->sd_max_dirres;

		error = gfs2_inplace_reserve(dip);
		if (error)
			goto fail_quota_locks;

		error = gfs2_trans_begin(sdp,
					 sdp->sd_max_dirres +
					 al->al_rgd->rd_ri.ri_length +
					 2 * RES_DINODE + RES_UNLINKED +
					 RES_STATFS + RES_QUOTA, 0);
		if (error)
			goto fail_ipreserv;
	} else {
		error = gfs2_trans_begin(sdp,
					 RES_LEAF +
					 2 * RES_DINODE +
					 RES_UNLINKED, 0);
		if (error)
			goto fail_quota_locks;
	}

	error = gfs2_dir_add(dip, name, &ip->i_num, IF2DT(ip->i_di.di_mode));
	if (error)
		goto fail_end_trans;

	error = gfs2_meta_inode_buffer(ip, &dibh);
	if (error)
		goto fail_end_trans;
	ip->i_di.di_nlink = 1;
	gfs2_trans_add_bh(ip->i_gl, dibh, 1);
	gfs2_dinode_out(&ip->i_di, dibh->b_data);
	brelse(dibh);

	error = gfs2_unlinked_ondisk_rm(sdp, ul);
	if (error)
		goto fail_end_trans;

	return 0;

 fail_end_trans:
	gfs2_trans_end(sdp);

 fail_ipreserv:
	if (dip->i_alloc.al_rgd)
		gfs2_inplace_release(dip);

 fail_quota_locks:
	gfs2_quota_unlock(dip);

 fail:
	gfs2_alloc_put(dip);

	return error;
}

/**
 * gfs2_createi - Create a new inode
 * @ghs: An array of two holders
 * @name: The name of the new file
 * @mode: the permissions on the new inode
 *
 * @ghs[0] is an initialized holder for the directory
 * @ghs[1] is the holder for the inode lock
 *
 * If the return value is not NULL, the glocks on both the directory and the new
 * file are held.  A transaction has been started and an inplace reservation
 * is held, as well.
 *
 * Returns: An inode
 */

struct inode *gfs2_createi(struct gfs2_holder *ghs, struct qstr *name, unsigned int mode)
{
	struct inode *inode;
	struct gfs2_inode *dip = get_gl2ip(ghs->gh_gl);
	struct gfs2_sbd *sdp = dip->i_sbd;
	struct gfs2_unlinked *ul;
	struct gfs2_inode *ip;
	int error;

	if (!name->len || name->len > GFS2_FNAMESIZE)
		return ERR_PTR(-ENAMETOOLONG);

	error = gfs2_unlinked_get(sdp, &ul);
	if (error)
		return ERR_PTR(error);

	gfs2_holder_reinit(LM_ST_EXCLUSIVE, 0, ghs);
	error = gfs2_glock_nq(ghs);
	if (error)
		goto fail;

	error = create_ok(dip, name, mode);
	if (error)
		goto fail_gunlock;

	error = pick_formal_ino(sdp, &ul->ul_ut.ut_inum.no_formal_ino);
	if (error)
		goto fail_gunlock;

	error = alloc_dinode(dip, ul);
	if (error)
		goto fail_gunlock;

	if (ul->ul_ut.ut_inum.no_addr < dip->i_num.no_addr) {
		gfs2_glock_dq(ghs);

		error = gfs2_glock_nq_num(sdp,
					  ul->ul_ut.ut_inum.no_addr,
					  &gfs2_inode_glops,
					  LM_ST_EXCLUSIVE, GL_SKIP,
					  ghs + 1);
		if (error) {
			gfs2_unlinked_put(sdp, ul);
			return ERR_PTR(error);
		}

		gfs2_holder_reinit(LM_ST_EXCLUSIVE, 0, ghs);
		error = gfs2_glock_nq(ghs);
		if (error) {
			gfs2_glock_dq_uninit(ghs + 1);
			gfs2_unlinked_put(sdp, ul);
			return ERR_PTR(error);
		}

		error = create_ok(dip, name, mode);
		if (error)
			goto fail_gunlock2;
	} else {
		error = gfs2_glock_nq_num(sdp,
					  ul->ul_ut.ut_inum.no_addr,
					  &gfs2_inode_glops,
					  LM_ST_EXCLUSIVE, GL_SKIP,
					  ghs + 1);
		if (error)
			goto fail_gunlock;
	}

	error = make_dinode(dip, ghs[1].gh_gl, mode, ul);
	if (error)
		goto fail_gunlock2;

	error = gfs2_inode_get(ghs[1].gh_gl, &ul->ul_ut.ut_inum, CREATE, &ip);
	if (error)
		goto fail_gunlock2;

	error = gfs2_inode_refresh(ip);
	if (error)
		goto fail_iput;

	error = gfs2_acl_create(dip, ip);
	if (error)
		goto fail_iput;

	error = link_dinode(dip, name, ip, ul);
	if (error)
		goto fail_iput;

	gfs2_unlinked_put(sdp, ul);

	inode = gfs2_ip2v(ip);
	gfs2_inode_put(ip);
	if (!inode)
		return ERR_PTR(-ENOMEM);
	return inode;

 fail_iput:
	gfs2_inode_put(ip);

 fail_gunlock2:
	gfs2_glock_dq_uninit(ghs + 1);

 fail_gunlock:
	gfs2_glock_dq(ghs);

 fail:
	gfs2_unlinked_put(sdp, ul);

	return ERR_PTR(error);
}

/**
 * gfs2_unlinki - Unlink a file
 * @dip: The inode of the directory
 * @name: The name of the file to be unlinked
 * @ip: The inode of the file to be removed
 *
 * Assumes Glocks on both dip and ip are held.
 *
 * Returns: errno
 */

int gfs2_unlinki(struct gfs2_inode *dip, struct qstr *name,
		 struct gfs2_inode *ip, struct gfs2_unlinked *ul)
{
	struct gfs2_sbd *sdp = dip->i_sbd;
	int error;

	error = gfs2_dir_del(dip, name);
	if (error)
		return error;

	error = gfs2_change_nlink(ip, -1);
	if (error)
		return error;

	/* If this inode is being unlinked from the directory structure,
	   we need to mark that in the log so that it isn't lost during
	   a crash. */

	if (!ip->i_di.di_nlink) {
		ul->ul_ut.ut_inum = ip->i_num;
		error = gfs2_unlinked_ondisk_add(sdp, ul);
		if (!error)
			set_bit(GLF_STICKY, &ip->i_gl->gl_flags);
	}

	return error;
}

/**
 * gfs2_rmdiri - Remove a directory
 * @dip: The parent directory of the directory to be removed
 * @name: The name of the directory to be removed
 * @ip: The GFS2 inode of the directory to be removed
 *
 * Assumes Glocks on dip and ip are held
 *
 * Returns: errno
 */

int gfs2_rmdiri(struct gfs2_inode *dip, struct qstr *name,
		struct gfs2_inode *ip, struct gfs2_unlinked *ul)
{
	struct gfs2_sbd *sdp = dip->i_sbd;
	struct qstr dotname;
	int error;

	if (ip->i_di.di_entries != 2) {
		if (gfs2_consist_inode(ip))
			gfs2_dinode_print(&ip->i_di);
		return -EIO;
	}

	error = gfs2_dir_del(dip, name);
	if (error)
		return error;

	error = gfs2_change_nlink(dip, -1);
	if (error)
		return error;

	dotname.len = 1;
	dotname.name = ".";
	error = gfs2_dir_del(ip, &dotname);
	if (error)
		return error;

	dotname.len = 2;
	dotname.name = "..";
	error = gfs2_dir_del(ip, &dotname);
	if (error)
		return error;

	error = gfs2_change_nlink(ip, -2);
	if (error)
		return error;

	/* This inode is being unlinked from the directory structure and
	   we need to mark that in the log so that it isn't lost during
	   a crash. */

	ul->ul_ut.ut_inum = ip->i_num;
	error = gfs2_unlinked_ondisk_add(sdp, ul);
	if (!error)
		set_bit(GLF_STICKY, &ip->i_gl->gl_flags);

	return error;
}

/*
 * gfs2_unlink_ok - check to see that a inode is still in a directory
 * @dip: the directory
 * @name: the name of the file
 * @ip: the inode
 *
 * Assumes that the lock on (at least) @dip is held.
 *
 * Returns: 0 if the parent/child relationship is correct, errno if it isn't
 */

int gfs2_unlink_ok(struct gfs2_inode *dip, struct qstr *name,
		   struct gfs2_inode *ip)
{
	struct gfs2_inum inum;
	unsigned int type;
	int error;

	if (IS_IMMUTABLE(ip->i_vnode) || IS_APPEND(ip->i_vnode))
		return -EPERM;

	if ((dip->i_di.di_mode & S_ISVTX) &&
	    dip->i_di.di_uid != current->fsuid &&
	    ip->i_di.di_uid != current->fsuid &&
	    !capable(CAP_FOWNER))
		return -EPERM;

	if (IS_APPEND(dip->i_vnode))
		return -EPERM;

	error = gfs2_repermission(dip->i_vnode, MAY_WRITE | MAY_EXEC, NULL);
	if (error)
		return error;

	error = gfs2_dir_search(dip, name, &inum, &type);
	if (error)
		return error;

	if (!gfs2_inum_equal(&inum, &ip->i_num))
		return -ENOENT;

	if (IF2DT(ip->i_di.di_mode) != type) {
		gfs2_consist_inode(dip);
		return -EIO;
	}

	return 0;
}

/*
 * gfs2_ok_to_move - check if it's ok to move a directory to another directory
 * @this: move this
 * @to: to here
 *
 * Follow @to back to the root and make sure we don't encounter @this
 * Assumes we already hold the rename lock.
 *
 * Returns: errno
 */

int gfs2_ok_to_move(struct gfs2_inode *this, struct gfs2_inode *to)
{
	struct gfs2_sbd *sdp = this->i_sbd;
	struct inode *dir = to->i_vnode;
	struct inode *tmp;
	struct qstr dotdot;
	int error = 0;

	memset(&dotdot, 0, sizeof(struct qstr));
	dotdot.name = "..";
	dotdot.len = 2;

	igrab(dir);

	for (;;) {
		if (dir == this->i_vnode) {
			error = -EINVAL;
			break;
		}
		if (dir == sdp->sd_root_dir) {
			error = 0;
			break;
		}

		error = gfs2_lookupi(dir, &dotdot, 1, &tmp);
		if (error)
			break;

		iput(dir);
		dir = tmp;
	}

	iput(dir);

	return error;
}

/**
 * gfs2_readlinki - return the contents of a symlink
 * @ip: the symlink's inode
 * @buf: a pointer to the buffer to be filled
 * @len: a pointer to the length of @buf
 *
 * If @buf is too small, a piece of memory is kmalloc()ed and needs
 * to be freed by the caller.
 *
 * Returns: errno
 */

int gfs2_readlinki(struct gfs2_inode *ip, char **buf, unsigned int *len)
{
	struct gfs2_holder i_gh;
	struct buffer_head *dibh;
	unsigned int x;
	int error;

	gfs2_holder_init(ip->i_gl, LM_ST_SHARED, GL_ATIME, &i_gh);
	error = gfs2_glock_nq_atime(&i_gh);
	if (error) {
		gfs2_holder_uninit(&i_gh);
		return error;
	}

	if (!ip->i_di.di_size) {
		gfs2_consist_inode(ip);
		error = -EIO;
		goto out;
	}

	error = gfs2_meta_inode_buffer(ip, &dibh);
	if (error)
		goto out;

	x = ip->i_di.di_size + 1;
	if (x > *len) {
		*buf = kmalloc(x, GFP_KERNEL);
		if (!*buf) {
			error = -ENOMEM;
			goto out_brelse;
		}
	}

	memcpy(*buf, dibh->b_data + sizeof(struct gfs2_dinode), x);
	*len = x;

 out_brelse:
	brelse(dibh);

 out:
	gfs2_glock_dq_uninit(&i_gh);

	return error;
}

/**
 * gfs2_glock_nq_atime - Acquire a hold on an inode's glock, and
 *       conditionally update the inode's atime
 * @gh: the holder to acquire
 *
 * Tests atime (access time) for gfs2_read, gfs2_readdir and gfs2_mmap
 * Update if the difference between the current time and the inode's current
 * atime is greater than an interval specified at mount.
 *
 * Returns: errno
 */

int gfs2_glock_nq_atime(struct gfs2_holder *gh)
{
	struct gfs2_glock *gl = gh->gh_gl;
	struct gfs2_sbd *sdp = gl->gl_sbd;
	struct gfs2_inode *ip = get_gl2ip(gl);
	int64_t curtime, quantum = gfs2_tune_get(sdp, gt_atime_quantum);
	unsigned int state;
	int flags;
	int error;

	if (gfs2_assert_warn(sdp, gh->gh_flags & GL_ATIME) ||
	    gfs2_assert_warn(sdp, !(gh->gh_flags & GL_ASYNC)) ||
	    gfs2_assert_warn(sdp, gl->gl_ops == &gfs2_inode_glops))
		return -EINVAL;

	state = gh->gh_state;
	flags = gh->gh_flags;

	error = gfs2_glock_nq(gh);
	if (error)
		return error;

	if (test_bit(SDF_NOATIME, &sdp->sd_flags) ||
	    (sdp->sd_vfs->s_flags & MS_RDONLY))
		return 0;

	curtime = get_seconds();
	if (curtime - ip->i_di.di_atime >= quantum) {
		gfs2_glock_dq(gh);
		gfs2_holder_reinit(LM_ST_EXCLUSIVE,
				  gh->gh_flags & ~LM_FLAG_ANY,
				  gh);
		error = gfs2_glock_nq(gh);
		if (error)
			return error;

		/* Verify that atime hasn't been updated while we were
		   trying to get exclusive lock. */

		curtime = get_seconds();
		if (curtime - ip->i_di.di_atime >= quantum) {
			struct buffer_head *dibh;

			error = gfs2_trans_begin(sdp, RES_DINODE, 0);
			if (error == -EROFS)
				return 0;
			if (error)
				goto fail;

			error = gfs2_meta_inode_buffer(ip, &dibh);
			if (error)
				goto fail_end_trans;

			ip->i_di.di_atime = curtime;

			gfs2_trans_add_bh(ip->i_gl, dibh, 1);
			gfs2_dinode_out(&ip->i_di, dibh->b_data);
			brelse(dibh);

			gfs2_trans_end(sdp);
		}

		/* If someone else has asked for the glock,
		   unlock and let them have it. Then reacquire
		   in the original state. */
		if (gfs2_glock_is_blocking(gl)) {
			gfs2_glock_dq(gh);
			gfs2_holder_reinit(state, flags, gh);
			return gfs2_glock_nq(gh);
		}
	}

	return 0;

 fail_end_trans:
	gfs2_trans_end(sdp);

 fail:
	gfs2_glock_dq(gh);

	return error;
}

/**
 * glock_compare_atime - Compare two struct gfs2_glock structures for sort
 * @arg_a: the first structure
 * @arg_b: the second structure
 *
 * Returns: 1 if A > B
 *         -1 if A < B
 *          0 if A = B
 */

static int glock_compare_atime(const void *arg_a, const void *arg_b)
{
	struct gfs2_holder *gh_a = *(struct gfs2_holder **)arg_a;
	struct gfs2_holder *gh_b = *(struct gfs2_holder **)arg_b;
	struct lm_lockname *a = &gh_a->gh_gl->gl_name;
	struct lm_lockname *b = &gh_b->gh_gl->gl_name;
	int ret = 0;

	if (a->ln_number > b->ln_number)
		ret = 1;
	else if (a->ln_number < b->ln_number)
		ret = -1;
	else {
		if (gh_a->gh_state == LM_ST_SHARED &&
		    gh_b->gh_state == LM_ST_EXCLUSIVE)
			ret = 1;
		else if (gh_a->gh_state == LM_ST_SHARED &&
			 (gh_b->gh_flags & GL_ATIME))
			ret = 1;
	}

	return ret;
}

/**
 * gfs2_glock_nq_m_atime - acquire multiple glocks where one may need an
 *      atime update
 * @num_gh: the number of structures
 * @ghs: an array of struct gfs2_holder structures
 *
 * Returns: 0 on success (all glocks acquired),
 *          errno on failure (no glocks acquired)
 */

int gfs2_glock_nq_m_atime(unsigned int num_gh, struct gfs2_holder *ghs)
{
	struct gfs2_holder **p;
	unsigned int x;
	int error = 0;

	if (!num_gh)
		return 0;

	if (num_gh == 1) {
		ghs->gh_flags &= ~(LM_FLAG_TRY | GL_ASYNC);
		if (ghs->gh_flags & GL_ATIME)
			error = gfs2_glock_nq_atime(ghs);
		else
			error = gfs2_glock_nq(ghs);
		return error;
	}

	p = kcalloc(num_gh, sizeof(struct gfs2_holder *), GFP_KERNEL);
	if (!p)
		return -ENOMEM;

	for (x = 0; x < num_gh; x++)
		p[x] = &ghs[x];

	sort(p, num_gh, sizeof(struct gfs2_holder *), glock_compare_atime,NULL);

	for (x = 0; x < num_gh; x++) {
		p[x]->gh_flags &= ~(LM_FLAG_TRY | GL_ASYNC);

		if (p[x]->gh_flags & GL_ATIME)
			error = gfs2_glock_nq_atime(p[x]);
		else
			error = gfs2_glock_nq(p[x]);

		if (error) {
			while (x--)
				gfs2_glock_dq(p[x]);
			break;
		}
	}

	kfree(p);

	return error;
}

/**
 * gfs2_try_toss_vnode - See if we can toss a vnode from memory
 * @ip: the inode
 *
 * Returns:  1 if the vnode was tossed
 */

void gfs2_try_toss_vnode(struct gfs2_inode *ip)
{
	struct inode *inode;

	inode = gfs2_ip2v_lookup(ip);
	if (!inode)
		return;

	d_prune_aliases(inode);

	if (S_ISDIR(ip->i_di.di_mode)) {
		struct list_head *head = &inode->i_dentry;
		struct dentry *d = NULL;

		spin_lock(&dcache_lock);
		if (list_empty(head))
			spin_unlock(&dcache_lock);
		else {
			d = list_entry(head->next, struct dentry, d_alias);
			dget_locked(d);
			spin_unlock(&dcache_lock);

			if (have_submounts(d))
				dput(d);
			else {
				shrink_dcache_parent(d);
				dput(d);
				d_prune_aliases(inode);
			}
		}
	}

	inode->i_nlink = 0;
	iput(inode);
}


static int
__gfs2_setattr_simple(struct gfs2_inode *ip, struct iattr *attr)
{
	struct buffer_head *dibh;
	int error;

	error = gfs2_meta_inode_buffer(ip, &dibh);
	if (!error) {
		error = inode_setattr(ip->i_vnode, attr);
		gfs2_assert_warn(ip->i_sbd, !error);
		gfs2_inode_attr_out(ip);

		gfs2_trans_add_bh(ip->i_gl, dibh, 1);
		gfs2_dinode_out(&ip->i_di, dibh->b_data);
		brelse(dibh);
	}
	return error;
}

/**
 * gfs2_setattr_simple -
 * @ip:
 * @attr:
 *
 * Called with a reference on the vnode.
 *
 * Returns: errno
 */

int gfs2_setattr_simple(struct gfs2_inode *ip, struct iattr *attr)
{
	int error;

	if (get_transaction)
		return __gfs2_setattr_simple(ip, attr);

	error = gfs2_trans_begin(ip->i_sbd, RES_DINODE, 0);
	if (error)
		return error;

	error = __gfs2_setattr_simple(ip, attr);

	gfs2_trans_end(ip->i_sbd);

	return error;
}

int gfs2_repermission(struct inode *inode, int mask, struct nameidata *nd)
{
	return permission(inode, mask, nd);
}

