Linux Audio

Check our new training course

Loading...
v4.6
 
  1/*
  2 * Copyright (c) 2014 Anna Schumaker <Anna.Schumaker@Netapp.com>
  3 */
  4#include <linux/fs.h>
  5#include <linux/sunrpc/sched.h>
  6#include <linux/nfs.h>
  7#include <linux/nfs3.h>
  8#include <linux/nfs4.h>
  9#include <linux/nfs_xdr.h>
 10#include <linux/nfs_fs.h>
 11#include "nfs4_fs.h"
 12#include "nfs42.h"
 13#include "iostat.h"
 14#include "pnfs.h"
 
 15#include "internal.h"
 16
 17#define NFSDBG_FACILITY NFSDBG_PROC
 
 18
 19static int _nfs42_proc_fallocate(struct rpc_message *msg, struct file *filep,
 20		struct nfs_lock_context *lock, loff_t offset, loff_t len)
 21{
 22	struct inode *inode = file_inode(filep);
 23	struct nfs_server *server = NFS_SERVER(inode);
 24	struct nfs42_falloc_args args = {
 25		.falloc_fh	= NFS_FH(inode),
 26		.falloc_offset	= offset,
 27		.falloc_length	= len,
 28		.falloc_bitmask	= server->cache_consistency_bitmask,
 29	};
 30	struct nfs42_falloc_res res = {
 31		.falloc_server	= server,
 32	};
 33	int status;
 34
 35	msg->rpc_argp = &args;
 36	msg->rpc_resp = &res;
 37
 38	status = nfs4_set_rw_stateid(&args.falloc_stateid, lock->open_context,
 39			lock, FMODE_WRITE);
 40	if (status)
 41		return status;
 42
 43	res.falloc_fattr = nfs_alloc_fattr();
 44	if (!res.falloc_fattr)
 45		return -ENOMEM;
 46
 47	status = nfs4_call_sync(server->client, server, msg,
 48				&args.seq_args, &res.seq_res, 0);
 49	if (status == 0)
 50		status = nfs_post_op_update_inode(inode, res.falloc_fattr);
 51
 52	kfree(res.falloc_fattr);
 53	return status;
 54}
 55
 56static int nfs42_proc_fallocate(struct rpc_message *msg, struct file *filep,
 57				loff_t offset, loff_t len)
 58{
 59	struct nfs_server *server = NFS_SERVER(file_inode(filep));
 60	struct nfs4_exception exception = { };
 61	struct nfs_lock_context *lock;
 62	int err;
 63
 64	lock = nfs_get_lock_context(nfs_file_open_context(filep));
 65	if (IS_ERR(lock))
 66		return PTR_ERR(lock);
 67
 68	exception.inode = file_inode(filep);
 69	exception.state = lock->open_context->state;
 70
 71	do {
 72		err = _nfs42_proc_fallocate(msg, filep, lock, offset, len);
 73		if (err == -ENOTSUPP) {
 74			err = -EOPNOTSUPP;
 75			break;
 76		}
 77		err = nfs4_handle_exception(server, err, &exception);
 78	} while (exception.retry);
 79
 80	nfs_put_lock_context(lock);
 81	return err;
 82}
 83
 84int nfs42_proc_allocate(struct file *filep, loff_t offset, loff_t len)
 85{
 86	struct rpc_message msg = {
 87		.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_ALLOCATE],
 88	};
 89	struct inode *inode = file_inode(filep);
 90	int err;
 91
 92	if (!nfs_server_capable(inode, NFS_CAP_ALLOCATE))
 93		return -EOPNOTSUPP;
 94
 95	inode_lock(inode);
 96
 97	err = nfs42_proc_fallocate(&msg, filep, offset, len);
 98	if (err == -EOPNOTSUPP)
 99		NFS_SERVER(inode)->caps &= ~NFS_CAP_ALLOCATE;
100
101	inode_unlock(inode);
102	return err;
103}
104
105int nfs42_proc_deallocate(struct file *filep, loff_t offset, loff_t len)
106{
107	struct rpc_message msg = {
108		.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_DEALLOCATE],
109	};
110	struct inode *inode = file_inode(filep);
111	int err;
112
113	if (!nfs_server_capable(inode, NFS_CAP_DEALLOCATE))
114		return -EOPNOTSUPP;
115
116	nfs_wb_all(inode);
117	inode_lock(inode);
 
 
 
