/*
 *  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);
		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);
}
