home *** CD-ROM | disk | FTP | other *** search
/ ftp.parl.clemson.edu / 2015-02-07.ftp.parl.clemson.edu.tar / ftp.parl.clemson.edu / pub / pvfs2 / orangefs-2.8.3-20110323.tar.gz / orangefs-2.8.3-20110323.tar / orangefs / patches / pnfs / p00001_pnfs_pvfs2layoutsupport.patch < prev    next >
Text File  |  2008-01-07  |  28KB  |  754 lines

  1.  
  2. Modify the NFS exported PVFS2 client to support the PVFS2 pNFS layout driver.
  3. This is done by supporting the pNFS export operations that manage the pNFS
  4. data layout information.
  5.  
  6. When a pNFS client requests a data layout for a file, the exported PVFS2
  7. client module retrieves the layout from the PVFS2 metadata server and returns
  8. it to the nfs server.  To retrieve the layout, the pvfs2 getattr operation has
  9. been modified to retrieve the data servers and their data handles.  The
  10. exported PVFS2 client performs an upcall to execute the getattr operation,
  11. encodes the results and sends the layout back to the nfs server process.
  12.  
  13. A pNFS layout type proc variable has been added so multiple layout types can
  14. be supported in the future.
  15.  
  16. This patch compiles against a version of the 2.6.18.3 linux kernel.
  17.  
  18. ---
  19.  
  20.  pvfs-2.6.3-pnfsfilelayout-dhildeb/include/pvfs2-debug.h                     |    3 
  21.  pvfs-2.6.3-pnfsfilelayout-dhildeb/include/pvfs2-sysint.h                    |    2 
  22.  pvfs-2.6.3-pnfsfilelayout-dhildeb/src/apps/kernel/linux/pvfs2-client-core.c |   94 ++++
  23.  pvfs-2.6.3-pnfsfilelayout-dhildeb/src/client/sysint/client-state-machine.h  |    2 
  24.  pvfs-2.6.3-pnfsfilelayout-dhildeb/src/client/sysint/sys-getattr.sm          |   22 +
  25.  pvfs-2.6.3-pnfsfilelayout-dhildeb/src/io/dev/pint-dev-shared.h              |    5 
  26.  pvfs-2.6.3-pnfsfilelayout-dhildeb/src/kernel/linux-2.6/Makefile.in          |   12 
  27.  pvfs-2.6.3-pnfsfilelayout-dhildeb/src/kernel/linux-2.6/downcall.h           |    3 
  28.  pvfs-2.6.3-pnfsfilelayout-dhildeb/src/kernel/linux-2.6/inode.c              |    2 
  29.  pvfs-2.6.3-pnfsfilelayout-dhildeb/src/kernel/linux-2.6/pnfs.c               |  204 ++++++++++
  30.  pvfs-2.6.3-pnfsfilelayout-dhildeb/src/kernel/linux-2.6/pvfs2-kernel.h       |    4 
  31.  pvfs-2.6.3-pnfsfilelayout-dhildeb/src/kernel/linux-2.6/pvfs2-mod.c          |    4 
  32.  pvfs-2.6.3-pnfsfilelayout-dhildeb/src/kernel/linux-2.6/pvfs2-pnfs.h         |   47 ++
  33.  pvfs-2.6.3-pnfsfilelayout-dhildeb/src/kernel/linux-2.6/pvfs2-proc.c         |    7 
  34.  pvfs-2.6.3-pnfsfilelayout-dhildeb/src/kernel/linux-2.6/pvfs2-utils.c        |    9 
  35.  pvfs-2.6.3-pnfsfilelayout-dhildeb/src/kernel/linux-2.6/super.c              |   18 
  36.  16 files changed, 430 insertions(+), 8 deletions(-)
  37.  
  38. diff -puN include/pvfs2-sysint.h~pvfs2layoutsupport include/pvfs2-sysint.h
  39. --- pvfs-2.6.3-pnfsfilelayout/include/pvfs2-sysint.h~pvfs2layoutsupport    2008-01-05 15:53:59.000000000 -0800
  40. +++ pvfs-2.6.3-pnfsfilelayout-dhildeb/include/pvfs2-sysint.h    2008-01-05 15:53:59.000000000 -0800
  41. @@ -22,6 +22,7 @@
  42.  
  43.  #include "pvfs2-types.h"
  44.  #include "pvfs2-request.h"
  45. +#include "pvfs2-attr.h"
  46.  
  47.  /** Holds a non-blocking system interface operation handle. */
  48.  typedef PVFS_id_gen_t PVFS_sys_op_id;
  49. @@ -92,6 +93,7 @@ typedef struct PVFS_sysresp_lookup_s PVF
  50.  struct PVFS_sysresp_getattr_s
  51.  {
  52.      PVFS_sys_attr attr;
  53. +    PVFS_metafile_attr layout;
  54.  };
  55.  typedef struct PVFS_sysresp_getattr_s PVFS_sysresp_getattr;
  56.  
  57. diff -puN src/apps/kernel/linux/pvfs2-client.c~pvfs2layoutsupport src/apps/kernel/linux/pvfs2-client.c
  58. diff -puN src/client/sysint/client-state-machine.h~pvfs2layoutsupport src/client/sysint/client-state-machine.h
  59. --- pvfs-2.6.3-pnfsfilelayout/src/client/sysint/client-state-machine.h~pvfs2layoutsupport    2008-01-05 15:53:59.000000000 -0800
  60. +++ pvfs-2.6.3-pnfsfilelayout-dhildeb/src/client/sysint/client-state-machine.h    2008-01-05 15:53:59.000000000 -0800
  61. @@ -405,6 +405,8 @@ typedef struct PINT_sm_getattr_state
  62.      PVFS_size * size_array;
  63.      PVFS_size size;
  64.  
  65. +    PVFS_metafile_attr layout;
  66. +
  67.      int flags;
  68.      
  69.  } PINT_sm_getattr_state;
  70. diff -puN src/io/dev/pint-dev-shared.h~pvfs2layoutsupport src/io/dev/pint-dev-shared.h
  71. --- pvfs-2.6.3-pnfsfilelayout/src/io/dev/pint-dev-shared.h~pvfs2layoutsupport    2008-01-05 15:53:59.000000000 -0800
  72. +++ pvfs-2.6.3-pnfsfilelayout-dhildeb/src/io/dev/pint-dev-shared.h    2008-01-05 17:46:17.000000000 -0800
  73. @@ -18,6 +18,11 @@
  74.  #include <sys/ioctl.h>  /* needed for constructing the _IO macros */
  75.  #endif
  76.  
  77. +/* DH: This is also defined in the nfs header files.
  78. + */
  79. +#define PVFS2_MAX_LAYOUT_LEN 256
  80. +#define PVFS2_MAX_DEVLIST_LEN 256
  81. +
  82.  /* version number for use in communicating between kernel space and user
  83.   * space
  84.   */
  85. diff -puN src/kernel/linux-2.6/downcall.h~pvfs2layoutsupport src/kernel/linux-2.6/downcall.h
  86. --- pvfs-2.6.3-pnfsfilelayout/src/kernel/linux-2.6/downcall.h~pvfs2layoutsupport    2008-01-05 15:53:59.000000000 -0800
  87. +++ pvfs-2.6.3-pnfsfilelayout-dhildeb/src/kernel/linux-2.6/downcall.h    2008-01-05 17:50:23.000000000 -0800
  88. @@ -11,6 +11,7 @@
  89.   */
  90.  
  91.  /* TODO: we might want to try to avoid this inclusion  */
  92. +#include "pvfs2-attr.h"
  93.  #include "pvfs2-sysint.h"
  94.  
  95.  #ifndef __DOWNCALL_H
  96. @@ -49,6 +50,8 @@ typedef struct
  97.  {
  98.      PVFS_sys_attr attributes;
  99.      char link_target[PVFS2_NAME_LEN];
  100. +    int layout_size;
  101. +    char layout[PVFS2_MAX_LAYOUT_LEN];
  102.  } pvfs2_getattr_response_t;
  103.  
  104.  /* the setattr response is a blank downcall */
  105. diff -puN src/kernel/linux-2.6/Makefile.in~pvfs2layoutsupport src/kernel/linux-2.6/Makefile.in
  106. --- pvfs-2.6.3-pnfsfilelayout/src/kernel/linux-2.6/Makefile.in~pvfs2layoutsupport    2008-01-05 15:53:59.000000000 -0800
  107. +++ pvfs-2.6.3-pnfsfilelayout-dhildeb/src/kernel/linux-2.6/Makefile.in    2008-01-05 15:53:59.000000000 -0800
  108. @@ -49,23 +49,27 @@ csrc = \
  109.      xattr-trusted.c \
  110.      xattr-default.c \
  111.      waitqueue.c \
  112. -    pvfs2-proc.c
  113. +    pvfs2-proc.c \
  114. +    pnfs.c
  115.  hsrc = \
  116.      pvfs2-kernel.h \
  117.      pvfs2-dev-proto.h \
  118.      pvfs2-bufmap.h \
  119.      upcall.h \
  120.      downcall.h \
  121. -    pvfs2-proc.h
  122. +    pvfs2-proc.h \
  123. +    pvfs2-pnfs.h
  124.  
  125.  objs = $(csrc:.c=.o)
  126.  othergen = pvfs2.o pvfs2.ko pvfs2.mod.c pvfs2.mod.o
  127.  othergendir = .tmp_versions  # around 2.6.6 this is generated locally
  128.  cmds = $(patsubst %,.%.cmd,$(objs) $(othergen))
  129.  
  130. +KDIR := @LINUX_KERNEL_SRC@
  131.  ifneq ($(KERNELRELEASE),)
  132.  
  133.  EXTRA_CFLAGS = \
  134. +    -I$(KDIR)/include/linux \
  135.      -I$(absolute_src_dir)/ \
  136.      -I$(absolute_build_dir)/ \
  137.      -I$(absolute_src_dir)/include \
  138. @@ -74,6 +78,9 @@ EXTRA_CFLAGS = \
  139.      -I$(absolute_src_dir)/src/common/quickhash \
  140.       -I$(absolute_src_dir)/src/proto \
  141.      -I$(absolute_src_dir)/src/common/gossip \
  142. +    -I$(absolute_src_dir)/src/io/trove \
  143. +    -I$(absolute_src_dir)/src/io/description \
  144. +    -I$(absolute_src_dir)/src/proto \
  145.      -I$(absolute_src_dir)/src/common/misc
  146.  
  147.  EXTRA_CFLAGS += @MMAP_RA_CACHE@
  148. @@ -90,7 +97,6 @@ else
  149.  
  150.  #KDIR    := /lib/modules/$(shell uname -r)/build
  151.  #KDIR    := /usr/src/linux-$(shell uname -r)
  152. -KDIR    := @LINUX_KERNEL_SRC@
  153.  PWD    := $(shell pwd)
  154.  
  155.  default: links
  156. diff -puN src/kernel/linux-2.6/pvfs2-kernel.h~pvfs2layoutsupport src/kernel/linux-2.6/pvfs2-kernel.h
  157. --- pvfs-2.6.3-pnfsfilelayout/src/kernel/linux-2.6/pvfs2-kernel.h~pvfs2layoutsupport    2008-01-05 15:53:59.000000000 -0800
  158. +++ pvfs-2.6.3-pnfsfilelayout-dhildeb/src/kernel/linux-2.6/pvfs2-kernel.h    2008-01-05 17:50:23.000000000 -0800
  159. @@ -382,6 +382,8 @@ typedef struct
  160.      unsigned long pinode_flags;
  161.      /* All allocated pvfs2_inode_t objects are chained to a list */
  162.      struct list_head list;
  163. +    int layout_size;
  164. +    char layout[PVFS2_MAX_LAYOUT_LEN];
  165.  } pvfs2_inode_t;
  166.  
  167.  #define P_ATIME_FLAG 0
  168. @@ -989,6 +991,8 @@ do {                                    
  169.  int service_operation(pvfs2_kernel_op_t* op, const char* op_name, 
  170.      int flags);
  171.  
  172. +extern int layouttype;
  173. +
  174.  /** handles two possible error cases, depending on context.
  175.   *
  176.   *  by design, our vfs i/o errors need to be handled in one of two ways,
  177. diff -puN include/pvfs2-debug.h~pvfs2layoutsupport include/pvfs2-debug.h
  178. --- pvfs-2.6.3-pnfsfilelayout/include/pvfs2-debug.h~pvfs2layoutsupport    2008-01-05 15:53:59.000000000 -0800
  179. +++ pvfs-2.6.3-pnfsfilelayout-dhildeb/include/pvfs2-debug.h    2008-01-05 15:53:59.000000000 -0800
  180. @@ -99,8 +99,9 @@ const char *PVFS_debug_get_next_debug_ke
  181.  #define GOSSIP_PROC_DEBUG             ((uint64_t)1 << 12)
  182.  #define GOSSIP_XATTR_DEBUG            ((uint64_t)1 << 13)
  183.  #define GOSSIP_INIT_DEBUG             ((uint64_t)1 << 14)
  184. +#define GOSSIP_PNFS_DEBUG             ((uint64_t)1 << 15)
  185.  
  186. -#define GOSSIP_MAX_NR                 15
  187. +#define GOSSIP_MAX_NR                 16
  188.  #define GOSSIP_MAX_DEBUG              (((uint64_t)1 << GOSSIP_MAX_NR) - 1)
  189.  
  190.  /*
  191. diff -puN src/kernel/linux-2.6/pvfs2-mod.c~pvfs2layoutsupport src/kernel/linux-2.6/pvfs2-mod.c
  192. --- pvfs-2.6.3-pnfsfilelayout/src/kernel/linux-2.6/pvfs2-mod.c~pvfs2layoutsupport    2008-01-05 15:53:59.000000000 -0800
  193. +++ pvfs-2.6.3-pnfsfilelayout-dhildeb/src/kernel/linux-2.6/pvfs2-mod.c    2008-01-05 17:50:23.000000000 -0800
  194. @@ -10,6 +10,8 @@
  195.  #include "pvfs2-kernel.h"
  196.  #include "pvfs2-proc.h"
  197.  #include "pvfs2-internal.h"
  198. +#include "pvfs2-pnfs.h"
  199. +#include "nfs4.h"
  200.  
  201.  #ifndef PVFS2_VERSION
  202.  #define PVFS2_VERSION "Unknown"
  203. @@ -27,6 +29,8 @@ static int hash_table_size = 509;
  204.  int gossip_debug_mask = 0;
  205.  int op_timeout_secs = PVFS2_DEFAULT_OP_TIMEOUT_SECS;
  206.  
  207. +int layouttype = LAYOUT_PVFS2;
  208. +
  209.  MODULE_LICENSE("GPL");
  210.  MODULE_AUTHOR("PVFS2 Development Team");
  211.  MODULE_DESCRIPTION("The Linux Kernel VFS interface to PVFS2");
  212. diff -puN src/kernel/linux-2.6/pvfs2-proc.c~pvfs2layoutsupport src/kernel/linux-2.6/pvfs2-proc.c
  213. --- pvfs-2.6.3-pnfsfilelayout/src/kernel/linux-2.6/pvfs2-proc.c~pvfs2layoutsupport    2008-01-05 15:53:59.000000000 -0800
  214. +++ pvfs-2.6.3-pnfsfilelayout-dhildeb/src/kernel/linux-2.6/pvfs2-proc.c    2008-01-05 17:52:21.000000000 -0800
  215. @@ -12,6 +12,8 @@
  216.  #include <linux/sysctl.h>
  217.  #include <linux/proc_fs.h>
  218.  #include "pvfs2-proc.h"
  219. +#include "pvfs2-pnfs.h"
  220. +#include "nfs4.h"
  221.  
  222.  #ifndef PVFS2_VERSION
  223.  #define PVFS2_VERSION "Unknown"
  224. @@ -260,6 +262,8 @@ static struct pvfs2_param_extra perf_res
  225.  };
  226.  static int min_debug[] = {0}, max_debug[] = {GOSSIP_MAX_DEBUG};
  227.  static int min_op_timeout_secs[] = {0}, max_op_timeout_secs[] = {INT_MAX};
  228. +/* DH: LAYOUT_NFSV4_FILES defined in the nfs header files */
  229. +static int min_layouttype[] = {LAYOUT_NFSV4_FILES}, max_layouttype[] = {5};
  230.  static ctl_table pvfs2_acache_table[] = {
  231.      /* controls acache timeout */
  232.      {1, "timeout-msecs", NULL, sizeof(int), 0644, NULL,
  233. @@ -324,6 +328,9 @@ static ctl_table pvfs2_table[] = {
  234.      {7, "perf-counters", NULL, 0, 0555, pvfs2_pc_table},
  235.      /* subdir for ncache control */
  236.      {8, "ncache", NULL, 0, 0555, pvfs2_ncache_table},
  237. +    {9, "layouttype", &layouttype, sizeof(int), 0644, NULL,
  238. +        &proc_dointvec_minmax, &sysctl_intvec,
  239. +        NULL, &min_layouttype, &max_layouttype},
  240.      {0}
  241.  };
  242.  static ctl_table fs_table[] = {
  243. diff -puN src/apps/kernel/linux/pvfs2-client-core.c~pvfs2layoutsupport src/apps/kernel/linux/pvfs2-client-core.c
  244. --- pvfs-2.6.3-pnfsfilelayout/src/apps/kernel/linux/pvfs2-client-core.c~pvfs2layoutsupport    2008-01-05 15:53:59.000000000 -0800
  245. +++ pvfs-2.6.3-pnfsfilelayout-dhildeb/src/apps/kernel/linux/pvfs2-client-core.c    2008-01-05 17:50:23.000000000 -0800
  246. @@ -15,6 +15,7 @@
  247.  #include <signal.h>
  248.  #include <getopt.h>
  249.  
  250. +#define __PINT_REQPROTO_ENCODE_FUNCS_C
  251.  #include "pvfs2.h"
  252.  #include "gossip.h"
  253.  #include "job.h"
  254. @@ -543,6 +544,80 @@ static PVFS_error post_symlink_request(v
  255.      return ret;
  256.  }
  257.  
  258. +/* DH: Copy from the PVFS_metafile_attr struct into a contiguous
  259. +  * region which can be sent back to the I/O module on the client
  260. +  */
  261. + static int
  262. + pnfs_serialize_layout(pvfs2_getattr_response_t* getattr, PVFS_metafile_attr* layout, PVFS_object_ref* refn)
  263. + {
  264. +     char* buffer = getattr->layout;
  265. +     int dfiles_size,dist_size,blob_size = 0;
  266. +     int ret;
  267. +
  268. +     gossip_debug(GOSSIP_CLIENT_DEBUG,"serialize_layout: Begin\n");
  269. +     if (layout->dfile_count <= 0 || layout->dist_size <= 0)
  270. +     {
  271. +     gossip_debug(GOSSIP_CLIENT_DEBUG,"serialize_layout: No layout to serialize\n");
  272. +     return 0;
  273. +     }
  274. +     dfiles_size = layout->dfile_count  * sizeof(PVFS_handle);
  275. +     dist_size = PINT_DIST_PACK_SIZE(layout->dist);
  276. +     blob_size = dfiles_size + dist_size;
  277. +
  278. +     /* Add on 4 bytes for count of dfiles and 4 for total blob size
  279. +      * plus 4 bytes for the fs_id
  280. +      * Total blob size is required since we are using the ioctl
  281. +      * interface which doesn't allow passing in the size of the blob
  282. +      */
  283. +     blob_size += 12;
  284. +
  285. +     gossip_debug(GOSSIP_CLIENT_DEBUG,
  286. +          "serialize_layout: Blob sz:%d #dfiles: %d dfiles sz:%d dist sz:%d\n",
  287. +          blob_size,
  288. +          layout->dfile_count,
  289. +          dfiles_size,
  290. +          dist_size);
  291. +
  292. +     /* Ensure size of blob isn't larger than the max */
  293. +     if (blob_size > PVFS2_MAX_LAYOUT_LEN) {
  294. +     gossip_err("serialize_layout: Error!  Size of layout is > than max size %d\n",
  295. +           (int)PVFS2_MAX_LAYOUT_LEN);
  296. +    ret = -EIO;
  297. +     goto out_cleanup;
  298. +     }
  299. +     if (layout->dfile_array == NULL) {
  300. +     gossip_err("serialize_layout: Error!  dfile_array is NULL\n");
  301. +    ret = -EIO;
  302. +     goto out_cleanup;
  303. +     }
  304. +     if (layout->dist == NULL) {
  305. +     gossip_err("serialize_layout: Error!  dist is NULL\n");
  306. +    ret = -EIO;
  307. +     goto out_cleanup;
  308. +     }
  309. +
  310. +     /* Add blob size */
  311. +     encode_int32_t(&buffer, &blob_size);
  312. +
  313. +     /* Add fs_id */
  314. +     encode_int32_t(&buffer, &refn->fs_id);
  315. +
  316. +     encode_PVFS_metafile_attr_dfiles(&buffer, layout); /* dfile array */
  317. +     encode_PVFS_metafile_attr_dist(&buffer, layout); /* dist */
  318. +
  319. +     gossip_debug(GOSSIP_CLIENT_DEBUG,"fs_id:%d\n", refn->fs_id);
  320. +     gossip_debug(GOSSIP_CLIENT_DEBUG,"# dfiles:%d\n", layout->dfile_count);
  321. +     gossip_debug(GOSSIP_CLIENT_DEBUG,"dfile #0:%llu\n", llu(layout->dfile_array[0]));
  322. +     PINT_dist_dump(layout->dist);
  323. +
  324. +     ret = blob_size;
  325. +out_cleanup:
  326. +     free(layout->dfile_array);
  327. +     PINT_dist_free(layout->dist);
  328. +     gossip_debug(GOSSIP_CLIENT_DEBUG,"serialize_layout: (err:%d)\n", ret);
  329. +     return ret;
  330. +}
  331. +
  332.  static PVFS_error post_getattr_request(vfs_request_t *vfs_request)
  333.  {
  334.      PVFS_error ret = -PVFS_EINVAL;
  335. @@ -2089,6 +2164,7 @@ static inline void package_downcall_memb
  336.      vfs_request_t *vfs_request, int *error_code)
  337.  {
  338.      int ret = -PVFS_EINVAL;
  339. +    int layout_bytes_cp = 0;
  340.      assert(vfs_request);
  341.      assert(error_code);
  342.  
  343. @@ -2214,6 +2290,24 @@ static inline void package_downcall_memb
  344.  
  345.                      free(attr->link_target);
  346.                  }
  347. +
  348. +        /* DH: This should return the dfiles and dist since
  349. +         * PVFS_ATTR_SYS_ALL includes PVFS_ATTR_SYS_SIZE which requires them
  350. +         * I will now return the layout in all cases.
  351. +         * Note: It is cached in the kernel after the first request.
  352. +         */
  353. +        /* Serialize the layout so it can be sent in the downcall */
  354. +        layout_bytes_cp = pnfs_serialize_layout(&vfs_request->out_downcall.resp.getattr,
  355. +                            &vfs_request->response.getattr.layout,
  356. +                            &vfs_request->in_upcall.req.getattr.refn);
  357. +
  358. +        /* If there was an error, fail the entire getattr request */
  359. +        if (layout_bytes_cp < 0) {
  360. +            *error_code = layout_bytes_cp;
  361. +            layout_bytes_cp = 0;
  362. +        }
  363. +        gossip_debug(GOSSIP_CLIENT_DEBUG,"lbc: %d)\n", layout_bytes_cp);
  364. +        vfs_request->out_downcall.resp.getattr.layout_size = layout_bytes_cp;
  365.              }
  366.              break;
  367.          case PVFS2_VFS_OP_SETATTR:
  368. diff -puN src/client/sysint/sys-getattr.sm~pvfs2layoutsupport src/client/sysint/sys-getattr.sm
  369. --- pvfs-2.6.3-pnfsfilelayout/src/client/sysint/sys-getattr.sm~pvfs2layoutsupport    2008-01-05 15:53:59.000000000 -0800
  370. +++ pvfs-2.6.3-pnfsfilelayout-dhildeb/src/client/sysint/sys-getattr.sm    2008-01-05 15:53:59.000000000 -0800
  371. @@ -807,6 +807,8 @@ static int getattr_set_sys_response(PINT
  372.  {
  373.      PVFS_sysresp_getattr * sysresp = NULL;
  374.      PVFS_object_attr *attr = NULL;
  375. +    PVFS_metafile_attr *layout = NULL;
  376. +    PVFS_size df_array_size;
  377.  
  378.      if(js_p->error_code != 0)
  379.      {
  380. @@ -815,6 +817,7 @@ static int getattr_set_sys_response(PINT
  381.      }
  382.  
  383.      attr = &sm_p->getattr.attr;
  384. +    layout = &sm_p->getattr.attr.u.meta;
  385.      assert(attr);
  386.      
  387.      /* If we get to this state action, 
  388. @@ -904,6 +907,25 @@ static int getattr_set_sys_response(PINT
  389.      sysresp->attr.size  = 0;
  390.      sysresp->attr.objtype = attr->objtype;
  391.  
  392. +    /* DH: Set the values of the layout that were stored in the cache. */
  393. +    if(attr->objtype == PVFS_TYPE_METAFILE &&
  394. +       sm_p->getattr.req_attrmask & PVFS_ATTR_META_DFILES &&
  395. +       sm_p->getattr.req_attrmask & PVFS_ATTR_META_DIST) {
  396. +    gossip_debug(GOSSIP_CLIENT_DEBUG, "pNFS: Setting layout\n");
  397. +    /* file handles */
  398. +    df_array_size = layout->dfile_count * sizeof(PVFS_handle);
  399. +    sysresp->layout.dfile_count = layout->dfile_count;
  400. +    sysresp->layout.dfile_array = malloc(df_array_size);
  401. +    if (!sysresp->layout.dfile_array) {
  402. +        js_p->error_code = -PVFS_ENOMEM;
  403. +        return 0;
  404. +    }
  405. +    memcpy(sysresp->layout.dfile_array, layout->dfile_array, df_array_size);
  406. +    /* dist */
  407. +    sysresp->layout.dist = PINT_dist_copy(layout->dist);
  408. +    sysresp->layout.dist_size = layout->dist_size;
  409. +    }
  410. +
  411.      if (js_p->error_code == 0)
  412.      {
  413.          /* convert outgoing attribute mask based on what we got */
  414. diff -puN src/kernel/linux-2.6/inode.c~pvfs2layoutsupport src/kernel/linux-2.6/inode.c
  415. --- pvfs-2.6.3-pnfsfilelayout/src/kernel/linux-2.6/inode.c~pvfs2layoutsupport    2008-01-05 15:53:59.000000000 -0800
  416. +++ pvfs-2.6.3-pnfsfilelayout-dhildeb/src/kernel/linux-2.6/inode.c    2008-01-05 15:53:59.000000000 -0800
  417. @@ -503,6 +503,8 @@ struct inode *pvfs2_get_custom_inode_com
  418.              return NULL;
  419.          }
  420.  
  421. +    pvfs2_inode->layout_size = -1;
  422. +
  423.          /*
  424.           * Since we are using the same function to create a new on-disk object
  425.           * as well as to create an in-memory object, the mode of the object
  426. diff -puN /dev/null src/kernel/linux-2.6/pnfs.c
  427. --- /dev/null    2007-11-26 10:11:24.475597181 -0800
  428. +++ pvfs-2.6.3-pnfsfilelayout-dhildeb/src/kernel/linux-2.6/pnfs.c    2008-01-05 17:50:23.000000000 -0800
  429. @@ -0,0 +1,204 @@
  430. +/*
  431. + * (C) 2001 Clemson University and The University of Chicago
  432. + *
  433. + * See COPYING in top-level directory.
  434. + */
  435. +
  436. +#include "pvfs2-kernel.h"
  437. +#include "pvfs2-pnfs.h"
  438. +
  439. +#include "param.h"
  440. +#include "sunrpc/svc.h"
  441. +#include "sunrpc/debug.h"
  442. +#include "nfsd/nfsd.h"
  443. +#include "nfs4.h"
  444. +#include "nfsd/state.h"
  445. +#include "nfsd/pnfsd.h"
  446. +
  447. +#include "nfsd/nfs4layoutxdr.h"
  448. +
  449. +/* used to protect the layout information for an inode */
  450. +spinlock_t pvfs2_layout_lock = SPIN_LOCK_UNLOCKED;
  451. +
  452. +/****** Common Functions ******/
  453. +static int
  454. +pvfs2_layout_type(void)
  455. +{
  456. +    return layouttype;
  457. +}
  458. +
  459. +/****** PVFS2 Layout Functions ******/
  460. +
  461. +/* Set pvfs2 layout information for return to nfsd.
  462. + * DH-TODO: This is copying from the pvfs2_inode_t struct
  463. + * (which exists in a cache), to NFSD alloc'd memory.  It
  464. + * is probably better that NFSD manages its own memory, so
  465. + * even though there is copying from the downcall struct to
  466. + * the pvfs2_inode_t and now to nfsd, this may make sense.
  467. + * Better to optimize the downcall -> pvfs2_inode_t copy.
  468. + */
  469. +static int
  470. +set_pvfs2_layout(struct nfsd4_pnfs_layoutget* req, void* layout, int layout_size)
  471. +{
  472. +    struct pvfs2_layout* lay_t;
  473. +    gossip_debug(GOSSIP_PNFS_DEBUG,"%s: Begin copying %d bytes\n",__FUNCTION__,layout_size);
  474. +    if (req->lg_layout)
  475. +    {
  476. +    gossip_debug(GOSSIP_PNFS_DEBUG,"%s: Existing layout, freeing existing memory\n",__FUNCTION__);
  477. +    kfree(req->lg_layout);
  478. +    }
  479. +
  480. +    if (layout_size > req->lg_mxcnt)
  481. +    {
  482. +    gossip_err("%s: Layout blob (%d) is larger than buffer (%d)\n",
  483. +           __FUNCTION__,
  484. +           layout_size,
  485. +           req->lg_mxcnt);
  486. +    return -EIO;
  487. +    }
  488. +
  489. +    lay_t = (struct pvfs2_layout*)kmalloc(sizeof(struct pvfs2_layout), GFP_KERNEL);
  490. +    lay_t->layout = layout;
  491. +    lay_t->length = layout_size;
  492. +
  493. +    /* set return layout for nfsd */
  494. +    req->lg_layout = (void*)lay_t;
  495. +
  496. +    gossip_debug(GOSSIP_PNFS_DEBUG,"%s: XDR PVFS2 LAYOUT\n", __FUNCTION__);
  497. +    gossip_debug(GOSSIP_PNFS_DEBUG,"\tblob size:%d\n", ((int*)layout)[0]);
  498. +    gossip_debug(GOSSIP_PNFS_DEBUG,"\tfsid:%d\n", ((int*)layout)[1]);
  499. +    gossip_debug(GOSSIP_PNFS_DEBUG,"\t# dfiles:%d\n", ((int*)layout)[2]);
  500. +    layout += 12;
  501. +    gossip_debug(GOSSIP_PNFS_DEBUG,"\tdfile 0:%llu\n", ((u64*)layout)[0]);
  502. +
  503. +    return 0;
  504. +}
  505. +
  506. +/* Retrieves pvfs2 pNFS layout from mds */
  507. +static int
  508. +pvfs2_pvfs2layout_getattr(struct inode * inode, int attributes)
  509. +{
  510. +    pvfs2_inode_t* pvfs2_inode = PVFS2_I(inode);
  511. +    int ret;
  512. +
  513. +    gossip_debug(GOSSIP_PNFS_DEBUG,"%s: Start\n", __FUNCTION__);
  514. +    spin_lock(&pvfs2_layout_lock);
  515. +
  516. +    /* Check if layout has already been retrieve for this inode */
  517. +    if (pvfs2_inode->layout_size <= 0)
  518. +    {
  519. +    /* perform upcall to retrieve layout */
  520. +    gossip_debug(GOSSIP_PNFS_DEBUG,"%s: Retrieving pNFS layout\n", __FUNCTION__);
  521. +        ret = pvfs2_inode_getattr(inode, attributes);
  522. +    if (ret || pvfs2_inode->layout_size <= 0)
  523. +    {
  524. +        gossip_err("%s: Error!  Could not retrieve layout (%d)\n",__FUNCTION__,ret);
  525. +        ret = -ENOSYS;
  526. +    }
  527. +    } else {
  528. +    gossip_debug(GOSSIP_PNFS_DEBUG,"%s: Using cached pNFS layout\n", __FUNCTION__);
  529. +    ret = 0;
  530. +    }
  531. +
  532. +    spin_unlock(&pvfs2_layout_lock);
  533. +    return ret;
  534. +}
  535. +
  536. +/* Retrieves pvfs2 data layout information about the specified file.
  537. + * return- positive 0
  538. + * negative -ENOSYS or pvfs2_inode_getattr error
  539. + */
  540. +static int
  541. +pvfs2_layout_get(struct inode * inode, void* buf)
  542. +{
  543. +    int ret;
  544. +    struct nfsd4_pnfs_layoutget *layout_request = (struct nfsd4_pnfs_layoutget*)buf;
  545. +    pvfs2_inode_t* pvfs2_inode = PVFS2_I(inode);
  546. +
  547. +    gossip_debug(GOSSIP_PNFS_DEBUG,"%s: off:%Lu ex:%Lu macc:%d iomode:%d\n", __FUNCTION__,
  548. +        layout_request->lg_seg.offset,
  549. +        layout_request->lg_seg.length,
  550. +        layout_request->lg_mxcnt,
  551. +        layout_request->lg_seg.iomode);
  552. +
  553. +    if ((ret = pvfs2_pvfs2layout_getattr(inode, PVFS_ATTR_META_ALL)) < 0)
  554. +    return -ENOSYS;
  555. +
  556. +    ret = set_pvfs2_layout(layout_request,
  557. +                           pvfs2_inode->layout,
  558. +                           pvfs2_inode->layout_size);
  559. +    if (ret)
  560. +    gossip_err("%s: Error!  Could not copy attributes (%d)\n",__FUNCTION__,ret);
  561. +
  562. +    return ret;
  563. +}
  564. +
  565. +static void
  566. +pvfs2_layout_free(void *layout)
  567. +{
  568. +    struct pvfs2_layout* lay_t;
  569. +
  570. +    if (!layout)
  571. +    return;
  572. +
  573. +    gossip_debug(GOSSIP_PNFS_DEBUG,"pvfs2: Freeing server layout struct\n");
  574. +    lay_t = (struct pvfs2_layout*)layout;
  575. +    kfree(lay_t);
  576. +}
  577. +
  578. +/* pNFS: encodes opaque layout
  579. + * Arg: resp - xdr buffer pointer
  580. + * layout - file system defined
  581. + * Ret: new value of xdr buffer pointer
  582. +   int (*layout_encode)(u32 *p, u32 *end, void *layout);
  583. + */
  584. +static int
  585. +pvfs2_layout_encode(u32 *p, u32 *end, void *layout)
  586. +{
  587. +    struct pvfs2_layout *plo;
  588. +    int lay_length;
  589. +
  590. +    gossip_debug(GOSSIP_PNFS_DEBUG,"%s: Encoding pvfs2 layout\n", __FUNCTION__);
  591. +
  592. +    if (!layout)
  593. +    {
  594. +    gossip_err("%s: ERROR! No layout to encode.\n", __FUNCTION__);
  595. +    return -ENOMEM;
  596. +    }
  597. +
  598. +    plo = (struct pvfs2_layout*)layout;
  599. +
  600. +    gossip_debug(GOSSIP_PNFS_DEBUG,"%s: Layout length %d\n", __FUNCTION__, plo->length);
  601. +
  602. +    lay_length = 4 + plo->length;
  603. +    if (p + XDR_QUADLEN(lay_length) > end)
  604. +    {
  605. +    gossip_err("Layout length (%d) exceeds available xdr buffer",plo->length);
  606. +    return -ENOMEM;
  607. +    }
  608. +
  609. +    /* Write length and layout */
  610. +    WRITE32(plo->length);
  611. +    WRITEMEM(plo->layout, plo->length);
  612. +
  613. +    /* update xdr pointer */
  614. +    return lay_length;
  615. +}
  616. +
  617. +/* export ops for each layout type */
  618. +struct export_operations pvfs2layout_export_ops =
  619. +{
  620. +    .layout_type   = pvfs2_layout_type,
  621. +    .layout_get    = pvfs2_layout_get,
  622. +    .layout_free   = pvfs2_layout_free,
  623. +    .layout_encode = pvfs2_layout_encode,
  624. +};
  625. +
  626. +/*
  627. + * Local variables:
  628. + *  c-indent-level: 4
  629. + *  c-basic-offset: 4
  630. + * End:
  631. + *
  632. + * vim: ts=8 sts=4 sw=4 expandtab
  633. + */
  634. diff -puN /dev/null src/kernel/linux-2.6/pvfs2-pnfs.h
  635. --- /dev/null    2007-11-26 10:11:24.475597181 -0800
  636. +++ pvfs-2.6.3-pnfsfilelayout-dhildeb/src/kernel/linux-2.6/pvfs2-pnfs.h    2008-01-05 17:50:23.000000000 -0800
  637. @@ -0,0 +1,47 @@
  638. +/*
  639. + * (C) 2006 CITI @ the University of Michigan
  640. + *
  641. + * See COPYING in top-level directory.
  642. + */
  643. +
  644. +/** \defgroup pvfs2linux PVFS2 Linux kernel support
  645. + *
  646. + *  pNFS definitions
  647. + *
  648. + * @{
  649. + */
  650. +
  651. +/** \file
  652. + *  Declarations and macros for the pNFS Linux kernel support.
  653. + */
  654. +
  655. +#ifndef __PVFS2_PNFS_H
  656. +#define __PVFS2_PNFS_H
  657. +
  658. +/* pnfs-pvfs2 layout structure */
  659. +struct pvfs2_layout {
  660. +    u32     length;
  661. +    void    *layout;
  662. +};
  663. +
  664. +extern struct export_operations pvfs2layout_export_ops;
  665. +
  666. +/* Structs need to be defined just to compile kernel module since they
  667. + * are used in include/linux/nfs4_pnfs.h.
  668. + */
  669. +struct nfs_write_data;
  670. +struct nfs_read_data;
  671. +struct pnfs_layoutcommit_arg;
  672. +struct pnfs_layoutcommit_res;
  673. +
  674. +#endif
  675. +/* @} */
  676. +
  677. +/*
  678. + * Local variables:
  679. + *  c-indent-level: 4
  680. + *  c-basic-offset: 4
  681. + * End:
  682. + *
  683. + * vim: ts=8 sts=4 sw=4 expandtab
  684. + */
  685. diff -puN src/kernel/linux-2.6/pvfs2-utils.c~pvfs2layoutsupport src/kernel/linux-2.6/pvfs2-utils.c
  686. --- pvfs-2.6.3-pnfsfilelayout/src/kernel/linux-2.6/pvfs2-utils.c~pvfs2layoutsupport    2008-01-05 15:53:59.000000000 -0800
  687. +++ pvfs-2.6.3-pnfsfilelayout-dhildeb/src/kernel/linux-2.6/pvfs2-utils.c    2008-01-05 15:53:59.000000000 -0800
  688. @@ -510,6 +510,15 @@ int pvfs2_inode_getattr(struct inode *in
  689.                  ret = -ENOENT;
  690.                  goto copy_attr_failure;
  691.              }
  692. +        /* DH: Copy layout blob for pnfs */
  693. +        gossip_debug(GOSSIP_PNFS_DEBUG,
  694. +             "%s: Server copy layout from userland size:%d\n",
  695. +             __FUNCTION__,new_op->downcall.resp.getattr.layout_size);
  696. +        pvfs2_inode->layout_size = new_op->downcall.resp.getattr.layout_size;
  697. +        if (pvfs2_inode->layout_size > 0)
  698. +        {
  699. +        memcpy(pvfs2_inode->layout,new_op->downcall.resp.getattr.layout,pvfs2_inode->layout_size);
  700. +        }
  701.          }
  702.  
  703.        copy_attr_failure:
  704. diff -puN src/kernel/linux-2.6/super.c~pvfs2layoutsupport src/kernel/linux-2.6/super.c
  705. --- pvfs-2.6.3-pnfsfilelayout/src/kernel/linux-2.6/super.c~pvfs2layoutsupport    2008-01-05 15:53:59.000000000 -0800
  706. +++ pvfs-2.6.3-pnfsfilelayout-dhildeb/src/kernel/linux-2.6/super.c    2008-01-05 17:50:23.000000000 -0800
  707. @@ -7,6 +7,8 @@
  708.  #include "pvfs2-kernel.h"
  709.  #include "pvfs2-bufmap.h"
  710.  #include "pvfs2-internal.h"
  711. +#include "pvfs2-pnfs.h"
  712. +#include "nfs4.h"
  713.  
  714.  /* list for storing pvfs2 specific superblocks in use */
  715.  LIST_HEAD(pvfs2_superblocks);
  716. @@ -245,7 +247,7 @@ static void pvfs2_read_inode(
  717.      }
  718.  }
  719.  
  720. -#else /* !PVFS2_LINUX_KERNEL_2_4 */
  721. +#else /* PVFS2_LINUX_KERNEL_2_4 */
  722.  
  723.  static void pvfs2_read_inode(
  724.      struct inode *inode)
  725. @@ -1018,8 +1020,6 @@ struct super_block* pvfs2_get_sb(
  726.  
  727.  #else /* !PVFS2_LINUX_KERNEL_2_4 */
  728.  
  729. -static struct export_operations pvfs2_export_ops = {};
  730. -
  731.  int pvfs2_fill_sb(
  732.      struct super_block *sb,
  733.      void *data,
  734. @@ -1097,7 +1097,17 @@ int pvfs2_fill_sb(
  735.      }
  736.      root_dentry->d_op = &pvfs2_dentry_operations;
  737.  
  738. -    sb->s_export_op = &pvfs2_export_ops;
  739. +
  740. +    /* Set layout export operations for each layout type */
  741. +    switch (layouttype) {
  742. +        case LAYOUT_PVFS2:
  743. +        gossip_debug(GOSSIP_PNFS_DEBUG,"Setting pvfs2 layout export ops\n");
  744. +        sb->s_export_op = &pvfs2layout_export_ops;
  745. +        break;
  746. +        default:
  747. +        gossip_err("Invalid layouttype, no export ops to set! (%d)\n", layouttype);
  748. +    }
  749. +
  750.      sb->s_root = root_dentry;
  751.      return 0;
  752.  }
  753. _
  754.