aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
Diffstat (limited to 'fs')
-rw-r--r--fs/nfs/objlayout/objio_osd.c157
-rw-r--r--fs/nfs/objlayout/objlayout.c68
-rw-r--r--fs/nfs/objlayout/objlayout.h8
3 files changed, 233 insertions, 0 deletions
diff --git a/fs/nfs/objlayout/objio_osd.c b/fs/nfs/objlayout/objio_osd.c
index 08f1d90b4ce7..2255e2d22d05 100644
--- a/fs/nfs/objlayout/objio_osd.c
+++ b/fs/nfs/objlayout/objio_osd.c
@@ -46,6 +46,68 @@
46 46
47#define _LLU(x) ((unsigned long long)x) 47#define _LLU(x) ((unsigned long long)x)
48 48
49struct objio_dev_ent {
50 struct nfs4_deviceid_node id_node;
51 struct osd_dev *od;
52};
53
54static void
55objio_free_deviceid_node(struct nfs4_deviceid_node *d)
56{
57 struct objio_dev_ent *de = container_of(d, struct objio_dev_ent, id_node);
58
59 dprintk("%s: free od=%p\n", __func__, de->od);
60 osduld_put_device(de->od);
61 kfree(de);
62}
63
64static struct objio_dev_ent *_dev_list_find(const struct nfs_server *nfss,
65 const struct nfs4_deviceid *d_id)
66{
67 struct nfs4_deviceid_node *d;
68 struct objio_dev_ent *de;
69
70 d = nfs4_find_get_deviceid(nfss->pnfs_curr_ld, nfss->nfs_client, d_id);
71 if (!d)
72 return NULL;
73
74 de = container_of(d, struct objio_dev_ent, id_node);
75 return de;
76}
77
78static struct objio_dev_ent *
79_dev_list_add(const struct nfs_server *nfss,
80 const struct nfs4_deviceid *d_id, struct osd_dev *od,
81 gfp_t gfp_flags)
82{
83 struct nfs4_deviceid_node *d;
84 struct objio_dev_ent *de = kzalloc(sizeof(*de), gfp_flags);
85 struct objio_dev_ent *n;
86
87 if (!de) {
88 dprintk("%s: -ENOMEM od=%p\n", __func__, od);
89 return NULL;
90 }
91
92 dprintk("%s: Adding od=%p\n", __func__, od);
93 nfs4_init_deviceid_node(&de->id_node,
94 nfss->pnfs_curr_ld,
95 nfss->nfs_client,
96 d_id);
97 de->od = od;
98
99 d = nfs4_insert_deviceid_node(&de->id_node);
100 n = container_of(d, struct objio_dev_ent, id_node);
101 if (n != de) {
102 dprintk("%s: Race with other n->od=%p\n", __func__, n->od);
103 objio_free_deviceid_node(&de->id_node);
104 de = n;
105 }
106
107 atomic_inc(&de->id_node.ref);
108 return de;
109}
110
49struct caps_buffers { 111struct caps_buffers {
50 u8 caps_key[OSD_CRYPTO_KEYID_SIZE]; 112 u8 caps_key[OSD_CRYPTO_KEYID_SIZE];
51 u8 creds[OSD_CAP_LEN]; 113 u8 creds[OSD_CAP_LEN];
@@ -74,6 +136,90 @@ OBJIO_LSEG(struct pnfs_layout_segment *lseg)
74 return container_of(lseg, struct objio_segment, lseg); 136 return container_of(lseg, struct objio_segment, lseg);
75} 137}
76 138
139/* Send and wait for a get_device_info of devices in the layout,
140 then look them up with the osd_initiator library */
141static struct objio_dev_ent *_device_lookup(struct pnfs_layout_hdr *pnfslay,
142 struct objio_segment *objio_seg, unsigned comp,
143 gfp_t gfp_flags)
144{
145 struct pnfs_osd_deviceaddr *deviceaddr;
146 struct nfs4_deviceid *d_id;
147 struct objio_dev_ent *ode;
148 struct osd_dev *od;
149 struct osd_dev_info odi;
150 int err;
151
152 d_id = &objio_seg->comps[comp].oc_object_id.oid_device_id;
153
154 ode = _dev_list_find(NFS_SERVER(pnfslay->plh_inode), d_id);
155 if (ode)
156 return ode;
157
158 err = objlayout_get_deviceinfo(pnfslay, d_id, &deviceaddr, gfp_flags);
159 if (unlikely(err)) {
160 dprintk("%s: objlayout_get_deviceinfo dev(%llx:%llx) =>%d\n",
161 __func__, _DEVID_LO(d_id), _DEVID_HI(d_id), err);
162 return ERR_PTR(err);
163 }
164
165 odi.systemid_len = deviceaddr->oda_systemid.len;
166 if (odi.systemid_len > sizeof(odi.systemid)) {
167 err = -EINVAL;
168 goto out;
169 } else if (odi.systemid_len)
170 memcpy(odi.systemid, deviceaddr->oda_systemid.data,
171 odi.systemid_len);
172 odi.osdname_len = deviceaddr->oda_osdname.len;
173 odi.osdname = (u8 *)deviceaddr->oda_osdname.data;
174
175 if (!odi.osdname_len && !odi.systemid_len) {
176 dprintk("%s: !odi.osdname_len && !odi.systemid_len\n",
177 __func__);
178 err = -ENODEV;
179 goto out;
180 }
181
182 od = osduld_info_lookup(&odi);
183 if (unlikely(IS_ERR(od))) {
184 err = PTR_ERR(od);
185 dprintk("%s: osduld_info_lookup => %d\n", __func__, err);
186 goto out;
187 }
188
189 ode = _dev_list_add(NFS_SERVER(pnfslay->plh_inode), d_id, od,
190 gfp_flags);
191
192out:
193 dprintk("%s: return=%d\n", __func__, err);
194 objlayout_put_deviceinfo(deviceaddr);
195 return err ? ERR_PTR(err) : ode;
196}
197
198static int objio_devices_lookup(struct pnfs_layout_hdr *pnfslay,
199 struct objio_segment *objio_seg,
200 gfp_t gfp_flags)
201{
202 unsigned i;
203 int err;
204
205 /* lookup all devices */
206 for (i = 0; i < objio_seg->num_comps; i++) {
207 struct objio_dev_ent *ode;
208
209 ode = _device_lookup(pnfslay, objio_seg, i, gfp_flags);
210 if (unlikely(IS_ERR(ode))) {
211 err = PTR_ERR(ode);
212 goto out;
213 }
214 objio_seg->ods[i] = ode;
215 }
216 err = 0;
217
218out:
219 dprintk("%s: return=%d\n", __func__, err);
220 return err;
221}
222
77static int _verify_data_map(struct pnfs_osd_layout *layout) 223static int _verify_data_map(struct pnfs_osd_layout *layout)
78{ 224{
79 struct pnfs_osd_data_map *data_map = &layout->olo_map; 225 struct pnfs_osd_data_map *data_map = &layout->olo_map;
@@ -171,6 +317,9 @@ int objio_alloc_lseg(struct pnfs_layout_segment **outp,
171 317
172 objio_seg->num_comps = layout.olo_num_comps; 318 objio_seg->num_comps = layout.olo_num_comps;
173 objio_seg->comps_index = layout.olo_comps_index; 319 objio_seg->comps_index = layout.olo_comps_index;
320 err = objio_devices_lookup(pnfslay, objio_seg, gfp_flags);
321 if (err)
322 goto err;
174 323
175 objio_seg->mirrors_p1 = layout.olo_map.odm_mirror_cnt + 1; 324 objio_seg->mirrors_p1 = layout.olo_map.odm_mirror_cnt + 1;
176 objio_seg->stripe_unit = layout.olo_map.odm_stripe_unit; 325 objio_seg->stripe_unit = layout.olo_map.odm_stripe_unit;
@@ -199,8 +348,14 @@ err:
199 348
200void objio_free_lseg(struct pnfs_layout_segment *lseg) 349void objio_free_lseg(struct pnfs_layout_segment *lseg)
201{ 350{
351 int i;
202 struct objio_segment *objio_seg = OBJIO_LSEG(lseg); 352 struct objio_segment *objio_seg = OBJIO_LSEG(lseg);
203 353
354 for (i = 0; i < objio_seg->num_comps; i++) {
355 if (!objio_seg->ods[i])
356 break;
357 nfs4_put_deviceid_node(&objio_seg->ods[i]->id_node);
358 }
204 kfree(objio_seg); 359 kfree(objio_seg);
205} 360}
206 361
@@ -211,6 +366,8 @@ static struct pnfs_layoutdriver_type objlayout_type = {
211 366
212 .alloc_lseg = objlayout_alloc_lseg, 367 .alloc_lseg = objlayout_alloc_lseg,
213 .free_lseg = objlayout_free_lseg, 368 .free_lseg = objlayout_free_lseg,
369
370 .free_deviceid_node = objio_free_deviceid_node,
214}; 371};
215 372
216MODULE_DESCRIPTION("pNFS Layout Driver for OSD2 objects"); 373MODULE_DESCRIPTION("pNFS Layout Driver for OSD2 objects");
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}
diff --git a/fs/nfs/objlayout/objlayout.h b/fs/nfs/objlayout/objlayout.h
index 066280a07fa8..0814271bb9ba 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,
56extern void objio_free_lseg(struct pnfs_layout_segment *lseg); 56extern void objio_free_lseg(struct pnfs_layout_segment *lseg);
57 57
58/* 58/*
59 * callback API
60 */
61extern int objlayout_get_deviceinfo(struct pnfs_layout_hdr *pnfslay,
62 struct nfs4_deviceid *d_id, struct pnfs_osd_deviceaddr **deviceaddr,
63 gfp_t gfp_flags);
64extern void objlayout_put_deviceinfo(struct pnfs_osd_deviceaddr *deviceaddr);
65
66/*
59 * exported generic objects function vectors 67 * exported generic objects function vectors
60 */ 68 */
61extern struct pnfs_layout_segment *objlayout_alloc_lseg( 69extern struct pnfs_layout_segment *objlayout_alloc_lseg(