diff options
Diffstat (limited to 'fs/nfs/objlayout/objlayout.c')
-rw-r--r-- | fs/nfs/objlayout/objlayout.c | 68 |
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 | */ | ||
108 | struct 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 | */ | ||
117 | int 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 | |||
159 | err_out: | ||
160 | __free_page(page); | ||
161 | return err; | ||
162 | } | ||
163 | |||
164 | void 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 | } | ||