xref: /openbmc/linux/fs/nfs/unlink.c (revision 7ae9fb1b7ecbb5d85d07857943f677fd1a559b18)
1b2441318SGreg Kroah-Hartman // SPDX-License-Identifier: GPL-2.0
21da177e4SLinus Torvalds /*
31da177e4SLinus Torvalds  *  linux/fs/nfs/unlink.c
41da177e4SLinus Torvalds  *
51da177e4SLinus Torvalds  * nfs sillydelete handling
61da177e4SLinus Torvalds  *
71da177e4SLinus Torvalds  */
81da177e4SLinus Torvalds 
91da177e4SLinus Torvalds #include <linux/slab.h>
101da177e4SLinus Torvalds #include <linux/string.h>
111da177e4SLinus Torvalds #include <linux/dcache.h>
121da177e4SLinus Torvalds #include <linux/sunrpc/sched.h>
131da177e4SLinus Torvalds #include <linux/sunrpc/clnt.h>
141da177e4SLinus Torvalds #include <linux/nfs_fs.h>
15b35e7041SLinus Torvalds #include <linux/sched.h>
16b35e7041SLinus Torvalds #include <linux/wait.h>
17779c5179SJeff Layton #include <linux/namei.h>
18f7be7284SJeff Layton #include <linux/fsnotify.h>
191da177e4SLinus Torvalds 
20ef818a28SSteve Dickson #include "internal.h"
21472cfbd9SAndy Adamson #include "nfs4_fs.h"
22779c5179SJeff Layton #include "iostat.h"
23779c5179SJeff Layton #include "delegation.h"
24ef818a28SSteve Dickson 
2570ded201STrond Myklebust #include "nfstrace.h"
2670ded201STrond Myklebust 
271da177e4SLinus Torvalds /**
28e4eff1a6STrond Myklebust  * nfs_free_unlinkdata - release data from a sillydelete operation.
291da177e4SLinus Torvalds  * @data: pointer to unlink structure.
301da177e4SLinus Torvalds  */
311da177e4SLinus Torvalds static void
nfs_free_unlinkdata(struct nfs_unlinkdata * data)32e4eff1a6STrond Myklebust nfs_free_unlinkdata(struct nfs_unlinkdata *data)
331da177e4SLinus Torvalds {
34a52458b4SNeilBrown 	put_cred(data->cred);
35e4eff1a6STrond Myklebust 	kfree(data->args.name.name);
361da177e4SLinus Torvalds 	kfree(data);
371da177e4SLinus Torvalds }
381da177e4SLinus Torvalds 
391da177e4SLinus Torvalds /**
401da177e4SLinus Torvalds  * nfs_async_unlink_done - Sillydelete post-processing
411da177e4SLinus Torvalds  * @task: rpc_task of the sillydelete
42302fad7bSTrond Myklebust  * @calldata: pointer to nfs_unlinkdata
431da177e4SLinus Torvalds  *
441da177e4SLinus Torvalds  * Do the directory attribute update.
451da177e4SLinus Torvalds  */
nfs_async_unlink_done(struct rpc_task * task,void * calldata)46963d8fe5STrond Myklebust static void nfs_async_unlink_done(struct rpc_task *task, void *calldata)
471da177e4SLinus Torvalds {
48963d8fe5STrond Myklebust 	struct nfs_unlinkdata *data = calldata;
49884be175SAl Viro 	struct inode *dir = d_inode(data->dentry->d_parent);
501da177e4SLinus Torvalds 
5170ded201STrond Myklebust 	trace_nfs_sillyrename_unlink(data, task->tk_status);
52e4eff1a6STrond Myklebust 	if (!NFS_PROTO(dir)->unlink_done(task, dir))
53d00c5d43STrond Myklebust 		rpc_restart_call_prepare(task);
541da177e4SLinus Torvalds }
551da177e4SLinus Torvalds 
561da177e4SLinus Torvalds /**
571da177e4SLinus Torvalds  * nfs_async_unlink_release - Release the sillydelete data.
58302fad7bSTrond Myklebust  * @calldata: struct nfs_unlinkdata to release
591da177e4SLinus Torvalds  *
601da177e4SLinus Torvalds  * We need to call nfs_put_unlinkdata as a 'tk_release' task since the
611da177e4SLinus Torvalds  * rpc_task would be freed too.
621da177e4SLinus Torvalds  */
nfs_async_unlink_release(void * calldata)63963d8fe5STrond Myklebust static void nfs_async_unlink_release(void *calldata)
641da177e4SLinus Torvalds {
65963d8fe5STrond Myklebust 	struct nfs_unlinkdata	*data = calldata;
66884be175SAl Viro 	struct dentry *dentry = data->dentry;
67884be175SAl Viro 	struct super_block *sb = dentry->d_sb;
68565277f6STrond Myklebust 
69884be175SAl Viro 	up_read_non_owner(&NFS_I(d_inode(dentry->d_parent))->rmdir_sem);
70884be175SAl Viro 	d_lookup_done(dentry);
71e4eff1a6STrond Myklebust 	nfs_free_unlinkdata(data);
72884be175SAl Viro 	dput(dentry);
73322b2b90STrond Myklebust 	nfs_sb_deactive(sb);
741da177e4SLinus Torvalds }
751da177e4SLinus Torvalds 
nfs_unlink_prepare(struct rpc_task * task,void * calldata)7617280175STrond Myklebust static void nfs_unlink_prepare(struct rpc_task *task, void *calldata)
77472cfbd9SAndy Adamson {
78472cfbd9SAndy Adamson 	struct nfs_unlinkdata *data = calldata;
79884be175SAl Viro 	struct inode *dir = d_inode(data->dentry->d_parent);
80884be175SAl Viro 	NFS_PROTO(dir)->unlink_rpc_prepare(task, data);
81472cfbd9SAndy Adamson }
82472cfbd9SAndy Adamson 
83963d8fe5STrond Myklebust static const struct rpc_call_ops nfs_unlink_ops = {
84963d8fe5STrond Myklebust 	.rpc_call_done = nfs_async_unlink_done,
85963d8fe5STrond Myklebust 	.rpc_release = nfs_async_unlink_release,
86472cfbd9SAndy Adamson 	.rpc_call_prepare = nfs_unlink_prepare,
87963d8fe5STrond Myklebust };
88963d8fe5STrond Myklebust 
nfs_do_call_unlink(struct inode * inode,struct nfs_unlinkdata * data)89ed7e9ad0STrond Myklebust static void nfs_do_call_unlink(struct inode *inode, struct nfs_unlinkdata *data)
90e4eff1a6STrond Myklebust {
915138fde0STrond Myklebust 	struct rpc_message msg = {
925138fde0STrond Myklebust 		.rpc_argp = &data->args,
935138fde0STrond Myklebust 		.rpc_resp = &data->res,
945138fde0STrond Myklebust 		.rpc_cred = data->cred,
955138fde0STrond Myklebust 	};
96c970aa85STrond Myklebust 	struct rpc_task_setup task_setup_data = {
975138fde0STrond Myklebust 		.rpc_message = &msg,
98c970aa85STrond Myklebust 		.callback_ops = &nfs_unlink_ops,
99c970aa85STrond Myklebust 		.callback_data = data,
1001daef0a8STrond Myklebust 		.workqueue = nfsiod_workqueue,
10149cd3254STrond Myklebust 		.flags = RPC_TASK_ASYNC | RPC_TASK_CRED_NOREF,
102c970aa85STrond Myklebust 	};
103e4eff1a6STrond Myklebust 	struct rpc_task *task;
104884be175SAl Viro 	struct inode *dir = d_inode(data->dentry->d_parent);
105118f09edSOlga Kornievskaia 
106118f09edSOlga Kornievskaia 	if (nfs_server_capable(inode, NFS_CAP_MOVEABLE))
107118f09edSOlga Kornievskaia 		task_setup_data.flags |= RPC_TASK_MOVEABLE;
108118f09edSOlga Kornievskaia 
1091daef0a8STrond Myklebust 	nfs_sb_active(dir->i_sb);
110e4eff1a6STrond Myklebust 	data->args.fh = NFS_FH(dir);
111d346890bSTrond Myklebust 	nfs_fattr_init(data->res.dir_attr);
112e4eff1a6STrond Myklebust 
113ed7e9ad0STrond Myklebust 	NFS_PROTO(dir)->unlink_setup(&msg, data->dentry, inode);
114c970aa85STrond Myklebust 
1155138fde0STrond Myklebust 	task_setup_data.rpc_client = NFS_CLIENT(dir);
116c970aa85STrond Myklebust 	task = rpc_run_task(&task_setup_data);
117e4eff1a6STrond Myklebust 	if (!IS_ERR(task))
118bf294b41STrond Myklebust 		rpc_put_task_async(task);
119565277f6STrond Myklebust }
120565277f6STrond Myklebust 
nfs_call_unlink(struct dentry * dentry,struct inode * inode,struct nfs_unlinkdata * data)121ed7e9ad0STrond Myklebust static int nfs_call_unlink(struct dentry *dentry, struct inode *inode, struct nfs_unlinkdata *data)
122565277f6STrond Myklebust {
123884be175SAl Viro 	struct inode *dir = d_inode(dentry->d_parent);
124884be175SAl Viro 	struct dentry *alias;
125565277f6STrond Myklebust 
126884be175SAl Viro 	down_read_non_owner(&NFS_I(dir)->rmdir_sem);
127884be175SAl Viro 	alias = d_alloc_parallel(dentry->d_parent, &data->args.name, &data->wq);
128884be175SAl Viro 	if (IS_ERR(alias)) {
129884be175SAl Viro 		up_read_non_owner(&NFS_I(dir)->rmdir_sem);
130884be175SAl Viro 		return 0;
131565277f6STrond Myklebust 	}
132884be175SAl Viro 	if (!d_in_lookup(alias)) {
133884be175SAl Viro 		int ret;
134884be175SAl Viro 		void *devname_garbage = NULL;
135884be175SAl Viro 
136884be175SAl Viro 		/*
137884be175SAl Viro 		 * Hey, we raced with lookup... See if we need to transfer
138884be175SAl Viro 		 * the sillyrename information to the aliased dentry.
139884be175SAl Viro 		 */
140884be175SAl Viro 		spin_lock(&alias->d_lock);
141884be175SAl Viro 		if (d_really_is_positive(alias) &&
142*5776a9cdSTrond Myklebust 		    !nfs_compare_fh(NFS_FH(inode), NFS_FH(d_inode(alias))) &&
143884be175SAl Viro 		    !(alias->d_flags & DCACHE_NFSFS_RENAMED)) {
144884be175SAl Viro 			devname_garbage = alias->d_fsdata;
145884be175SAl Viro 			alias->d_fsdata = data;
146884be175SAl Viro 			alias->d_flags |= DCACHE_NFSFS_RENAMED;
147884be175SAl Viro 			ret = 1;
148884be175SAl Viro 		} else
149884be175SAl Viro 			ret = 0;
150884be175SAl Viro 		spin_unlock(&alias->d_lock);
151884be175SAl Viro 		dput(alias);
152884be175SAl Viro 		up_read_non_owner(&NFS_I(dir)->rmdir_sem);
153884be175SAl Viro 		/*
154884be175SAl Viro 		 * If we'd displaced old cached devname, free it.  At that
155884be175SAl Viro 		 * point dentry is definitely not a root, so we won't need
156884be175SAl Viro 		 * that anymore.
157884be175SAl Viro 		 */
158884be175SAl Viro 		kfree(devname_garbage);
159565277f6STrond Myklebust 		return ret;
160565277f6STrond Myklebust 	}
161884be175SAl Viro 	data->dentry = alias;
162ed7e9ad0STrond Myklebust 	nfs_do_call_unlink(inode, data);
163884be175SAl Viro 	return 1;
164e4eff1a6STrond Myklebust }
165e4eff1a6STrond Myklebust 
1661da177e4SLinus Torvalds /**
1671da177e4SLinus Torvalds  * nfs_async_unlink - asynchronous unlinking of a file
168302fad7bSTrond Myklebust  * @dentry: parent directory of dentry
169302fad7bSTrond Myklebust  * @name: name of dentry to unlink
1701da177e4SLinus Torvalds  */
171779c5179SJeff Layton static int
nfs_async_unlink(struct dentry * dentry,const struct qstr * name)172beffb8feSAl Viro nfs_async_unlink(struct dentry *dentry, const struct qstr *name)
1731da177e4SLinus Torvalds {
1741da177e4SLinus Torvalds 	struct nfs_unlinkdata *data;
1751da177e4SLinus Torvalds 	int status = -ENOMEM;
176b1942c5fSAl Viro 	void *devname_garbage = NULL;
1771da177e4SLinus Torvalds 
178bd647545SEric Sesterhenn 	data = kzalloc(sizeof(*data), GFP_KERNEL);
179e4eff1a6STrond Myklebust 	if (data == NULL)
1801da177e4SLinus Torvalds 		goto out;
181884be175SAl Viro 	data->args.name.name = kstrdup(name->name, GFP_KERNEL);
182884be175SAl Viro 	if (!data->args.name.name)
183884be175SAl Viro 		goto out_free;
184884be175SAl Viro 	data->args.name.len = name->len;
1851da177e4SLinus Torvalds 
186a52458b4SNeilBrown 	data->cred = get_current_cred();
187d346890bSTrond Myklebust 	data->res.dir_attr = &data->dir_attr;
188884be175SAl Viro 	init_waitqueue_head(&data->wq);
1891da177e4SLinus Torvalds 
190e4eff1a6STrond Myklebust 	status = -EBUSY;
1911da177e4SLinus Torvalds 	spin_lock(&dentry->d_lock);
192e4eff1a6STrond Myklebust 	if (dentry->d_flags & DCACHE_NFSFS_RENAMED)
193e4eff1a6STrond Myklebust 		goto out_unlock;
1941da177e4SLinus Torvalds 	dentry->d_flags |= DCACHE_NFSFS_RENAMED;
195b1942c5fSAl Viro 	devname_garbage = dentry->d_fsdata;
196e4eff1a6STrond Myklebust 	dentry->d_fsdata = data;
1971da177e4SLinus Torvalds 	spin_unlock(&dentry->d_lock);
198b1942c5fSAl Viro 	/*
199b1942c5fSAl Viro 	 * If we'd displaced old cached devname, free it.  At that
200b1942c5fSAl Viro 	 * point dentry is definitely not a root, so we won't need
201b1942c5fSAl Viro 	 * that anymore.
202b1942c5fSAl Viro 	 */
203b1942c5fSAl Viro 	kfree(devname_garbage);
204e4eff1a6STrond Myklebust 	return 0;
205e4eff1a6STrond Myklebust out_unlock:
206e4eff1a6STrond Myklebust 	spin_unlock(&dentry->d_lock);
207a52458b4SNeilBrown 	put_cred(data->cred);
208884be175SAl Viro 	kfree(data->args.name.name);
2091da177e4SLinus Torvalds out_free:
2101da177e4SLinus Torvalds 	kfree(data);
211e4eff1a6STrond Myklebust out:
2121da177e4SLinus Torvalds 	return status;
2131da177e4SLinus Torvalds }
2141da177e4SLinus Torvalds 
2151da177e4SLinus Torvalds /**
2161da177e4SLinus Torvalds  * nfs_complete_unlink - Initialize completion of the sillydelete
2171da177e4SLinus Torvalds  * @dentry: dentry to delete
218e4eff1a6STrond Myklebust  * @inode: inode
2191da177e4SLinus Torvalds  *
2201da177e4SLinus Torvalds  * Since we're most likely to be called by dentry_iput(), we
2211da177e4SLinus Torvalds  * only use the dentry to find the sillydelete. We then copy the name
2221da177e4SLinus Torvalds  * into the qstr.
2231da177e4SLinus Torvalds  */
2241da177e4SLinus Torvalds void
nfs_complete_unlink(struct dentry * dentry,struct inode * inode)225e4eff1a6STrond Myklebust nfs_complete_unlink(struct dentry *dentry, struct inode *inode)
2261da177e4SLinus Torvalds {
227884be175SAl Viro 	struct nfs_unlinkdata	*data;
2281da177e4SLinus Torvalds 
2291da177e4SLinus Torvalds 	spin_lock(&dentry->d_lock);
2301da177e4SLinus Torvalds 	dentry->d_flags &= ~DCACHE_NFSFS_RENAMED;
231e4eff1a6STrond Myklebust 	data = dentry->d_fsdata;
232b1942c5fSAl Viro 	dentry->d_fsdata = NULL;
2331da177e4SLinus Torvalds 	spin_unlock(&dentry->d_lock);
234e4eff1a6STrond Myklebust 
235ed7e9ad0STrond Myklebust 	if (NFS_STALE(inode) || !nfs_call_unlink(dentry, inode, data))
236e4eff1a6STrond Myklebust 		nfs_free_unlinkdata(data);
2371da177e4SLinus Torvalds }
238779c5179SJeff Layton 
239d3d4152aSJeff Layton /* Cancel a queued async unlink. Called when a sillyrename run fails. */
240d3d4152aSJeff Layton static void
nfs_cancel_async_unlink(struct dentry * dentry)241d3d4152aSJeff Layton nfs_cancel_async_unlink(struct dentry *dentry)
242d3d4152aSJeff Layton {
243d3d4152aSJeff Layton 	spin_lock(&dentry->d_lock);
244d3d4152aSJeff Layton 	if (dentry->d_flags & DCACHE_NFSFS_RENAMED) {
245d3d4152aSJeff Layton 		struct nfs_unlinkdata *data = dentry->d_fsdata;
246d3d4152aSJeff Layton 
247d3d4152aSJeff Layton 		dentry->d_flags &= ~DCACHE_NFSFS_RENAMED;
248b1942c5fSAl Viro 		dentry->d_fsdata = NULL;
249d3d4152aSJeff Layton 		spin_unlock(&dentry->d_lock);
250d3d4152aSJeff Layton 		nfs_free_unlinkdata(data);
251d3d4152aSJeff Layton 		return;
252d3d4152aSJeff Layton 	}
253d3d4152aSJeff Layton 	spin_unlock(&dentry->d_lock);
254d3d4152aSJeff Layton }
255d3d4152aSJeff Layton 
256d3d4152aSJeff Layton /**
257d3d4152aSJeff Layton  * nfs_async_rename_done - Sillyrename post-processing
258d3d4152aSJeff Layton  * @task: rpc_task of the sillyrename
259d3d4152aSJeff Layton  * @calldata: nfs_renamedata for the sillyrename
260d3d4152aSJeff Layton  *
261d3d4152aSJeff Layton  * Do the directory attribute updates and the d_move
262d3d4152aSJeff Layton  */
nfs_async_rename_done(struct rpc_task * task,void * calldata)263d3d4152aSJeff Layton static void nfs_async_rename_done(struct rpc_task *task, void *calldata)
264d3d4152aSJeff Layton {
265d3d4152aSJeff Layton 	struct nfs_renamedata *data = calldata;
266d3d4152aSJeff Layton 	struct inode *old_dir = data->old_dir;
267d3d4152aSJeff Layton 	struct inode *new_dir = data->new_dir;
26873ca1001SJeff Layton 	struct dentry *old_dentry = data->old_dentry;
269d3d4152aSJeff Layton 
27070ded201STrond Myklebust 	trace_nfs_sillyrename_rename(old_dir, old_dentry,
27170ded201STrond Myklebust 			new_dir, data->new_dentry, task->tk_status);
272d3d4152aSJeff Layton 	if (!NFS_PROTO(old_dir)->rename_done(task, old_dir, new_dir)) {
273d00c5d43STrond Myklebust 		rpc_restart_call_prepare(task);
274d3d4152aSJeff Layton 		return;
275d3d4152aSJeff Layton 	}
276d3d4152aSJeff Layton 
27796f9d8c0SJeff Layton 	if (data->complete)
27896f9d8c0SJeff Layton 		data->complete(task, data);
279d3d4152aSJeff Layton }
280d3d4152aSJeff Layton 
281d3d4152aSJeff Layton /**
282d3d4152aSJeff Layton  * nfs_async_rename_release - Release the sillyrename data.
283d3d4152aSJeff Layton  * @calldata: the struct nfs_renamedata to be released
284d3d4152aSJeff Layton  */
nfs_async_rename_release(void * calldata)285d3d4152aSJeff Layton static void nfs_async_rename_release(void *calldata)
286d3d4152aSJeff Layton {
287d3d4152aSJeff Layton 	struct nfs_renamedata	*data = calldata;
288d3d4152aSJeff Layton 	struct super_block *sb = data->old_dir->i_sb;
289d3d4152aSJeff Layton 
2902b0143b5SDavid Howells 	if (d_really_is_positive(data->old_dentry))
2912b0143b5SDavid Howells 		nfs_mark_for_revalidate(d_inode(data->old_dentry));
292d3d4152aSJeff Layton 
293818a8dbeSBenjamin Coddington 	/* The result of the rename is unknown. Play it safe by
294818a8dbeSBenjamin Coddington 	 * forcing a new lookup */
295818a8dbeSBenjamin Coddington 	if (data->cancelled) {
296818a8dbeSBenjamin Coddington 		spin_lock(&data->old_dir->i_lock);
297818a8dbeSBenjamin Coddington 		nfs_force_lookup_revalidate(data->old_dir);
298818a8dbeSBenjamin Coddington 		spin_unlock(&data->old_dir->i_lock);
299818a8dbeSBenjamin Coddington 		if (data->new_dir != data->old_dir) {
300818a8dbeSBenjamin Coddington 			spin_lock(&data->new_dir->i_lock);
301818a8dbeSBenjamin Coddington 			nfs_force_lookup_revalidate(data->new_dir);
302818a8dbeSBenjamin Coddington 			spin_unlock(&data->new_dir->i_lock);
303818a8dbeSBenjamin Coddington 		}
304818a8dbeSBenjamin Coddington 	}
305818a8dbeSBenjamin Coddington 
306d3d4152aSJeff Layton 	dput(data->old_dentry);
307d3d4152aSJeff Layton 	dput(data->new_dentry);
308d3d4152aSJeff Layton 	iput(data->old_dir);
309d3d4152aSJeff Layton 	iput(data->new_dir);
310d3d4152aSJeff Layton 	nfs_sb_deactive(sb);
311a52458b4SNeilBrown 	put_cred(data->cred);
312d3d4152aSJeff Layton 	kfree(data);
313d3d4152aSJeff Layton }
314d3d4152aSJeff Layton 
nfs_rename_prepare(struct rpc_task * task,void * calldata)315d3d4152aSJeff Layton static void nfs_rename_prepare(struct rpc_task *task, void *calldata)
316d3d4152aSJeff Layton {
317d3d4152aSJeff Layton 	struct nfs_renamedata *data = calldata;
318c6bfa1a1SBryan Schumaker 	NFS_PROTO(data->old_dir)->rename_rpc_prepare(task, data);
319d3d4152aSJeff Layton }
320d3d4152aSJeff Layton 
321d3d4152aSJeff Layton static const struct rpc_call_ops nfs_rename_ops = {
322d3d4152aSJeff Layton 	.rpc_call_done = nfs_async_rename_done,
323d3d4152aSJeff Layton 	.rpc_release = nfs_async_rename_release,
324d3d4152aSJeff Layton 	.rpc_call_prepare = nfs_rename_prepare,
325d3d4152aSJeff Layton };
326d3d4152aSJeff Layton 
327d3d4152aSJeff Layton /**
328d3d4152aSJeff Layton  * nfs_async_rename - perform an asynchronous rename operation
329d3d4152aSJeff Layton  * @old_dir: directory that currently holds the dentry to be renamed
330d3d4152aSJeff Layton  * @new_dir: target directory for the rename
331d3d4152aSJeff Layton  * @old_dentry: original dentry to be renamed
332d3d4152aSJeff Layton  * @new_dentry: dentry to which the old_dentry should be renamed
333302fad7bSTrond Myklebust  * @complete: Function to run on successful completion
334d3d4152aSJeff Layton  *
335d3d4152aSJeff Layton  * It's expected that valid references to the dentries and inodes are held
336d3d4152aSJeff Layton  */
3370e862a40SJeff Layton struct rpc_task *
nfs_async_rename(struct inode * old_dir,struct inode * new_dir,struct dentry * old_dentry,struct dentry * new_dentry,void (* complete)(struct rpc_task *,struct nfs_renamedata *))338d3d4152aSJeff Layton nfs_async_rename(struct inode *old_dir, struct inode *new_dir,
33996f9d8c0SJeff Layton 		 struct dentry *old_dentry, struct dentry *new_dentry,
34096f9d8c0SJeff Layton 		 void (*complete)(struct rpc_task *, struct nfs_renamedata *))
341d3d4152aSJeff Layton {
342d3d4152aSJeff Layton 	struct nfs_renamedata *data;
343d3d4152aSJeff Layton 	struct rpc_message msg = { };
344d3d4152aSJeff Layton 	struct rpc_task_setup task_setup_data = {
345d3d4152aSJeff Layton 		.rpc_message = &msg,
346d3d4152aSJeff Layton 		.callback_ops = &nfs_rename_ops,
347d3d4152aSJeff Layton 		.workqueue = nfsiod_workqueue,
348d3d4152aSJeff Layton 		.rpc_client = NFS_CLIENT(old_dir),
34949cd3254STrond Myklebust 		.flags = RPC_TASK_ASYNC | RPC_TASK_CRED_NOREF,
350d3d4152aSJeff Layton 	};
351d3d4152aSJeff Layton 
352118f09edSOlga Kornievskaia 	if (nfs_server_capable(old_dir, NFS_CAP_MOVEABLE) &&
353118f09edSOlga Kornievskaia 	    nfs_server_capable(new_dir, NFS_CAP_MOVEABLE))
354118f09edSOlga Kornievskaia 		task_setup_data.flags |= RPC_TASK_MOVEABLE;
355118f09edSOlga Kornievskaia 
356dfb4f309SBenny Halevy 	data = kzalloc(sizeof(*data), GFP_KERNEL);
357d3d4152aSJeff Layton 	if (data == NULL)
358d3d4152aSJeff Layton 		return ERR_PTR(-ENOMEM);
35988dee0ccSTrond Myklebust 	task_setup_data.task = &data->task;
3601174dd1fSTrond Myklebust 	task_setup_data.callback_data = data;
361d3d4152aSJeff Layton 
362a52458b4SNeilBrown 	data->cred = get_current_cred();
363d3d4152aSJeff Layton 
364d3d4152aSJeff Layton 	msg.rpc_argp = &data->args;
365d3d4152aSJeff Layton 	msg.rpc_resp = &data->res;
366d3d4152aSJeff Layton 	msg.rpc_cred = data->cred;
367d3d4152aSJeff Layton 
368d3d4152aSJeff Layton 	/* set up nfs_renamedata */
369d3d4152aSJeff Layton 	data->old_dir = old_dir;
370a4118ee1SAl Viro 	ihold(old_dir);
371d3d4152aSJeff Layton 	data->new_dir = new_dir;
372a4118ee1SAl Viro 	ihold(new_dir);
373d3d4152aSJeff Layton 	data->old_dentry = dget(old_dentry);
374d3d4152aSJeff Layton 	data->new_dentry = dget(new_dentry);
375d3d4152aSJeff Layton 	nfs_fattr_init(&data->old_fattr);
376d3d4152aSJeff Layton 	nfs_fattr_init(&data->new_fattr);
37796f9d8c0SJeff Layton 	data->complete = complete;
378d3d4152aSJeff Layton 
379d3d4152aSJeff Layton 	/* set up nfs_renameargs */
380d3d4152aSJeff Layton 	data->args.old_dir = NFS_FH(old_dir);
381d3d4152aSJeff Layton 	data->args.old_name = &old_dentry->d_name;
382d3d4152aSJeff Layton 	data->args.new_dir = NFS_FH(new_dir);
383d3d4152aSJeff Layton 	data->args.new_name = &new_dentry->d_name;
384d3d4152aSJeff Layton 
385d3d4152aSJeff Layton 	/* set up nfs_renameres */
386d3d4152aSJeff Layton 	data->res.old_fattr = &data->old_fattr;
387d3d4152aSJeff Layton 	data->res.new_fattr = &data->new_fattr;
388d3d4152aSJeff Layton 
389d3d4152aSJeff Layton 	nfs_sb_active(old_dir->i_sb);
390d3d4152aSJeff Layton 
391f2c2c552STrond Myklebust 	NFS_PROTO(data->old_dir)->rename_setup(&msg, old_dentry, new_dentry);
392d3d4152aSJeff Layton 
393f7732d65STrond Myklebust 	return rpc_run_task(&task_setup_data);
394d3d4152aSJeff Layton }
395d3d4152aSJeff Layton 
39696f9d8c0SJeff Layton /*
39796f9d8c0SJeff Layton  * Perform tasks needed when a sillyrename is done such as cancelling the
39896f9d8c0SJeff Layton  * queued async unlink if it failed.
39996f9d8c0SJeff Layton  */
40096f9d8c0SJeff Layton static void
nfs_complete_sillyrename(struct rpc_task * task,struct nfs_renamedata * data)40196f9d8c0SJeff Layton nfs_complete_sillyrename(struct rpc_task *task, struct nfs_renamedata *data)
40296f9d8c0SJeff Layton {
403f7be7284SJeff Layton 	struct dentry *dentry = data->old_dentry;
404f7be7284SJeff Layton 
405f7be7284SJeff Layton 	if (task->tk_status != 0) {
406f7be7284SJeff Layton 		nfs_cancel_async_unlink(dentry);
407f7be7284SJeff Layton 		return;
408f7be7284SJeff Layton 	}
40996f9d8c0SJeff Layton }
41096f9d8c0SJeff Layton 
411c2dd1378STrond Myklebust #define SILLYNAME_PREFIX ".nfs"
412c2dd1378STrond Myklebust #define SILLYNAME_PREFIX_LEN ((unsigned)sizeof(SILLYNAME_PREFIX) - 1)
413c2dd1378STrond Myklebust #define SILLYNAME_FILEID_LEN ((unsigned)sizeof(u64) << 1)
414c2dd1378STrond Myklebust #define SILLYNAME_COUNTER_LEN ((unsigned)sizeof(unsigned int) << 1)
415c2dd1378STrond Myklebust #define SILLYNAME_LEN (SILLYNAME_PREFIX_LEN + \
416c2dd1378STrond Myklebust 		SILLYNAME_FILEID_LEN + \
417c2dd1378STrond Myklebust 		SILLYNAME_COUNTER_LEN)
418c2dd1378STrond Myklebust 
419779c5179SJeff Layton /**
420779c5179SJeff Layton  * nfs_sillyrename - Perform a silly-rename of a dentry
421779c5179SJeff Layton  * @dir: inode of directory that contains dentry
422779c5179SJeff Layton  * @dentry: dentry to be sillyrenamed
423779c5179SJeff Layton  *
424779c5179SJeff Layton  * NFSv2/3 is stateless and the server doesn't know when the client is
425779c5179SJeff Layton  * holding a file open. To prevent application problems when a file is
426779c5179SJeff Layton  * unlinked while it's still open, the client performs a "silly-rename".
427779c5179SJeff Layton  * That is, it renames the file to a hidden file in the same directory,
428779c5179SJeff Layton  * and only performs the unlink once the last reference to it is put.
429779c5179SJeff Layton  *
430779c5179SJeff Layton  * The final cleanup is done during dentry_iput.
431674e405bSJ. Bruce Fields  *
432674e405bSJ. Bruce Fields  * (Note: NFSv4 is stateful, and has opens, so in theory an NFSv4 server
433674e405bSJ. Bruce Fields  * could take responsibility for keeping open files referenced.  The server
434674e405bSJ. Bruce Fields  * would also need to ensure that opened-but-deleted files were kept over
435674e405bSJ. Bruce Fields  * reboots.  However, we may not assume a server does so.  (RFC 5661
436674e405bSJ. Bruce Fields  * does provide an OPEN4_RESULT_PRESERVE_UNLINKED flag that a server can
437674e405bSJ. Bruce Fields  * use to advertise that it does this; some day we may take advantage of
438674e405bSJ. Bruce Fields  * it.))
439779c5179SJeff Layton  */
440779c5179SJeff Layton int
nfs_sillyrename(struct inode * dir,struct dentry * dentry)441779c5179SJeff Layton nfs_sillyrename(struct inode *dir, struct dentry *dentry)
442779c5179SJeff Layton {
443779c5179SJeff Layton 	static unsigned int sillycounter;
444c2dd1378STrond Myklebust 	unsigned char silly[SILLYNAME_LEN + 1];
445c2dd1378STrond Myklebust 	unsigned long long fileid;
446779c5179SJeff Layton 	struct dentry *sdentry;
4473cb3fd6dSTrond Myklebust 	struct inode *inode = d_inode(dentry);
448d3d4152aSJeff Layton 	struct rpc_task *task;
4494f5829d7SGeyslan G. Bem 	int            error = -EBUSY;
450779c5179SJeff Layton 
4516de1472fSAl Viro 	dfprintk(VFS, "NFS: silly-rename(%pd2, ct=%d)\n",
4526de1472fSAl Viro 		dentry, d_count(dentry));
453779c5179SJeff Layton 	nfs_inc_stats(dir, NFSIOS_SILLYRENAME);
454779c5179SJeff Layton 
455779c5179SJeff Layton 	/*
456779c5179SJeff Layton 	 * We don't allow a dentry to be silly-renamed twice.
457779c5179SJeff Layton 	 */
458779c5179SJeff Layton 	if (dentry->d_flags & DCACHE_NFSFS_RENAMED)
459779c5179SJeff Layton 		goto out;
460779c5179SJeff Layton 
4612b0143b5SDavid Howells 	fileid = NFS_FILEID(d_inode(dentry));
462779c5179SJeff Layton 
463779c5179SJeff Layton 	sdentry = NULL;
464779c5179SJeff Layton 	do {
465c2dd1378STrond Myklebust 		int slen;
466779c5179SJeff Layton 		dput(sdentry);
467779c5179SJeff Layton 		sillycounter++;
468c2dd1378STrond Myklebust 		slen = scnprintf(silly, sizeof(silly),
469c2dd1378STrond Myklebust 				SILLYNAME_PREFIX "%0*llx%0*x",
470c2dd1378STrond Myklebust 				SILLYNAME_FILEID_LEN, fileid,
471c2dd1378STrond Myklebust 				SILLYNAME_COUNTER_LEN, sillycounter);
472779c5179SJeff Layton 
4736de1472fSAl Viro 		dfprintk(VFS, "NFS: trying to rename %pd to %s\n",
4746de1472fSAl Viro 				dentry, silly);
475779c5179SJeff Layton 
476779c5179SJeff Layton 		sdentry = lookup_one_len(silly, dentry->d_parent, slen);
477779c5179SJeff Layton 		/*
478779c5179SJeff Layton 		 * N.B. Better to return EBUSY here ... it could be
479779c5179SJeff Layton 		 * dangerous to delete the file while it's in use.
480779c5179SJeff Layton 		 */
481779c5179SJeff Layton 		if (IS_ERR(sdentry))
482779c5179SJeff Layton 			goto out;
4832b0143b5SDavid Howells 	} while (d_inode(sdentry) != NULL); /* need negative lookup */
484779c5179SJeff Layton 
4853cb3fd6dSTrond Myklebust 	ihold(inode);
4863cb3fd6dSTrond Myklebust 
487d3d4152aSJeff Layton 	/* queue unlink first. Can't do this from rpc_release as it
488d3d4152aSJeff Layton 	 * has to allocate memory
489d3d4152aSJeff Layton 	 */
490884be175SAl Viro 	error = nfs_async_unlink(dentry, &sdentry->d_name);
491d3d4152aSJeff Layton 	if (error)
492d3d4152aSJeff Layton 		goto out_dput;
493d3d4152aSJeff Layton 
494d3d4152aSJeff Layton 	/* run the rename task, undo unlink if it fails */
49596f9d8c0SJeff Layton 	task = nfs_async_rename(dir, dir, dentry, sdentry,
49696f9d8c0SJeff Layton 					nfs_complete_sillyrename);
497d3d4152aSJeff Layton 	if (IS_ERR(task)) {
498d3d4152aSJeff Layton 		error = -EBUSY;
499d3d4152aSJeff Layton 		nfs_cancel_async_unlink(dentry);
500d3d4152aSJeff Layton 		goto out_dput;
501779c5179SJeff Layton 	}
502d3d4152aSJeff Layton 
503d3d4152aSJeff Layton 	/* wait for the RPC task to complete, unless a SIGKILL intervenes */
504d3d4152aSJeff Layton 	error = rpc_wait_for_completion_task(task);
505d3d4152aSJeff Layton 	if (error == 0)
506d3d4152aSJeff Layton 		error = task->tk_status;
5075a7a613aSTrond Myklebust 	switch (error) {
5085a7a613aSTrond Myklebust 	case 0:
5095a7a613aSTrond Myklebust 		/* The rename succeeded */
5105a7a613aSTrond Myklebust 		nfs_set_verifier(dentry, nfs_save_change_attribute(dir));
5113cb3fd6dSTrond Myklebust 		spin_lock(&inode->i_lock);
5123cb3fd6dSTrond Myklebust 		NFS_I(inode)->attr_gencount = nfs_inc_attr_generation_counter();
513ac46b3d7STrond Myklebust 		nfs_set_cache_invalid(inode, NFS_INO_INVALID_CHANGE |
514ac46b3d7STrond Myklebust 						     NFS_INO_INVALID_CTIME |
515ac46b3d7STrond Myklebust 						     NFS_INO_REVAL_FORCED);
5163cb3fd6dSTrond Myklebust 		spin_unlock(&inode->i_lock);
5175a7a613aSTrond Myklebust 		d_move(dentry, sdentry);
5185a7a613aSTrond Myklebust 		break;
5195a7a613aSTrond Myklebust 	case -ERESTARTSYS:
5205a7a613aSTrond Myklebust 		/* The result of the rename is unknown. Play it safe by
5215a7a613aSTrond Myklebust 		 * forcing a new lookup */
5225a7a613aSTrond Myklebust 		d_drop(dentry);
5235a7a613aSTrond Myklebust 		d_drop(sdentry);
5245a7a613aSTrond Myklebust 	}
525d3d4152aSJeff Layton 	rpc_put_task(task);
526d3d4152aSJeff Layton out_dput:
5273cb3fd6dSTrond Myklebust 	iput(inode);
528779c5179SJeff Layton 	dput(sdentry);
529779c5179SJeff Layton out:
530779c5179SJeff Layton 	return error;
531779c5179SJeff Layton }
532