aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/nfs42proc.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2015-11-09 21:11:22 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2015-11-09 21:11:22 -0500
commite6604ecb70d4b1dbc0372c6518b51c25c4b135a1 (patch)
tree2d12c51b84c3ba8472e59ddbe37da034e2c5251f /fs/nfs/nfs42proc.c
parent9d74288ca79249af4b906215788b37d52263b58b (diff)
parent941c3ff3102ccce440034d59cf9e4e9cc10b720d (diff)
Merge tag 'nfs-for-4.4-1' of git://git.linux-nfs.org/projects/trondmy/linux-nfs
Pull NFS client updates from Trond Myklebust: "Highlights include: New features: - RDMA client backchannel from Chuck - Support for NFSv4.2 file CLONE using the btrfs ioctl Bugfixes + cleanups: - Move socket data receive out of the bottom halves and into a workqueue - Refactor NFSv4 error handling so synchronous and asynchronous RPC handles errors identically. - Fix a panic when blocks or object layouts reads return a bad data length - Fix nfsroot so it can handle a 1024 byte long path. - Fix bad usage of page offset in bl_read_pagelist - Various NFSv4 callback cleanups+fixes - Fix GETATTR bitmap verification - Support hexadecimal number for sunrpc debug sysctl files" * tag 'nfs-for-4.4-1' of git://git.linux-nfs.org/projects/trondmy/linux-nfs: (53 commits) Sunrpc: Supports hexadecimal number for sysctl files of sunrpc debug nfs: Fix GETATTR bitmap verification nfs: Remove unused xdr page offsets in getacl/setacl arguments fs/nfs: remove unnecessary new_valid_dev check SUNRPC: fix variable type NFS: Enable client side NFSv4.1 backchannel to use other transports pNFS/flexfiles: Add support for FF_FLAGS_NO_IO_THRU_MDS pNFS/flexfiles: When mirrored, retry failed reads by switching mirrors SUNRPC: Remove the TCP-only restriction in bc_svc_process() svcrdma: Add backward direction service for RPC/RDMA transport xprtrdma: Handle incoming backward direction RPC calls xprtrdma: Add support for sending backward direction RPC replies xprtrdma: Pre-allocate Work Requests for backchannel xprtrdma: Pre-allocate backward rpc_rqst and send/receive buffers SUNRPC: Abstract backchannel operations xprtrdma: Saving IRQs no longer needed for rb_lock xprtrdma: Remove reply tasklet xprtrdma: Use workqueue to process RPC/RDMA replies xprtrdma: Replace send and receive arrays xprtrdma: Refactor reply handler error handling ...
Diffstat (limited to 'fs/nfs/nfs42proc.c')
-rw-r--r--fs/nfs/nfs42proc.c71
1 files changed, 71 insertions, 0 deletions
diff --git a/fs/nfs/nfs42proc.c b/fs/nfs/nfs42proc.c
index 0f020e4d8421..3e92a3cde15d 100644
--- a/fs/nfs/nfs42proc.c
+++ b/fs/nfs/nfs42proc.c
@@ -271,3 +271,74 @@ int nfs42_proc_layoutstats_generic(struct nfs_server *server,
271 return PTR_ERR(task); 271 return PTR_ERR(task);
272 return 0; 272 return 0;
273} 273}
274
275static int _nfs42_proc_clone(struct rpc_message *msg, struct file *src_f,
276 struct file *dst_f, loff_t src_offset,
277 loff_t dst_offset, loff_t count)
278{
279 struct inode *src_inode = file_inode(src_f);
280 struct inode *dst_inode = file_inode(dst_f);
281 struct nfs_server *server = NFS_SERVER(dst_inode);
282 struct nfs42_clone_args args = {
283 .src_fh = NFS_FH(src_inode),
284 .dst_fh = NFS_FH(dst_inode),
285 .src_offset = src_offset,
286 .dst_offset = dst_offset,
287 .dst_bitmask = server->cache_consistency_bitmask,
288 };
289 struct nfs42_clone_res res = {
290 .server = server,
291 };
292 int status;
293
294 msg->rpc_argp = &args;
295 msg->rpc_resp = &res;
296
297 status = nfs42_set_rw_stateid(&args.src_stateid, src_f, FMODE_READ);
298 if (status)
299 return status;
300
301 status = nfs42_set_rw_stateid(&args.dst_stateid, dst_f, FMODE_WRITE);
302 if (status)
303 return status;
304
305 res.dst_fattr = nfs_alloc_fattr();
306 if (!res.dst_fattr)
307 return -ENOMEM;
308
309 status = nfs4_call_sync(server->client, server, msg,
310 &args.seq_args, &res.seq_res, 0);
311 if (status == 0)
312 status = nfs_post_op_update_inode(dst_inode, res.dst_fattr);
313
314 kfree(res.dst_fattr);
315 return status;
316}
317
318int nfs42_proc_clone(struct file *src_f, struct file *dst_f,
319 loff_t src_offset, loff_t dst_offset, loff_t count)
320{
321 struct rpc_message msg = {
322 .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_CLONE],
323 };
324 struct inode *inode = file_inode(src_f);
325 struct nfs_server *server = NFS_SERVER(file_inode(src_f));
326 struct nfs4_exception exception = { };
327 int err;
328
329 if (!nfs_server_capable(inode, NFS_CAP_CLONE))
330 return -EOPNOTSUPP;
331
332 do {
333 err = _nfs42_proc_clone(&msg, src_f, dst_f, src_offset,
334 dst_offset, count);
335 if (err == -ENOTSUPP || err == -EOPNOTSUPP) {
336 NFS_SERVER(inode)->caps &= ~NFS_CAP_CLONE;
337 return -EOPNOTSUPP;
338 }
339 err = nfs4_handle_exception(server, err, &exception);
340 } while (exception.retry);
341
342 return err;
343
344}