118
119	err = nfs42_proc_fallocate(&msg, filep, offset, len);
120	if (err == 0)
121		truncate_pagecache_range(inode, offset, (offset + len) -1);
122	if (err == -EOPNOTSUPP)
123		NFS_SERVER(inode)->caps &= ~NFS_CAP_DEALLOCATE;
124
125	inode_unlock(inode);
126	return err;
127}
128
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
129static loff_t _nfs42_proc_llseek(struct file *filep,
130		struct nfs_lock_context *lock, loff_t offset, int whence)
131{
132	struct inode *inode = file_inode(filep);
133	struct nfs42_seek_args args = {
134		.sa_fh		= NFS_FH(inode),
135		.sa_offset	= offset,
136		.sa_what	= (whence == SEEK_HOLE) ?
137					NFS4_CONTENT_HOLE : NFS4_CONTENT_DATA,
138	};
139	struct nfs42_seek_res res;
140	struct rpc_message msg = {
141		.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_SEEK],
142		.rpc_argp = &args,
143		.rpc_resp = &res,
144	};
145	struct nfs_server *server = NFS_SERVER(inode);
146	int status;
147
148	if (!nfs_server_capable(inode, NFS_CAP_SEEK))
149		return -ENOTSUPP;
150
151	status = nfs4_set_rw_stateid(&args.sa_stateid, lock->open_context,
152			lock, FMODE_READ);
153	if (status)
154		return status;
155
156	nfs_wb_all(inode);
 
 
 
 
157	status = nfs4_call_sync(server->client, server, &msg,
158				&args.seq_args, &res.seq_res, 0);
159	if (status == -ENOTSUPP)
160		server->caps &= ~NFS_CAP_SEEK;
161	if (status)
162		return status;
163
164	return vfs_setpos(filep, res.sr_offset, inode->i_sb->s_maxbytes);
165}
166
167loff_t nfs42_proc_llseek(struct file *filep, loff_t offset, int whence)
168{
169	struct nfs_server *server = NFS_SERVER(file_inode(filep));
170	struct nfs4_exception exception = { };
171	struct nfs_lock_context *lock;
172	loff_t err;
173
174	lock = nfs_get_lock_context(nfs_file_open_context(filep));
175	if (IS_ERR(lock))
176		return PTR_ERR(lock);
177
178	exception.inode = file_inode(filep);
179	exception.state = lock->open_context->state;
180
181	do {
182		err = _nfs42_proc_llseek(filep, lock, offset, whence);
183		if (err >= 0)
184			break;
185		if (err == -ENOTSUPP) {
186			err = -EOPNOTSUPP;
187			break;
188		}
189		err = nfs4_handle_exception(server, err, &exception);
190	} while (exception.retry);
191
192	nfs_put_lock_context(lock);
193	return err;
194}
195
196
197static void
198nfs42_layoutstat_prepare(struct rpc_task *task, void *calldata)
199{
200	struct nfs42_layoutstat_data *data = calldata;
201	struct nfs_server *server = NFS_SERVER(data->args.inode);
 
 
202
203	nfs41_setup_sequence(nfs4_get_session(server), &data->args.seq_args,
204			     &data->res.seq_res, task);
 
 
 
 
 
 
 
 
 
205}
206
207static void
208nfs42_layoutstat_done(struct rpc_task *task, void *calldata)
209{
210	struct nfs42_layoutstat_data *data = calldata;
211	struct inode *inode = data->inode;
212	struct pnfs_layout_hdr *lo;
213
214	if (!nfs4_sequence_done(task, &data->res.seq_res))
215		return;
216
217	switch (task->tk_status) {
218	case 0:
219		break;
 
 
 
 
220	case -NFS4ERR_EXPIRED:
 
 
221	case -NFS4ERR_STALE_STATEID:
222	case -NFS4ERR_OLD_STATEID:
223	case -NFS4ERR_BAD_STATEID:
224		spin_lock(&inode->i_lock);
225		lo = NFS_I(inode)->layout;
226		if (lo && nfs4_stateid_match(&data->args.stateid,
 
227					     &lo->plh_stateid)) {
228			LIST_HEAD(head);
229
230			/*
231			 * Mark the bad layout state as invalid, then retry
232			 * with the current stateid.
233			 */
234			set_bit(NFS_LAYOUT_INVALID_STID, &lo->plh_flags);
235			pnfs_mark_matching_lsegs_invalid(lo, &head, NULL);
236			spin_unlock(&inode->i_lock);
237			pnfs_free_lseg_list(&head);
 
238		} else
239			spin_unlock(&inode->i_lock);
240		break;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
241	case -ENOTSUPP:
242	case -EOPNOTSUPP:
243		NFS_SERVER(inode)->caps &= ~NFS_CAP_LAYOUTSTATS;
244	default:
245		break;
246	}
247
248	dprintk("%s server returns %d\n", __func__, task->tk_status);
249}
250
251static void
252nfs42_layoutstat_release(void *calldata)
253{
254	struct nfs42_layoutstat_data *data = calldata;
255	struct nfs_server *nfss = NFS_SERVER(data->args.inode);
 
256
257	if (nfss->pnfs_curr_ld->cleanup_layoutstats)
258		nfss->pnfs_curr_ld->cleanup_layoutstats(data);
 
 
259
260	pnfs_put_layout_hdr(NFS_I(data->args.inode)->layout);
261	smp_mb__before_atomic();
262	clear_bit(NFS_INO_LAYOUTSTATS, &NFS_I(data->args.inode)->flags);
263	smp_mb__after_atomic();
264	nfs_iput_and_deactive(data->inode);
265	kfree(data->args.devinfo);
266	kfree(data);
267}
268
269static const struct rpc_call_ops nfs42_layoutstat_ops = {
270	.rpc_call_prepare = nfs42_layoutstat_prepare,
271	.rpc_call_done = nfs42_layoutstat_done,
272	.rpc_release = nfs42_layoutstat_release,
273};
274
275int nfs42_proc_layoutstats_generic(struct nfs_server *server,
276				   struct nfs42_layoutstat_data *data)
277{
278	struct rpc_message msg = {
279		.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_LAYOUTSTATS],
280		.rpc_argp = &data->args,
281		.rpc_resp = &data->res,
282	};
283	struct rpc_task_setup task_setup = {
284		.rpc_client = server->client,
285		.rpc_message = &msg,
286		.callback_ops = &nfs42_layoutstat_ops,
287		.callback_data = data,
288		.flags = RPC_TASK_ASYNC,
289	};
290	struct rpc_task *task;
291
292	data->inode = nfs_igrab_and_active(data->args.inode);
293	if (!data->inode) {
294		nfs42_layoutstat_release(data);
295		return -EAGAIN;
296	}
297	nfs4_init_sequence(&data->args.seq_args, &data->res.seq_res, 0);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
298	task = rpc_run_task(&task_setup);
299	if (IS_ERR(task))
300		return PTR_ERR(task);
 
301	return 0;
302}
 
