/*
 * Copyright 2000 by Hans Reiser, licensing governed by reiserfs/README
 */

#include <linux/fs.h>
#include <linux/reiserfs_fs.h>
#include <linux/time.h>
#include <asm/uaccess.h>
#include <linux/pagemap.h>
#include <linux/smp_lock.h>

static int reiserfs_unpack(struct inode *inode, struct file *filp);

/*
** reiserfs_ioctl - handler for ioctl for inode
** supported commands:
**  1) REISERFS_IOC_UNPACK - try to unpack tail from direct item into indirect
**                           and prevent packing file (argument arg has to be non-zero)
**  2) REISERFS_IOC_[GS]ETFLAGS, REISERFS_IOC_[GS]ETVERSION
**  3) That's all for a while ...
*/
int reiserfs_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
		   unsigned long arg)
{
	unsigned int flags;

	switch (cmd) {
	case REISERFS_IOC_UNPACK:
		if (S_ISREG(inode->i_mode)) {
			if (arg)
				return reiserfs_unpack(inode, filp);
			else
				return 0;
		} else
			return -ENOTTY;
		/* following two cases are taken from fs/ext2/ioctl.c by Remy
		   Card (card@masi.ibp.fr) */
	case REISERFS_IOC_GETFLAGS:
		if (!reiserfs_attrs(inode->i_sb))
			return -ENOTTY;

		flags = REISERFS_I(inode)->i_attrs;
		i_attrs_to_sd_attrs(inode, (__u16 *) & flags);
		return put_user(flags, (int __user *)arg);
	case REISERFS_IOC_SETFLAGS:{
			if (!reiserfs_attrs(inode->i_sb))
				return -ENOTTY;

			if (IS_RDONLY(inode))
				return -EROFS;

			if ((current->fsuid != inode->i_uid)
			    && !capable(CAP_FOWNER))
				return -EPERM;

			if (get_user(flags, (int __user *)arg))
				return -EFAULT;

			if (((flags ^ REISERFS_I(inode)->
			      i_attrs) & (REISERFS_IMMUTABLE_FL |
					  REISERFS_APPEND_FL))
			    && !capable(CAP_LINUX_IMMUTABLE))
				return -EPERM;

			if ((flags & REISERFS_NOTAIL_FL) &&
			    S_ISREG(inode->i_mode)) {
				int result;

				result = reiserfs_unpack(inode, filp);
				if (result)
					return result;
			}
			sd_attrs_to_i_attrs(flags, inode);
			REISERFS_I(inode)->i_attrs = flags;
			inode->i_ctime = CURRENT_TIME_SEC;
			mark_inode_dirty(inode);
			return 0;
		}
	case REISERFS_IOC_GETVERSION:
		return put_user(inode->i_generation, (int __user *)arg);
	case REISERFS_IOC_SETVERSION:
		if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER))
			return -EPERM;
		if (IS_RDONLY(inode))
			return -EROFS;
		if (get_user(inode->i_generation, (int __user *)arg))
			return -EFAULT;
		inode->i_ctime = CURRENT_TIME_SEC;
		mark_inode_dirty(inode);
		return 0;
	default:
		return -ENOTTY;
	}
}

/*
** reiserfs_unpack
** Function try to convert tail from direct item into indirect.
** It set up nopack attribute in the REISERFS_I(inode)->nopack
*/
static int reiserfs_unpack(struct inode *inode, struct file *filp)
{
	int retval = 0;
	int index;
	struct page *page;
	struct address_space *mapping;
	unsigned long write_from;
	unsigned long blocksize = inode->i_sb->s_blocksize;

	if (inode->i_size == 0) {
		REISERFS_I(inode)->i_flags |= i_nopack_mask;
		return 0;
	}
	/* ioctl already done */
	if (REISERFS_I(inode)->i_flags & i_nopack_mask) {
		return 0;
	}
	reiserfs_write_lock(inode->i_sb);

	/* we need to make sure nobody is changing the file size beneath
	 ** us
	 */
	down(&inode->i_sem);

	write_from = inode->i_size & (blocksize - 1);
	/* if we are on a block boundary, we are already unpacked.  */
	if (write_from == 0) {
		REISERFS_I(inode)->i_flags |= i_nopack_mask;
		goto out;
	}

	/* we unpack by finding the page with the tail, and calling
	 ** reiserfs_prepare_write on that page.  This will force a 
	 ** reiserfs_get_block to unpack the tail for us.
	 */
	index = inode->i_size >> PAGE_CACHE_SHIFT;
	mapping = inode->i_mapping;
	page = grab_cache_page(mapping, index);
	retval = -ENOMEM;
	if (!page) {
		goto out;
	}
	retval =
	    mapping->a_ops->prepare_write(NULL, page, write_from, write_from);
	if (retval)
		goto out_unlock;

	/* conversion can change page contents, must flush */
	flush_dcache_page(page);
	retval =
	    mapping->a_ops->commit_write(NULL, page, write_from, write_from);
	REISERFS_I(inode)->i_flags |= i_nopack_mask;

      out_unlock:
	unlock_page(page);
	page_cache_release(page);

      out:
	up(&inode->i_sem);
	reiserfs_write_unlock(inode->i_sb);
	return retval;
}
