GNU Linux-libre 4.9.284-gnu1
[releases.git] / fs / nfs / nfs42proc.c
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
19 static 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
56 static int nfs42_proc_fallocate(struct rpc_message *msg, struct file *filep,
57                                 loff_t offset, loff_t len)
58 {
59         struct inode *inode = file_inode(filep);
60         struct nfs_server *server = NFS_SERVER(inode);
61         struct nfs4_exception exception = { };
62         struct nfs_lock_context *lock;
63         int err;
64
65         lock = nfs_get_lock_context(nfs_file_open_context(filep));
66         if (IS_ERR(lock))
67                 return PTR_ERR(lock);
68
69         exception.inode = inode;
70         exception.state = lock->open_context->state;
71
72         err = nfs_sync_inode(inode);
73         if (err)
74                 goto out;
75
76         do {
77                 err = _nfs42_proc_fallocate(msg, filep, lock, offset, len);
78                 if (err == -ENOTSUPP) {
79                         err = -EOPNOTSUPP;
80                         break;
81                 }
82                 err = nfs4_handle_exception(server, err, &exception);
83         } while (exception.retry);
84 out:
85         nfs_put_lock_context(lock);
86         return err;
87 }
88
89 int nfs42_proc_allocate(struct file *filep, loff_t offset, loff_t len)
90 {
91         struct rpc_message msg = {
92                 .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_ALLOCATE],
93         };
94         struct inode *inode = file_inode(filep);
95         int err;
96
97         if (!nfs_server_capable(inode, NFS_CAP_ALLOCATE))
98                 return -EOPNOTSUPP;
99
100         inode_lock(inode);
101
102         err = nfs42_proc_fallocate(&msg, filep, offset, len);
103         if (err == -EOPNOTSUPP)
104                 NFS_SERVER(inode)->caps &= ~NFS_CAP_ALLOCATE;
105
106         inode_unlock(inode);
107         return err;
108 }
109
110 int nfs42_proc_deallocate(struct file *filep, loff_t offset, loff_t len)
111 {
112         struct rpc_message msg = {
113                 .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_DEALLOCATE],
114         };
115         struct inode *inode = file_inode(filep);
116         int err;
117
118         if (!nfs_server_capable(inode, NFS_CAP_DEALLOCATE))
119                 return -EOPNOTSUPP;
120
121         inode_lock(inode);
122
123         err = nfs42_proc_fallocate(&msg, filep, offset, len);
124         if (err == 0)
125                 truncate_pagecache_range(inode, offset, (offset + len) -1);
126         if (err == -EOPNOTSUPP)
127                 NFS_SERVER(inode)->caps &= ~NFS_CAP_DEALLOCATE;
128
129         inode_unlock(inode);
130         return err;
131 }
132
133 static ssize_t _nfs42_proc_copy(struct file *src,
134                                 struct nfs_lock_context *src_lock,
135                                 struct file *dst,
136                                 struct nfs_lock_context *dst_lock,
137                                 struct nfs42_copy_args *args,
138                                 struct nfs42_copy_res *res)
139 {
140         struct rpc_message msg = {
141                 .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_COPY],
142                 .rpc_argp = args,
143                 .rpc_resp = res,
144         };
145         struct inode *dst_inode = file_inode(dst);
146         struct nfs_server *server = NFS_SERVER(dst_inode);
147         loff_t pos_src = args->src_pos;
148         loff_t pos_dst = args->dst_pos;
149         size_t count = args->count;
150         int status;
151
152         status = nfs4_set_rw_stateid(&args->src_stateid, src_lock->open_context,
153                                      src_lock, FMODE_READ);
154         if (status)
155                 return status;
156
157         status = nfs_filemap_write_and_wait_range(file_inode(src)->i_mapping,
158                         pos_src, pos_src + (loff_t)count - 1);
159         if (status)
160                 return status;
161
162         status = nfs4_set_rw_stateid(&args->dst_stateid, dst_lock->open_context,
163                                      dst_lock, FMODE_WRITE);
164         if (status)
165                 return status;
166
167         status = nfs_sync_inode(dst_inode);
168         if (status)
169                 return status;
170
171         status = nfs4_call_sync(server->client, server, &msg,
172                                 &args->seq_args, &res->seq_res, 0);
173         if (status == -ENOTSUPP)
174                 server->caps &= ~NFS_CAP_COPY;
175         if (status)
176                 return status;
177
178         if (res->write_res.verifier.committed != NFS_FILE_SYNC) {
179                 status = nfs_commit_file(dst, &res->write_res.verifier.verifier);
180                 if (status)
181                         return status;
182         }
183
184         truncate_pagecache_range(dst_inode, pos_dst,
185                                  pos_dst + res->write_res.count);
186
187         return res->write_res.count;
188 }
189
190 ssize_t nfs42_proc_copy(struct file *src, loff_t pos_src,
191                         struct file *dst, loff_t pos_dst,
192                         size_t count)
193 {
194         struct nfs_server *server = NFS_SERVER(file_inode(dst));
195         struct nfs_lock_context *src_lock;
196         struct nfs_lock_context *dst_lock;
197         struct nfs42_copy_args args = {
198                 .src_fh         = NFS_FH(file_inode(src)),
199                 .src_pos        = pos_src,
200                 .dst_fh         = NFS_FH(file_inode(dst)),
201                 .dst_pos        = pos_dst,
202                 .count          = count,
203         };
204         struct nfs42_copy_res res;
205         struct nfs4_exception src_exception = {
206                 .inode          = file_inode(src),
207                 .stateid        = &args.src_stateid,
208         };
209         struct nfs4_exception dst_exception = {
210                 .inode          = file_inode(dst),
211                 .stateid        = &args.dst_stateid,
212         };
213         ssize_t err, err2;
214
215         if (!nfs_server_capable(file_inode(dst), NFS_CAP_COPY))
216                 return -EOPNOTSUPP;
217
218         src_lock = nfs_get_lock_context(nfs_file_open_context(src));
219         if (IS_ERR(src_lock))
220                 return PTR_ERR(src_lock);
221
222         src_exception.state = src_lock->open_context->state;
223
224         dst_lock = nfs_get_lock_context(nfs_file_open_context(dst));
225         if (IS_ERR(dst_lock)) {
226                 err = PTR_ERR(dst_lock);
227                 goto out_put_src_lock;
228         }
229
230         dst_exception.state = dst_lock->open_context->state;
231
232         do {
233                 inode_lock(file_inode(dst));
234                 err = _nfs42_proc_copy(src, src_lock,
235                                 dst, dst_lock,
236                                 &args, &res);
237                 inode_unlock(file_inode(dst));
238
239                 if (err >= 0)
240                         break;
241                 if (err == -ENOTSUPP) {
242                         err = -EOPNOTSUPP;
243                         break;
244                 }
245
246                 err2 = nfs4_handle_exception(server, err, &src_exception);
247                 err  = nfs4_handle_exception(server, err, &dst_exception);
248                 if (!err)
249                         err = err2;
250         } while (src_exception.retry || dst_exception.retry);
251
252         nfs_put_lock_context(dst_lock);
253 out_put_src_lock:
254         nfs_put_lock_context(src_lock);
255         return err;
256 }
257
258 static loff_t _nfs42_proc_llseek(struct file *filep,
259                 struct nfs_lock_context *lock, loff_t offset, int whence)
260 {
261         struct inode *inode = file_inode(filep);
262         struct nfs42_seek_args args = {
263                 .sa_fh          = NFS_FH(inode),
264                 .sa_offset      = offset,
265                 .sa_what        = (whence == SEEK_HOLE) ?
266                                         NFS4_CONTENT_HOLE : NFS4_CONTENT_DATA,
267         };
268         struct nfs42_seek_res res;
269         struct rpc_message msg = {
270                 .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_SEEK],
271                 .rpc_argp = &args,
272                 .rpc_resp = &res,
273         };
274         struct nfs_server *server = NFS_SERVER(inode);
275         int status;
276
277         if (!nfs_server_capable(inode, NFS_CAP_SEEK))
278                 return -ENOTSUPP;
279
280         status = nfs4_set_rw_stateid(&args.sa_stateid, lock->open_context,
281                         lock, FMODE_READ);
282         if (status)
283                 return status;
284
285         status = nfs_filemap_write_and_wait_range(inode->i_mapping,
286                         offset, LLONG_MAX);
287         if (status)
288                 return status;
289
290         status = nfs4_call_sync(server->client, server, &msg,
291                                 &args.seq_args, &res.seq_res, 0);
292         if (status == -ENOTSUPP)
293                 server->caps &= ~NFS_CAP_SEEK;
294         if (status)
295                 return status;
296
297         if (whence == SEEK_DATA && res.sr_eof)
298                 return -NFS4ERR_NXIO;
299         else
300                 return vfs_setpos(filep, res.sr_offset, inode->i_sb->s_maxbytes);
301 }
302
303 loff_t nfs42_proc_llseek(struct file *filep, loff_t offset, int whence)
304 {
305         struct nfs_server *server = NFS_SERVER(file_inode(filep));
306         struct nfs4_exception exception = { };
307         struct nfs_lock_context *lock;
308         loff_t err;
309
310         lock = nfs_get_lock_context(nfs_file_open_context(filep));
311         if (IS_ERR(lock))
312                 return PTR_ERR(lock);
313
314         exception.inode = file_inode(filep);
315         exception.state = lock->open_context->state;
316
317         do {
318                 err = _nfs42_proc_llseek(filep, lock, offset, whence);
319                 if (err >= 0)
320                         break;
321                 if (err == -ENOTSUPP) {
322                         err = -EOPNOTSUPP;
323                         break;
324                 }
325                 err = nfs4_handle_exception(server, err, &exception);
326         } while (exception.retry);
327
328         nfs_put_lock_context(lock);
329         return err;
330 }
331
332
333 static void
334 nfs42_layoutstat_prepare(struct rpc_task *task, void *calldata)
335 {
336         struct nfs42_layoutstat_data *data = calldata;
337         struct inode *inode = data->inode;
338         struct nfs_server *server = NFS_SERVER(inode);
339         struct pnfs_layout_hdr *lo;
340
341         spin_lock(&inode->i_lock);
342         lo = NFS_I(inode)->layout;
343         if (!pnfs_layout_is_valid(lo)) {
344                 spin_unlock(&inode->i_lock);
345                 rpc_exit(task, 0);
346                 return;
347         }
348         nfs4_stateid_copy(&data->args.stateid, &lo->plh_stateid);
349         spin_unlock(&inode->i_lock);
350         nfs41_setup_sequence(nfs4_get_session(server), &data->args.seq_args,
351                              &data->res.seq_res, task);
352
353 }
354
355 static void
356 nfs42_layoutstat_done(struct rpc_task *task, void *calldata)
357 {
358         struct nfs42_layoutstat_data *data = calldata;
359         struct inode *inode = data->inode;
360         struct pnfs_layout_hdr *lo;
361
362         if (!nfs4_sequence_done(task, &data->res.seq_res))
363                 return;
364
365         switch (task->tk_status) {
366         case 0:
367                 break;
368         case -NFS4ERR_EXPIRED:
369         case -NFS4ERR_ADMIN_REVOKED:
370         case -NFS4ERR_DELEG_REVOKED:
371         case -NFS4ERR_STALE_STATEID:
372         case -NFS4ERR_BAD_STATEID:
373                 spin_lock(&inode->i_lock);
374                 lo = NFS_I(inode)->layout;
375                 if (pnfs_layout_is_valid(lo) &&
376                     nfs4_stateid_match(&data->args.stateid,
377                                              &lo->plh_stateid)) {
378                         LIST_HEAD(head);
379
380                         /*
381                          * Mark the bad layout state as invalid, then retry
382                          * with the current stateid.
383                          */
384                         pnfs_mark_layout_stateid_invalid(lo, &head);
385                         spin_unlock(&inode->i_lock);
386                         pnfs_free_lseg_list(&head);
387                 } else
388                         spin_unlock(&inode->i_lock);
389                 break;
390         case -NFS4ERR_OLD_STATEID:
391                 spin_lock(&inode->i_lock);
392                 lo = NFS_I(inode)->layout;
393                 if (pnfs_layout_is_valid(lo) &&
394                     nfs4_stateid_match_other(&data->args.stateid,
395                                         &lo->plh_stateid)) {
396                         /* Do we need to delay before resending? */
397                         if (!nfs4_stateid_is_newer(&lo->plh_stateid,
398                                                 &data->args.stateid))
399                                 rpc_delay(task, HZ);
400                         rpc_restart_call_prepare(task);
401                 }
402                 spin_unlock(&inode->i_lock);
403                 break;
404         case -ENOTSUPP:
405         case -EOPNOTSUPP:
406                 NFS_SERVER(inode)->caps &= ~NFS_CAP_LAYOUTSTATS;
407         }
408
409         dprintk("%s server returns %d\n", __func__, task->tk_status);
410 }
411
412 static void
413 nfs42_layoutstat_release(void *calldata)
414 {
415         struct nfs42_layoutstat_data *data = calldata;
416         struct nfs_server *nfss = NFS_SERVER(data->args.inode);
417
418         if (nfss->pnfs_curr_ld->cleanup_layoutstats)
419                 nfss->pnfs_curr_ld->cleanup_layoutstats(data);
420
421         pnfs_put_layout_hdr(NFS_I(data->args.inode)->layout);
422         smp_mb__before_atomic();
423         clear_bit(NFS_INO_LAYOUTSTATS, &NFS_I(data->args.inode)->flags);
424         smp_mb__after_atomic();
425         nfs_iput_and_deactive(data->inode);
426         kfree(data->args.devinfo);
427         kfree(data);
428 }
429
430 static const struct rpc_call_ops nfs42_layoutstat_ops = {
431         .rpc_call_prepare = nfs42_layoutstat_prepare,
432         .rpc_call_done = nfs42_layoutstat_done,
433         .rpc_release = nfs42_layoutstat_release,
434 };
435
436 int nfs42_proc_layoutstats_generic(struct nfs_server *server,
437                                    struct nfs42_layoutstat_data *data)
438 {
439         struct rpc_message msg = {
440                 .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_LAYOUTSTATS],
441                 .rpc_argp = &data->args,
442                 .rpc_resp = &data->res,
443         };
444         struct rpc_task_setup task_setup = {
445                 .rpc_client = server->client,
446                 .rpc_message = &msg,
447                 .callback_ops = &nfs42_layoutstat_ops,
448                 .callback_data = data,
449                 .flags = RPC_TASK_ASYNC,
450         };
451         struct rpc_task *task;
452
453         data->inode = nfs_igrab_and_active(data->args.inode);
454         if (!data->inode) {
455                 nfs42_layoutstat_release(data);
456                 return -EAGAIN;
457         }
458         nfs4_init_sequence(&data->args.seq_args, &data->res.seq_res, 0);
459         task = rpc_run_task(&task_setup);
460         if (IS_ERR(task))
461                 return PTR_ERR(task);
462         rpc_put_task(task);
463         return 0;
464 }
465
466 static int _nfs42_proc_clone(struct rpc_message *msg, struct file *src_f,
467                 struct file *dst_f, struct nfs_lock_context *src_lock,
468                 struct nfs_lock_context *dst_lock, loff_t src_offset,
469                 loff_t dst_offset, loff_t count)
470 {
471         struct inode *src_inode = file_inode(src_f);
472         struct inode *dst_inode = file_inode(dst_f);
473         struct nfs_server *server = NFS_SERVER(dst_inode);
474         struct nfs42_clone_args args = {
475                 .src_fh = NFS_FH(src_inode),
476                 .dst_fh = NFS_FH(dst_inode),
477                 .src_offset = src_offset,
478                 .dst_offset = dst_offset,
479                 .count = count,
480                 .dst_bitmask = server->cache_consistency_bitmask,
481         };
482         struct nfs42_clone_res res = {
483                 .server = server,
484         };
485         int status;
486
487         msg->rpc_argp = &args;
488         msg->rpc_resp = &res;
489
490         status = nfs4_set_rw_stateid(&args.src_stateid, src_lock->open_context,
491                         src_lock, FMODE_READ);
492         if (status)
493                 return status;
494
495         status = nfs4_set_rw_stateid(&args.dst_stateid, dst_lock->open_context,
496                         dst_lock, FMODE_WRITE);
497         if (status)
498                 return status;
499
500         res.dst_fattr = nfs_alloc_fattr();
501         if (!res.dst_fattr)
502                 return -ENOMEM;
503
504         status = nfs4_call_sync(server->client, server, msg,
505                                 &args.seq_args, &res.seq_res, 0);
506         if (status == 0)
507                 status = nfs_post_op_update_inode(dst_inode, res.dst_fattr);
508
509         kfree(res.dst_fattr);
510         return status;
511 }
512
513 int nfs42_proc_clone(struct file *src_f, struct file *dst_f,
514                      loff_t src_offset, loff_t dst_offset, loff_t count)
515 {
516         struct rpc_message msg = {
517                 .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_CLONE],
518         };
519         struct inode *inode = file_inode(src_f);
520         struct nfs_server *server = NFS_SERVER(file_inode(src_f));
521         struct nfs_lock_context *src_lock;
522         struct nfs_lock_context *dst_lock;
523         struct nfs4_exception src_exception = { };
524         struct nfs4_exception dst_exception = { };
525         int err, err2;
526
527         if (!nfs_server_capable(inode, NFS_CAP_CLONE))
528                 return -EOPNOTSUPP;
529
530         src_lock = nfs_get_lock_context(nfs_file_open_context(src_f));
531         if (IS_ERR(src_lock))
532                 return PTR_ERR(src_lock);
533
534         src_exception.inode = file_inode(src_f);
535         src_exception.state = src_lock->open_context->state;
536
537         dst_lock = nfs_get_lock_context(nfs_file_open_context(dst_f));
538         if (IS_ERR(dst_lock)) {
539                 err = PTR_ERR(dst_lock);
540                 goto out_put_src_lock;
541         }
542
543         dst_exception.inode = file_inode(dst_f);
544         dst_exception.state = dst_lock->open_context->state;
545
546         do {
547                 err = _nfs42_proc_clone(&msg, src_f, dst_f, src_lock, dst_lock,
548                                         src_offset, dst_offset, count);
549                 if (err == -ENOTSUPP || err == -EOPNOTSUPP) {
550                         NFS_SERVER(inode)->caps &= ~NFS_CAP_CLONE;
551                         err = -EOPNOTSUPP;
552                         break;
553                 }
554
555                 err2 = nfs4_handle_exception(server, err, &src_exception);
556                 err = nfs4_handle_exception(server, err, &dst_exception);
557                 if (!err)
558                         err = err2;
559         } while (src_exception.retry || dst_exception.retry);
560
561         nfs_put_lock_context(dst_lock);
562 out_put_src_lock:
563         nfs_put_lock_context(src_lock);
564         return err;
565 }