/*
 *  linux/fs/nfs/unlink.c
 *
 * nfs sillydelete handling
 *
 * NOTE: we rely on holding the BKL for list manipulation protection.
 */

#include <linux/slab.h>
#include <linux/string.h>
#include <linux/dcache.h>
#include <linux/sunrpc/sched.h>
#include <linux/sunrpc/clnt.h>
#include <linux/nfs_fs.h>


struct nfs_unlinkdata {
	struct nfs_unlinkdata	*next;
	struct dentry	*dir, *dentry;
	struct qstr	name;
	struct rpc_task	task;
	struct rpc_cred	*cred;
	unsigned int	count;
};

static struct nfs_unlinkdata	*nfs_deletes;
static RPC_WAITQ(nfs_delete_queue, "nfs_delete_queue");

/**
 * nfs_detach_unlinkdata - Remove asynchronous unlink from global list
 * @data: pointer to descriptor
 */
static inline void
nfs_detach_unlinkdata(struct nfs_unlinkdata *data)
{
	struct nfs_unlinkdata	**q;

	for (q = &nfs_deletes; *q != NULL; q = &((*q)->next)) {
		if (*q == data) {
			*q = data->next;
			break;
		}
	}
}

/**
 * nfs_put_unlinkdata - release data from a sillydelete operation.
 * @data: pointer to unlink structure.
 */
static void
nfs_put_unlinkdata(struct nfs_unlinkdata *data)
{
	if (--data->count == 0) {
		nfs_detach_unlinkdata(data);
		if (data->name.name != NULL)
			kfree(data->name.name);
		kfree(data);
	}
}

#define NAME_ALLOC_LEN(len)	((len+16) & ~15)
/**
 * nfs_copy_dname - copy dentry name to data structure
 * @dentry: pointer to dentry
 * @data: nfs_unlinkdata
 */
static inline void
nfs_copy_dname(struct dentry *dentry, struct nfs_unlinkdata *data)
{
	char		*str;
	int		len = dentry->d_name.len;

	str = kmalloc(NAME_ALLOC_LEN(len), GFP_KERNEL);
	if (!str)
		return;
	memcpy(str, dentry->d_name.name, len);
	if (!data->name.len) {
		data->name.len = len;
		data->name.name = str;
	} else
		kfree(str);
}

/**
 * nfs_async_unlink_init - Initialize the RPC info
 * @task: rpc_task of the sillydelete
 *
 * We delay initializing RPC info until after the call to dentry_iput()
 * in order to minimize races against rename().
 */
static void
nfs_async_unlink_init(struct rpc_task *task)
{
	struct nfs_unlinkdata	*data = (struct nfs_unlinkdata *)task->tk_calldata;
	struct dentry		*dir = data->dir;
	struct rpc_message	msg = {
		.rpc_cred	= data->cred,
	};
	int			status = -ENOENT;

	if (!data->name.len)
		goto out_err;

	status = NFS_PROTO(dir->d_inode)->unlink_setup(&msg, dir, &data->name);
	if (status < 0)
		goto out_err;
	nfs_begin_data_update(dir->d_inode);
	rpc_call_setup(task, &msg, 0);
	return;
 out_err:
	rpc_exit(task, status);
}

/**
 * nfs_async_unlink_done - Sillydelete post-processing
 * @task: rpc_task of the sillydelete
 *
 * Do the directory attribute update.
 */
static void
nfs_async_unlink_done(struct rpc_task *task)
{
	struct nfs_unlinkdata	*data = (struct nfs_unlinkdata *)task->tk_calldata;
	struct dentry		*dir = data->dir;
	struct inode		*dir_i;

	if (!dir)
		return;
	dir_i = dir->d_inode;
	nfs_end_data_update(dir_i);
	if (NFS_PROTO(dir_i)->unlink_done(dir, task))
		return;
	put_rpccred(data->cred);
	data->cred = NULL;
	dput(dir);
}

/**
 * nfs_async_unlink_release - Release the sillydelete data.
 * @task: rpc_task of the sillydelete
 *
 * We need to call nfs_put_unlinkdata as a 'tk_release' task since the
 * rpc_task would be freed too.
 */
static void
nfs_async_unlink_release(struct rpc_task *task)
{
	struct nfs_unlinkdata	*data = (struct nfs_unlinkdata *)task->tk_calldata;
	nfs_put_unlinkdata(data);
}

/**
 * nfs_async_unlink - asynchronous unlinking of a file
 * @dentry: dentry to unlink
 */
int
nfs_async_unlink(struct dentry *dentry)
{
	struct dentry	*dir = dentry->d_parent;
	struct nfs_unlinkdata	*data;
	struct rpc_task	*task;
	struct rpc_clnt	*clnt = NFS_CLIENT(dir->d_inode);
	int		status = -ENOMEM;

	data = kmalloc(sizeof(*data), GFP_KERNEL);
	if (!data)
		goto out;
	memset(data, 0, sizeof(*data));

	data->cred = rpcauth_lookupcred(clnt->cl_auth, 0);
	if (IS_ERR(data->cred)) {
		status = PTR_ERR(data->cred);
		goto out_free;
	}
	data->dir = dget(dir);
	data->dentry = dentry;

	data->next = nfs_deletes;
	nfs_deletes = data;
	data->count = 1;

	task = &data->task;
	rpc_init_task(task, clnt, nfs_async_unlink_done , RPC_TASK_ASYNC);
	task->tk_calldata = data;
	task->tk_action = nfs_async_unlink_init;
	task->tk_release = nfs_async_unlink_release;

	spin_lock(&dentry->d_lock);
	dentry->d_flags |= DCACHE_NFSFS_RENAMED;
	spin_unlock(&dentry->d_lock);

	rpc_sleep_on(&nfs_delete_queue, task, NULL, NULL);
	status = 0;
 out:
	return status;
out_free:
	kfree(data);
	return status;
}

/**
 * nfs_complete_unlink - Initialize completion of the sillydelete
 * @dentry: dentry to delete
 *
 * Since we're most likely to be called by dentry_iput(), we
 * only use the dentry to find the sillydelete. We then copy the name
 * into the qstr.
 */
void
nfs_complete_unlink(struct dentry *dentry)
{
	struct nfs_unlinkdata	*data;

	for(data = nfs_deletes; data != NULL; data = data->next) {
		if (dentry == data->dentry)
			break;
	}
	if (!data)
		return;
	data->count++;
	nfs_copy_dname(dentry, data);
	spin_lock(&dentry->d_lock);
	dentry->d_flags &= ~DCACHE_NFSFS_RENAMED;
	spin_unlock(&dentry->d_lock);
	rpc_wake_up_task(&data->task);
	nfs_put_unlinkdata(data);
}
