From: Jim Rees <rees@umich.edu>
To: Benny Halevy <bhalevy@panasas.com>
Cc: linux-nfs@vger.kernel.org, peter honeyman <honey@citi.umich.edu>
Subject: [PATCH 18/88] pnfsblock: construct and load md table
Date: Tue, 7 Jun 2011 13:27:56 -0400 [thread overview]
Message-ID: <b79d3be4930b16115d20c69e22a19ff0b6e225b5.1307464382.git.rees@umich.edu> (raw)
In-Reply-To: <cover.1307464381.git.rees@umich.edu>
From: Fred Isaman <iisaman@citi.umich.edu>
Uses preparsed information gathered from GETDEVICEINFO to
create a dm device table that represents the given volume
topology.
Signed-off-by: Fred Isaman <iisaman@citi.umich.edu>
Signed-off-by: Benny Halevy <bhalevy@panasas.com>
---
fs/nfs/blocklayout/blocklayout.h | 3 +-
fs/nfs/blocklayout/blocklayoutdm.c | 191 +++++++++++++++++++++++++++++++++++-
2 files changed, 191 insertions(+), 3 deletions(-)
diff --git a/fs/nfs/blocklayout/blocklayout.h b/fs/nfs/blocklayout/blocklayout.h
index b705906..d695f8e 100644
--- a/fs/nfs/blocklayout/blocklayout.h
+++ b/fs/nfs/blocklayout/blocklayout.h
@@ -40,7 +40,8 @@
extern struct class shost_class; /* exported from drivers/scsi/hosts.c */
extern int dm_dev_create(struct dm_ioctl *param); /* from dm-ioctl.c */
extern int dm_dev_remove(struct dm_ioctl *param); /* from dm-ioctl.c */
-
+extern int dm_do_resume(struct dm_ioctl *param);
+extern int dm_table_load(struct dm_ioctl *param, size_t param_size);
struct block_mount_id {
struct super_block *bm_sb; /* back pointer */
diff --git a/fs/nfs/blocklayout/blocklayoutdm.c b/fs/nfs/blocklayout/blocklayoutdm.c
index 0e04494..4bff748 100644
--- a/fs/nfs/blocklayout/blocklayoutdm.c
+++ b/fs/nfs/blocklayout/blocklayoutdm.c
@@ -36,6 +36,31 @@
#define NFSDBG_FACILITY NFSDBG_PNFS_LD
+/* Defines used for calculating memory usage in nfs4_blk_flatten() */
+#define ARGSIZE 24 /* Max bytes needed for linear target arg string */
+#define SPECSIZE (sizeof8(struct dm_target_spec) + ARGSIZE)
+#define SPECS_PER_PAGE (PAGE_SIZE / SPECSIZE)
+#define SPEC_HEADER_ADJUST (SPECS_PER_PAGE - \
+ (PAGE_SIZE - sizeof8(struct dm_ioctl)) / SPECSIZE)
+#define roundup8(x) (((x)+7) & ~7)
+#define sizeof8(x) roundup8(sizeof(x))
+
+/* Given x>=1, return smallest n such that 2**n >= x */
+static unsigned long find_order(int x)
+{
+ unsigned long rv = 0;
+ for (x--; x; x >>= 1)
+ rv++;
+ return rv;
+}
+
+/* Debugging aid */
+static void print_extent(u64 meta_offset, dev_t disk,
+ u64 disk_offset, u64 length)
+{
+ dprintk("%lli:, %d:%d %lli, %lli\n", meta_offset, MAJOR(disk),
+ MINOR(disk), disk_offset, length);
+}
static int dev_create(const char *name, dev_t *dev)
{
struct dm_ioctl ctrl;
@@ -60,6 +85,14 @@ static int dev_remove(const char *name)
return dm_dev_remove(&ctrl);
}
+static int dev_resume(const char *name)
+{
+ struct dm_ioctl ctrl;
+ memset(&ctrl, 0, sizeof(ctrl));
+ strncpy(ctrl.name, name, DM_NAME_LEN-1);
+ return dm_do_resume(&ctrl);
+}
+
/*
* Release meta device
*/
@@ -141,10 +174,164 @@ struct pnfs_block_dev *nfs4_blk_init_metadev(struct super_block *sb,
return NULL;
}
-/* Stub */
+/*
+ * Given a vol_offset into root, returns the disk and disk_offset it
+ * corresponds to, as well as the length of the contiguous segment thereafter.
+ * All offsets/lengths are in 512-byte sectors.
+ */
+static int nfs4_blk_resolve(int root, struct pnfs_blk_volume *vols,
+ u64 vol_offset, dev_t *disk, u64 *disk_offset,
+ u64 *length)
+{
+ struct pnfs_blk_volume *node;
+ u64 node_offset;
+
+ /* Walk down device tree until we hit a leaf node (VOLUME_SIMPLE) */
+ node = &vols[root];
+ node_offset = vol_offset;
+ *length = node->bv_size;
+ while (1) {
+ dprintk("offset=%lli, length=%lli\n",
+ node_offset, *length);
+ if (node_offset > node->bv_size)
+ return -EIO;
+ switch (node->bv_type) {
+ case PNFS_BLOCK_VOLUME_SIMPLE:
+ *disk = node->bv_dev;
+ dprintk("%s VOLUME_SIMPLE: node->bv_dev %d:%d\n",
+ __func__,
+ MAJOR(node->bv_dev),
+ MINOR(node->bv_dev));
+ *disk_offset = node_offset;
+ *length = min(*length, node->bv_size - node_offset);
+ return 0;
+ case PNFS_BLOCK_VOLUME_SLICE:
+ dprintk("%s VOLUME_SLICE:\n", __func__);
+ *length = min(*length, node->bv_size - node_offset);
+ node_offset += node->bv_offset;
+ node = node->bv_vols[0];
+ break;
+ case PNFS_BLOCK_VOLUME_CONCAT: {
+ u64 next = 0, sum = 0;
+ int i;
+ dprintk("%s VOLUME_CONCAT:\n", __func__);
+ for (i = 0; i < node->bv_vol_n; i++) {
+ next = sum + node->bv_vols[i]->bv_size;
+ if (node_offset < next)
+ break;
+ sum = next;
+ }
+ *length = min(*length, next - node_offset);
+ node_offset -= sum;
+ node = node->bv_vols[i];
+ }
+ break;
+ case PNFS_BLOCK_VOLUME_STRIPE: {
+ u64 global_s_no;
+ u64 stripe_pos;
+ u64 local_s_no;
+ u64 disk_number;
+
+ dprintk("%s VOLUME_STRIPE:\n", __func__);
+ global_s_no = node_offset;
+ /* BUG - note this assumes stripe_unit <= 2**32 */
+ stripe_pos = (u64) do_div(global_s_no,
+ (u32)node->bv_stripe_unit);
+ local_s_no = global_s_no;
+ disk_number = (u64) do_div(local_s_no,
+ (u32) node->bv_vol_n);
+ *length = min(*length,
+ node->bv_stripe_unit - stripe_pos);
+ node_offset = local_s_no * node->bv_stripe_unit +
+ stripe_pos;
+ node = node->bv_vols[disk_number];
+ }
+ break;
+ default:
+ return -EIO;
+ }
+ }
+}
+
+/*
+ * Create an LVM dm device table that represents the volume topology returned
+ * by GETDEVICELIST or GETDEVICEINFO.
+ *
+ * vols: topology with VOLUME_SIMPLEs mapped to visable scsi disks.
+ * size: number of volumes in vols.
+ */
int nfs4_blk_flatten(struct pnfs_blk_volume *vols, int size,
struct pnfs_block_dev *bdev)
{
- return 0;
+ u64 meta_offset = 0;
+ u64 meta_size = vols[size-1].bv_size;
+ dev_t disk;
+ u64 disk_offset, len;
+ int status = 0, count = 0, pages_needed;
+ struct dm_ioctl *ctl;
+ struct dm_target_spec *spec;
+ char *args = NULL;
+ unsigned long p;
+
+ dprintk("%s enter. mdevname %s number of volumes %d\n", __func__,
+ bdev->bm_mdevname, size);
+
+ /* We need to reserve memory to store segments, so need to count
+ * segments. This means we resolve twice, basically throwing away
+ * all info from first run apart from the count. Seems like
+ * there should be a better way.
+ */
+ for (meta_offset = 0; meta_offset < meta_size; meta_offset += len) {
+ status = nfs4_blk_resolve(size-1, vols, meta_offset, &disk,
+ &disk_offset, &len);
+ /* TODO Check status */
+ count += 1;
+ }
+
+ dprintk("%s: Have %i segments\n", __func__, count);
+ pages_needed = ((count + SPEC_HEADER_ADJUST) / SPECS_PER_PAGE) + 1;
+ dprintk("%s: Need %i pages\n", __func__, pages_needed);
+ p = __get_free_pages(GFP_KERNEL, find_order(pages_needed));
+ if (!p)
+ return -ENOMEM;
+ /* A dm_ioctl is placed at the beginning, followed by a series of
+ * (dm_target_spec, argument string) pairs.
+ */
+ ctl = (struct dm_ioctl *) p;
+ spec = (struct dm_target_spec *) (p + sizeof8(*ctl));
+ memset(ctl, 0, sizeof(*ctl));
+ ctl->data_start = (char *) spec - (char *) ctl;
+ ctl->target_count = count;
+ strncpy(ctl->name, bdev->bm_mdevname, DM_NAME_LEN);
+
+ dprintk("%s ctl->name %s\n", __func__, ctl->name);
+ for (meta_offset = 0; meta_offset < meta_size; meta_offset += len) {
+ status = nfs4_blk_resolve(size-1, vols, meta_offset, &disk,
+ &disk_offset, &len);
+ if (!len)
+ break;
+ /* TODO Check status */
+ print_extent(meta_offset, disk, disk_offset, len);
+ spec->sector_start = meta_offset;
+ spec->length = len;
+ spec->status = 0;
+ strcpy(spec->target_type, "linear");
+ args = (char *) (spec + 1);
+ sprintf(args, "%i:%i %lli",
+ MAJOR(disk), MINOR(disk), disk_offset);
+ dprintk("%s args %s\n", __func__, args);
+ spec->next = roundup8(sizeof(*spec) + strlen(args) + 1);
+ spec = (struct dm_target_spec *) (((char *) spec) + spec->next);
+ }
+ ctl->data_size = (char *) spec - (char *) ctl;
+
+ status = dm_table_load(ctl, ctl->data_size);
+ dprintk("%s dm_table_load returns %d\n", __func__, status);
+
+ dev_resume(bdev->bm_mdevname);
+
+ free_pages(p, find_order(pages_needed));
+ dprintk("%s returns %d\n", __func__, status);
+ return status;
}
--
1.7.4.1
next prev parent reply other threads:[~2011-06-07 17:27 UTC|newest]
Thread overview: 136+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-06-07 17:24 [PATCH 00/88] pnfs block layout driver rees
2011-06-07 17:26 ` [PATCH 01/88] pnfs: add set-clear layoutdriver interface Jim Rees
2011-06-07 17:26 ` [PATCH 02/88] pnfs: let layoutcommit code handle multiple segments Jim Rees
2011-06-07 17:26 ` [PATCH 03/88] pnfs_post_submit: Restore "pnfs: pnfs_do_flush" part 1 Jim Rees
2011-06-07 17:26 ` [PATCH 04/88] pnfs_post_submit: Restore the pnfs_write_end part of "pnfs: commit and pnfs_write_end" Jim Rees
2011-06-07 17:26 ` [PATCH 05/88] pnfs: xdr support for three word attribute bitmap Jim Rees
2011-06-07 17:26 ` [PATCH 06/88] pnfs: HACK: ask for layout_blksize on mount Jim Rees
2011-06-07 17:26 ` [PATCH 07/88] pnfs: HACK: modify write_end_cleanup Jim Rees
2011-06-07 17:26 ` [PATCH 08/88] HACK: propagate fsdata into nfs_writepage_setup Jim Rees
2011-06-07 17:26 ` [PATCH 09/88] pnfs: HACK: adjust eof handling Jim Rees
2011-06-07 17:27 ` [PATCH 10/88] pnfsblock: define PNFS_BLOCK Kconfig option Jim Rees
2011-06-07 17:27 ` [PATCH 11/88] pnfsblock: blocklayout stub Jim Rees
2011-06-07 17:27 ` [PATCH 12/88] pnfsblock: expose scsi interface Jim Rees
2011-06-07 17:27 ` [PATCH 13/88] pnfsblock: scan scsi devices Jim Rees
2011-06-07 17:27 ` [PATCH 14/88] pnfsblock: call and parse getdevicelist Jim Rees
2011-06-07 17:27 ` [PATCH 15/88] pnfsblock: dm kernel interface Jim Rees
2011-06-07 17:27 ` [PATCH 16/88] pnfsblock: select BLK_DEV_DM when PNFS_BLOCK is configured Jim Rees
2011-06-07 17:27 ` [PATCH 17/88] pnfsblock: create and destroy dm metadevice Jim Rees
2011-06-07 17:27 ` Jim Rees [this message]
2011-06-07 17:28 ` [PATCH 19/88] pnfsblock: layout alloc and free Jim Rees
2011-06-07 17:28 ` [PATCH 20/88] pnfsblock: basic extent code Jim Rees
2011-06-07 17:28 ` [PATCH 21/88] pnfsblock: lseg alloc and free Jim Rees
2011-06-07 17:28 ` [PATCH 22/88] pnfsblock: xdr decode pnfs_block_layout4 Jim Rees
2011-06-07 17:28 ` [PATCH 23/88] pnfsblock: merge extents Jim Rees
2011-06-07 17:28 ` [PATCH 24/88] pnfsblock: find_get_extent Jim Rees
2011-06-07 17:28 ` [PATCH 25/88] pnfsblock: bl_read_pagelist Jim Rees
2011-06-07 17:28 ` [PATCH 26/88] pnfsblock: allow use of PG_owner_priv_1 flag Jim Rees
2011-06-07 17:29 ` [PATCH 27/88] pnfsblock: read path error handling Jim Rees
2011-06-07 17:29 ` [PATCH 28/88] pnfsblock: SPLITME: add extent manipulation functions Jim Rees
2011-06-07 17:29 ` [PATCH 29/88] pnfsblock: write_begin Jim Rees
2011-06-07 17:29 ` [PATCH 30/88] pnfsblock: write_end Jim Rees
2011-06-07 17:29 ` [PATCH 31/88] pnfsblock: write_end_cleanup Jim Rees
2011-06-07 17:29 ` [PATCH 32/88] pnfsblock: bl_write_pagelist support functions Jim Rees
2011-06-07 17:29 ` [PATCH 33/88] pnfsblock: bl_write_pagelist Jim Rees
2011-06-07 17:29 ` [PATCH 34/88] pnfsblock: note written INVAL areas for layoutcommit Jim Rees
2011-06-07 17:30 ` [PATCH 35/88] pnfsblock: bl_setup_layoutcommit Jim Rees
2011-06-07 17:30 ` [PATCH 36/88] pnfsblock: encode_layoutcommit Jim Rees
2011-06-07 17:30 ` [PATCH 37/88] pnfsblock: cleanup_layoutcommit Jim Rees
2011-06-07 17:30 ` [PATCH 38/88] pnfsblock: merge rw extents Jim Rees
2011-06-07 17:30 ` [PATCH 39/88] pnfsblock: debugging dprintks for clist info Jim Rees
2011-06-07 17:30 ` [PATCH 40/88] SQAUSHME: blocklayoutdriver: NULL pointer reference when committing too many extents Jim Rees
2011-06-07 17:30 ` [PATCH 41/88] SQUASHME: pnfs-block: remove of CONFIG_PNFS fallout Jim Rees
2011-06-07 17:30 ` [PATCH 42/88] SQUASHME: pnfsblock: Fix a memory leak Jim Rees
2011-06-07 17:31 ` [PATCH 43/88] SQUASHME: pnfsblock: fix bug when decoding block device info Jim Rees
2011-06-07 17:31 ` [PATCH 44/88] SQUASHME: pnfsblock: Wrong extent refcount in block extents list Jim Rees
2011-06-07 17:31 ` [PATCH 45/88] SQUASHME: pnfsblock: Implement release_inval_marks Jim Rees
2011-06-07 17:31 ` [PATCH 46/88] SQUASHME: pnfsblock: Fix missing extent in commit list Jim Rees
2011-06-07 17:31 ` [PATCH 47/88] pnfsblock: use the session max response size for getdeviceinfo's maxcount Jim Rees
2011-06-07 17:31 ` [PATCH 48/88] SQUASHME: pnfs-block: fix compile breakage Jim Rees
2011-06-07 17:31 ` [PATCH 49/88] SQUASHME: pnfs-block: convert APIs pnfs-post-submit Jim Rees
2011-06-07 17:32 ` [PATCH 50/88] pnfsblock: Lookup list entry of layouts and tags in reverse order Jim Rees
2011-06-07 17:32 ` [PATCH 51/88] pnfsblock: expose block_class interface Jim Rees
2011-06-07 17:32 ` [PATCH 52/88] pnfsblock: iterating all local block disks instead of only scsi disks when initializing mount point Jim Rees
2011-06-07 17:32 ` [PATCH 53/88] SQUASHME: pnfsblock: set pnfs_blksize before calling set_pnfs_layoutdriver Jim Rees
2011-06-07 17:32 ` [PATCH 54/88] SQUASHME: pnfsblock: get rid of threshold policy ops Jim Rees
2011-06-07 17:32 ` [PATCH 55/88] SQUASHME: pnfsblock: write_begin adjust for removed fields Jim Rees
2011-06-07 17:32 ` [PATCH 56/88] SQUASHME: pnfsblock: write_end adjust for removed ok_to_use_pnfs Jim Rees
2011-06-07 17:32 ` [PATCH 57/88] SQUASHME: pnfsblock: write_end_cleanup " Jim Rees
2011-06-07 17:32 ` [PATCH 58/88] SQUASHME: pnfsblock: bl_write_pagelist support functions adjust for missing PG_USE_PNFS Jim Rees
2011-06-07 17:33 ` [PATCH 59/88] SQUASHME: pnfsblock: bl_write_pagelist " Jim Rees
2011-06-07 17:33 ` [PATCH 60/88] SQUASHME: pnfs-block: nfs4_blk_add_block_disk ret must be signed Jim Rees
2011-06-07 17:33 ` [PATCH 61/88] SQUASHME: pnfs-block: use new alloc/free_layout API Jim Rees
2011-06-07 17:33 ` [PATCH 62/88] SQUASHME: pnfs-block: use new commit api Jim Rees
2011-06-07 17:33 ` [PATCH 63/88] SQUASHME: pnfs-block: use new read_pagelist api Jim Rees
2011-06-07 17:33 ` [PATCH 64/88] SQUASHME: pnfs-block: use new write_pagelist api Jim Rees
2011-06-07 17:33 ` [PATCH 65/88] pnfs-block: Add support for simple rpc pipefs Jim Rees
2011-06-07 17:33 ` [PATCH 66/88] pnfs-block: Remove device creation from kernel Jim Rees
2011-06-07 17:33 ` [PATCH 67/88] SQUASHME: pnfs-block: apply types rename Jim Rees
2011-06-07 17:34 ` [PATCH 68/88] SQUASHME: pnfs-block: Revert "pnfsblock: expose block_class interface" Jim Rees
2011-06-07 17:34 ` [PATCH 69/88] SQUASHME: pnfsblock: remove obsolete include file from blocklayout.h Jim Rees
2011-06-07 17:34 ` [PATCH 70/88] SQUASHME: pnfsblock: use nfs4_deviceid Jim Rees
2011-06-07 17:34 ` [PATCH 71/88] SQUASHME: pnfsblock: no callback ops Jim Rees
2011-06-07 17:34 ` [PATCH 72/88] SQAUSHME: pnfsblock: no PNFS_NFS_SERVER Jim Rees
2011-06-07 17:34 ` [PATCH 73/88] SQUASHME: pnfsblock: no dev_notify_types Jim Rees
2011-06-07 17:34 ` [PATCH 74/88] SQUASHME: pnfsblock: use new struct pnfs_layout_hdr Jim Rees
2011-06-07 17:34 ` [PATCH 75/88] SQUASHME: pnfsblock: compile error in blocklayout code Jim Rees
2011-06-07 17:34 ` [PATCH 76/88] SQUASHME: pnfs-block: deprecate get_stripesize Jim Rees
2011-06-07 17:35 ` [PATCH 77/88] move include lines out of include file Jim Rees
2011-06-07 17:35 ` [PATCH 78/88] SQUASHME: pnfs-block: use {set,clear}_layoutdriver Jim Rees
2011-06-07 17:35 ` [PATCH 79/88] SQUASHME: pnfs-block: Return failure from bl_initialize_mountpoint Jim Rees
2011-06-07 17:35 ` [PATCH 80/88] SQUASHME: pnfs-block: fixup setup_layoutcommit arguments Jim Rees
2011-06-07 17:35 ` [PATCH 81/88] SQUASHME: pnfs-block: fixup cleanup_layoutcommit arguments Jim Rees
2011-06-07 17:35 ` [PATCH 82/88] SQUASHME: pnfs-block: fixup encode_layoutcommit arguments Jim Rees
2011-06-07 17:35 ` [PATCH 83/88] SQUASHME: pnfs-block: fixup layoutcommit methods args Jim Rees
2011-06-07 17:35 ` [PATCH 84/88] pnfs-block: fix blocklayoutdev.c for new blkdev_get_by_dev() Jim Rees
2011-06-07 17:35 ` [PATCH 85/88] SQUASHME: pnfs-block: use pnfs_layout_hdr field prefix Jim Rees
2011-06-07 17:35 ` [PATCH 86/88] SQUASHME: pnfs: blocklayout: port block layout code Jim Rees
2011-06-08 1:27 ` Benny Halevy
2011-06-08 2:06 ` Benny Halevy
2011-06-08 7:38 ` Peng Tao
2011-06-07 17:36 ` [PATCH 87/88] Add configurable prefetch size for layoutget Jim Rees
2011-06-08 2:01 ` Benny Halevy
2011-06-08 2:18 ` Jim Rees
2011-06-08 7:15 ` Peng Tao
2011-06-09 6:06 ` Benny Halevy
2011-06-09 11:49 ` Jim Rees
2011-06-09 13:32 ` Benny Halevy
2011-06-09 13:58 ` Jim Rees
2011-06-09 15:07 ` Peng Tao
2011-06-09 21:22 ` Benny Halevy
2011-06-10 6:00 ` tao.peng
2011-06-10 12:33 ` Benny Halevy
2011-06-10 14:09 ` tao.peng
2011-06-10 19:23 ` Benny Halevy
2011-06-10 20:03 ` Fred Isaman
2011-06-10 21:15 ` Benny Halevy
2011-06-11 1:46 ` Peng Tao
2011-06-10 23:20 ` Boaz Harrosh
2011-06-11 2:19 ` Peng Tao
2011-06-12 14:40 ` Boaz Harrosh
2011-06-12 18:46 ` Peng Tao
2011-06-11 1:35 ` Peng Tao
2011-06-09 21:23 ` Benny Halevy
2011-06-10 5:36 ` tao.peng
2011-06-10 12:36 ` Benny Halevy
2011-06-10 14:17 ` tao.peng
2011-06-10 19:02 ` Benny Halevy
2011-06-09 15:01 ` Peng Tao
2011-06-09 14:54 ` Peng Tao
2011-06-09 21:30 ` Benny Halevy
2011-06-10 6:02 ` tao.peng
2011-06-10 12:47 ` Benny Halevy
2011-06-10 14:30 ` tao.peng
2011-06-10 19:07 ` Benny Halevy
2011-06-10 16:23 ` Boaz Harrosh
2011-06-10 16:44 ` Boaz Harrosh
2011-06-09 6:08 ` Benny Halevy
2011-06-07 17:36 ` [PATCH 88/88] NFS41: do not update isize if inode needs layoutcommit Jim Rees
2011-06-08 2:05 ` Benny Halevy
2011-06-08 7:06 ` Peng Tao
2011-06-08 7:29 ` Peng Tao
2011-06-09 21:52 ` [PATCH 00/88] pnfs block layout driver Boaz Harrosh
2011-06-09 22:15 ` Jim Rees
2011-06-10 2:16 ` Boaz Harrosh
2011-06-10 2:20 ` Boaz Harrosh
2011-06-10 4:04 ` Benny Halevy
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=b79d3be4930b16115d20c69e22a19ff0b6e225b5.1307464382.git.rees@umich.edu \
--to=rees@umich.edu \
--cc=bhalevy@panasas.com \
--cc=honey@citi.umich.edu \
--cc=linux-nfs@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).