All of lore.kernel.org
 help / color / mirror / Atom feed
From: Boaz Harrosh <bharrosh@panasas.com>
To: Benny Halevy <bhalevy@panasas.com>
Cc: Trond Myklebust <Trond.Myklebust@netapp.com>, linux-nfs@vger.kernel.org
Subject: [PATCH v9 16/18] pnfs-obj: objio_osd device information retrieval and caching
Date: Thu, 26 May 2011 22:07:15 +0300	[thread overview]
Message-ID: <4DDEA4E3.70002@panasas.com> (raw)
In-Reply-To: <1306358914-17403-1-git-send-email-bhalevy@panasas.com>


When a new layout is received in objio_alloc_lseg all device_ids
referenced are retrieved. The device information is queried for from MDS
and then the osd_device is looked-up from the osd-initiator library. The
devices are cached in a per-mount-point list, for later use. At unmount
all devices are "put" back to the library.

objlayout_get_deviceinfo(), objlayout_put_deviceinfo() middleware
API for retrieving device information given a device_id.

TODO: The device cache can get big. Cap its size. Keep an LRU and start
      to return devices which were not used, when list gets to big, or
      when new entries allocation fail.

[pnfs-obj: Bugs in new global-device-cache code]
Signed-off-by: Boaz Harrosh <bharrosh@panasas.com>
[gfp_flags]
[use global device cache]
[use layout driver in global device cache]
Signed-off-by: Benny Halevy <bhalevy@panasas.com>
---
 fs/nfs/objlayout/objio_osd.c |  157 ++++++++++++++++++++++++++++++++++++++++++
 fs/nfs/objlayout/objlayout.c |   68 ++++++++++++++++++
 fs/nfs/objlayout/objlayout.h |    8 ++
 3 files changed, 233 insertions(+), 0 deletions(-)

diff --git a/fs/nfs/objlayout/objio_osd.c b/fs/nfs/objlayout/objio_osd.c
index 08f1d90..2255e2d 100644
--- a/fs/nfs/objlayout/objio_osd.c
+++ b/fs/nfs/objlayout/objio_osd.c
@@ -46,6 +46,68 @@
 
 #define _LLU(x) ((unsigned long long)x)
 
+struct objio_dev_ent {
+	struct nfs4_deviceid_node id_node;
+	struct osd_dev *od;
+};
+
+static void
+objio_free_deviceid_node(struct nfs4_deviceid_node *d)
+{
+	struct objio_dev_ent *de = container_of(d, struct objio_dev_ent, id_node);
+
+	dprintk("%s: free od=%p\n", __func__, de->od);
+	osduld_put_device(de->od);
+	kfree(de);
+}
+
+static struct objio_dev_ent *_dev_list_find(const struct nfs_server *nfss,
+	const struct nfs4_deviceid *d_id)
+{
+	struct nfs4_deviceid_node *d;
+	struct objio_dev_ent *de;
+
+	d = nfs4_find_get_deviceid(nfss->pnfs_curr_ld, nfss->nfs_client, d_id);
+	if (!d)
+		return NULL;
+
+	de = container_of(d, struct objio_dev_ent, id_node);
+	return de;
+}
+
+static struct objio_dev_ent *
+_dev_list_add(const struct nfs_server *nfss,
+	const struct nfs4_deviceid *d_id, struct osd_dev *od,
+	gfp_t gfp_flags)
+{
+	struct nfs4_deviceid_node *d;
+	struct objio_dev_ent *de = kzalloc(sizeof(*de), gfp_flags);
+	struct objio_dev_ent *n;
+
+	if (!de) {
+		dprintk("%s: -ENOMEM od=%p\n", __func__, od);
+		return NULL;
+	}
+
+	dprintk("%s: Adding od=%p\n", __func__, od);
+	nfs4_init_deviceid_node(&de->id_node,
+				nfss->pnfs_curr_ld,
+				nfss->nfs_client,
+				d_id);
+	de->od = od;
+
+	d = nfs4_insert_deviceid_node(&de->id_node);
+	n = container_of(d, struct objio_dev_ent, id_node);
+	if (n != de) {
+		dprintk("%s: Race with other n->od=%p\n", __func__, n->od);
+		objio_free_deviceid_node(&de->id_node);
+		de = n;
+	}
+
+	atomic_inc(&de->id_node.ref);
+	return de;
+}
+
 struct caps_buffers {
 	u8 caps_key[OSD_CRYPTO_KEYID_SIZE];
 	u8 creds[OSD_CAP_LEN];
@@ -74,6 +136,90 @@ OBJIO_LSEG(struct pnfs_layout_segment *lseg)
 	return container_of(lseg, struct objio_segment, lseg);
 }
 
