1b24ad07d4f535b5dd5d0cc90d75325e25cb536d
[cascardo/linux.git] / fs / nfs / callback_proc.c
1 /*
2  * linux/fs/nfs/callback_proc.c
3  *
4  * Copyright (C) 2004 Trond Myklebust
5  *
6  * NFSv4 callback procedures
7  */
8 #include <linux/nfs4.h>
9 #include <linux/nfs_fs.h>
10 #include <linux/slab.h>
11 #include <linux/rcupdate.h>
12 #include "nfs4_fs.h"
13 #include "callback.h"
14 #include "delegation.h"
15 #include "internal.h"
16 #include "pnfs.h"
17 #include "nfs4session.h"
18 #include "nfs4trace.h"
19
20 #define NFSDBG_FACILITY NFSDBG_CALLBACK
21
22 __be32 nfs4_callback_getattr(struct cb_getattrargs *args,
23                              struct cb_getattrres *res,
24                              struct cb_process_state *cps)
25 {
26         struct nfs_delegation *delegation;
27         struct nfs_inode *nfsi;
28         struct inode *inode;
29
30         res->status = htonl(NFS4ERR_OP_NOT_IN_SESSION);
31         if (!cps->clp) /* Always set for v4.0. Set in cb_sequence for v4.1 */
32                 goto out;
33
34         res->bitmap[0] = res->bitmap[1] = 0;
35         res->status = htonl(NFS4ERR_BADHANDLE);
36
37         dprintk_rcu("NFS: GETATTR callback request from %s\n",
38                 rpc_peeraddr2str(cps->clp->cl_rpcclient, RPC_DISPLAY_ADDR));
39
40         inode = nfs_delegation_find_inode(cps->clp, &args->fh);
41         if (inode == NULL) {
42                 trace_nfs4_cb_getattr(cps->clp, &args->fh, NULL,
43                                 -ntohl(res->status));
44                 goto out;
45         }
46         nfsi = NFS_I(inode);
47         rcu_read_lock();
48         delegation = rcu_dereference(nfsi->delegation);
49         if (delegation == NULL || (delegation->type & FMODE_WRITE) == 0)
50                 goto out_iput;
51         res->size = i_size_read(inode);
52         res->change_attr = delegation->change_attr;
53         if (nfsi->nrequests != 0)
54                 res->change_attr++;
55         res->ctime = inode->i_ctime;
56         res->mtime = inode->i_mtime;
57         res->bitmap[0] = (FATTR4_WORD0_CHANGE|FATTR4_WORD0_SIZE) &
58                 args->bitmap[0];
59         res->bitmap[1] = (FATTR4_WORD1_TIME_METADATA|FATTR4_WORD1_TIME_MODIFY) &
60                 args->bitmap[1];
61         res->status = 0;
62 out_iput:
63         rcu_read_unlock();
64         trace_nfs4_cb_getattr(cps->clp, &args->fh, inode, -ntohl(res->status));
65         iput(inode);
66 out:
67         dprintk("%s: exit with status = %d\n", __func__, ntohl(res->status));
68         return res->status;
69 }
70
71 __be32 nfs4_callback_recall(struct cb_recallargs *args, void *dummy,
72                             struct cb_process_state *cps)
73 {
74         struct inode *inode;
75         __be32 res;
76         
77         res = htonl(NFS4ERR_OP_NOT_IN_SESSION);
78         if (!cps->clp) /* Always set for v4.0. Set in cb_sequence for v4.1 */
79                 goto out;
80
81         dprintk_rcu("NFS: RECALL callback request from %s\n",
82                 rpc_peeraddr2str(cps->clp->cl_rpcclient, RPC_DISPLAY_ADDR));
83
84         res = htonl(NFS4ERR_BADHANDLE);
85         inode = nfs_delegation_find_inode(cps->clp, &args->fh);
86         if (inode == NULL)
87                 goto out;
88         /* Set up a helper thread to actually return the delegation */
89         switch (nfs_async_inode_return_delegation(inode, &args->stateid)) {
90         case 0:
91                 res = 0;
92                 break;
93         case -ENOENT:
94                 res = htonl(NFS4ERR_BAD_STATEID);
95                 break;
96         default:
97                 res = htonl(NFS4ERR_RESOURCE);
98         }
99         trace_nfs4_recall_delegation(inode, -ntohl(res));
100         iput(inode);
101 out:
102         dprintk("%s: exit with status = %d\n", __func__, ntohl(res));
103         return res;
104 }
105
106 #if defined(CONFIG_NFS_V4_1)
107
108 /*
109  * Lookup a layout by filehandle.
110  *
111  * Note: gets a refcount on the layout hdr and on its respective inode.
112  * Caller must put the layout hdr and the inode.
113  *
114  * TODO: keep track of all layouts (and delegations) in a hash table
115  * hashed by filehandle.
116  */
117 static struct pnfs_layout_hdr * get_layout_by_fh_locked(struct nfs_client *clp,
118                 struct nfs_fh *fh, nfs4_stateid *stateid)
119 {
120         struct nfs_server *server;
121         struct inode *ino;
122         struct pnfs_layout_hdr *lo;
123
124         list_for_each_entry_rcu(server, &clp->cl_superblocks, client_link) {
125                 list_for_each_entry(lo, &server->layouts, plh_layouts) {
126                         if (!nfs4_stateid_match_other(&lo->plh_stateid, stateid))
127                                 continue;
128                         if (nfs_compare_fh(fh, &NFS_I(lo->plh_inode)->fh))
129                                 continue;
130                         ino = igrab(lo->plh_inode);
131                         if (!ino)
132                                 break;
133                         spin_lock(&ino->i_lock);
134                         /* Is this layout in the process of being freed? */
135                         if (NFS_I(ino)->layout != lo) {
136                                 spin_unlock(&ino->i_lock);
137                                 iput(ino);
138                                 break;
139                         }
140                         pnfs_get_layout_hdr(lo);
141                         spin_unlock(&ino->i_lock);
142                         return lo;
143                 }
144         }
145
146         return NULL;
147 }
148
149 static struct pnfs_layout_hdr * get_layout_by_fh(struct nfs_client *clp,
150                 struct nfs_fh *fh, nfs4_stateid *stateid)
151 {
152         struct pnfs_layout_hdr *lo;
153
154         spin_lock(&clp->cl_lock);
155         rcu_read_lock();
156         lo = get_layout_by_fh_locked(clp, fh, stateid);
157         rcu_read_unlock();
158         spin_unlock(&clp->cl_lock);
159
160         return lo;
161 }
162
163 /*
164  * Enforce RFC5661 section 12.5.5.2.1. (Layout Recall and Return Sequencing)
165  */
166 static bool pnfs_check_stateid_sequence(struct pnfs_layout_hdr *lo,
167                                         const nfs4_stateid *new)
168 {
169         u32 oldseq, newseq;
170
171         oldseq = be32_to_cpu(lo->plh_stateid.seqid);
172         newseq = be32_to_cpu(new->seqid);
173
174         if (newseq > oldseq + 1)
175                 return false;
176         return true;
177 }
178
179 static u32 initiate_file_draining(struct nfs_client *clp,
180                                   struct cb_layoutrecallargs *args)
181 {
182         struct inode *ino;
183         struct pnfs_layout_hdr *lo;
184         u32 rv = NFS4ERR_NOMATCHING_LAYOUT;
185         LIST_HEAD(free_me_list);
186
187         lo = get_layout_by_fh(clp, &args->cbl_fh, &args->cbl_stateid);
188         if (!lo)
189                 goto out;
190
191         ino = lo->plh_inode;
192
193         spin_lock(&ino->i_lock);
194         if (!pnfs_check_stateid_sequence(lo, &args->cbl_stateid)) {
195                 rv = NFS4ERR_DELAY;
196                 goto unlock;
197         }
198         pnfs_set_layout_stateid(lo, &args->cbl_stateid, true);
199         spin_unlock(&ino->i_lock);
200
201         pnfs_layoutcommit_inode(ino, false);
202
203         spin_lock(&ino->i_lock);
204         /*
205          * Enforce RFC5661 Section 12.5.5.2.1.5 (Bulk Recall and Return)
206          */
207         if (test_bit(NFS_LAYOUT_BULK_RECALL, &lo->plh_flags)) {
208                 rv = NFS4ERR_DELAY;
209                 goto unlock;
210         }
211
212         if (pnfs_mark_matching_lsegs_invalid(lo, &free_me_list,
213                                         &args->cbl_range)) {
214                 pnfs_mark_matching_lsegs_return(lo,
215                                 &free_me_list,
216                                 &args->cbl_range);
217                 rv = NFS4ERR_DELAY;
218                 goto unlock;
219         }
220
221         if (NFS_SERVER(ino)->pnfs_curr_ld->return_range) {
222                 NFS_SERVER(ino)->pnfs_curr_ld->return_range(lo,
223                         &args->cbl_range);
224         }
225         pnfs_mark_layout_returned_if_empty(lo);
226 unlock:
227         spin_unlock(&ino->i_lock);
228         pnfs_free_lseg_list(&free_me_list);
229         pnfs_put_layout_hdr(lo);
230         trace_nfs4_cb_layoutrecall_inode(clp, &args->cbl_fh, ino, -rv);
231         iput(ino);
232 out:
233         return rv;
234 }
235
236 static u32 initiate_bulk_draining(struct nfs_client *clp,
237                                   struct cb_layoutrecallargs *args)
238 {
239         int stat;
240
241         if (args->cbl_recall_type == RETURN_FSID)
242                 stat = pnfs_destroy_layouts_byfsid(clp, &args->cbl_fsid, true);
243         else
244                 stat = pnfs_destroy_layouts_byclid(clp, true);
245         if (stat != 0)
246                 return NFS4ERR_DELAY;
247         return NFS4ERR_NOMATCHING_LAYOUT;
248 }
249
250 static u32 do_callback_layoutrecall(struct nfs_client *clp,
251                                     struct cb_layoutrecallargs *args)
252 {
253         u32 res;
254
255         dprintk("%s enter, type=%i\n", __func__, args->cbl_recall_type);
256         if (args->cbl_recall_type == RETURN_FILE)
257                 res = initiate_file_draining(clp, args);
258         else
259                 res = initiate_bulk_draining(clp, args);
260         dprintk("%s returning %i\n", __func__, res);
261         return res;
262
263 }
264
265 __be32 nfs4_callback_layoutrecall(struct cb_layoutrecallargs *args,
266                                   void *dummy, struct cb_process_state *cps)
267 {
268         u32 res;
269
270         dprintk("%s: -->\n", __func__);
271
272         if (cps->clp)
273                 res = do_callback_layoutrecall(cps->clp, args);
274         else
275                 res = NFS4ERR_OP_NOT_IN_SESSION;
276
277         dprintk("%s: exit with status = %d\n", __func__, res);
278         return cpu_to_be32(res);
279 }
280
281 static void pnfs_recall_all_layouts(struct nfs_client *clp)
282 {
283         struct cb_layoutrecallargs args;
284
285         /* Pretend we got a CB_LAYOUTRECALL(ALL) */
286         memset(&args, 0, sizeof(args));
287         args.cbl_recall_type = RETURN_ALL;
288         /* FIXME we ignore errors, what should we do? */
289         do_callback_layoutrecall(clp, &args);
290 }
291
292 __be32 nfs4_callback_devicenotify(struct cb_devicenotifyargs *args,
293                                   void *dummy, struct cb_process_state *cps)
294 {
295         int i;
296         __be32 res = 0;
297         struct nfs_client *clp = cps->clp;
298         struct nfs_server *server = NULL;
299
300         dprintk("%s: -->\n", __func__);
301
302         if (!clp) {
303                 res = cpu_to_be32(NFS4ERR_OP_NOT_IN_SESSION);
304                 goto out;
305         }
306
307         for (i = 0; i < args->ndevs; i++) {
308                 struct cb_devicenotifyitem *dev = &args->devs[i];
309
310                 if (!server ||
311                     server->pnfs_curr_ld->id != dev->cbd_layout_type) {
312                         rcu_read_lock();
313                         list_for_each_entry_rcu(server, &clp->cl_superblocks, client_link)
314                                 if (server->pnfs_curr_ld &&
315                                     server->pnfs_curr_ld->id == dev->cbd_layout_type) {
316                                         rcu_read_unlock();
317                                         goto found;
318                                 }
319                         rcu_read_unlock();
320                         dprintk("%s: layout type %u not found\n",
321                                 __func__, dev->cbd_layout_type);
322                         continue;
323                 }
324
325         found:
326                 nfs4_delete_deviceid(server->pnfs_curr_ld, clp, &dev->cbd_dev_id);
327         }
328
329 out:
330         kfree(args->devs);
331         dprintk("%s: exit with status = %u\n",
332                 __func__, be32_to_cpu(res));
333         return res;
334 }
335
336 /*
337  * Validate the sequenceID sent by the server.
338  * Return success if the sequenceID is one more than what we last saw on
339  * this slot, accounting for wraparound.  Increments the slot's sequence.
340  *
341  * We don't yet implement a duplicate request cache, instead we set the
342  * back channel ca_maxresponsesize_cached to zero. This is OK for now
343  * since we only currently implement idempotent callbacks anyway.
344  *
345  * We have a single slot backchannel at this time, so we don't bother
346  * checking the used_slots bit array on the table.  The lower layer guarantees
347  * a single outstanding callback request at a time.
348  */
349 static __be32
350 validate_seqid(struct nfs4_slot_table *tbl, struct cb_sequenceargs * args)
351 {
352         struct nfs4_slot *slot;
353
354         dprintk("%s enter. slotid %u seqid %u\n",
355                 __func__, args->csa_slotid, args->csa_sequenceid);
356
357         if (args->csa_slotid >= NFS41_BC_MAX_CALLBACKS)
358                 return htonl(NFS4ERR_BADSLOT);
359
360         slot = tbl->slots + args->csa_slotid;
361         dprintk("%s slot table seqid: %u\n", __func__, slot->seq_nr);
362
363         /* Normal */
364         if (likely(args->csa_sequenceid == slot->seq_nr + 1))
365                 goto out_ok;
366
367         /* Replay */
368         if (args->csa_sequenceid == slot->seq_nr) {
369                 dprintk("%s seqid %u is a replay\n",
370                         __func__, args->csa_sequenceid);
371                 /* Signal process_op to set this error on next op */
372                 if (args->csa_cachethis == 0)
373                         return htonl(NFS4ERR_RETRY_UNCACHED_REP);
374
375                 /* The ca_maxresponsesize_cached is 0 with no DRC */
376                 else if (args->csa_cachethis == 1)
377                         return htonl(NFS4ERR_REP_TOO_BIG_TO_CACHE);
378         }
379
380         /* Wraparound */
381         if (args->csa_sequenceid == 1 && (slot->seq_nr + 1) == 0) {
382                 slot->seq_nr = 1;
383                 goto out_ok;
384         }
385
386         /* Misordered request */
387         return htonl(NFS4ERR_SEQ_MISORDERED);
388 out_ok:
389         tbl->highest_used_slotid = args->csa_slotid;
390         return htonl(NFS4_OK);
391 }
392
393 /*
394  * For each referring call triple, check the session's slot table for
395  * a match.  If the slot is in use and the sequence numbers match, the
396  * client is still waiting for a response to the original request.
397  */
398 static bool referring_call_exists(struct nfs_client *clp,
399                                   uint32_t nrclists,
400                                   struct referring_call_list *rclists)
401 {
402         bool status = 0;
403         int i, j;
404         struct nfs4_session *session;
405         struct nfs4_slot_table *tbl;
406         struct referring_call_list *rclist;
407         struct referring_call *ref;
408
409         /*
410          * XXX When client trunking is implemented, this becomes
411          * a session lookup from within the loop
412          */
413         session = clp->cl_session;
414         tbl = &session->fc_slot_table;
415
416         for (i = 0; i < nrclists; i++) {
417                 rclist = &rclists[i];
418                 if (memcmp(session->sess_id.data,
419                            rclist->rcl_sessionid.data,
420                            NFS4_MAX_SESSIONID_LEN) != 0)
421                         continue;
422
423                 for (j = 0; j < rclist->rcl_nrefcalls; j++) {
424                         ref = &rclist->rcl_refcalls[j];
425
426                         dprintk("%s: sessionid %x:%x:%x:%x sequenceid %u "
427                                 "slotid %u\n", __func__,
428                                 ((u32 *)&rclist->rcl_sessionid.data)[0],
429                                 ((u32 *)&rclist->rcl_sessionid.data)[1],
430                                 ((u32 *)&rclist->rcl_sessionid.data)[2],
431                                 ((u32 *)&rclist->rcl_sessionid.data)[3],
432                                 ref->rc_sequenceid, ref->rc_slotid);
433
434                         spin_lock(&tbl->slot_tbl_lock);
435                         status = (test_bit(ref->rc_slotid, tbl->used_slots) &&
436                                   tbl->slots[ref->rc_slotid].seq_nr ==
437                                         ref->rc_sequenceid);
438                         spin_unlock(&tbl->slot_tbl_lock);
439                         if (status)
440                                 goto out;
441                 }
442         }
443
444 out:
445         return status;
446 }
447
448 __be32 nfs4_callback_sequence(struct cb_sequenceargs *args,
449                               struct cb_sequenceres *res,
450                               struct cb_process_state *cps)
451 {
452         struct nfs4_slot_table *tbl;
453         struct nfs4_slot *slot;
454         struct nfs_client *clp;
455         int i;
456         __be32 status = htonl(NFS4ERR_BADSESSION);
457
458         clp = nfs4_find_client_sessionid(cps->net, args->csa_addr,
459                                          &args->csa_sessionid, cps->minorversion);
460         if (clp == NULL)
461                 goto out;
462
463         if (!(clp->cl_session->flags & SESSION4_BACK_CHAN))
464                 goto out;
465
466         tbl = &clp->cl_session->bc_slot_table;
467         slot = tbl->slots + args->csa_slotid;
468
469         spin_lock(&tbl->slot_tbl_lock);
470         /* state manager is resetting the session */
471         if (test_bit(NFS4_SLOT_TBL_DRAINING, &tbl->slot_tbl_state)) {
472                 status = htonl(NFS4ERR_DELAY);
473                 /* Return NFS4ERR_BADSESSION if we're draining the session
474                  * in order to reset it.
475                  */
476                 if (test_bit(NFS4CLNT_SESSION_RESET, &clp->cl_state))
477                         status = htonl(NFS4ERR_BADSESSION);
478                 goto out_unlock;
479         }
480
481         memcpy(&res->csr_sessionid, &args->csa_sessionid,
482                sizeof(res->csr_sessionid));
483         res->csr_sequenceid = args->csa_sequenceid;
484         res->csr_slotid = args->csa_slotid;
485         res->csr_highestslotid = NFS41_BC_MAX_CALLBACKS - 1;
486         res->csr_target_highestslotid = NFS41_BC_MAX_CALLBACKS - 1;
487
488         status = validate_seqid(tbl, args);
489         if (status)
490                 goto out_unlock;
491
492         cps->slotid = args->csa_slotid;
493
494         /*
495          * Check for pending referring calls.  If a match is found, a
496          * related callback was received before the response to the original
497          * call.
498          */
499         if (referring_call_exists(clp, args->csa_nrclists, args->csa_rclists)) {
500                 status = htonl(NFS4ERR_DELAY);
501                 goto out_unlock;
502         }
503
504         /*
505          * RFC5661 20.9.3
506          * If CB_SEQUENCE returns an error, then the state of the slot
507          * (sequence ID, cached reply) MUST NOT change.
508          */
509         slot->seq_nr++;
510 out_unlock:
511         spin_unlock(&tbl->slot_tbl_lock);
512
513 out:
514         cps->clp = clp; /* put in nfs4_callback_compound */
515         for (i = 0; i < args->csa_nrclists; i++)
516                 kfree(args->csa_rclists[i].rcl_refcalls);
517         kfree(args->csa_rclists);
518
519         if (status == htonl(NFS4ERR_RETRY_UNCACHED_REP)) {
520                 cps->drc_status = status;
521                 status = 0;
522         } else
523                 res->csr_status = status;
524
525         trace_nfs4_cb_sequence(args, res, status);
526         dprintk("%s: exit with status = %d res->csr_status %d\n", __func__,
527                 ntohl(status), ntohl(res->csr_status));
528         return status;
529 }
530
531 static bool
532 validate_bitmap_values(unsigned long mask)
533 {
534         return (mask & ~RCA4_TYPE_MASK_ALL) == 0;
535 }
536
537 __be32 nfs4_callback_recallany(struct cb_recallanyargs *args, void *dummy,
538                                struct cb_process_state *cps)
539 {
540         __be32 status;
541         fmode_t flags = 0;
542
543         status = cpu_to_be32(NFS4ERR_OP_NOT_IN_SESSION);
544         if (!cps->clp) /* set in cb_sequence */
545                 goto out;
546
547         dprintk_rcu("NFS: RECALL_ANY callback request from %s\n",
548                 rpc_peeraddr2str(cps->clp->cl_rpcclient, RPC_DISPLAY_ADDR));
549
550         status = cpu_to_be32(NFS4ERR_INVAL);
551         if (!validate_bitmap_values(args->craa_type_mask))
552                 goto out;
553
554         status = cpu_to_be32(NFS4_OK);
555         if (test_bit(RCA4_TYPE_MASK_RDATA_DLG, (const unsigned long *)
556                      &args->craa_type_mask))
557                 flags = FMODE_READ;
558         if (test_bit(RCA4_TYPE_MASK_WDATA_DLG, (const unsigned long *)
559                      &args->craa_type_mask))
560                 flags |= FMODE_WRITE;
561         if (test_bit(RCA4_TYPE_MASK_FILE_LAYOUT, (const unsigned long *)
562                      &args->craa_type_mask))
563                 pnfs_recall_all_layouts(cps->clp);
564         if (flags)
565                 nfs_expire_unused_delegation_types(cps->clp, flags);
566 out:
567         dprintk("%s: exit with status = %d\n", __func__, ntohl(status));
568         return status;
569 }
570
571 /* Reduce the fore channel's max_slots to the target value */
572 __be32 nfs4_callback_recallslot(struct cb_recallslotargs *args, void *dummy,
573                                 struct cb_process_state *cps)
574 {
575         struct nfs4_slot_table *fc_tbl;
576         __be32 status;
577
578         status = htonl(NFS4ERR_OP_NOT_IN_SESSION);
579         if (!cps->clp) /* set in cb_sequence */
580                 goto out;
581
582         dprintk_rcu("NFS: CB_RECALL_SLOT request from %s target highest slotid %u\n",
583                 rpc_peeraddr2str(cps->clp->cl_rpcclient, RPC_DISPLAY_ADDR),
584                 args->crsa_target_highest_slotid);
585
586         fc_tbl = &cps->clp->cl_session->fc_slot_table;
587
588         status = htonl(NFS4_OK);
589
590         nfs41_set_target_slotid(fc_tbl, args->crsa_target_highest_slotid);
591         nfs41_notify_server(cps->clp);
592 out:
593         dprintk("%s: exit with status = %d\n", __func__, ntohl(status));
594         return status;
595 }
596 #endif /* CONFIG_NFS_V4_1 */