diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2015-11-09 21:11:22 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2015-11-09 21:11:22 -0500 |
commit | e6604ecb70d4b1dbc0372c6518b51c25c4b135a1 (patch) | |
tree | 2d12c51b84c3ba8472e59ddbe37da034e2c5251f /fs/nfs/nfs42proc.c | |
parent | 9d74288ca79249af4b906215788b37d52263b58b (diff) | |
parent | 941c3ff3102ccce440034d59cf9e4e9cc10b720d (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.c | 71 |
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 | |||
275 | static 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 | |||
318 | int 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 | } | ||