303
304static int _nfs42_proc_clone(struct rpc_message *msg, struct file *src_f,
305		struct file *dst_f, struct nfs_lock_context *src_lock,
306		struct nfs_lock_context *dst_lock, loff_t src_offset,
307		loff_t dst_offset, loff_t count)
308{
309	struct inode *src_inode = file_inode(src_f);
310	struct inode *dst_inode = file_inode(dst_f);
311	struct nfs_server *server = NFS_SERVER(dst_inode);
312	struct nfs42_clone_args args = {
313		.src_fh = NFS_FH(src_inode),
314		.dst_fh = NFS_FH(dst_inode),
315		.src_offset = src_offset,
316		.dst_offset = dst_offset,
317		.count = count,
318		.dst_bitmask = server->cache_consistency_bitmask,
319	};
320	struct nfs42_clone_res res = {
321		.server	= server,
322	};
323	int status;
324
325	msg->rpc_argp = &args;
326	msg->rpc_resp = &res;
327
328	status = nfs4_set_rw_stateid(&args.src_stateid, src_lock->open_context,
329			src_lock, FMODE_READ);
330	if (status)
331		return status;
332
333	status = nfs4_set_rw_stateid(&args.dst_stateid, dst_lock->open_context,
334			dst_lock, FMODE_WRITE);
335	if (status)
336		return status;
337
338	res.dst_fattr = nfs_alloc_fattr();
339	if (!res.dst_fattr)
340		return -ENOMEM;
341
342	status = nfs4_call_sync(server->client, server, msg,
343				&args.seq_args, &res.seq_res, 0);
344	if (status == 0)
345		status = nfs_post_op_update_inode(dst_inode, res.dst_fattr);
346
347	kfree(res.dst_fattr);
348	return status;
349}
350
351int nfs42_proc_clone(struct file *src_f, struct file *dst_f,
352		     loff_t src_offset, loff_t dst_offset, loff_t count)
353{
354	struct rpc_message msg = {
355		.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_CLONE],
356	};
357	struct inode *inode = file_inode(src_f);
358	struct nfs_server *server = NFS_SERVER(file_inode(src_f));
359	struct nfs_lock_context *src_lock;
360	struct nfs_lock_context *dst_lock;
361	struct nfs4_exception src_exception = { };
362	struct nfs4_exception dst_exception = { };
363	int err, err2;
364
365	if (!nfs_server_capable(inode, NFS_CAP_CLONE))
366		return -EOPNOTSUPP;
367
368	src_lock = nfs_get_lock_context(nfs_file_open_context(src_f));
369	if (IS_ERR(src_lock))
370		return PTR_ERR(src_lock);
371
372	src_exception.inode = file_inode(src_f);
373	src_exception.state = src_lock->open_context->state;
374
375	dst_lock = nfs_get_lock_context(nfs_file_open_context(dst_f));
376	if (IS_ERR(dst_lock)) {
377		err = PTR_ERR(dst_lock);
378		goto out_put_src_lock;
379	}
380
381	dst_exception.inode = file_inode(dst_f);
382	dst_exception.state = dst_lock->open_context->state;
383
384	do {
385		err = _nfs42_proc_clone(&msg, src_f, dst_f, src_lock, dst_lock,
386					src_offset, dst_offset, count);
387		if (err == -ENOTSUPP || err == -EOPNOTSUPP) {
388			NFS_SERVER(inode)->caps &= ~NFS_CAP_CLONE;
389			err = -EOPNOTSUPP;
390			break;
391		}
392
393		err2 = nfs4_handle_exception(server, err, &src_exception);
394		err = nfs4_handle_exception(server, err, &dst_exception);
395		if (!err)
396			err = err2;
397	} while (src_exception.retry || dst_exception.retry);
398
399	nfs_put_lock_context(dst_lock);
400out_put_src_lock:
401	nfs_put_lock_context(src_lock);
402	return err;
403}
v5.4
  1// SPDX-License-Identifier: GPL-2.0
  2/*
  3 * Copyright (c) 2014 Anna Schumaker <Anna.Schumaker@Netapp.com>
  4 */
  5#include <linux/fs.h>
  6#include <linux/sunrpc/sched.h>
  7#include <linux/nfs.h>
  8#include <linux/nfs3.h>
  9#include <linux/nfs4.h>
 10#include <linux/nfs_xdr.h>
 11#include <linux/nfs_fs.h>
 12#include "nfs4_fs.h"
 13#include "nfs42.h"
 14#include "iostat.h"
 15#include "pnfs.h"
 16#include "nfs4session.h"
 17#include "internal.h"
 18
 19#define NFSDBG_FACILITY NFSDBG_PROC
 20static int nfs42_do_offload_cancel_async(struct file *dst, nfs4_stateid *std);
 21
 22static int _nfs42_proc_fallocate(struct rpc_message *msg, struct file *filep,
 23		struct nfs_lock_context *lock, loff_t offset, loff_t len)
 24{
 25	struct inode *inode = file_inode(filep);
 26	struct nfs_server *server = NFS_SERVER(inode);
 27	struct nfs42_falloc_args args = {
 28		.falloc_fh	= NFS_FH(inode),
 29		.falloc_offset	= offset,
 30		.falloc_length	= len,
 31		.falloc_bitmask	= server->cache_consistency_bitmask,
 32	};
 33	struct nfs42_falloc_res res = {
 34		.falloc_server	= server,
 35	};
 36	int status;
 37
 38	msg->rpc_argp = &args;
 39	msg->rpc_resp = &res;
 40
 41	status = nfs4_set_rw_stateid(&args.falloc_stateid, lock->open_context,
 42			lock, FMODE_WRITE);
 43	if (status)
 44		return status;
 45
 46	res.falloc_fattr = nfs_alloc_fattr();
 47	if (!res.falloc_fattr)
 48		return -ENOMEM;
 49
 50	status = nfs4_call_sync(server->client, server, msg,
 51				&args.seq_args, &res.seq_res, 0);
 52	if (status == 0)
 53		status = nfs_post_op_update_inode(inode, res.falloc_fattr);
 54
 55	kfree(res.falloc_fattr);
 56	return status;
 57}
 58
 59static int nfs42_proc_fallocate(struct rpc_message *msg, struct file *filep,
 60				loff_t offset, loff_t len)
 61{
 62	struct nfs_server *server = NFS_SERVER(file_inode(filep));
 63	struct nfs4_exception exception = { };
 64	struct nfs_lock_context *lock;
 65	int err;
 66
 67	lock = nfs_get_lock_context(nfs_file_open_context(filep));
 68	if (IS_ERR(lock))
 69		return PTR_ERR(lock);
 70
 71	exception.inode = file_inode(filep);
 72	exception.state = lock->open_context->state;
 73
 74	do {
 75		err = _nfs42_proc_fallocate(msg, filep, lock, offset, len);
 76		if (err == -ENOTSUPP) {
 77			err = -EOPNOTSUPP;
 78			break;
 79		}
 80		err = nfs4_handle_exception(server, err, &exception);
 81	} while (exception.retry);
 82
 83	nfs_put_lock_context(lock);
 84	return err;
 85}
 86
 87int nfs42_proc_allocate(struct file *filep, loff_t offset, loff_t len)
 88{
 89	struct rpc_message msg = {
 90		.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_ALLOCATE],
 91	};
 92	struct inode *inode = file_inode(filep);
 93	int err;
 94
 95	if (!nfs_server_capable(inode, NFS_CAP_ALLOCATE))
 96		return -EOPNOTSUPP;
 97
 98	inode_lock(inode);
 99
