diff options
Diffstat (limited to 'fs/nfs/objlayout/objio_osd.c')
-rw-r--r-- | fs/nfs/objlayout/objio_osd.c | 113 |
1 files changed, 41 insertions, 72 deletions
diff --git a/fs/nfs/objlayout/objio_osd.c b/fs/nfs/objlayout/objio_osd.c index ae05278b3761..c6e4bda63000 100644 --- a/fs/nfs/objlayout/objio_osd.c +++ b/fs/nfs/objlayout/objio_osd.c | |||
@@ -60,52 +60,6 @@ objio_free_deviceid_node(struct nfs4_deviceid_node *d) | |||
60 | kfree(de); | 60 | kfree(de); |
61 | } | 61 | } |
62 | 62 | ||
63 | static struct objio_dev_ent *_dev_list_find(const struct nfs_server *nfss, | ||
64 | const struct nfs4_deviceid *d_id) | ||
65 | { | ||
66 | struct nfs4_deviceid_node *d; | ||
67 | struct objio_dev_ent *de; | ||
68 | |||
69 | d = nfs4_find_get_deviceid(nfss->pnfs_curr_ld, nfss->nfs_client, d_id); | ||
70 | if (!d) | ||
71 | return NULL; | ||
72 | |||
73 | de = container_of(d, struct objio_dev_ent, id_node); | ||
74 | return de; | ||
75 | } | ||
76 | |||
77 | static struct objio_dev_ent * | ||
78 | _dev_list_add(const struct nfs_server *nfss, | ||
79 | const struct nfs4_deviceid *d_id, struct osd_dev *od, | ||
80 | gfp_t gfp_flags) | ||
81 | { | ||
82 | struct nfs4_deviceid_node *d; | ||
83 | struct objio_dev_ent *de = kzalloc(sizeof(*de), gfp_flags); | ||
84 | struct objio_dev_ent *n; | ||
85 | |||
86 | if (!de) { | ||
87 | dprintk("%s: -ENOMEM od=%p\n", __func__, od); | ||
88 | return NULL; | ||
89 | } | ||
90 | |||
91 | dprintk("%s: Adding od=%p\n", __func__, od); | ||
92 | nfs4_init_deviceid_node(&de->id_node, | ||
93 | nfss->pnfs_curr_ld, | ||
94 | nfss->nfs_client, | ||
95 | d_id); | ||
96 | de->od.od = od; | ||
97 | |||
98 | d = nfs4_insert_deviceid_node(&de->id_node); | ||
99 | n = container_of(d, struct objio_dev_ent, id_node); | ||
100 | if (n != de) { | ||
101 | dprintk("%s: Race with other n->od=%p\n", __func__, n->od.od); | ||
102 | objio_free_deviceid_node(&de->id_node); | ||
103 | de = n; | ||
104 | } | ||
105 | |||
106 | return de; | ||
107 | } | ||
108 | |||
109 | struct objio_segment { | 63 | struct objio_segment { |
110 | struct pnfs_layout_segment lseg; | 64 | struct pnfs_layout_segment lseg; |
111 | 65 | ||
@@ -130,29 +84,24 @@ struct objio_state { | |||
130 | 84 | ||
131 | /* Send and wait for a get_device_info of devices in the layout, | 85 | /* Send and wait for a get_device_info of devices in the layout, |
132 | then look them up with the osd_initiator library */ | 86 | then look them up with the osd_initiator library */ |
133 | static int objio_devices_lookup(struct pnfs_layout_hdr *pnfslay, | 87 | struct nfs4_deviceid_node * |
134 | struct objio_segment *objio_seg, unsigned c, struct nfs4_deviceid *d_id, | 88 | objio_alloc_deviceid_node(struct nfs_server *server, struct pnfs_device *pdev, |
135 | gfp_t gfp_flags) | 89 | gfp_t gfp_flags) |
136 | { | 90 | { |
137 | struct pnfs_osd_deviceaddr *deviceaddr; | 91 | struct pnfs_osd_deviceaddr *deviceaddr; |
138 | struct objio_dev_ent *ode; | 92 | struct objio_dev_ent *ode = NULL; |
139 | struct osd_dev *od; | 93 | struct osd_dev *od; |
140 | struct osd_dev_info odi; | 94 | struct osd_dev_info odi; |
141 | bool retry_flag = true; | 95 | bool retry_flag = true; |
96 | __be32 *p; | ||
142 | int err; | 97 | int err; |
143 | 98 | ||
144 | ode = _dev_list_find(NFS_SERVER(pnfslay->plh_inode), d_id); | 99 | deviceaddr = kzalloc(sizeof(*deviceaddr), gfp_flags); |
145 | if (ode) { | 100 | if (!deviceaddr) |
146 | objio_seg->oc.ods[c] = &ode->od; /* must use container_of */ | 101 | return NULL; |
147 | return 0; | ||
148 | } | ||
149 | 102 | ||
150 | err = objlayout_get_deviceinfo(pnfslay, d_id, &deviceaddr, gfp_flags); | 103 | p = page_address(pdev->pages[0]); |
151 | if (unlikely(err)) { | 104 | pnfs_osd_xdr_decode_deviceaddr(deviceaddr, p); |
152 | dprintk("%s: objlayout_get_deviceinfo dev(%llx:%llx) =>%d\n", | ||
153 | __func__, _DEVID_LO(d_id), _DEVID_HI(d_id), err); | ||
154 | return err; | ||
155 | } | ||
156 | 105 | ||
157 | odi.systemid_len = deviceaddr->oda_systemid.len; | 106 | odi.systemid_len = deviceaddr->oda_systemid.len; |
158 | if (odi.systemid_len > sizeof(odi.systemid)) { | 107 | if (odi.systemid_len > sizeof(odi.systemid)) { |
@@ -188,14 +137,24 @@ retry_lookup: | |||
188 | goto out; | 137 | goto out; |
189 | } | 138 | } |
190 | 139 | ||
191 | ode = _dev_list_add(NFS_SERVER(pnfslay->plh_inode), d_id, od, | ||
192 | gfp_flags); | ||
193 | objio_seg->oc.ods[c] = &ode->od; /* must use container_of */ | ||
194 | dprintk("Adding new dev_id(%llx:%llx)\n", | 140 | dprintk("Adding new dev_id(%llx:%llx)\n", |
195 | _DEVID_LO(d_id), _DEVID_HI(d_id)); | 141 | _DEVID_LO(&pdev->dev_id), _DEVID_HI(&pdev->dev_id)); |
142 | |||
143 | ode = kzalloc(sizeof(*ode), gfp_flags); | ||
144 | if (!ode) { | ||
145 | dprintk("%s: -ENOMEM od=%p\n", __func__, od); | ||
146 | goto out; | ||
147 | } | ||
148 | |||
149 | nfs4_init_deviceid_node(&ode->id_node, server, &pdev->dev_id); | ||
150 | kfree(deviceaddr); | ||
151 | |||
152 | ode->od.od = od; | ||
153 | return &ode->id_node; | ||
154 | |||
196 | out: | 155 | out: |
197 | objlayout_put_deviceinfo(deviceaddr); | 156 | kfree(deviceaddr); |
198 | return err; | 157 | return NULL; |
199 | } | 158 | } |
200 | 159 | ||
201 | static void copy_single_comp(struct ore_components *oc, unsigned c, | 160 | static void copy_single_comp(struct ore_components *oc, unsigned c, |
@@ -254,6 +213,7 @@ int objio_alloc_lseg(struct pnfs_layout_segment **outp, | |||
254 | struct xdr_stream *xdr, | 213 | struct xdr_stream *xdr, |
255 | gfp_t gfp_flags) | 214 | gfp_t gfp_flags) |
256 | { | 215 | { |
216 | struct nfs_server *server = NFS_SERVER(pnfslay->plh_inode); | ||
257 | struct objio_segment *objio_seg; | 217 | struct objio_segment *objio_seg; |
258 | struct pnfs_osd_xdr_decode_layout_iter iter; | 218 | struct pnfs_osd_xdr_decode_layout_iter iter; |
259 | struct pnfs_osd_layout layout; | 219 | struct pnfs_osd_layout layout; |
@@ -283,13 +243,21 @@ int objio_alloc_lseg(struct pnfs_layout_segment **outp, | |||
283 | objio_seg->oc.first_dev = layout.olo_comps_index; | 243 | objio_seg->oc.first_dev = layout.olo_comps_index; |
284 | cur_comp = 0; | 244 | cur_comp = 0; |
285 | while (pnfs_osd_xdr_decode_layout_comp(&src_comp, &iter, xdr, &err)) { | 245 | while (pnfs_osd_xdr_decode_layout_comp(&src_comp, &iter, xdr, &err)) { |
246 | struct nfs4_deviceid_node *d; | ||
247 | struct objio_dev_ent *ode; | ||
248 | |||
286 | copy_single_comp(&objio_seg->oc, cur_comp, &src_comp); | 249 | copy_single_comp(&objio_seg->oc, cur_comp, &src_comp); |
287 | err = objio_devices_lookup(pnfslay, objio_seg, cur_comp, | 250 | |
288 | &src_comp.oc_object_id.oid_device_id, | 251 | d = nfs4_find_get_deviceid(server, |
289 | gfp_flags); | 252 | &src_comp.oc_object_id.oid_device_id, |
290 | if (err) | 253 | pnfslay->plh_lc_cred, gfp_flags); |
254 | if (!d) { | ||
255 | err = -ENXIO; | ||
291 | goto err; | 256 | goto err; |
292 | ++cur_comp; | 257 | } |
258 | |||
259 | ode = container_of(d, struct objio_dev_ent, id_node); | ||
260 | objio_seg->oc.ods[cur_comp++] = &ode->od; | ||
293 | } | 261 | } |
294 | /* pnfs_osd_xdr_decode_layout_comp returns false on error */ | 262 | /* pnfs_osd_xdr_decode_layout_comp returns false on error */ |
295 | if (unlikely(err)) | 263 | if (unlikely(err)) |
@@ -653,6 +621,7 @@ static struct pnfs_layoutdriver_type objlayout_type = { | |||
653 | .flags = PNFS_LAYOUTRET_ON_SETATTR | | 621 | .flags = PNFS_LAYOUTRET_ON_SETATTR | |
654 | PNFS_LAYOUTRET_ON_ERROR, | 622 | PNFS_LAYOUTRET_ON_ERROR, |
655 | 623 | ||
624 | .max_deviceinfo_size = PAGE_SIZE, | ||
656 | .owner = THIS_MODULE, | 625 | .owner = THIS_MODULE, |
657 | .alloc_layout_hdr = objlayout_alloc_layout_hdr, | 626 | .alloc_layout_hdr = objlayout_alloc_layout_hdr, |
658 | .free_layout_hdr = objlayout_free_layout_hdr, | 627 | .free_layout_hdr = objlayout_free_layout_hdr, |