aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/objlayout/objlayout.c
diff options
context:
space:
mode:
authorBoaz Harrosh <bharrosh@panasas.com>2011-05-26 14:45:34 -0400
committerBoaz Harrosh <bharrosh@panasas.com>2011-05-29 13:53:33 -0400
commitb6c05f1693115164c7b797152ac7ea3ef8e5d296 (patch)
tree24430851c2569f4db76b13f41e82514326fbb878 /fs/nfs/objlayout/objlayout.c
parent09f5bf4e6d0607399c16ec7a2d8d166f31086686 (diff)
pnfs-obj: objio_osd device information retrieval and caching
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>
Diffstat (limited to 'fs/nfs/objlayout/objlayout.c')
-rw-r--r--fs/nfs/objlayout/objlayout.c68
1 files changed, 68 insertions, 0 deletions
diff --git a/fs/nfs/objlayout/objlayout.c b/fs/nfs/objlayout/objlayout.c
index 946526763d38..10e5fca3b7fb 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)
102 objio_free_lseg(lseg); 102 objio_free_lseg(lseg);
103} 103}
104 104
105/*
106 * Get Device Info API for io engines
107 */
108struct objlayout_deviceinfo {
109 struct page *page;
110 struct pnfs_osd_deviceaddr da; /* This must be last */
111};
112
113/* Initialize and call nfs_getdeviceinfo, then decode and return a
114 * "struct pnfs_osd_deviceaddr *" Eventually objlayout_put_deviceinfo()
115 * should be called.
116 */
117int objlayout_get_deviceinfo(struct pnfs_layout_hdr *pnfslay,
118 struct nfs4_deviceid *d_id, struct pnfs_osd_deviceaddr **deviceaddr,
119 gfp_t gfp_flags)
120{
121 struct objlayout_deviceinfo *odi;
122 struct pnfs_device pd;
123 struct super_block *sb;
124 struct page *page, **pages;
125 u32 *p;
126 int err;
127
128 page = alloc_page(gfp_flags);
129 if (!page)
130 return -ENOMEM;
131
132 pages = &page;
133 pd.pages = pages;
134
135 memcpy(&pd.dev_id, d_id, sizeof(*d_id));
136 pd.layout_type = LAYOUT_OSD2_OBJECTS;
137 pd.pages = &page;
138 pd.pgbase = 0;
139 pd.pglen = PAGE_SIZE;
140 pd.mincount = 0;
141
142 sb = pnfslay->plh_inode->i_sb;
143 err = nfs4_proc_getdeviceinfo(NFS_SERVER(pnfslay->plh_inode), &pd);
144 dprintk("%s nfs_getdeviceinfo returned %d\n", __func__, err);
145 if (err)
146 goto err_out;
147
148 p = page_address(page);
149 odi = kzalloc(sizeof(*odi), gfp_flags);
150 if (!odi) {
151 err = -ENOMEM;
152 goto err_out;
153 }
154 pnfs_osd_xdr_decode_deviceaddr(&odi->da, p);
155 odi->page = page;
156 *deviceaddr = &odi->da;
157 return 0;
158
159err_out:
160 __free_page(page);
161 return err;
162}
163
164void objlayout_put_deviceinfo(struct pnfs_osd_deviceaddr *deviceaddr)
165{
166 struct objlayout_deviceinfo *odi = container_of(deviceaddr,
167 struct objlayout_deviceinfo,
168 da);
169
170 __free_page(odi->page);
171 kfree(odi);
172}