root/fs/nfs/filelayout/filelayout.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. filelayout_get_dense_offset
  2. filelayout_get_dserver_offset
  3. filelayout_reset_write
  4. filelayout_reset_read
  5. filelayout_async_handle_error
  6. filelayout_read_done_cb
  7. filelayout_set_layoutcommit
  8. filelayout_test_devid_unavailable
  9. filelayout_reset_to_mds
  10. filelayout_read_prepare
  11. filelayout_read_call_done
  12. filelayout_read_count_stats
  13. filelayout_write_done_cb
  14. filelayout_commit_done_cb
  15. filelayout_write_prepare
  16. filelayout_write_call_done
  17. filelayout_write_count_stats
  18. filelayout_commit_prepare
  19. filelayout_commit_count_stats
  20. filelayout_read_pagelist
  21. filelayout_write_pagelist
  22. filelayout_check_deviceid
  23. filelayout_check_layout
  24. _filelayout_free_lseg
  25. filelayout_decode_layout
  26. filelayout_free_lseg
  27. filelayout_alloc_commit_info
  28. filelayout_alloc_lseg
  29. filelayout_pg_test
  30. fl_pnfs_update_layout
  31. filelayout_pg_init_read
  32. filelayout_pg_init_write
  33. select_bucket_index
  34. filelayout_mark_request_commit
  35. calc_ds_index_from_commit
  36. select_ds_fh_from_commit
  37. filelayout_initiate_commit
  38. filelayout_search_commit_reqs
  39. filelayout_commit_pagelist
  40. filelayout_alloc_deviceid_node
  41. filelayout_free_deviceid_node
  42. filelayout_alloc_layout_hdr
  43. filelayout_free_layout_hdr
  44. filelayout_get_ds_info
  45. nfs4filelayout_init
  46. nfs4filelayout_exit

   1 /*
   2  *  Module for the pnfs nfs4 file layout driver.
   3  *  Defines all I/O and Policy interface operations, plus code
   4  *  to register itself with the pNFS client.
   5  *
   6  *  Copyright (c) 2002
   7  *  The Regents of the University of Michigan
   8  *  All Rights Reserved
   9  *
  10  *  Dean Hildebrand <dhildebz@umich.edu>
  11  *
  12  *  Permission is granted to use, copy, create derivative works, and
  13  *  redistribute this software and such derivative works for any purpose,
  14  *  so long as the name of the University of Michigan is not used in
  15  *  any advertising or publicity pertaining to the use or distribution
  16  *  of this software without specific, written prior authorization. If
  17  *  the above copyright notice or any other identification of the
  18  *  University of Michigan is included in any copy of any portion of
  19  *  this software, then the disclaimer below must also be included.
  20  *
  21  *  This software is provided as is, without representation or warranty
  22  *  of any kind either express or implied, including without limitation
  23  *  the implied warranties of merchantability, fitness for a particular
  24  *  purpose, or noninfringement.  The Regents of the University of
  25  *  Michigan shall not be liable for any damages, including special,
  26  *  indirect, incidental, or consequential damages, with respect to any
  27  *  claim arising out of or in connection with the use of the software,
  28  *  even if it has been or is hereafter advised of the possibility of
  29  *  such damages.
  30  */
  31 
  32 #include <linux/nfs_fs.h>
  33 #include <linux/nfs_page.h>
  34 #include <linux/module.h>
  35 #include <linux/backing-dev.h>
  36 
  37 #include <linux/sunrpc/metrics.h>
  38 
  39 #include "../nfs4session.h"
  40 #include "../internal.h"
  41 #include "../delegation.h"
  42 #include "filelayout.h"
  43 #include "../nfs4trace.h"
  44 
  45 #define NFSDBG_FACILITY         NFSDBG_PNFS_LD
  46 
  47 MODULE_LICENSE("GPL");
  48 MODULE_AUTHOR("Dean Hildebrand <dhildebz@umich.edu>");
  49 MODULE_DESCRIPTION("The NFSv4 file layout driver");
  50 
  51 #define FILELAYOUT_POLL_RETRY_MAX     (15*HZ)
  52 
  53 static loff_t
  54 filelayout_get_dense_offset(struct nfs4_filelayout_segment *flseg,
  55                             loff_t offset)
  56 {
  57         u32 stripe_width = flseg->stripe_unit * flseg->dsaddr->stripe_count;
  58         u64 stripe_no;
  59         u32 rem;
  60 
  61         offset -= flseg->pattern_offset;
  62         stripe_no = div_u64(offset, stripe_width);
  63         div_u64_rem(offset, flseg->stripe_unit, &rem);
  64 
  65         return stripe_no * flseg->stripe_unit + rem;
  66 }
  67 
  68 /* This function is used by the layout driver to calculate the
  69  * offset of the file on the dserver based on whether the
  70  * layout type is STRIPE_DENSE or STRIPE_SPARSE
  71  */
  72 static loff_t
  73 filelayout_get_dserver_offset(struct pnfs_layout_segment *lseg, loff_t offset)
  74 {
  75         struct nfs4_filelayout_segment *flseg = FILELAYOUT_LSEG(lseg);
  76 
  77         switch (flseg->stripe_type) {
  78         case STRIPE_SPARSE:
  79                 return offset;
  80 
  81         case STRIPE_DENSE:
  82                 return filelayout_get_dense_offset(flseg, offset);
  83         }
  84 
  85         BUG();
  86 }
  87 
  88 static void filelayout_reset_write(struct nfs_pgio_header *hdr)
  89 {
  90         struct rpc_task *task = &hdr->task;
  91 
  92         if (!test_and_set_bit(NFS_IOHDR_REDO, &hdr->flags)) {
  93                 dprintk("%s Reset task %5u for i/o through MDS "
  94                         "(req %s/%llu, %u bytes @ offset %llu)\n", __func__,
  95                         hdr->task.tk_pid,
  96                         hdr->inode->i_sb->s_id,
  97                         (unsigned long long)NFS_FILEID(hdr->inode),
  98                         hdr->args.count,
  99                         (unsigned long long)hdr->args.offset);
 100 
 101                 task->tk_status = pnfs_write_done_resend_to_mds(hdr);
 102         }
 103 }
 104 
 105 static void filelayout_reset_read(struct nfs_pgio_header *hdr)
 106 {
 107         struct rpc_task *task = &hdr->task;
 108 
 109         if (!test_and_set_bit(NFS_IOHDR_REDO, &hdr->flags)) {
 110                 dprintk("%s Reset task %5u for i/o through MDS "
 111                         "(req %s/%llu, %u bytes @ offset %llu)\n", __func__,
 112                         hdr->task.tk_pid,
 113                         hdr->inode->i_sb->s_id,
 114                         (unsigned long long)NFS_FILEID(hdr->inode),
 115                         hdr->args.count,
 116                         (unsigned long long)hdr->args.offset);
 117 
 118                 task->tk_status = pnfs_read_done_resend_to_mds(hdr);
 119         }
 120 }
 121 
 122 static int filelayout_async_handle_error(struct rpc_task *task,
 123                                          struct nfs4_state *state,
 124                                          struct nfs_client *clp,
 125                                          struct pnfs_layout_segment *lseg)
 126 {
 127         struct pnfs_layout_hdr *lo = lseg->pls_layout;
 128         struct inode *inode = lo->plh_inode;
 129         struct nfs4_deviceid_node *devid = FILELAYOUT_DEVID_NODE(lseg);
 130         struct nfs4_slot_table *tbl = &clp->cl_session->fc_slot_table;
 131 
 132         if (task->tk_status >= 0)
 133                 return 0;
 134 
 135         switch (task->tk_status) {
 136         /* DS session errors */
 137         case -NFS4ERR_BADSESSION:
 138         case -NFS4ERR_BADSLOT:
 139         case -NFS4ERR_BAD_HIGH_SLOT:
 140         case -NFS4ERR_DEADSESSION:
 141         case -NFS4ERR_CONN_NOT_BOUND_TO_SESSION:
 142         case -NFS4ERR_SEQ_FALSE_RETRY:
 143         case -NFS4ERR_SEQ_MISORDERED:
 144                 dprintk("%s ERROR %d, Reset session. Exchangeid "
 145                         "flags 0x%x\n", __func__, task->tk_status,
 146                         clp->cl_exchange_flags);
 147                 nfs4_schedule_session_recovery(clp->cl_session, task->tk_status);
 148                 break;
 149         case -NFS4ERR_DELAY:
 150         case -NFS4ERR_GRACE:
 151                 rpc_delay(task, FILELAYOUT_POLL_RETRY_MAX);
 152                 break;
 153         case -NFS4ERR_RETRY_UNCACHED_REP:
 154                 break;
 155         /* Invalidate Layout errors */
 156         case -NFS4ERR_ACCESS:
 157         case -NFS4ERR_PNFS_NO_LAYOUT:
 158         case -ESTALE:           /* mapped NFS4ERR_STALE */
 159         case -EBADHANDLE:       /* mapped NFS4ERR_BADHANDLE */
 160         case -EISDIR:           /* mapped NFS4ERR_ISDIR */
 161         case -NFS4ERR_FHEXPIRED:
 162         case -NFS4ERR_WRONG_TYPE:
 163                 dprintk("%s Invalid layout error %d\n", __func__,
 164                         task->tk_status);
 165                 /*
 166                  * Destroy layout so new i/o will get a new layout.
 167                  * Layout will not be destroyed until all current lseg
 168                  * references are put. Mark layout as invalid to resend failed
 169                  * i/o and all i/o waiting on the slot table to the MDS until
 170                  * layout is destroyed and a new valid layout is obtained.
 171                  */
 172                 pnfs_destroy_layout(NFS_I(inode));
 173                 rpc_wake_up(&tbl->slot_tbl_waitq);
 174                 goto reset;
 175         /* RPC connection errors */
 176         case -ECONNREFUSED:
 177         case -EHOSTDOWN:
 178         case -EHOSTUNREACH:
 179         case -ENETUNREACH:
 180         case -EIO:
 181         case -ETIMEDOUT:
 182         case -EPIPE:
 183                 dprintk("%s DS connection error %d\n", __func__,
 184                         task->tk_status);
 185                 nfs4_mark_deviceid_unavailable(devid);
 186                 pnfs_error_mark_layout_for_return(inode, lseg);
 187                 pnfs_set_lo_fail(lseg);
 188                 rpc_wake_up(&tbl->slot_tbl_waitq);
 189                 /* fall through */
 190         default:
 191 reset:
 192                 dprintk("%s Retry through MDS. Error %d\n", __func__,
 193                         task->tk_status);
 194                 return -NFS4ERR_RESET_TO_MDS;
 195         }
 196         task->tk_status = 0;
 197         return -EAGAIN;
 198 }
 199 
 200 /* NFS_PROTO call done callback routines */
 201 
 202 static int filelayout_read_done_cb(struct rpc_task *task,
 203                                 struct nfs_pgio_header *hdr)
 204 {
 205         int err;
 206 
 207         trace_nfs4_pnfs_read(hdr, task->tk_status);
 208         err = filelayout_async_handle_error(task, hdr->args.context->state,
 209                                             hdr->ds_clp, hdr->lseg);
 210 
 211         switch (err) {
 212         case -NFS4ERR_RESET_TO_MDS:
 213                 filelayout_reset_read(hdr);
 214                 return task->tk_status;
 215         case -EAGAIN:
 216                 rpc_restart_call_prepare(task);
 217                 return -EAGAIN;
 218         }
 219 
 220         return 0;
 221 }
 222 
 223 /*
 224  * We reference the rpc_cred of the first WRITE that triggers the need for
 225  * a LAYOUTCOMMIT, and use it to send the layoutcommit compound.
 226  * rfc5661 is not clear about which credential should be used.
 227  */
 228 static void
 229 filelayout_set_layoutcommit(struct nfs_pgio_header *hdr)
 230 {
 231         loff_t end_offs = 0;
 232 
 233         if (FILELAYOUT_LSEG(hdr->lseg)->commit_through_mds ||
 234             hdr->res.verf->committed == NFS_FILE_SYNC)
 235                 return;
 236         if (hdr->res.verf->committed == NFS_DATA_SYNC)
 237                 end_offs = hdr->mds_offset + (loff_t)hdr->res.count;
 238 
 239         /* Note: if the write is unstable, don't set end_offs until commit */
 240         pnfs_set_layoutcommit(hdr->inode, hdr->lseg, end_offs);
 241         dprintk("%s inode %lu pls_end_pos %lu\n", __func__, hdr->inode->i_ino,
 242                 (unsigned long) NFS_I(hdr->inode)->layout->plh_lwb);
 243 }
 244 
 245 bool
 246 filelayout_test_devid_unavailable(struct nfs4_deviceid_node *node)
 247 {
 248         return filelayout_test_devid_invalid(node) ||
 249                 nfs4_test_deviceid_unavailable(node);
 250 }
 251 
 252 static bool
 253 filelayout_reset_to_mds(struct pnfs_layout_segment *lseg)
 254 {
 255         struct nfs4_deviceid_node *node = FILELAYOUT_DEVID_NODE(lseg);
 256 
 257         return filelayout_test_devid_unavailable(node);
 258 }
 259 
 260 /*
 261  * Call ops for the async read/write cases
 262  * In the case of dense layouts, the offset needs to be reset to its
 263  * original value.
 264  */
 265 static void filelayout_read_prepare(struct rpc_task *task, void *data)
 266 {
 267         struct nfs_pgio_header *hdr = data;
 268 
 269         if (unlikely(test_bit(NFS_CONTEXT_BAD, &hdr->args.context->flags))) {
 270                 rpc_exit(task, -EIO);
 271                 return;
 272         }
 273         if (filelayout_reset_to_mds(hdr->lseg)) {
 274                 dprintk("%s task %u reset io to MDS\n", __func__, task->tk_pid);
 275                 filelayout_reset_read(hdr);
 276                 rpc_exit(task, 0);
 277                 return;
 278         }
 279         hdr->pgio_done_cb = filelayout_read_done_cb;
 280 
 281         if (nfs4_setup_sequence(hdr->ds_clp,
 282                         &hdr->args.seq_args,
 283                         &hdr->res.seq_res,
 284                         task))
 285                 return;
 286         if (nfs4_set_rw_stateid(&hdr->args.stateid, hdr->args.context,
 287                         hdr->args.lock_context, FMODE_READ) == -EIO)
 288                 rpc_exit(task, -EIO); /* lost lock, terminate I/O */
 289 }
 290 
 291 static void filelayout_read_call_done(struct rpc_task *task, void *data)
 292 {
 293         struct nfs_pgio_header *hdr = data;
 294 
 295         dprintk("--> %s task->tk_status %d\n", __func__, task->tk_status);
 296 
 297         if (test_bit(NFS_IOHDR_REDO, &hdr->flags) &&
 298             task->tk_status == 0) {
 299                 nfs41_sequence_done(task, &hdr->res.seq_res);
 300                 return;
 301         }
 302 
 303         /* Note this may cause RPC to be resent */
 304         hdr->mds_ops->rpc_call_done(task, data);
 305 }
 306 
 307 static void filelayout_read_count_stats(struct rpc_task *task, void *data)
 308 {
 309         struct nfs_pgio_header *hdr = data;
 310 
 311         rpc_count_iostats(task, NFS_SERVER(hdr->inode)->client->cl_metrics);
 312 }
 313 
 314 static int filelayout_write_done_cb(struct rpc_task *task,
 315                                 struct nfs_pgio_header *hdr)
 316 {
 317         int err;
 318 
 319         trace_nfs4_pnfs_write(hdr, task->tk_status);
 320         err = filelayout_async_handle_error(task, hdr->args.context->state,
 321                                             hdr->ds_clp, hdr->lseg);
 322 
 323         switch (err) {
 324         case -NFS4ERR_RESET_TO_MDS:
 325                 filelayout_reset_write(hdr);
 326                 return task->tk_status;
 327         case -EAGAIN:
 328                 rpc_restart_call_prepare(task);
 329                 return -EAGAIN;
 330         }
 331 
 332         filelayout_set_layoutcommit(hdr);
 333 
 334         /* zero out the fattr */
 335         hdr->fattr.valid = 0;
 336         if (task->tk_status >= 0)
 337                 nfs_writeback_update_inode(hdr);
 338 
 339         return 0;
 340 }
 341 
 342 static int filelayout_commit_done_cb(struct rpc_task *task,
 343                                      struct nfs_commit_data *data)
 344 {
 345         int err;
 346 
 347         trace_nfs4_pnfs_commit_ds(data, task->tk_status);
 348         err = filelayout_async_handle_error(task, NULL, data->ds_clp,
 349                                             data->lseg);
 350 
 351         switch (err) {
 352         case -NFS4ERR_RESET_TO_MDS:
 353                 pnfs_generic_prepare_to_resend_writes(data);
 354                 return -EAGAIN;
 355         case -EAGAIN:
 356                 rpc_restart_call_prepare(task);
 357                 return -EAGAIN;
 358         }
 359 
 360         pnfs_set_layoutcommit(data->inode, data->lseg, data->lwb);
 361 
 362         return 0;
 363 }
 364 
 365 static void filelayout_write_prepare(struct rpc_task *task, void *data)
 366 {
 367         struct nfs_pgio_header *hdr = data;
 368 
 369         if (unlikely(test_bit(NFS_CONTEXT_BAD, &hdr->args.context->flags))) {
 370                 rpc_exit(task, -EIO);
 371                 return;
 372         }
 373         if (filelayout_reset_to_mds(hdr->lseg)) {
 374                 dprintk("%s task %u reset io to MDS\n", __func__, task->tk_pid);
 375                 filelayout_reset_write(hdr);
 376                 rpc_exit(task, 0);
 377                 return;
 378         }
 379         if (nfs4_setup_sequence(hdr->ds_clp,
 380                         &hdr->args.seq_args,
 381                         &hdr->res.seq_res,
 382                         task))
 383                 return;
 384         if (nfs4_set_rw_stateid(&hdr->args.stateid, hdr->args.context,
 385                         hdr->args.lock_context, FMODE_WRITE) == -EIO)
 386                 rpc_exit(task, -EIO); /* lost lock, terminate I/O */
 387 }
 388 
 389 static void filelayout_write_call_done(struct rpc_task *task, void *data)
 390 {
 391         struct nfs_pgio_header *hdr = data;
 392 
 393         if (test_bit(NFS_IOHDR_REDO, &hdr->flags) &&
 394             task->tk_status == 0) {
 395                 nfs41_sequence_done(task, &hdr->res.seq_res);
 396                 return;
 397         }
 398 
 399         /* Note this may cause RPC to be resent */
 400         hdr->mds_ops->rpc_call_done(task, data);
 401 }
 402 
 403 static void filelayout_write_count_stats(struct rpc_task *task, void *data)
 404 {
 405         struct nfs_pgio_header *hdr = data;
 406 
 407         rpc_count_iostats(task, NFS_SERVER(hdr->inode)->client->cl_metrics);
 408 }
 409 
 410 static void filelayout_commit_prepare(struct rpc_task *task, void *data)
 411 {
 412         struct nfs_commit_data *wdata = data;
 413 
 414         nfs4_setup_sequence(wdata->ds_clp,
 415                         &wdata->args.seq_args,
 416                         &wdata->res.seq_res,
 417                         task);
 418 }
 419 
 420 static void filelayout_commit_count_stats(struct rpc_task *task, void *data)
 421 {
 422         struct nfs_commit_data *cdata = data;
 423 
 424         rpc_count_iostats(task, NFS_SERVER(cdata->inode)->client->cl_metrics);
 425 }
 426 
 427 static const struct rpc_call_ops filelayout_read_call_ops = {
 428         .rpc_call_prepare = filelayout_read_prepare,
 429         .rpc_call_done = filelayout_read_call_done,
 430         .rpc_count_stats = filelayout_read_count_stats,
 431         .rpc_release = pnfs_generic_rw_release,
 432 };
 433 
 434 static const struct rpc_call_ops filelayout_write_call_ops = {
 435         .rpc_call_prepare = filelayout_write_prepare,
 436         .rpc_call_done = filelayout_write_call_done,
 437         .rpc_count_stats = filelayout_write_count_stats,
 438         .rpc_release = pnfs_generic_rw_release,
 439 };
 440 
 441 static const struct rpc_call_ops filelayout_commit_call_ops = {
 442         .rpc_call_prepare = filelayout_commit_prepare,
 443         .rpc_call_done = pnfs_generic_write_commit_done,
 444         .rpc_count_stats = filelayout_commit_count_stats,
 445         .rpc_release = pnfs_generic_commit_release,
 446 };
 447 
 448 static enum pnfs_try_status
 449 filelayout_read_pagelist(struct nfs_pgio_header *hdr)
 450 {
 451         struct pnfs_layout_segment *lseg = hdr->lseg;
 452         struct nfs4_pnfs_ds *ds;
 453         struct rpc_clnt *ds_clnt;
 454         loff_t offset = hdr->args.offset;
 455         u32 j, idx;
 456         struct nfs_fh *fh;
 457 
 458         dprintk("--> %s ino %lu pgbase %u req %zu@%llu\n",
 459                 __func__, hdr->inode->i_ino,
 460                 hdr->args.pgbase, (size_t)hdr->args.count, offset);
 461 
 462         /* Retrieve the correct rpc_client for the byte range */
 463         j = nfs4_fl_calc_j_index(lseg, offset);
 464         idx = nfs4_fl_calc_ds_index(lseg, j);
 465         ds = nfs4_fl_prepare_ds(lseg, idx);
 466         if (!ds)
 467                 return PNFS_NOT_ATTEMPTED;
 468 
 469         ds_clnt = nfs4_find_or_create_ds_client(ds->ds_clp, hdr->inode);
 470         if (IS_ERR(ds_clnt))
 471                 return PNFS_NOT_ATTEMPTED;
 472 
 473         dprintk("%s USE DS: %s cl_count %d\n", __func__,
 474                 ds->ds_remotestr, refcount_read(&ds->ds_clp->cl_count));
 475 
 476         /* No multipath support. Use first DS */
 477         refcount_inc(&ds->ds_clp->cl_count);
 478         hdr->ds_clp = ds->ds_clp;
 479         hdr->ds_commit_idx = idx;
 480         fh = nfs4_fl_select_ds_fh(lseg, j);
 481         if (fh)
 482                 hdr->args.fh = fh;
 483 
 484         hdr->args.offset = filelayout_get_dserver_offset(lseg, offset);
 485         hdr->mds_offset = offset;
 486 
 487         /* Perform an asynchronous read to ds */
 488         nfs_initiate_pgio(ds_clnt, hdr, hdr->cred,
 489                           NFS_PROTO(hdr->inode), &filelayout_read_call_ops,
 490                           0, RPC_TASK_SOFTCONN);
 491         return PNFS_ATTEMPTED;
 492 }
 493 
 494 /* Perform async writes. */
 495 static enum pnfs_try_status
 496 filelayout_write_pagelist(struct nfs_pgio_header *hdr, int sync)
 497 {
 498         struct pnfs_layout_segment *lseg = hdr->lseg;
 499         struct nfs4_pnfs_ds *ds;
 500         struct rpc_clnt *ds_clnt;
 501         loff_t offset = hdr->args.offset;
 502         u32 j, idx;
 503         struct nfs_fh *fh;
 504 
 505         /* Retrieve the correct rpc_client for the byte range */
 506         j = nfs4_fl_calc_j_index(lseg, offset);
 507         idx = nfs4_fl_calc_ds_index(lseg, j);
 508         ds = nfs4_fl_prepare_ds(lseg, idx);
 509         if (!ds)
 510                 return PNFS_NOT_ATTEMPTED;
 511 
 512         ds_clnt = nfs4_find_or_create_ds_client(ds->ds_clp, hdr->inode);
 513         if (IS_ERR(ds_clnt))
 514                 return PNFS_NOT_ATTEMPTED;
 515 
 516         dprintk("%s ino %lu sync %d req %zu@%llu DS: %s cl_count %d\n",
 517                 __func__, hdr->inode->i_ino, sync, (size_t) hdr->args.count,
 518                 offset, ds->ds_remotestr, refcount_read(&ds->ds_clp->cl_count));
 519 
 520         hdr->pgio_done_cb = filelayout_write_done_cb;
 521         refcount_inc(&ds->ds_clp->cl_count);
 522         hdr->ds_clp = ds->ds_clp;
 523         hdr->ds_commit_idx = idx;
 524         fh = nfs4_fl_select_ds_fh(lseg, j);
 525         if (fh)
 526                 hdr->args.fh = fh;
 527         hdr->args.offset = filelayout_get_dserver_offset(lseg, offset);
 528 
 529         /* Perform an asynchronous write */
 530         nfs_initiate_pgio(ds_clnt, hdr, hdr->cred,
 531                           NFS_PROTO(hdr->inode), &filelayout_write_call_ops,
 532                           sync, RPC_TASK_SOFTCONN);
 533         return PNFS_ATTEMPTED;
 534 }
 535 
 536 static int
 537 filelayout_check_deviceid(struct pnfs_layout_hdr *lo,
 538                           struct nfs4_filelayout_segment *fl,
 539                           gfp_t gfp_flags)
 540 {
 541         struct nfs4_deviceid_node *d;
 542         struct nfs4_file_layout_dsaddr *dsaddr;
 543         int status = -EINVAL;
 544 
 545         /* Is the deviceid already set? If so, we're good. */
 546         if (fl->dsaddr != NULL)
 547                 return 0;
 548 
 549         /* find and reference the deviceid */
 550         d = nfs4_find_get_deviceid(NFS_SERVER(lo->plh_inode), &fl->deviceid,
 551                         lo->plh_lc_cred, gfp_flags);
 552         if (d == NULL)
 553                 goto out;
 554 
 555         dsaddr = container_of(d, struct nfs4_file_layout_dsaddr, id_node);
 556         /* Found deviceid is unavailable */
 557         if (filelayout_test_devid_unavailable(&dsaddr->id_node))
 558                 goto out_put;
 559 
 560         if (fl->first_stripe_index >= dsaddr->stripe_count) {
 561                 dprintk("%s Bad first_stripe_index %u\n",
 562                                 __func__, fl->first_stripe_index);
 563                 goto out_put;
 564         }
 565 
 566         if ((fl->stripe_type == STRIPE_SPARSE &&
 567             fl->num_fh > 1 && fl->num_fh != dsaddr->ds_num) ||
 568             (fl->stripe_type == STRIPE_DENSE &&
 569             fl->num_fh != dsaddr->stripe_count)) {
 570                 dprintk("%s num_fh %u not valid for given packing\n",
 571                         __func__, fl->num_fh);
 572                 goto out_put;
 573         }
 574         status = 0;
 575 
 576         /*
 577          * Atomic compare and xchange to ensure we don't scribble
 578          * over a non-NULL pointer.
 579          */
 580         if (cmpxchg(&fl->dsaddr, NULL, dsaddr) != NULL)
 581                 goto out_put;
 582 out:
 583         return status;
 584 out_put:
 585         nfs4_fl_put_deviceid(dsaddr);
 586         goto out;
 587 }
 588 
 589 /*
 590  * filelayout_check_layout()
 591  *
 592  * Make sure layout segment parameters are sane WRT the device.
 593  * At this point no generic layer initialization of the lseg has occurred,
 594  * and nothing has been added to the layout_hdr cache.
 595  *
 596  */
 597 static int
 598 filelayout_check_layout(struct pnfs_layout_hdr *lo,
 599                         struct nfs4_filelayout_segment *fl,
 600                         struct nfs4_layoutget_res *lgr,
 601                         gfp_t gfp_flags)
 602 {
 603         int status = -EINVAL;
 604 
 605         dprintk("--> %s\n", __func__);
 606 
 607         /* FIXME: remove this check when layout segment support is added */
 608         if (lgr->range.offset != 0 ||
 609             lgr->range.length != NFS4_MAX_UINT64) {
 610                 dprintk("%s Only whole file layouts supported. Use MDS i/o\n",
 611                         __func__);
 612                 goto out;
 613         }
 614 
 615         if (fl->pattern_offset > lgr->range.offset) {
 616                 dprintk("%s pattern_offset %lld too large\n",
 617                                 __func__, fl->pattern_offset);
 618                 goto out;
 619         }
 620 
 621         if (!fl->stripe_unit) {
 622                 dprintk("%s Invalid stripe unit (%u)\n",
 623                         __func__, fl->stripe_unit);
 624                 goto out;
 625         }
 626 
 627         status = 0;
 628 out:
 629         dprintk("--> %s returns %d\n", __func__, status);
 630         return status;
 631 }
 632 
 633 static void _filelayout_free_lseg(struct nfs4_filelayout_segment *fl)
 634 {
 635         int i;
 636 
 637         if (fl->fh_array) {
 638                 for (i = 0; i < fl->num_fh; i++) {
 639                         if (!fl->fh_array[i])
 640                                 break;
 641                         kfree(fl->fh_array[i]);
 642                 }
 643                 kfree(fl->fh_array);
 644         }
 645         kfree(fl);
 646 }
 647 
 648 static int
 649 filelayout_decode_layout(struct pnfs_layout_hdr *flo,
 650                          struct nfs4_filelayout_segment *fl,
 651                          struct nfs4_layoutget_res *lgr,
 652                          gfp_t gfp_flags)
 653 {
 654         struct xdr_stream stream;
 655         struct xdr_buf buf;
 656         struct page *scratch;
 657         __be32 *p;
 658         uint32_t nfl_util;
 659         int i;
 660 
 661         dprintk("%s: set_layout_map Begin\n", __func__);
 662 
 663         scratch = alloc_page(gfp_flags);
 664         if (!scratch)
 665                 return -ENOMEM;
 666 
 667         xdr_init_decode_pages(&stream, &buf, lgr->layoutp->pages, lgr->layoutp->len);
 668         xdr_set_scratch_buffer(&stream, page_address(scratch), PAGE_SIZE);
 669 
 670         /* 20 = ufl_util (4), first_stripe_index (4), pattern_offset (8),
 671          * num_fh (4) */
 672         p = xdr_inline_decode(&stream, NFS4_DEVICEID4_SIZE + 20);
 673         if (unlikely(!p))
 674                 goto out_err;
 675 
 676         memcpy(&fl->deviceid, p, sizeof(fl->deviceid));
 677         p += XDR_QUADLEN(NFS4_DEVICEID4_SIZE);
 678         nfs4_print_deviceid(&fl->deviceid);
 679 
 680         nfl_util = be32_to_cpup(p++);
 681         if (nfl_util & NFL4_UFLG_COMMIT_THRU_MDS)
 682                 fl->commit_through_mds = 1;
 683         if (nfl_util & NFL4_UFLG_DENSE)
 684                 fl->stripe_type = STRIPE_DENSE;
 685         else
 686                 fl->stripe_type = STRIPE_SPARSE;
 687         fl->stripe_unit = nfl_util & ~NFL4_UFLG_MASK;
 688 
 689         fl->first_stripe_index = be32_to_cpup(p++);
 690         p = xdr_decode_hyper(p, &fl->pattern_offset);
 691         fl->num_fh = be32_to_cpup(p++);
 692 
 693         dprintk("%s: nfl_util 0x%X num_fh %u fsi %u po %llu\n",
 694                 __func__, nfl_util, fl->num_fh, fl->first_stripe_index,
 695                 fl->pattern_offset);
 696 
 697         /* Note that a zero value for num_fh is legal for STRIPE_SPARSE.
 698          * Futher checking is done in filelayout_check_layout */
 699         if (fl->num_fh >
 700             max(NFS4_PNFS_MAX_STRIPE_CNT, NFS4_PNFS_MAX_MULTI_CNT))
 701                 goto out_err;
 702 
 703         if (fl->num_fh > 0) {
 704                 fl->fh_array = kcalloc(fl->num_fh, sizeof(fl->fh_array[0]),
 705                                        gfp_flags);
 706                 if (!fl->fh_array)
 707                         goto out_err;
 708         }
 709 
 710         for (i = 0; i < fl->num_fh; i++) {
 711                 /* Do we want to use a mempool here? */
 712                 fl->fh_array[i] = kmalloc(sizeof(struct nfs_fh), gfp_flags);
 713                 if (!fl->fh_array[i])
 714                         goto out_err;
 715 
 716                 p = xdr_inline_decode(&stream, 4);
 717                 if (unlikely(!p))
 718                         goto out_err;
 719                 fl->fh_array[i]->size = be32_to_cpup(p++);
 720                 if (sizeof(struct nfs_fh) < fl->fh_array[i]->size) {
 721                         printk(KERN_ERR "NFS: Too big fh %d received %d\n",
 722                                i, fl->fh_array[i]->size);
 723                         goto out_err;
 724                 }
 725 
 726                 p = xdr_inline_decode(&stream, fl->fh_array[i]->size);
 727                 if (unlikely(!p))
 728                         goto out_err;
 729                 memcpy(fl->fh_array[i]->data, p, fl->fh_array[i]->size);
 730                 dprintk("DEBUG: %s: fh len %d\n", __func__,
 731                         fl->fh_array[i]->size);
 732         }
 733 
 734         __free_page(scratch);
 735         return 0;
 736 
 737 out_err:
 738         __free_page(scratch);
 739         return -EIO;
 740 }
 741 
 742 static void
 743 filelayout_free_lseg(struct pnfs_layout_segment *lseg)
 744 {
 745         struct nfs4_filelayout_segment *fl = FILELAYOUT_LSEG(lseg);
 746 
 747         dprintk("--> %s\n", __func__);
 748         if (fl->dsaddr != NULL)
 749                 nfs4_fl_put_deviceid(fl->dsaddr);
 750         /* This assumes a single RW lseg */
 751         if (lseg->pls_range.iomode == IOMODE_RW) {
 752                 struct nfs4_filelayout *flo;
 753 
 754                 flo = FILELAYOUT_FROM_HDR(lseg->pls_layout);
 755                 flo->commit_info.nbuckets = 0;
 756                 kfree(flo->commit_info.buckets);
 757                 flo->commit_info.buckets = NULL;
 758         }
 759         _filelayout_free_lseg(fl);
 760 }
 761 
 762 static int
 763 filelayout_alloc_commit_info(struct pnfs_layout_segment *lseg,
 764                              struct nfs_commit_info *cinfo,
 765                              gfp_t gfp_flags)
 766 {
 767         struct nfs4_filelayout_segment *fl = FILELAYOUT_LSEG(lseg);
 768         struct pnfs_commit_bucket *buckets;
 769         int size, i;
 770 
 771         if (fl->commit_through_mds)
 772                 return 0;
 773 
 774         size = (fl->stripe_type == STRIPE_SPARSE) ?
 775                 fl->dsaddr->ds_num : fl->dsaddr->stripe_count;
 776 
 777         if (cinfo->ds->nbuckets >= size) {
 778                 /* This assumes there is only one IOMODE_RW lseg.  What
 779                  * we really want to do is have a layout_hdr level
 780                  * dictionary of <multipath_list4, fh> keys, each
 781                  * associated with a struct list_head, populated by calls
 782                  * to filelayout_write_pagelist().
 783                  * */
 784                 return 0;
 785         }
 786 
 787         buckets = kcalloc(size, sizeof(struct pnfs_commit_bucket),
 788                           gfp_flags);
 789         if (!buckets)
 790                 return -ENOMEM;
 791         for (i = 0; i < size; i++) {
 792                 INIT_LIST_HEAD(&buckets[i].written);
 793                 INIT_LIST_HEAD(&buckets[i].committing);
 794                 /* mark direct verifier as unset */
 795                 buckets[i].direct_verf.committed = NFS_INVALID_STABLE_HOW;
 796         }
 797 
 798         spin_lock(&cinfo->inode->i_lock);
 799         if (cinfo->ds->nbuckets >= size)
 800                 goto out;
 801         for (i = 0; i < cinfo->ds->nbuckets; i++) {
 802                 list_splice(&cinfo->ds->buckets[i].written,
 803                             &buckets[i].written);
 804                 list_splice(&cinfo->ds->buckets[i].committing,
 805                             &buckets[i].committing);
 806                 buckets[i].direct_verf.committed =
 807                         cinfo->ds->buckets[i].direct_verf.committed;
 808                 buckets[i].wlseg = cinfo->ds->buckets[i].wlseg;
 809                 buckets[i].clseg = cinfo->ds->buckets[i].clseg;
 810         }
 811         swap(cinfo->ds->buckets, buckets);
 812         cinfo->ds->nbuckets = size;
 813 out:
 814         spin_unlock(&cinfo->inode->i_lock);
 815         kfree(buckets);
 816         return 0;
 817 }
 818 
 819 static struct pnfs_layout_segment *
 820 filelayout_alloc_lseg(struct pnfs_layout_hdr *layoutid,
 821                       struct nfs4_layoutget_res *lgr,
 822                       gfp_t gfp_flags)
 823 {
 824         struct nfs4_filelayout_segment *fl;
 825         int rc;
 826 
 827         dprintk("--> %s\n", __func__);
 828         fl = kzalloc(sizeof(*fl), gfp_flags);
 829         if (!fl)
 830                 return NULL;
 831 
 832         rc = filelayout_decode_layout(layoutid, fl, lgr, gfp_flags);
 833         if (rc != 0 || filelayout_check_layout(layoutid, fl, lgr, gfp_flags)) {
 834                 _filelayout_free_lseg(fl);
 835                 return NULL;
 836         }
 837         return &fl->generic_hdr;
 838 }
 839 
 840 /*
 841  * filelayout_pg_test(). Called by nfs_can_coalesce_requests()
 842  *
 843  * Return 0 if @req cannot be coalesced into @pgio, otherwise return the number
 844  * of bytes (maximum @req->wb_bytes) that can be coalesced.
 845  */
 846 static size_t
 847 filelayout_pg_test(struct nfs_pageio_descriptor *pgio, struct nfs_page *prev,
 848                    struct nfs_page *req)
 849 {
 850         unsigned int size;
 851         u64 p_stripe, r_stripe;
 852         u32 stripe_offset;
 853         u64 segment_offset = pgio->pg_lseg->pls_range.offset;
 854         u32 stripe_unit = FILELAYOUT_LSEG(pgio->pg_lseg)->stripe_unit;
 855 
 856         /* calls nfs_generic_pg_test */
 857         size = pnfs_generic_pg_test(pgio, prev, req);
 858         if (!size)
 859                 return 0;
 860 
 861         /* see if req and prev are in the same stripe */
 862         if (prev) {
 863                 p_stripe = (u64)req_offset(prev) - segment_offset;
 864                 r_stripe = (u64)req_offset(req) - segment_offset;
 865                 do_div(p_stripe, stripe_unit);
 866                 do_div(r_stripe, stripe_unit);
 867 
 868                 if (p_stripe != r_stripe)
 869                         return 0;
 870         }
 871 
 872         /* calculate remaining bytes in the current stripe */
 873         div_u64_rem((u64)req_offset(req) - segment_offset,
 874                         stripe_unit,
 875                         &stripe_offset);
 876         WARN_ON_ONCE(stripe_offset > stripe_unit);
 877         if (stripe_offset >= stripe_unit)
 878                 return 0;
 879         return min(stripe_unit - (unsigned int)stripe_offset, size);
 880 }
 881 
 882 static struct pnfs_layout_segment *
 883 fl_pnfs_update_layout(struct inode *ino,
 884                       struct nfs_open_context *ctx,
 885                       loff_t pos,
 886                       u64 count,
 887                       enum pnfs_iomode iomode,
 888                       bool strict_iomode,
 889                       gfp_t gfp_flags)
 890 {
 891         struct pnfs_layout_segment *lseg = NULL;
 892         struct pnfs_layout_hdr *lo;
 893         struct nfs4_filelayout_segment *fl;
 894         int status;
 895 
 896         lseg = pnfs_update_layout(ino, ctx, pos, count, iomode, strict_iomode,
 897                                   gfp_flags);
 898         if (IS_ERR_OR_NULL(lseg))
 899                 goto out;
 900 
 901         lo = NFS_I(ino)->layout;
 902         fl = FILELAYOUT_LSEG(lseg);
 903 
 904         status = filelayout_check_deviceid(lo, fl, gfp_flags);
 905         if (status) {
 906                 pnfs_put_lseg(lseg);
 907                 lseg = NULL;
 908         }
 909 out:
 910         return lseg;
 911 }
 912 
 913 static void
 914 filelayout_pg_init_read(struct nfs_pageio_descriptor *pgio,
 915                         struct nfs_page *req)
 916 {
 917         pnfs_generic_pg_check_layout(pgio);
 918         if (!pgio->pg_lseg) {
 919                 pgio->pg_lseg = fl_pnfs_update_layout(pgio->pg_inode,
 920                                                       nfs_req_openctx(req),
 921                                                       0,
 922                                                       NFS4_MAX_UINT64,
 923                                                       IOMODE_READ,
 924                                                       false,
 925                                                       GFP_KERNEL);
 926                 if (IS_ERR(pgio->pg_lseg)) {
 927                         pgio->pg_error = PTR_ERR(pgio->pg_lseg);
 928                         pgio->pg_lseg = NULL;
 929                         return;
 930                 }
 931         }
 932         /* If no lseg, fall back to read through mds */
 933         if (pgio->pg_lseg == NULL)
 934                 nfs_pageio_reset_read_mds(pgio);
 935 }
 936 
 937 static void
 938 filelayout_pg_init_write(struct nfs_pageio_descriptor *pgio,
 939                          struct nfs_page *req)
 940 {
 941         struct nfs_commit_info cinfo;
 942         int status;
 943 
 944         pnfs_generic_pg_check_layout(pgio);
 945         if (!pgio->pg_lseg) {
 946                 pgio->pg_lseg = fl_pnfs_update_layout(pgio->pg_inode,
 947                                                       nfs_req_openctx(req),
 948                                                       0,
 949                                                       NFS4_MAX_UINT64,
 950                                                       IOMODE_RW,
 951                                                       false,
 952                                                       GFP_NOFS);
 953                 if (IS_ERR(pgio->pg_lseg)) {
 954                         pgio->pg_error = PTR_ERR(pgio->pg_lseg);
 955                         pgio->pg_lseg = NULL;
 956                         return;
 957                 }
 958         }
 959 
 960         /* If no lseg, fall back to write through mds */
 961         if (pgio->pg_lseg == NULL)
 962                 goto out_mds;
 963         nfs_init_cinfo(&cinfo, pgio->pg_inode, pgio->pg_dreq);
 964         status = filelayout_alloc_commit_info(pgio->pg_lseg, &cinfo, GFP_NOFS);
 965         if (status < 0) {
 966                 pnfs_put_lseg(pgio->pg_lseg);
 967                 pgio->pg_lseg = NULL;
 968                 goto out_mds;
 969         }
 970         return;
 971 out_mds:
 972         nfs_pageio_reset_write_mds(pgio);
 973 }
 974 
 975 static const struct nfs_pageio_ops filelayout_pg_read_ops = {
 976         .pg_init = filelayout_pg_init_read,
 977         .pg_test = filelayout_pg_test,
 978         .pg_doio = pnfs_generic_pg_readpages,
 979         .pg_cleanup = pnfs_generic_pg_cleanup,
 980 };
 981 
 982 static const struct nfs_pageio_ops filelayout_pg_write_ops = {
 983         .pg_init = filelayout_pg_init_write,
 984         .pg_test = filelayout_pg_test,
 985         .pg_doio = pnfs_generic_pg_writepages,
 986         .pg_cleanup = pnfs_generic_pg_cleanup,
 987 };
 988 
 989 static u32 select_bucket_index(struct nfs4_filelayout_segment *fl, u32 j)
 990 {
 991         if (fl->stripe_type == STRIPE_SPARSE)
 992                 return nfs4_fl_calc_ds_index(&fl->generic_hdr, j);
 993         else
 994                 return j;
 995 }
 996 
 997 static void
 998 filelayout_mark_request_commit(struct nfs_page *req,
 999                                struct pnfs_layout_segment *lseg,
1000                                struct nfs_commit_info *cinfo,
1001                                u32 ds_commit_idx)
1002 
1003 {
1004         struct nfs4_filelayout_segment *fl = FILELAYOUT_LSEG(lseg);
1005         u32 i, j;
1006 
1007         if (fl->commit_through_mds) {
1008                 nfs_request_add_commit_list(req, cinfo);
1009         } else {
1010                 /* Note that we are calling nfs4_fl_calc_j_index on each page
1011                  * that ends up being committed to a data server.  An attractive
1012                  * alternative is to add a field to nfs_write_data and nfs_page
1013                  * to store the value calculated in filelayout_write_pagelist
1014                  * and just use that here.
1015                  */
1016                 j = nfs4_fl_calc_j_index(lseg, req_offset(req));
1017                 i = select_bucket_index(fl, j);
1018                 pnfs_layout_mark_request_commit(req, lseg, cinfo, i);
1019         }
1020 }
1021 
1022 static u32 calc_ds_index_from_commit(struct pnfs_layout_segment *lseg, u32 i)
1023 {
1024         struct nfs4_filelayout_segment *flseg = FILELAYOUT_LSEG(lseg);
1025 
1026         if (flseg->stripe_type == STRIPE_SPARSE)
1027                 return i;
1028         else
1029                 return nfs4_fl_calc_ds_index(lseg, i);
1030 }
1031 
1032 static struct nfs_fh *
1033 select_ds_fh_from_commit(struct pnfs_layout_segment *lseg, u32 i)
1034 {
1035         struct nfs4_filelayout_segment *flseg = FILELAYOUT_LSEG(lseg);
1036 
1037         if (flseg->stripe_type == STRIPE_SPARSE) {
1038                 if (flseg->num_fh == 1)
1039                         i = 0;
1040                 else if (flseg->num_fh == 0)
1041                         /* Use the MDS OPEN fh set in nfs_read_rpcsetup */
1042                         return NULL;
1043         }
1044         return flseg->fh_array[i];
1045 }
1046 
1047 static int filelayout_initiate_commit(struct nfs_commit_data *data, int how)
1048 {
1049         struct pnfs_layout_segment *lseg = data->lseg;
1050         struct nfs4_pnfs_ds *ds;
1051         struct rpc_clnt *ds_clnt;
1052         u32 idx;
1053         struct nfs_fh *fh;
1054 
1055         idx = calc_ds_index_from_commit(lseg, data->ds_commit_index);
1056         ds = nfs4_fl_prepare_ds(lseg, idx);
1057         if (!ds)
1058                 goto out_err;
1059 
1060         ds_clnt = nfs4_find_or_create_ds_client(ds->ds_clp, data->inode);
1061         if (IS_ERR(ds_clnt))
1062                 goto out_err;
1063 
1064         dprintk("%s ino %lu, how %d cl_count %d\n", __func__,
1065                 data->inode->i_ino, how, refcount_read(&ds->ds_clp->cl_count));
1066         data->commit_done_cb = filelayout_commit_done_cb;
1067         refcount_inc(&ds->ds_clp->cl_count);
1068         data->ds_clp = ds->ds_clp;
1069         fh = select_ds_fh_from_commit(lseg, data->ds_commit_index);
1070         if (fh)
1071                 data->args.fh = fh;
1072         return nfs_initiate_commit(ds_clnt, data, NFS_PROTO(data->inode),
1073                                    &filelayout_commit_call_ops, how,
1074                                    RPC_TASK_SOFTCONN);
1075 out_err:
1076         pnfs_generic_prepare_to_resend_writes(data);
1077         pnfs_generic_commit_release(data);
1078         return -EAGAIN;
1079 }
1080 
1081 /* filelayout_search_commit_reqs - Search lists in @cinfo for the head reqest
1082  *                                 for @page
1083  * @cinfo - commit info for current inode
1084  * @page - page to search for matching head request
1085  *
1086  * Returns a the head request if one is found, otherwise returns NULL.
1087  */
1088 static struct nfs_page *
1089 filelayout_search_commit_reqs(struct nfs_commit_info *cinfo, struct page *page)
1090 {
1091         struct nfs_page *freq, *t;
1092         struct pnfs_commit_bucket *b;
1093         int i;
1094 
1095         /* Linearly search the commit lists for each bucket until a matching
1096          * request is found */
1097         for (i = 0, b = cinfo->ds->buckets; i < cinfo->ds->nbuckets; i++, b++) {
1098                 list_for_each_entry_safe(freq, t, &b->written, wb_list) {
1099                         if (freq->wb_page == page)
1100                                 return freq->wb_head;
1101                 }
1102                 list_for_each_entry_safe(freq, t, &b->committing, wb_list) {
1103                         if (freq->wb_page == page)
1104                                 return freq->wb_head;
1105                 }
1106         }
1107 
1108         return NULL;
1109 }
1110 
1111 static int
1112 filelayout_commit_pagelist(struct inode *inode, struct list_head *mds_pages,
1113                            int how, struct nfs_commit_info *cinfo)
1114 {
1115         return pnfs_generic_commit_pagelist(inode, mds_pages, how, cinfo,
1116                                             filelayout_initiate_commit);
1117 }
1118 
1119 static struct nfs4_deviceid_node *
1120 filelayout_alloc_deviceid_node(struct nfs_server *server,
1121                 struct pnfs_device *pdev, gfp_t gfp_flags)
1122 {
1123         struct nfs4_file_layout_dsaddr *dsaddr;
1124 
1125         dsaddr = nfs4_fl_alloc_deviceid_node(server, pdev, gfp_flags);
1126         if (!dsaddr)
1127                 return NULL;
1128         return &dsaddr->id_node;
1129 }
1130 
1131 static void
1132 filelayout_free_deviceid_node(struct nfs4_deviceid_node *d)
1133 {
1134         nfs4_fl_free_deviceid(container_of(d, struct nfs4_file_layout_dsaddr, id_node));
1135 }
1136 
1137 static struct pnfs_layout_hdr *
1138 filelayout_alloc_layout_hdr(struct inode *inode, gfp_t gfp_flags)
1139 {
1140         struct nfs4_filelayout *flo;
1141 
1142         flo = kzalloc(sizeof(*flo), gfp_flags);
1143         return flo != NULL ? &flo->generic_hdr : NULL;
1144 }
1145 
1146 static void
1147 filelayout_free_layout_hdr(struct pnfs_layout_hdr *lo)
1148 {
1149         kfree(FILELAYOUT_FROM_HDR(lo));
1150 }
1151 
1152 static struct pnfs_ds_commit_info *
1153 filelayout_get_ds_info(struct inode *inode)
1154 {
1155         struct pnfs_layout_hdr *layout = NFS_I(inode)->layout;
1156 
1157         if (layout == NULL)
1158                 return NULL;
1159         else
1160                 return &FILELAYOUT_FROM_HDR(layout)->commit_info;
1161 }
1162 
1163 static struct pnfs_layoutdriver_type filelayout_type = {
1164         .id                     = LAYOUT_NFSV4_1_FILES,
1165         .name                   = "LAYOUT_NFSV4_1_FILES",
1166         .owner                  = THIS_MODULE,
1167         .flags                  = PNFS_LAYOUTGET_ON_OPEN,
1168         .max_layoutget_response = 4096, /* 1 page or so... */
1169         .alloc_layout_hdr       = filelayout_alloc_layout_hdr,
1170         .free_layout_hdr        = filelayout_free_layout_hdr,
1171         .alloc_lseg             = filelayout_alloc_lseg,
1172         .free_lseg              = filelayout_free_lseg,
1173         .pg_read_ops            = &filelayout_pg_read_ops,
1174         .pg_write_ops           = &filelayout_pg_write_ops,
1175         .get_ds_info            = &filelayout_get_ds_info,
1176         .mark_request_commit    = filelayout_mark_request_commit,
1177         .clear_request_commit   = pnfs_generic_clear_request_commit,
1178         .scan_commit_lists      = pnfs_generic_scan_commit_lists,
1179         .recover_commit_reqs    = pnfs_generic_recover_commit_reqs,
1180         .search_commit_reqs     = filelayout_search_commit_reqs,
1181         .commit_pagelist        = filelayout_commit_pagelist,
1182         .read_pagelist          = filelayout_read_pagelist,
1183         .write_pagelist         = filelayout_write_pagelist,
1184         .alloc_deviceid_node    = filelayout_alloc_deviceid_node,
1185         .free_deviceid_node     = filelayout_free_deviceid_node,
1186         .sync                   = pnfs_nfs_generic_sync,
1187 };
1188 
1189 static int __init nfs4filelayout_init(void)
1190 {
1191         printk(KERN_INFO "%s: NFSv4 File Layout Driver Registering...\n",
1192                __func__);
1193         return pnfs_register_layoutdriver(&filelayout_type);
1194 }
1195 
1196 static void __exit nfs4filelayout_exit(void)
1197 {
1198         printk(KERN_INFO "%s: NFSv4 File Layout Driver Unregistering...\n",
1199                __func__);
1200         pnfs_unregister_layoutdriver(&filelayout_type);
1201 }
1202 
1203 MODULE_ALIAS("nfs-layouttype4-1");
1204 
1205 module_init(nfs4filelayout_init);
1206 module_exit(nfs4filelayout_exit);

/* [<][>][^][v][top][bottom][index][help] */