+/* Send and wait for a get_device_info of devices in the layout,
+   then look them up with the osd_initiator library */
+static struct objio_dev_ent *_device_lookup(struct pnfs_layout_hdr *pnfslay,
+				struct objio_segment *objio_seg, unsigned comp,
+				gfp_t gfp_flags)
+{
+	struct pnfs_osd_deviceaddr *deviceaddr;
+	struct nfs4_deviceid *d_id;
+	struct objio_dev_ent *ode;
+	struct osd_dev *od;
+	struct osd_dev_info odi;
+	int err;
+
+	d_id = &objio_seg->comps[comp].oc_object_id.oid_device_id;
+
+	ode = _dev_list_find(NFS_SERVER(pnfslay->plh_inode), d_id);
+	if (ode)
+		return ode;
+
+	err = objlayout_get_deviceinfo(pnfslay, d_id, &deviceaddr, gfp_flags);
+	if (unlikely(err)) {
+		dprintk("%s: objlayout_get_deviceinfo dev(%llx:%llx) =>%d\n",
+			__func__, _DEVID_LO(d_id), _DEVID_HI(d_id), err);
+		return ERR_PTR(err);
+	}
+
+	odi.systemid_len = deviceaddr->oda_systemid.len;
+	if (odi.systemid_len > sizeof(odi.systemid)) {
+		err = -EINVAL;
+		goto out;
+	} else if (odi.systemid_len)
+		memcpy(odi.systemid, deviceaddr->oda_systemid.data,
+		       odi.systemid_len);
+	odi.osdname_len	 = deviceaddr->oda_osdname.len;
+	odi.osdname	 = (u8 *)deviceaddr->oda_osdname.data;
+
+	if (!odi.osdname_len && !odi.systemid_len) {
+		dprintk("%s: !odi.osdname_len && !odi.systemid_len\n",
+			__func__);
+		err = -ENODEV;
+		goto out;
+	}
+
+	od = osduld_info_lookup(&odi);
+	if (unlikely(IS_ERR(od))) {
+		err = PTR_ERR(od);
+		dprintk("%s: osduld_info_lookup => %d\n", __func__, err);
+		goto out;
+	}
+
+	ode = _dev_list_add(NFS_SERVER(pnfslay->plh_inode), d_id, od,
+			    gfp_flags);
+
+out:
+	dprintk("%s: return=%d\n", __func__, err);
+	objlayout_put_deviceinfo(deviceaddr);
+	return err ? ERR_PTR(err) : ode;
+}
+
+static int objio_devices_lookup(struct pnfs_layout_hdr *pnfslay,
+	struct objio_segment *objio_seg,
+	gfp_t gfp_flags)
+{
+	unsigned i;
+	int err;
+
+	/* lookup all devices */
+	for (i = 0; i < objio_seg->num_comps; i++) {
+		struct objio_dev_ent *ode;
+
+		ode = _device_lookup(pnfslay, objio_seg, i, gfp_flags);
+		if (unlikely(IS_ERR(ode))) {
+			err = PTR_ERR(ode);
+			goto out;
+		}
+		objio_seg->ods[i] = ode;
+	}
+	err = 0;
+
+out:
+	dprintk("%s: return=%d\n", __func__, err);
+	return err;
+}
+
 static int _verify_data_map(struct pnfs_osd_layout *layout)
 {
 	struct pnfs_osd_data_map *data_map = &layout->olo_map;
@@ -171,6 +317,9 @@ int objio_alloc_lseg(struct pnfs_layout_segment **outp,
 
 	objio_seg->num_comps = layout.olo_num_comps;
 	objio_seg->comps_index = layout.olo_comps_index;
+	err = objio_devices_lookup(pnfslay, objio_seg, gfp_flags);
+	if (err)
+		goto err;
 
 	objio_seg->mirrors_p1 = layout.olo_map.odm_mirror_cnt + 1;
 	objio_seg->stripe_unit = layout.olo_map.odm_stripe_unit;
@@ -199,8 +348,14 @@ err:
 
 void objio_free_lseg(struct pnfs_layout_segment *lseg)
 {
+	int i;
 	struct objio_segment *objio_seg = OBJIO_LSEG(lseg);
 
+	for (i = 0; i < objio_seg->num_comps; i++) {
+		if (!objio_seg->ods[i])
+			break;
+		nfs4_put_deviceid_node(&objio_seg->ods[i]->id_node);
+	}
 	kfree(objio_seg);
 }
 
@@ -211,6 +366,8 @@ static struct pnfs_layoutdriver_type objlayout_type = {
 
 	.alloc_lseg              = objlayout_alloc_lseg,
 	.free_lseg               = objlayout_free_lseg,
+
+	.free_deviceid_node	 = objio_free_deviceid_node,
 };
 
 MODULE_DESCRIPTION("pNFS Layout Driver for OSD2 objects");
diff --git a/fs/nfs/objlayout/objlayout.c b/fs/nfs/objlayout/objlayout.c
index 9465267..10e5fca 100644
--- a/fs/nfs/objlayout/objlayout.c
+++ b/fs/nfs/objlayout/objlayout.c
@@ -102,3 +102,71 @@ objlayout_free_lseg(struct pnfs_layout_segment *lseg)
 	objio_free_lseg(lseg);
 }
 
+/*
+ * Get Device Info API for io engines
+ */
+struct objlayout_deviceinfo {
+	struct page *page;
+	struct pnfs_osd_deviceaddr da; /* This must be last */
+};
+
+/* Initialize and call nfs_getdeviceinfo, then decode and return a
+ * "struct pnfs_osd_deviceaddr *" Eventually objlayout_put_deviceinfo()
+ * should be called.
+ */
+int objlayout_get_deviceinfo(struct pnfs_layout_hdr *pnfslay,
+	struct nfs4_deviceid *d_id, struct pnfs_osd_deviceaddr **deviceaddr,
+	gfp_t gfp_flags)
+{
+	struct objlayout_deviceinfo *odi;
+	struct pnfs_device pd;
+	struct super_block *sb;
+	struct page *page, **pages;
+	u32 *p;
+	int err;
+
+	page = alloc_page(gfp_flags);
+	if (!page)
+		return -ENOMEM;
+
+	pages = &page;
+	pd.pages = pages;
+
+	memcpy(&pd.dev_id, d_id, sizeof(*d_id));
+	pd.layout_type = LAYOUT_OSD2_OBJECTS;
+	pd.pages = &page;
+	pd.pgbase = 0;
+	pd.pglen = PAGE_SIZE;
+	pd.mincount = 0;
+
+	sb = pnfslay->plh_inode->i_sb;
+	err = nfs4_proc_getdeviceinfo(NFS_SERVER(pnfslay->plh_inode), &pd);
+	dprintk("%s nfs_getdeviceinfo returned %d\n", __func__, err);
+	if (err)
+		goto err_out;
+
+	p = page_address(page);
+	odi = kzalloc(sizeof(*odi), gfp_flags);
+	if (!odi) {
+		err = -ENOMEM;
+		goto err_out;
+	}
+	pnfs_osd_xdr_decode_deviceaddr(&odi->da, p);
+	odi->page = page;
+	*deviceaddr = &odi->da;
+	return 0;
+
+err_out:
+	__free_page(page);
+	return err;
+}
+
+void objlayout_put_deviceinfo(struct pnfs_osd_deviceaddr *deviceaddr)
+{
+	struct objlayout_deviceinfo *odi = container_of(deviceaddr,
+						struct objlayout_deviceinfo,
+						da);
+
+	__free_page(odi->page);
+	kfree(odi);
+}
diff --git a/fs/nfs/objlayout/objlayout.h b/fs/nfs/objlayout/objlayout.h
index 066280a..0814271 100644
--- a/fs/nfs/objlayout/objlayout.h
+++ b/fs/nfs/objlayout/objlayout.h
@@ -56,6 +56,14 @@ extern int objio_alloc_lseg(struct pnfs_layout_segment **outp,
 extern void objio_free_lseg(struct pnfs_layout_segment *lseg);
 
 /*
+ * callback API
+ */
+extern int objlayout_get_deviceinfo(struct pnfs_layout_hdr *pnfslay,
+	struct nfs4_deviceid *d_id, struct pnfs_osd_deviceaddr **deviceaddr,
+	gfp_t gfp_flags);
+extern void objlayout_put_deviceinfo(struct pnfs_osd_deviceaddr *deviceaddr);
+
+/*
  * exported generic objects function vectors
  */
 extern struct pnfs_layout_segment *objlayout_alloc_lseg(
-- 
1.7.2.3



  parent reply	other threads:[~2011-05-26 19:07 UTC|newest]

Thread overview: 58+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-05-25 21:24 [PATCHSET v8 0/32] pnfs for 2.6.40 Benny Halevy
2011-05-25 21:26 ` [PATCH v8 01/32] NFSv4.1: fix typo in filelayout_check_layout Benny Halevy
2011-05-25 21:26 ` [PATCH v8 02/32] NFSv4.1: use struct nfs_client to qualify deviceid Benny Halevy
2011-05-25 21:26 ` [PATCH v8 03/32] pnfs: resolve header dependency in pnfs.h Benny Halevy
2011-05-25 21:26 ` [PATCH v8 04/32] NFSv4.1: make deviceid cache global Benny Halevy
2011-05-25 21:27 ` [PATCH v8 05/32] NFSv4.1: purge deviceid cache on nfs_free_client Benny Halevy
2011-05-29  8:06   ` [PATCH] SQUASHME: into NFSv4.1: purge deviceid cache - let ver < 4.1 compile Boaz Harrosh
2011-05-25 21:27 ` [PATCH v8 06/32] pnfs: CB_NOTIFY_DEVICEID Benny Halevy
2011-05-25 21:27 ` [PATCH v8 07/32] NFSv4.1: use layout driver in global device cache Benny Halevy
2011-05-25 21:27 ` [PATCH v8 08/32] SUNRPC: introduce xdr_init_decode_pages Benny Halevy
2011-05-25 21:27 ` [PATCH v8 09/32] pnfs: Use byte-range for layoutget Benny Halevy
2011-05-25 21:27 ` [PATCH v8 10/32] pnfs: align layoutget requests on page boundaries Benny Halevy
2011-05-25 21:27 ` [PATCH v8 11/32] pnfs: Use byte-range for cb_layoutrecall Benny Halevy
2011-05-25 21:27 ` [PATCH v8 12/32] pnfs: client stats Benny Halevy
2011-05-25 21:28 ` [PATCH v8 13/32] pnfs-obj: objlayoutdriver module skeleton Benny Halevy
2011-05-25 21:28 ` [PATCH v8 14/32] pnfs-obj: pnfs_osd XDR definitions Benny Halevy
2011-05-25 21:28 ` [PATCH v8 15/32] pnfs-obj: pnfs_osd XDR client implementation Benny Halevy
2011-05-25 21:28 ` [PATCH v8 16/32] pnfs-obj: decode layout, alloc/free lseg Benny Halevy
2011-05-26 19:05   ` [PATCH] SQUASHME V2: objio alloc/free lseg Bugs fixes Boaz Harrosh
2011-05-25 21:28 ` [PATCH v8 17/32] pnfs-obj: objio_osd device information retrieval and caching Benny Halevy
2011-05-26 14:04   ` Boaz Harrosh
2011-05-26 16:09     ` Benny Halevy
2011-05-26 19:07   ` Boaz Harrosh [this message]
2011-05-26 19:09     ` [PATCH v9 16/18] " Boaz Harrosh
2011-05-29 18:14     ` Benny Halevy
2011-05-25 21:28 ` [PATCH v8 18/32] pnfs: alloc and free layout_hdr layoutdriver methods Benny Halevy
2011-05-25 21:28 ` [PATCH v8 19/32] pnfs-obj: define per-inode private structure Benny Halevy
2011-05-25 21:28 ` [PATCH v8 20/32] pnfs: support for non-rpc layout drivers Benny Halevy
2011-05-25 21:29 ` [PATCH v8 21/32] pnfs-obj: osd raid engine read/write implementation Benny Halevy
2011-05-26 19:12   ` [PATCH resend3] SQUASHME: objio read/write patch: Bugs fixes Boaz Harrosh
2011-05-25 21:29 ` [PATCH v8 22/32] pnfs: layoutreturn Benny Halevy
2011-05-27 14:25   ` Boaz Harrosh
2011-05-25 21:29 ` [PATCH v8 23/32] pnfs: layoutret_on_setattr Benny Halevy
2011-05-25 21:29 ` [PATCH v8 24/32] pnfs: encode_layoutreturn Benny Halevy
2011-05-25 21:29 ` [PATCH v8 25/32] pnfs-obj: report errors and .encode_layoutreturn Implementation Benny Halevy
2011-05-26 19:14   ` Boaz Harrosh
2011-05-26 19:15   ` [PATCH v9 " Boaz Harrosh
2011-05-25 21:29 ` [PATCH v8 26/32] pnfs: encode_layoutcommit Benny Halevy
2011-05-25 21:29 ` [PATCH v8 27/32] pnfs-obj: objlayout_encode_layoutcommit implementation Benny Halevy
2011-05-25 21:29 ` [PATCH v8 28/32] NFSv4.1: unify pnfs_pageio_init functions Benny Halevy
2011-05-27 15:28   ` Boaz Harrosh
2011-05-27 15:37   ` [PATCH] SQUASHME: Fix BUG in: " Boaz Harrosh
2011-05-29  8:09     ` Boaz Harrosh
2011-05-29  8:10   ` [PATCH v2] " Boaz Harrosh
2011-05-25 21:30 ` [PATCH v8 29/32] NFSv4.1: change pg_test return type to bool Benny Halevy
2011-05-25 21:30 ` [PATCH v8 30/32] NFSv4.1: use pnfs_generic_pg_test directly by layout driver Benny Halevy
2011-05-25 21:30 ` [PATCH v8 31/32] NFSv4.1: define nfs_generic_pg_test Benny Halevy
2011-05-26 14:18   ` Boaz Harrosh
2011-05-26 18:20     ` Benny Halevy
2011-05-26 19:03       ` Boaz Harrosh
2011-05-26 19:17   ` Subject: [PATCH] SQUASHME: Move a check from nfs_pageio_do_add_request to nfs_generic_pg_test Boaz Harrosh
2011-05-26 19:58     ` Boaz Harrosh
2011-05-26 20:11       ` Trond Myklebust
2011-05-27  7:22         ` Boaz Harrosh
2011-05-25 21:30 ` [PATCH v8 32/32] pnfs-obj: pg_test check for max_io_size Benny Halevy
2011-05-26 14:57 ` [PATCHSET v8 0/32] pnfs for 2.6.40 Boaz Harrosh
2011-05-26 16:14   ` Benny Halevy
2011-05-29  8:56 ` Boaz Harrosh

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=4DDEA4E3.70002@panasas.com \
    --to=bharrosh@panasas.com \
    --cc=Trond.Myklebust@netapp.com \
    --cc=bhalevy@panasas.com \
    --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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.