NFSv4.1: Remove assertion BUG_ON()s from the files and generic layout code
[profile/ivi/kernel-adaptation-intel-automotive.git] / fs / nfs / nfs4filelayoutdev.c
1 /*
2  *  Device operations for the pnfs nfs4 file layout driver.
3  *
4  *  Copyright (c) 2002
5  *  The Regents of the University of Michigan
6  *  All Rights Reserved
7  *
8  *  Dean Hildebrand <dhildebz@umich.edu>
9  *  Garth Goodson   <Garth.Goodson@netapp.com>
10  *
11  *  Permission is granted to use, copy, create derivative works, and
12  *  redistribute this software and such derivative works for any purpose,
13  *  so long as the name of the University of Michigan is not used in
14  *  any advertising or publicity pertaining to the use or distribution
15  *  of this software without specific, written prior authorization. If
16  *  the above copyright notice or any other identification of the
17  *  University of Michigan is included in any copy of any portion of
18  *  this software, then the disclaimer below must also be included.
19  *
20  *  This software is provided as is, without representation or warranty
21  *  of any kind either express or implied, including without limitation
22  *  the implied warranties of merchantability, fitness for a particular
23  *  purpose, or noninfringement.  The Regents of the University of
24  *  Michigan shall not be liable for any damages, including special,
25  *  indirect, incidental, or consequential damages, with respect to any
26  *  claim arising out of or in connection with the use of the software,
27  *  even if it has been or is hereafter advised of the possibility of
28  *  such damages.
29  */
30
31 #include <linux/nfs_fs.h>
32 #include <linux/vmalloc.h>
33 #include <linux/module.h>
34
35 #include "internal.h"
36 #include "nfs4filelayout.h"
37
38 #define NFSDBG_FACILITY         NFSDBG_PNFS_LD
39
40 static unsigned int dataserver_timeo = NFS4_DEF_DS_TIMEO;
41 static unsigned int dataserver_retrans = NFS4_DEF_DS_RETRANS;
42
43 /*
44  * Data server cache
45  *
46  * Data servers can be mapped to different device ids.
47  * nfs4_pnfs_ds reference counting
48  *   - set to 1 on allocation
49  *   - incremented when a device id maps a data server already in the cache.
50  *   - decremented when deviceid is removed from the cache.
51  */
52 static DEFINE_SPINLOCK(nfs4_ds_cache_lock);
53 static LIST_HEAD(nfs4_data_server_cache);
54
55 /* Debug routines */
56 void
57 print_ds(struct nfs4_pnfs_ds *ds)
58 {
59         if (ds == NULL) {
60                 printk("%s NULL device\n", __func__);
61                 return;
62         }
63         printk("        ds %s\n"
64                 "        ref count %d\n"
65                 "        client %p\n"
66                 "        cl_exchange_flags %x\n",
67                 ds->ds_remotestr,
68                 atomic_read(&ds->ds_count), ds->ds_clp,
69                 ds->ds_clp ? ds->ds_clp->cl_exchange_flags : 0);
70 }
71
72 static bool
73 same_sockaddr(struct sockaddr *addr1, struct sockaddr *addr2)
74 {
75         struct sockaddr_in *a, *b;
76         struct sockaddr_in6 *a6, *b6;
77
78         if (addr1->sa_family != addr2->sa_family)
79                 return false;
80
81         switch (addr1->sa_family) {
82         case AF_INET:
83                 a = (struct sockaddr_in *)addr1;
84                 b = (struct sockaddr_in *)addr2;
85
86                 if (a->sin_addr.s_addr == b->sin_addr.s_addr &&
87                     a->sin_port == b->sin_port)
88                         return true;
89                 break;
90
91         case AF_INET6:
92                 a6 = (struct sockaddr_in6 *)addr1;
93                 b6 = (struct sockaddr_in6 *)addr2;
94
95                 /* LINKLOCAL addresses must have matching scope_id */
96                 if (ipv6_addr_scope(&a6->sin6_addr) ==
97                     IPV6_ADDR_SCOPE_LINKLOCAL &&
98                     a6->sin6_scope_id != b6->sin6_scope_id)
99                         return false;
100
101                 if (ipv6_addr_equal(&a6->sin6_addr, &b6->sin6_addr) &&
102                     a6->sin6_port == b6->sin6_port)
103                         return true;
104                 break;
105
106         default:
107                 dprintk("%s: unhandled address family: %u\n",
108                         __func__, addr1->sa_family);
109                 return false;
110         }
111
112         return false;
113 }
114
115 static bool
116 _same_data_server_addrs_locked(const struct list_head *dsaddrs1,
117                                const struct list_head *dsaddrs2)
118 {
119         struct nfs4_pnfs_ds_addr *da1, *da2;
120
121         /* step through both lists, comparing as we go */
122         for (da1 = list_first_entry(dsaddrs1, typeof(*da1), da_node),
123              da2 = list_first_entry(dsaddrs2, typeof(*da2), da_node);
124              da1 != NULL && da2 != NULL;
125              da1 = list_entry(da1->da_node.next, typeof(*da1), da_node),
126              da2 = list_entry(da2->da_node.next, typeof(*da2), da_node)) {
127                 if (!same_sockaddr((struct sockaddr *)&da1->da_addr,
128                                    (struct sockaddr *)&da2->da_addr))
129                         return false;
130         }
131         if (da1 == NULL && da2 == NULL)
132                 return true;
133
134         return false;
135 }
136
137 /*
138  * Lookup DS by addresses.  nfs4_ds_cache_lock is held
139  */
140 static struct nfs4_pnfs_ds *
141 _data_server_lookup_locked(const struct list_head *dsaddrs)
142 {
143         struct nfs4_pnfs_ds *ds;
144
145         list_for_each_entry(ds, &nfs4_data_server_cache, ds_node)
146                 if (_same_data_server_addrs_locked(&ds->ds_addrs, dsaddrs))
147                         return ds;
148         return NULL;
149 }
150
151 /*
152  * Create an rpc connection to the nfs4_pnfs_ds data server
153  * Currently only supports IPv4 and IPv6 addresses
154  */
155 static int
156 nfs4_ds_connect(struct nfs_server *mds_srv, struct nfs4_pnfs_ds *ds)
157 {
158         struct nfs_client *clp = ERR_PTR(-EIO);
159         struct nfs4_pnfs_ds_addr *da;
160         int status = 0;
161
162         dprintk("--> %s DS %s au_flavor %d\n", __func__, ds->ds_remotestr,
163                 mds_srv->nfs_client->cl_rpcclient->cl_auth->au_flavor);
164
165         list_for_each_entry(da, &ds->ds_addrs, da_node) {
166                 dprintk("%s: DS %s: trying address %s\n",
167                         __func__, ds->ds_remotestr, da->da_remotestr);
168
169                 clp = nfs4_set_ds_client(mds_srv->nfs_client,
170                                         (struct sockaddr *)&da->da_addr,
171                                         da->da_addrlen, IPPROTO_TCP,
172                                         dataserver_timeo, dataserver_retrans);
173                 if (!IS_ERR(clp))
174                         break;
175         }
176
177         if (IS_ERR(clp)) {
178                 status = PTR_ERR(clp);
179                 goto out;
180         }
181
182         status = nfs4_init_ds_session(clp, mds_srv->nfs_client->cl_lease_time);
183         if (status)
184                 goto out_put;
185
186         ds->ds_clp = clp;
187         dprintk("%s [new] addr: %s\n", __func__, ds->ds_remotestr);
188 out:
189         return status;
190 out_put:
191         nfs_put_client(clp);
192         goto out;
193 }
194
195 static void
196 destroy_ds(struct nfs4_pnfs_ds *ds)
197 {
198         struct nfs4_pnfs_ds_addr *da;
199
200         dprintk("--> %s\n", __func__);
201         ifdebug(FACILITY)
202                 print_ds(ds);
203
204         if (ds->ds_clp)
205                 nfs_put_client(ds->ds_clp);
206
207         while (!list_empty(&ds->ds_addrs)) {
208                 da = list_first_entry(&ds->ds_addrs,
209                                       struct nfs4_pnfs_ds_addr,
210                                       da_node);
211                 list_del_init(&da->da_node);
212                 kfree(da->da_remotestr);
213                 kfree(da);
214         }
215
216         kfree(ds->ds_remotestr);
217         kfree(ds);
218 }
219
220 void
221 nfs4_fl_free_deviceid(struct nfs4_file_layout_dsaddr *dsaddr)
222 {
223         struct nfs4_pnfs_ds *ds;
224         int i;
225
226         nfs4_print_deviceid(&dsaddr->id_node.deviceid);
227
228         for (i = 0; i < dsaddr->ds_num; i++) {
229                 ds = dsaddr->ds_list[i];
230                 if (ds != NULL) {
231                         if (atomic_dec_and_lock(&ds->ds_count,
232                                                 &nfs4_ds_cache_lock)) {
233                                 list_del_init(&ds->ds_node);
234                                 spin_unlock(&nfs4_ds_cache_lock);
235                                 destroy_ds(ds);
236                         }
237                 }
238         }
239         kfree(dsaddr->stripe_indices);
240         kfree(dsaddr);
241 }
242
243 /*
244  * Create a string with a human readable address and port to avoid
245  * complicated setup around many dprinks.
246  */
247 static char *
248 nfs4_pnfs_remotestr(struct list_head *dsaddrs, gfp_t gfp_flags)
249 {
250         struct nfs4_pnfs_ds_addr *da;
251         char *remotestr;
252         size_t len;
253         char *p;
254
255         len = 3;        /* '{', '}' and eol */
256         list_for_each_entry(da, dsaddrs, da_node) {
257                 len += strlen(da->da_remotestr) + 1;    /* string plus comma */
258         }
259
260         remotestr = kzalloc(len, gfp_flags);
261         if (!remotestr)
262                 return NULL;
263
264         p = remotestr;
265         *(p++) = '{';
266         len--;
267         list_for_each_entry(da, dsaddrs, da_node) {
268                 size_t ll = strlen(da->da_remotestr);
269
270                 if (ll > len)
271                         goto out_err;
272
273                 memcpy(p, da->da_remotestr, ll);
274                 p += ll;
275                 len -= ll;
276
277                 if (len < 1)
278                         goto out_err;
279                 (*p++) = ',';
280                 len--;
281         }
282         if (len < 2)
283                 goto out_err;
284         *(p++) = '}';
285         *p = '\0';
286         return remotestr;
287 out_err:
288         kfree(remotestr);
289         return NULL;
290 }
291
292 static struct nfs4_pnfs_ds *
293 nfs4_pnfs_ds_add(struct list_head *dsaddrs, gfp_t gfp_flags)
294 {
295         struct nfs4_pnfs_ds *tmp_ds, *ds = NULL;
296         char *remotestr;
297
298         if (list_empty(dsaddrs)) {
299                 dprintk("%s: no addresses defined\n", __func__);
300                 goto out;
301         }
302
303         ds = kzalloc(sizeof(*ds), gfp_flags);
304         if (!ds)
305                 goto out;
306
307         /* this is only used for debugging, so it's ok if its NULL */
308         remotestr = nfs4_pnfs_remotestr(dsaddrs, gfp_flags);
309
310         spin_lock(&nfs4_ds_cache_lock);
311         tmp_ds = _data_server_lookup_locked(dsaddrs);
312         if (tmp_ds == NULL) {
313                 INIT_LIST_HEAD(&ds->ds_addrs);
314                 list_splice_init(dsaddrs, &ds->ds_addrs);
315                 ds->ds_remotestr = remotestr;
316                 atomic_set(&ds->ds_count, 1);
317                 INIT_LIST_HEAD(&ds->ds_node);
318                 ds->ds_clp = NULL;
319                 list_add(&ds->ds_node, &nfs4_data_server_cache);
320                 dprintk("%s add new data server %s\n", __func__,
321                         ds->ds_remotestr);
322         } else {
323                 kfree(remotestr);
324                 kfree(ds);
325                 atomic_inc(&tmp_ds->ds_count);
326                 dprintk("%s data server %s found, inc'ed ds_count to %d\n",
327                         __func__, tmp_ds->ds_remotestr,
328                         atomic_read(&tmp_ds->ds_count));
329                 ds = tmp_ds;
330         }
331         spin_unlock(&nfs4_ds_cache_lock);
332 out:
333         return ds;
334 }
335
336 /*
337  * Currently only supports ipv4, ipv6 and one multi-path address.
338  */
339 static struct nfs4_pnfs_ds_addr *
340 decode_ds_addr(struct net *net, struct xdr_stream *streamp, gfp_t gfp_flags)
341 {
342         struct nfs4_pnfs_ds_addr *da = NULL;
343         char *buf, *portstr;
344         __be16 port;
345         int nlen, rlen;
346         int tmp[2];
347         __be32 *p;
348         char *netid, *match_netid;
349         size_t len, match_netid_len;
350         char *startsep = "";
351         char *endsep = "";
352
353
354         /* r_netid */
355         p = xdr_inline_decode(streamp, 4);
356         if (unlikely(!p))
357                 goto out_err;
358         nlen = be32_to_cpup(p++);
359
360         p = xdr_inline_decode(streamp, nlen);
361         if (unlikely(!p))
362                 goto out_err;
363
364         netid = kmalloc(nlen+1, gfp_flags);
365         if (unlikely(!netid))
366                 goto out_err;
367
368         netid[nlen] = '\0';
369         memcpy(netid, p, nlen);
370
371         /* r_addr: ip/ip6addr with port in dec octets - see RFC 5665 */
372         p = xdr_inline_decode(streamp, 4);
373         if (unlikely(!p))
374                 goto out_free_netid;
375         rlen = be32_to_cpup(p);
376
377         p = xdr_inline_decode(streamp, rlen);
378         if (unlikely(!p))
379                 goto out_free_netid;
380
381         /* port is ".ABC.DEF", 8 chars max */
382         if (rlen > INET6_ADDRSTRLEN + IPV6_SCOPE_ID_LEN + 8) {
383                 dprintk("%s: Invalid address, length %d\n", __func__,
384                         rlen);
385                 goto out_free_netid;
386         }
387         buf = kmalloc(rlen + 1, gfp_flags);
388         if (!buf) {
389                 dprintk("%s: Not enough memory\n", __func__);
390                 goto out_free_netid;
391         }
392         buf[rlen] = '\0';
393         memcpy(buf, p, rlen);
394
395         /* replace port '.' with '-' */
396         portstr = strrchr(buf, '.');
397         if (!portstr) {
398                 dprintk("%s: Failed finding expected dot in port\n",
399                         __func__);
400                 goto out_free_buf;
401         }
402         *portstr = '-';
403
404         /* find '.' between address and port */
405         portstr = strrchr(buf, '.');
406         if (!portstr) {
407                 dprintk("%s: Failed finding expected dot between address and "
408                         "port\n", __func__);
409                 goto out_free_buf;
410         }
411         *portstr = '\0';
412
413         da = kzalloc(sizeof(*da), gfp_flags);
414         if (unlikely(!da))
415                 goto out_free_buf;
416
417         INIT_LIST_HEAD(&da->da_node);
418
419         if (!rpc_pton(net, buf, portstr-buf, (struct sockaddr *)&da->da_addr,
420                       sizeof(da->da_addr))) {
421                 dprintk("%s: error parsing address %s\n", __func__, buf);
422                 goto out_free_da;
423         }
424
425         portstr++;
426         sscanf(portstr, "%d-%d", &tmp[0], &tmp[1]);
427         port = htons((tmp[0] << 8) | (tmp[1]));
428
429         switch (da->da_addr.ss_family) {
430         case AF_INET:
431                 ((struct sockaddr_in *)&da->da_addr)->sin_port = port;
432                 da->da_addrlen = sizeof(struct sockaddr_in);
433                 match_netid = "tcp";
434                 match_netid_len = 3;
435                 break;
436
437         case AF_INET6:
438                 ((struct sockaddr_in6 *)&da->da_addr)->sin6_port = port;
439                 da->da_addrlen = sizeof(struct sockaddr_in6);
440                 match_netid = "tcp6";
441                 match_netid_len = 4;
442                 startsep = "[";
443                 endsep = "]";
444                 break;
445
446         default:
447                 dprintk("%s: unsupported address family: %u\n",
448                         __func__, da->da_addr.ss_family);
449                 goto out_free_da;
450         }
451
452         if (nlen != match_netid_len || strncmp(netid, match_netid, nlen)) {
453                 dprintk("%s: ERROR: r_netid \"%s\" != \"%s\"\n",
454                         __func__, netid, match_netid);
455                 goto out_free_da;
456         }
457
458         /* save human readable address */
459         len = strlen(startsep) + strlen(buf) + strlen(endsep) + 7;
460         da->da_remotestr = kzalloc(len, gfp_flags);
461
462         /* NULL is ok, only used for dprintk */
463         if (da->da_remotestr)
464                 snprintf(da->da_remotestr, len, "%s%s%s:%u", startsep,
465                          buf, endsep, ntohs(port));
466
467         dprintk("%s: Parsed DS addr %s\n", __func__, da->da_remotestr);
468         kfree(buf);
469         kfree(netid);
470         return da;
471
472 out_free_da:
473         kfree(da);
474 out_free_buf:
475         dprintk("%s: Error parsing DS addr: %s\n", __func__, buf);
476         kfree(buf);
477 out_free_netid:
478         kfree(netid);
479 out_err:
480         return NULL;
481 }
482
483 /* Decode opaque device data and return the result */
484 static struct nfs4_file_layout_dsaddr*
485 decode_device(struct inode *ino, struct pnfs_device *pdev, gfp_t gfp_flags)
486 {
487         int i;
488         u32 cnt, num;
489         u8 *indexp;
490         __be32 *p;
491         u8 *stripe_indices;
492         u8 max_stripe_index;
493         struct nfs4_file_layout_dsaddr *dsaddr = NULL;
494         struct xdr_stream stream;
495         struct xdr_buf buf;
496         struct page *scratch;
497         struct list_head dsaddrs;
498         struct nfs4_pnfs_ds_addr *da;
499
500         /* set up xdr stream */
501         scratch = alloc_page(gfp_flags);
502         if (!scratch)
503                 goto out_err;
504
505         xdr_init_decode_pages(&stream, &buf, pdev->pages, pdev->pglen);
506         xdr_set_scratch_buffer(&stream, page_address(scratch), PAGE_SIZE);
507
508         /* Get the stripe count (number of stripe index) */
509         p = xdr_inline_decode(&stream, 4);
510         if (unlikely(!p))
511                 goto out_err_free_scratch;
512
513         cnt = be32_to_cpup(p);
514         dprintk("%s stripe count  %d\n", __func__, cnt);
515         if (cnt > NFS4_PNFS_MAX_STRIPE_CNT) {
516                 printk(KERN_WARNING "NFS: %s: stripe count %d greater than "
517                        "supported maximum %d\n", __func__,
518                         cnt, NFS4_PNFS_MAX_STRIPE_CNT);
519                 goto out_err_free_scratch;
520         }
521
522         /* read stripe indices */
523         stripe_indices = kcalloc(cnt, sizeof(u8), gfp_flags);
524         if (!stripe_indices)
525                 goto out_err_free_scratch;
526
527         p = xdr_inline_decode(&stream, cnt << 2);
528         if (unlikely(!p))
529                 goto out_err_free_stripe_indices;
530
531         indexp = &stripe_indices[0];
532         max_stripe_index = 0;
533         for (i = 0; i < cnt; i++) {
534                 *indexp = be32_to_cpup(p++);
535                 max_stripe_index = max(max_stripe_index, *indexp);
536                 indexp++;
537         }
538
539         /* Check the multipath list count */
540         p = xdr_inline_decode(&stream, 4);
541         if (unlikely(!p))
542                 goto out_err_free_stripe_indices;
543
544         num = be32_to_cpup(p);
545         dprintk("%s ds_num %u\n", __func__, num);
546         if (num > NFS4_PNFS_MAX_MULTI_CNT) {
547                 printk(KERN_WARNING "NFS: %s: multipath count %d greater than "
548                         "supported maximum %d\n", __func__,
549                         num, NFS4_PNFS_MAX_MULTI_CNT);
550                 goto out_err_free_stripe_indices;
551         }
552
553         /* validate stripe indices are all < num */
554         if (max_stripe_index >= num) {
555                 printk(KERN_WARNING "NFS: %s: stripe index %u >= num ds %u\n",
556                         __func__, max_stripe_index, num);
557                 goto out_err_free_stripe_indices;
558         }
559
560         dsaddr = kzalloc(sizeof(*dsaddr) +
561                         (sizeof(struct nfs4_pnfs_ds *) * (num - 1)),
562                         gfp_flags);
563         if (!dsaddr)
564                 goto out_err_free_stripe_indices;
565
566         dsaddr->stripe_count = cnt;
567         dsaddr->stripe_indices = stripe_indices;
568         stripe_indices = NULL;
569         dsaddr->ds_num = num;
570         nfs4_init_deviceid_node(&dsaddr->id_node,
571                                 NFS_SERVER(ino)->pnfs_curr_ld,
572                                 NFS_SERVER(ino)->nfs_client,
573                                 &pdev->dev_id);
574
575         INIT_LIST_HEAD(&dsaddrs);
576
577         for (i = 0; i < dsaddr->ds_num; i++) {
578                 int j;
579                 u32 mp_count;
580
581                 p = xdr_inline_decode(&stream, 4);
582                 if (unlikely(!p))
583                         goto out_err_free_deviceid;
584
585                 mp_count = be32_to_cpup(p); /* multipath count */
586                 for (j = 0; j < mp_count; j++) {
587                         da = decode_ds_addr(NFS_SERVER(ino)->nfs_client->cl_net,
588                                             &stream, gfp_flags);
589                         if (da)
590                                 list_add_tail(&da->da_node, &dsaddrs);
591                 }
592                 if (list_empty(&dsaddrs)) {
593                         dprintk("%s: no suitable DS addresses found\n",
594                                 __func__);
595                         goto out_err_free_deviceid;
596                 }
597
598                 dsaddr->ds_list[i] = nfs4_pnfs_ds_add(&dsaddrs, gfp_flags);
599                 if (!dsaddr->ds_list[i])
600                         goto out_err_drain_dsaddrs;
601
602                 /* If DS was already in cache, free ds addrs */
603                 while (!list_empty(&dsaddrs)) {
604                         da = list_first_entry(&dsaddrs,
605                                               struct nfs4_pnfs_ds_addr,
606                                               da_node);
607                         list_del_init(&da->da_node);
608                         kfree(da->da_remotestr);
609                         kfree(da);
610                 }
611         }
612
613         __free_page(scratch);
614         return dsaddr;
615
616 out_err_drain_dsaddrs:
617         while (!list_empty(&dsaddrs)) {
618                 da = list_first_entry(&dsaddrs, struct nfs4_pnfs_ds_addr,
619                                       da_node);
620                 list_del_init(&da->da_node);
621                 kfree(da->da_remotestr);
622                 kfree(da);
623         }
624 out_err_free_deviceid:
625         nfs4_fl_free_deviceid(dsaddr);
626         /* stripe_indicies was part of dsaddr */
627         goto out_err_free_scratch;
628 out_err_free_stripe_indices:
629         kfree(stripe_indices);
630 out_err_free_scratch:
631         __free_page(scratch);
632 out_err:
633         dprintk("%s ERROR: returning NULL\n", __func__);
634         return NULL;
635 }
636
637 /*
638  * Decode the opaque device specified in 'dev' and add it to the cache of
639  * available devices.
640  */
641 static struct nfs4_file_layout_dsaddr *
642 decode_and_add_device(struct inode *inode, struct pnfs_device *dev, gfp_t gfp_flags)
643 {
644         struct nfs4_deviceid_node *d;
645         struct nfs4_file_layout_dsaddr *n, *new;
646
647         new = decode_device(inode, dev, gfp_flags);
648         if (!new) {
649                 printk(KERN_WARNING "NFS: %s: Could not decode or add device\n",
650                         __func__);
651                 return NULL;
652         }
653
654         d = nfs4_insert_deviceid_node(&new->id_node);
655         n = container_of(d, struct nfs4_file_layout_dsaddr, id_node);
656         if (n != new) {
657                 nfs4_fl_free_deviceid(new);
658                 return n;
659         }
660
661         return new;
662 }
663
664 /*
665  * Retrieve the information for dev_id, add it to the list
666  * of available devices, and return it.
667  */
668 struct nfs4_file_layout_dsaddr *
669 filelayout_get_device_info(struct inode *inode, struct nfs4_deviceid *dev_id, gfp_t gfp_flags)
670 {
671         struct pnfs_device *pdev = NULL;
672         u32 max_resp_sz;
673         int max_pages;
674         struct page **pages = NULL;
675         struct nfs4_file_layout_dsaddr *dsaddr = NULL;
676         int rc, i;
677         struct nfs_server *server = NFS_SERVER(inode);
678
679         /*
680          * Use the session max response size as the basis for setting
681          * GETDEVICEINFO's maxcount
682          */
683         max_resp_sz = server->nfs_client->cl_session->fc_attrs.max_resp_sz;
684         max_pages = nfs_page_array_len(0, max_resp_sz);
685         dprintk("%s inode %p max_resp_sz %u max_pages %d\n",
686                 __func__, inode, max_resp_sz, max_pages);
687
688         pdev = kzalloc(sizeof(struct pnfs_device), gfp_flags);
689         if (pdev == NULL)
690                 return NULL;
691
692         pages = kzalloc(max_pages * sizeof(struct page *), gfp_flags);
693         if (pages == NULL) {
694                 kfree(pdev);
695                 return NULL;
696         }
697         for (i = 0; i < max_pages; i++) {
698                 pages[i] = alloc_page(gfp_flags);
699                 if (!pages[i])
700                         goto out_free;
701         }
702
703         memcpy(&pdev->dev_id, dev_id, sizeof(*dev_id));
704         pdev->layout_type = LAYOUT_NFSV4_1_FILES;
705         pdev->pages = pages;
706         pdev->pgbase = 0;
707         pdev->pglen = max_resp_sz;
708         pdev->mincount = 0;
709
710         rc = nfs4_proc_getdeviceinfo(server, pdev);
711         dprintk("%s getdevice info returns %d\n", __func__, rc);
712         if (rc)
713                 goto out_free;
714
715         /*
716          * Found new device, need to decode it and then add it to the
717          * list of known devices for this mountpoint.
718          */
719         dsaddr = decode_and_add_device(inode, pdev, gfp_flags);
720 out_free:
721         for (i = 0; i < max_pages; i++)
722                 __free_page(pages[i]);
723         kfree(pages);
724         kfree(pdev);
725         dprintk("<-- %s dsaddr %p\n", __func__, dsaddr);
726         return dsaddr;
727 }
728
729 void
730 nfs4_fl_put_deviceid(struct nfs4_file_layout_dsaddr *dsaddr)
731 {
732         nfs4_put_deviceid_node(&dsaddr->id_node);
733 }
734
735 /*
736  * Want res = (offset - layout->pattern_offset)/ layout->stripe_unit
737  * Then: ((res + fsi) % dsaddr->stripe_count)
738  */
739 u32
740 nfs4_fl_calc_j_index(struct pnfs_layout_segment *lseg, loff_t offset)
741 {
742         struct nfs4_filelayout_segment *flseg = FILELAYOUT_LSEG(lseg);
743         u64 tmp;
744
745         tmp = offset - flseg->pattern_offset;
746         do_div(tmp, flseg->stripe_unit);
747         tmp += flseg->first_stripe_index;
748         return do_div(tmp, flseg->dsaddr->stripe_count);
749 }
750
751 u32
752 nfs4_fl_calc_ds_index(struct pnfs_layout_segment *lseg, u32 j)
753 {
754         return FILELAYOUT_LSEG(lseg)->dsaddr->stripe_indices[j];
755 }
756
757 struct nfs_fh *
758 nfs4_fl_select_ds_fh(struct pnfs_layout_segment *lseg, u32 j)
759 {
760         struct nfs4_filelayout_segment *flseg = FILELAYOUT_LSEG(lseg);
761         u32 i;
762
763         if (flseg->stripe_type == STRIPE_SPARSE) {
764                 if (flseg->num_fh == 1)
765                         i = 0;
766                 else if (flseg->num_fh == 0)
767                         /* Use the MDS OPEN fh set in nfs_read_rpcsetup */
768                         return NULL;
769                 else
770                         i = nfs4_fl_calc_ds_index(lseg, j);
771         } else
772                 i = j;
773         return flseg->fh_array[i];
774 }
775
776 struct nfs4_pnfs_ds *
777 nfs4_fl_prepare_ds(struct pnfs_layout_segment *lseg, u32 ds_idx)
778 {
779         struct nfs4_file_layout_dsaddr *dsaddr = FILELAYOUT_LSEG(lseg)->dsaddr;
780         struct nfs4_pnfs_ds *ds = dsaddr->ds_list[ds_idx];
781         struct nfs4_deviceid_node *devid = FILELAYOUT_DEVID_NODE(lseg);
782
783         if (filelayout_test_devid_unavailable(devid))
784                 return NULL;
785
786         if (ds == NULL) {
787                 printk(KERN_ERR "NFS: %s: No data server for offset index %d\n",
788                         __func__, ds_idx);
789                 filelayout_mark_devid_invalid(devid);
790                 return NULL;
791         }
792
793         if (!ds->ds_clp) {
794                 struct nfs_server *s = NFS_SERVER(lseg->pls_layout->plh_inode);
795                 int err;
796
797                 err = nfs4_ds_connect(s, ds);
798                 if (err) {
799                         nfs4_mark_deviceid_unavailable(devid);
800                         return NULL;
801                 }
802         }
803         return ds;
804 }
805
806 module_param(dataserver_retrans, uint, 0644);
807 MODULE_PARM_DESC(dataserver_retrans, "The  number of times the NFSv4.1 client "
808                         "retries a request before it attempts further "
809                         " recovery  action.");
810 module_param(dataserver_timeo, uint, 0644);
811 MODULE_PARM_DESC(dataserver_timeo, "The time (in tenths of a second) the "
812                         "NFSv4.1  client  waits for a response from a "
813                         " data server before it retries an NFS request.");