100	err = nfs42_proc_fallocate(&msg, filep, offset, len);
101	if (err == -EOPNOTSUPP)
102		NFS_SERVER(inode)->caps &= ~NFS_CAP_ALLOCATE;
103
104	inode_unlock(inode);
105	return err;
106}
107
108int nfs42_proc_deallocate(struct file *filep, loff_t offset, loff_t len)
109{
110	struct rpc_message msg = {
111		.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_DEALLOCATE],
112	};
113	struct inode *inode = file_inode(filep);
114	int err;
115
116	if (!nfs_server_capable(inode, NFS_CAP_DEALLOCATE))
117		return -EOPNOTSUPP;
118
 
119	inode_lock(inode);
120	err = nfs_sync_inode(inode);
121	if (err)
122		goto out_unlock;
123
124	err = nfs42_proc_fallocate(&msg, filep, offset, len);
125	if (err == 0)
126		truncate_pagecache_range(inode, offset, (offset + len) -1);
127	if (err == -EOPNOTSUPP)
128		NFS_SERVER(inode)->caps &= ~NFS_CAP_DEALLOCATE;
129out_unlock:
130	inode_unlock(inode);
131	return err;
132}
133
134static int handle_async_copy(struct nfs42_copy_res *res,
135			     struct nfs_server *server,
136			     struct file *src,
137			     struct file *dst,
138			     nfs4_stateid *src_stateid)
139{
140	struct nfs4_copy_state *copy, *tmp_copy;
141	int status = NFS4_OK;
142	bool found_pending = false;
143	struct nfs_open_context *ctx = nfs_file_open_context(dst);
144
145	copy = kzalloc(sizeof(struct nfs4_copy_state), GFP_NOFS);
146	if (!copy)
147		return -ENOMEM;
148
149	spin_lock(&server->nfs_client->cl_lock);
150	list_for_each_entry(tmp_copy, &server->nfs_client->pending_cb_stateids,
151				copies) {
152		if (memcmp(&res->write_res.stateid, &tmp_copy->stateid,
153				NFS4_STATEID_SIZE))
154			continue;
155		found_pending = true;
156		list_del(&tmp_copy->copies);
157		break;
158	}
159	if (found_pending) {
160		spin_unlock(&server->nfs_client->cl_lock);
161		kfree(copy);
162		copy = tmp_copy;
163		goto out;
164	}
165
166	memcpy(&copy->stateid, &res->write_res.stateid, NFS4_STATEID_SIZE);
167	init_completion(&copy->completion);
168	copy->parent_state = ctx->state;
169
170	list_add_tail(&copy->copies, &server->ss_copies);
171	spin_unlock(&server->nfs_client->cl_lock);
172
173	status = wait_for_completion_interruptible(&copy->completion);
174	spin_lock(&server->nfs_client->cl_lock);
175	list_del_init(&copy->copies);
176	spin_unlock(&server->nfs_client->cl_lock);
177	if (status == -ERESTARTSYS) {
178		goto out_cancel;
179	} else if (copy->flags) {
180		status = -EAGAIN;
181		goto out_cancel;
182	}
183out:
184	res->write_res.count = copy->count;
185	memcpy(&res->write_res.verifier, &copy->verf, sizeof(copy->verf));
186	status = -copy->error;
187
188	kfree(copy);
189	return status;
190out_cancel:
191	nfs42_do_offload_cancel_async(dst, &copy->stateid);
192	kfree(copy);
193	return status;
194}
195
196static int process_copy_commit(struct file *dst, loff_t pos_dst,
197			       struct nfs42_copy_res *res)
198{
199	struct nfs_commitres cres;
200	int status = -ENOMEM;
201
202	cres.verf = kzalloc(sizeof(struct nfs_writeverf), GFP_NOFS);
203	if (!cres.verf)
204		goto out;
205
206	status = nfs4_proc_commit(dst, pos_dst, res->write_res.count, &cres);
207	if (status)
208		goto out_free;
209	if (nfs_write_verifier_cmp(&res->write_res.verifier.verifier,
210				    &cres.verf->verifier)) {
211		dprintk("commit verf differs from copy verf\n");
212		status = -EAGAIN;
213	}
214out_free:
215	kfree(cres.verf);
216out:
217	return status;
218}
219
220static ssize_t _nfs42_proc_copy(struct file *src,
221				struct nfs_lock_context *src_lock,
222				struct file *dst,
223				struct nfs_lock_context *dst_lock,
224				struct nfs42_copy_args *args,
225				struct nfs42_copy_res *res)
226{
227	struct rpc_message msg = {
228		.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_COPY],
229		.rpc_argp = args,
230		.rpc_resp = res,
231	};
232	struct inode *dst_inode = file_inode(dst);
233	struct nfs_server *server = NFS_SERVER(dst_inode);
234	loff_t pos_src = args->src_pos;
235	loff_t pos_dst = args->dst_pos;
236	size_t count = args->count;
237	ssize_t status;
238
239	status = nfs4_set_rw_stateid(&args->src_stateid, src_lock->open_context,
240				     src_lock, FMODE_READ);
241	if (status)
242		return status;
243
244	status = nfs_filemap_write_and_wait_range(file_inode(src)->i_mapping,
245			pos_src, pos_src + (loff_t)count - 1);
246	if (status)
247		return status;
248
249	status = nfs4_set_rw_stateid(&args->dst_stateid, dst_lock->open_context,
250				     dst_lock, FMODE_WRITE);
251	if (status)
252		return status;
253
254	status = nfs_sync_inode(dst_inode);
255	if (status)
256		return status;
257
258	res->commit_res.verf = NULL;
259	if (args->sync) {
260		res->commit_res.verf =
261			kzalloc(sizeof(struct nfs_writeverf), GFP_NOFS);
262		if (!res->commit_res.verf)
263			return -ENOMEM;
264	}
265	set_bit(NFS_CLNT_DST_SSC_COPY_STATE,
266		&dst_lock->open_context->state->flags);
267
268	status = nfs4_call_sync(server->client, server, &msg,
269				&args->seq_args, &res->seq_res, 0);
270	if (status == -ENOTSUPP)
271		server->caps &= ~NFS_CAP_COPY;
272	if (status)
273		goto out;
274
275	if (args->sync &&
276		nfs_write_verifier_cmp(&res->write_res.verifier.verifier,
277				    &res->commit_res.verf->verifier)) {
278		status = -EAGAIN;
279		goto out;
280	}
281
282	if (!res->synchronous) {
283		status = handle_async_copy(res, server, src, dst,
284				&args->src_stateid);
285		if (status)
286			return status;
287	}
288
289	if ((!res->synchronous || !args->sync) &&
290			res->write_res.verifier.committed != NFS_FILE_SYNC) {
291		status = process_copy_commit(dst, pos_dst, res);
292		if (status)
293			return status;
294	}
295
296	truncate_pagecache_range(dst_inode, pos_dst,
297				 pos_dst + res->write_res.count);
298
299	status = res->write_res.count;
300out:
301	if (args->sync)
302		kfree(res->commit_res.verf);
303	return status;
304}
305
306ssize_t nfs42_proc_copy(struct file *src, loff_t pos_src,
307			struct file *dst, loff_t pos_dst,
308			size_t count)
309{
310	struct nfs_server *server = NFS_SERVER(file_inode(dst));
311	struct nfs_lock_context *src_lock;
312	struct nfs_lock_context *dst_lock;
313	struct nfs42_copy_args args = {
314		.src_fh		= NFS_FH(file_inode(src)),
315		.src_pos	= pos_src,
316		.dst_fh		= NFS_FH(file_inode(dst)),
317		.dst_pos	= pos_dst,
318		.count		= count,
319		.sync		= false,
320	};
321	struct nfs42_copy_res res;
322	struct nfs4_exception src_exception = {
323		.inode		= file_inode(src),
324		.stateid	= &args.src_stateid,
325	};
326	struct nfs4_exception dst_exception = {
327		.inode		= file_inode(dst),
328		.stateid	= &args.dst_stateid,
329	};
330	ssize_t err, err2;
331
332	src_lock = nfs_get_lock_context(nfs_file_open_context(src));
333	if (IS_ERR(src_lock))
334		return PTR_ERR(src_lock);
335
336	src_exception.state = src_lock->open_context->state;
337
338	dst_lock = nfs_get_lock_context(nfs_file_open_context(dst));
339	if (IS_ERR(dst_lock)) {
340		err = PTR_ERR(dst_lock);
341		goto out_put_src_lock;
342	}
343
344	dst_exception.state = dst_lock->open_context->state;
345
346	do {
347		inode_lock(file_inode(dst));
348		err = _nfs42_proc_copy(src, src_lock,
349				dst, dst_lock,
350				&args, &res);
351		inode_unlock(file_inode(dst));
352
353		if (err >= 0)
354			break;
355		if (err == -ENOTSUPP) {
356			err = -EOPNOTSUPP;
357			break;
358		} else if (err == -EAGAIN) {
359			dst_exception.retry = 1;
360			continue;
361		} else if (err == -NFS4ERR_OFFLOAD_NO_REQS && !args.sync) {
362			args.sync = true;
363			dst_exception.retry = 1;
364			continue;
365		}
366
367		err2 = nfs4_handle_exception(server, err, &src_exception);
368		err  = nfs4_handle_exception(server, err, &dst_exception);
369		if (!err)
370			err = err2;
371	} while (src_exception.retry || dst_exception.retry);
372
373	nfs_put_lock_context(dst_lock);
374out_put_src_lock:
375	nfs_put_lock_context(src_lock);
376	return err;
377}
378
379struct nfs42_offloadcancel_data {
380	struct nfs_server *seq_server;
381	struct nfs42_offload_status_args args;
382	struct nfs42_offload_status_res res;
383};
384
385static void nfs42_offload_cancel_prepare(struct rpc_task *task, void *calldata)
386{
387	struct nfs42_offloadcancel_data *data = calldata;
388
389	nfs4_setup_sequence(data->seq_server->nfs_client,
390				&data->args.osa_seq_args,
391				&data->res.osr_seq_res, task);
392}
393
394static void nfs42_offload_cancel_done(struct rpc_task *task, void *calldata)
395{
396	struct nfs42_offloadcancel_data *data = calldata;
397
398	nfs41_sequence_done(task, &data->res.osr_seq_res);
399	if (task->tk_status &&
400		nfs4_async_handle_error(task, data->seq_server, NULL,
401			NULL) == -EAGAIN)
402		rpc_restart_call_prepare(task);
403}
404
405static void nfs42_free_offloadcancel_data(void *data)
406{
407	kfree(data);
408}
409
410static const struct rpc_call_ops nfs42_offload_cancel_ops = {
411	.rpc_call_prepare = nfs42_offload_cancel_prepare,
412	.rpc_call_done = nfs42_offload_cancel_done,
413	.rpc_release = nfs42_free_offloadcancel_data,
414};
415
416static int nfs42_do_offload_cancel_async(struct file *dst,
417					 nfs4_stateid *stateid)
418{
419	struct nfs_server *dst_server = NFS_SERVER(file_inode(dst));
420	struct nfs42_offloadcancel_data *data = NULL;
421	struct nfs_open_context *ctx = nfs_file_open_context(dst);
422	struct rpc_task *task;
423	struct rpc_message msg = {
424		.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_OFFLOAD_CANCEL],
425		.rpc_cred = ctx->cred,
426	};
427	struct rpc_task_setup task_setup_data = {
428		.rpc_client = dst_server->client,
429		.rpc_message = &msg,
430		.callback_ops = &nfs42_offload_cancel_ops,
431		.workqueue = nfsiod_workqueue,
432		.flags = RPC_TASK_ASYNC,
433	};
434	int status;
435
436	if (!(dst_server->caps & NFS_CAP_OFFLOAD_CANCEL))
437		return -EOPNOTSUPP;
438
439	data = kzalloc(sizeof(struct nfs42_offloadcancel_data), GFP_NOFS);
440	if (data == NULL)
441		return -ENOMEM;
442
443	data->seq_server = dst_server;
444	data->args.osa_src_fh = NFS_FH(file_inode(dst));
445	memcpy(&data->args.osa_stateid, stateid,
446		sizeof(data->args.osa_stateid));
447	msg.rpc_argp = &data->args;
448	msg.rpc_resp = &data->res;
449	task_setup_data.callback_data = data;
450	nfs4_init_sequence(&data->args.osa_seq_args, &data->res.osr_seq_res,
451			   1, 0);
452	task = rpc_run_task(&task_setup_data);
453	if (IS_ERR(task))
454		return PTR_ERR(task);
455	status = rpc_wait_for_completion_task(task);
456	if (status == -ENOTSUPP)
457		dst_server->caps &= ~NFS_CAP_OFFLOAD_CANCEL;
458	rpc_put_task(task);
459	return status;
460}
461
462static loff_t _nfs42_proc_llseek(struct file *filep,
463		struct nfs_lock_context *lock, loff_t offset, int whence)
464{
465	struct inode *inode = file_inode(filep);
466	struct nfs42_seek_args args = {
467		.sa_fh		= NFS_FH(inode),
468		.sa_offset	= offset,
469		.sa_what	= (whence == SEEK_HOLE) ?
470					NFS4_CONTENT_HOLE : NFS4_CONTENT_DATA,
471	};
472	struct nfs42_seek_res res;
473	struct rpc_message msg = {
474		.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_SEEK],
475		.rpc_argp = &args,
476		.rpc_resp = &res,
477	};
478	struct nfs_server *server = NFS_SERVER(inode);
479	int status;
480
481	if (!nfs_server_capable(inode, NFS_CAP_SEEK))
482		return -ENOTSUPP;
483
484	status = nfs4_set_rw_stateid(&args.sa_stateid, lock->open_context,
485			lock, FMODE_READ);
486	if (status)
487		return status;
488
489	status = nfs_filemap_write_and_wait_range(inode->i_mapping,
490			offset, LLONG_MAX);
491	if (status)
492		return status;
493
494	status = nfs4_call_sync(server->client, server, &msg,
495				&args.seq_args, &res.seq_res, 0);
496	if (status == -ENOTSUPP)
497		server->caps &= ~NFS_CAP_SEEK;
498	if (status)
499		return status;
500
501	return vfs_setpos(filep, res.sr_offset, inode->i_sb->s_maxbytes);
502}
503
504loff_t nfs42_proc_llseek(struct file *filep, loff_t offset, int whence)
505{
506	struct nfs_server *server = NFS_SERVER(file_inode(filep));
507	struct nfs4_exception exception = { };
508	struct nfs_lock_context *lock;
509	loff_t err;
510
511	lock = nfs_get_lock_context(nfs_file_open_context(filep));
512	if (IS_ERR(lock))
513		return PTR_ERR(lock);
514
515	exception.inode = file_inode(filep);
516	exception.state = lock->open_context->state;
517
518	do {
519		err = _nfs42_proc_llseek(filep, lock, offset, whence);
520		if (err >= 0)
521			break;
522		if (err == -ENOTSUPP) {
523			err = -EOPNOTSUPP;
524			break;
525		}
526		err = nfs4_handle_exception(server, err, &exception);
527	} while (exception.retry);
528
529	nfs_put_lock_context(lock);
530	return err;
531}
532
533
534static void
535nfs42_layoutstat_prepare(struct rpc_task *task, void *calldata)
536{
537	struct nfs42_layoutstat_data *data = calldata;
538	struct inode *inode = data->inode;
539	struct nfs_server *server = NFS_SERVER(inode);
540	struct pnfs_layout_hdr *lo;
541
542	spin_lock(&inode->i_lock);
543	lo = NFS_I(inode)->layout;
544	if (!pnfs_layout_is_valid(lo)) {
545		spin_unlock(&inode->i_lock);
546		rpc_exit(task, 0);
547		return;
548	}
549	nfs4_stateid_copy(&data->args.stateid, &lo->plh_stateid);
550	spin_unlock(&inode->i_lock);
551	nfs4_setup_sequence(server->nfs_client, &data->args.seq_args,
552			    &data->res.seq_res, task);
553}
554
555static void
556nfs42_layoutstat_done(struct rpc_task *task, void *calldata)
557{
558	struct nfs42_layoutstat_data *data = calldata;
559	struct inode *inode = data->inode;
560	struct pnfs_layout_hdr *lo;
561
562	if (!nfs4_sequence_done(task, &data->res.seq_res))
563		return;
564
565	switch (task->tk_status) {
566	case 0:
567		break;
568	case -NFS4ERR_BADHANDLE:
569	case -ESTALE:
570		pnfs_destroy_layout(NFS_I(inode));
571		break;
572	case -NFS4ERR_EXPIRED:
573	case -NFS4ERR_ADMIN_REVOKED:
574	case -NFS4ERR_DELEG_REVOKED:
575	case -NFS4ERR_STALE_STATEID:
 
576	case -NFS4ERR_BAD_STATEID:
577		spin_lock(&inode->i_lock);
578		lo = NFS_I(inode)->layout;
579		if (pnfs_layout_is_valid(lo) &&
580		    nfs4_stateid_match(&data->args.stateid,
581					     &lo->plh_stateid)) {
582			LIST_HEAD(head);
583
584			/*
585			 * Mark the bad layout state as invalid, then retry
586			 * with the current stateid.
587			 */
588			pnfs_mark_layout_stateid_invalid(lo, &head);
 
589			spin_unlock(&inode->i_lock);
590			pnfs_free_lseg_list(&head);
591			nfs_commit_inode(inode, 0);
592		} else
593			spin_unlock(&inode->i_lock);
594		break;
595	case -NFS4ERR_OLD_STATEID:
596		spin_lock(&inode->i_lock);
597		lo = NFS_I(inode)->layout;
598		if (pnfs_layout_is_valid(lo) &&
599		    nfs4_stateid_match_other(&data->args.stateid,
600					&lo->plh_stateid)) {
601			/* Do we need to delay before resending? */
602			if (!nfs4_stateid_is_newer(&lo->plh_stateid,
603						&data->args.stateid))
604				rpc_delay(task, HZ);
605			rpc_restart_call_prepare(task);
606		}
607		spin_unlock(&inode->i_lock);
608		break;
609	case -ENOTSUPP:
610	case -EOPNOTSUPP:
611		NFS_SERVER(inode)->caps &= ~NFS_CAP_LAYOUTSTATS;
 
 
612	}
 
 
613}
614
615static void
616nfs42_layoutstat_release(void *calldata)
617{
618	struct nfs42_layoutstat_data *data = calldata;
619	struct nfs42_layoutstat_devinfo *devinfo = data->args.devinfo;
620	int i;
621
622	for (i = 0; i < data->args.num_dev; i++) {
623		if (devinfo[i].ld_private.ops && devinfo[i].ld_private.ops->free)
624			devinfo[i].ld_private.ops->free(&devinfo[i].ld_private);
625	}
626
627	pnfs_put_layout_hdr(NFS_I(data->args.inode)->layout);
628	smp_mb__before_atomic();
629	clear_bit(NFS_INO_LAYOUTSTATS, &NFS_I(data->args.inode)->flags);
630	smp_mb__after_atomic();
631	nfs_iput_and_deactive(data->inode);
632	kfree(data->args.devinfo);
633	kfree(data);
634}
635
636static const struct rpc_call_ops nfs42_layoutstat_ops = {
637	.rpc_call_prepare = nfs42_layoutstat_prepare,
638	.rpc_call_done = nfs42_layoutstat_done,
639	.rpc_release = nfs42_layoutstat_release,
640};
641
642int nfs42_proc_layoutstats_generic(struct nfs_server *server,
643				   struct nfs42_layoutstat_data *data)
644{
645	struct rpc_message msg = {
646		.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_LAYOUTSTATS],
647		.rpc_argp = &data->args,
648		.rpc_resp = &data->res,
649	};
650	struct rpc_task_setup task_setup = {
651		.rpc_client = server->client,
652		.rpc_message = &msg,
653		.callback_ops = &nfs42_layoutstat_ops,
654		.callback_data = data,
655		.flags = RPC_TASK_ASYNC,
656	};
657	struct rpc_task *task;
658
659	data->inode = nfs_igrab_and_active(data->args.inode);
660	if (!data->inode) {
661		nfs42_layoutstat_release(data);
662		return -EAGAIN;
663	}
664	nfs4_init_sequence(&data->args.seq_args, &data->res.seq_res, 0, 0);
665	task = rpc_run_task(&task_setup);
666	if (IS_ERR(task))
667		return PTR_ERR(task);
668	rpc_put_task(task);
669	return 0;
670}
671
672static struct nfs42_layouterror_data *
673nfs42_alloc_layouterror_data(struct pnfs_layout_segment *lseg, gfp_t gfp_flags)
674{
675	struct nfs42_layouterror_data *data;
676	struct inode *inode = lseg->pls_layout->plh_inode;
677
678	data = kzalloc(sizeof(*data), gfp_flags);
679	if (data) {
680		data->args.inode = data->inode = nfs_igrab_and_active(inode);
681		if (data->inode) {
682			data->lseg = pnfs_get_lseg(lseg);
683			if (data->lseg)
684				return data;
685			nfs_iput_and_deactive(data->inode);
686		}
687		kfree(data);
688	}
689	return NULL;
690}
691
692static void
693nfs42_free_layouterror_data(struct nfs42_layouterror_data *data)
694{
695	pnfs_put_lseg(data->lseg);
696	nfs_iput_and_deactive(data->inode);
697	kfree(data);
698}
699
700static void
701nfs42_layouterror_prepare(struct rpc_task *task, void *calldata)
702{
703	struct nfs42_layouterror_data *data = calldata;
704	struct inode *inode = data->inode;
705	struct nfs_server *server = NFS_SERVER(inode);
706	struct pnfs_layout_hdr *lo = data->lseg->pls_layout;
707	unsigned i;
708
709	spin_lock(&inode->i_lock);
710	if (!pnfs_layout_is_valid(lo)) {
711		spin_unlock(&inode->i_lock);
712		rpc_exit(task, 0);
713		return;
714	}
715	for (i = 0; i < data->args.num_errors; i++)
716		nfs4_stateid_copy(&data->args.errors[i].stateid,
717				&lo->plh_stateid);
718	spin_unlock(&inode->i_lock);
719	nfs4_setup_sequence(server->nfs_client, &data->args.seq_args,
720			    &data->res.seq_res, task);
721}
722
723static void
724nfs42_layouterror_done(struct rpc_task *task, void *calldata)
725{
726	struct nfs42_layouterror_data *data = calldata;
727	struct inode *inode = data->inode;
728	struct pnfs_layout_hdr *lo = data->lseg->pls_layout;
729
730	if (!nfs4_sequence_done(task, &data->res.seq_res))
731		return;
732
733	switch (task->tk_status) {
734	case 0:
735		break;
736	case -NFS4ERR_BADHANDLE:
737	case -ESTALE:
738		pnfs_destroy_layout(NFS_I(inode));
739		break;
740	case -NFS4ERR_EXPIRED:
741	case -NFS4ERR_ADMIN_REVOKED:
742	case -NFS4ERR_DELEG_REVOKED:
743	case -NFS4ERR_STALE_STATEID:
744	case -NFS4ERR_BAD_STATEID:
745		spin_lock(&inode->i_lock);
746		if (pnfs_layout_is_valid(lo) &&
747		    nfs4_stateid_match(&data->args.errors[0].stateid,
748					     &lo->plh_stateid)) {
749			LIST_HEAD(head);
750
751			/*
752			 * Mark the bad layout state as invalid, then retry
753			 * with the current stateid.
754			 */
755			pnfs_mark_layout_stateid_invalid(lo, &head);
756			spin_unlock(&inode->i_lock);
757			pnfs_free_lseg_list(&head);
758			nfs_commit_inode(inode, 0);
759		} else
760			spin_unlock(&inode->i_lock);
761		break;
762	case -NFS4ERR_OLD_STATEID:
763		spin_lock(&inode->i_lock);
764		if (pnfs_layout_is_valid(lo) &&
765		    nfs4_stateid_match_other(&data->args.errors[0].stateid,
766					&lo->plh_stateid)) {
767			/* Do we need to delay before resending? */
768			if (!nfs4_stateid_is_newer(&lo->plh_stateid,
769						&data->args.errors[0].stateid))
770				rpc_delay(task, HZ);
771			rpc_restart_call_prepare(task);
772		}
773		spin_unlock(&inode->i_lock);
774		break;
775	case -ENOTSUPP:
776	case -EOPNOTSUPP:
777		NFS_SERVER(inode)->caps &= ~NFS_CAP_LAYOUTERROR;
778	}
779}
780
781static void
782nfs42_layouterror_release(void *calldata)
783{
784	struct nfs42_layouterror_data *data = calldata;
785
786	nfs42_free_layouterror_data(data);
787}
788
789static const struct rpc_call_ops nfs42_layouterror_ops = {
790	.rpc_call_prepare = nfs42_layouterror_prepare,
791	.rpc_call_done = nfs42_layouterror_done,
792	.rpc_release = nfs42_layouterror_release,
793};
794
795int nfs42_proc_layouterror(struct pnfs_layout_segment *lseg,
796		const struct nfs42_layout_error *errors, size_t n)
797{
798	struct inode *inode = lseg->pls_layout->plh_inode;
799	struct nfs42_layouterror_data *data;
800	struct rpc_task *task;
801	struct rpc_message msg = {
802		.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_LAYOUTERROR],
803	};
804	struct rpc_task_setup task_setup = {
805		.rpc_message = &msg,
806		.callback_ops = &nfs42_layouterror_ops,
807		.flags = RPC_TASK_ASYNC,
808	};
809	unsigned int i;
810
811	if (!nfs_server_capable(inode, NFS_CAP_LAYOUTERROR))
812		return -EOPNOTSUPP;
813	if (n > NFS42_LAYOUTERROR_MAX)
814		return -EINVAL;
815	data = nfs42_alloc_layouterror_data(lseg, GFP_NOFS);
816	if (!data)
817		return -ENOMEM;
818	for (i = 0; i < n; i++) {
819		data->args.errors[i] = errors[i];
820		data->args.num_errors++;
821		data->res.num_errors++;
822	}
823	msg.rpc_argp = &data->args;
824	msg.rpc_resp = &data->res;
825	task_setup.callback_data = data;
826	task_setup.rpc_client = NFS_SERVER(inode)->client;
827	nfs4_init_sequence(&data->args.seq_args, &data->res.seq_res, 0, 0);
828	task = rpc_run_task(&task_setup);
829	if (IS_ERR(task))
830		return PTR_ERR(task);
831	rpc_put_task(task);
832	return 0;
833}
834EXPORT_SYMBOL_GPL(nfs42_proc_layouterror);
835
836static int _nfs42_proc_clone(struct rpc_message *msg, struct file *src_f,
837		struct file *dst_f, struct nfs_lock_context *src_lock,
838		struct nfs_lock_context *dst_lock, loff_t src_offset,
839		loff_t dst_offset, loff_t count)
840{
841	struct inode *src_inode = file_inode(src_f);
842	struct inode *dst_inode = file_inode(dst_f);
843	struct nfs_server *server = NFS_SERVER(dst_inode);
844	struct nfs42_clone_args args = {
845		.src_fh = NFS_FH(src_inode),
846		.dst_fh = NFS_FH(dst_inode),
847		.src_offset = src_offset,
848		.dst_offset = dst_offset,
849		.count = count,
850		.dst_bitmask = server->cache_consistency_bitmask,
851	};
852	struct nfs42_clone_res res = {
853		.server	= server,
854	};
855	int status;
856
857	msg->rpc_argp = &args;
858	msg->rpc_resp = &res;
859
860	status = nfs4_set_rw_stateid(&args.src_stateid, src_lock->open_context,
861			src_lock, FMODE_READ);
862	if (status)
863		return status;
864
865	status = nfs4_set_rw_stateid(&args.dst_stateid, dst_lock->open_context,
866			dst_lock, FMODE_WRITE);
867	if (status)
868		return status;
869
870	res.dst_fattr = nfs_alloc_fattr();
871	if (!res.dst_fattr)
872		return -ENOMEM;
873
874	status = nfs4_call_sync(server->client, server, msg,
875				&args.seq_args, &res.seq_res, 0);
876	if (status == 0)
877		status = nfs_post_op_update_inode(dst_inode, res.dst_fattr);
878
879	kfree(res.dst_fattr);
880	return status;
881}
882
883int nfs42_proc_clone(struct file *src_f, struct file *dst_f,
884		     loff_t src_offset, loff_t dst_offset, loff_t count)
885{
886	struct rpc_message msg = {
887		.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_CLONE],
888	};
889	struct inode *inode = file_inode(src_f);
890	struct nfs_server *server = NFS_SERVER(file_inode(src_f));
891	struct nfs_lock_context *src_lock;
892	struct nfs_lock_context *dst_lock;
893	struct nfs4_exception src_exception = { };
894	struct nfs4_exception dst_exception = { };
895	int err, err2;
896
897	if (!nfs_server_capable(inode, NFS_CAP_CLONE))
898		return -EOPNOTSUPP;
899
900	src_lock = nfs_get_lock_context(nfs_file_open_context(src_f));
901	if (IS_ERR(src_lock))
902		return PTR_ERR(src_lock);
903
904	src_exception.inode = file_inode(src_f);
905	src_exception.state = src_lock->open_context->state;
906
907	dst_lock = nfs_get_lock_context(nfs_file_open_context(dst_f));
908	if (IS_ERR(dst_lock)) {
909		err = PTR_ERR(dst_lock);
910		goto out_put_src_lock;
911	}
912
913	dst_exception.inode = file_inode(dst_f);
914	dst_exception.state = dst_lock->open_context->state;
915
916	do {
917		err = _nfs42_proc_clone(&msg, src_f, dst_f, src_lock, dst_lock,
918					src_offset, dst_offset, count);
919		if (err == -ENOTSUPP || err == -EOPNOTSUPP) {
920			NFS_SERVER(inode)->caps &= ~NFS_CAP_CLONE;
921			err = -EOPNOTSUPP;
922			break;
923		}
924
925		err2 = nfs4_handle_exception(server, err, &src_exception);
926		err = nfs4_handle_exception(server, err, &dst_exception);
927		if (!err)
928			err = err2;
929	} while (src_exception.retry || dst_exception.retry);
930
931	nfs_put_lock_context(dst_lock);
932out_put_src_lock:
933	nfs_put_lock_context(src_lock);
934	return err;
935}