diff options
author | Fred Isaman <iisaman@citi.umich.edu> | 2011-07-30 20:52:48 -0400 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2011-07-31 12:18:16 -0400 |
commit | 6d742ba538f98164f3c5e05cdcadb4ec6ddf504f (patch) | |
tree | b87c6f5d42eccfb028a207ce48dfa474c168fd1e /fs/nfs | |
parent | e9437ccef92a28ba4c9009404bb8c9b5672dc54a (diff) |
pnfsblock: bl_find_get_extent
Implement bl_find_get_extent(), one of the core extent manipulation
routines.
[pnfsblock: Lookup list entry of layouts and tags in reverse order]
Signed-off-by: Zhang Jingwang <zhangjingwang@nrchpc.ac.cn>
Signed-off-by: Fred Isaman <iisaman@citi.umich.edu>
Signed-off-by: Benny Halevy <bhalevy@panasas.com>
Signed-off-by: Jim Rees <rees@umich.edu>
pnfsblock: fix print format warnings for sector_t and size_t
gcc spews warnings about these on x86_64, e.g.:
fs/nfs/blocklayout/blocklayout.c:74: warning: format ‘%Lu’ expects type ‘long long unsigned int’, but argument 2 has type ‘sector_t’
fs/nfs/blocklayout/blocklayout.c:388: warning: format ‘%d’ expects type ‘int’, but argument 5 has type ‘size_t’
Signed-off-by: Benny Halevy <bhalevy@panasas.com>
Signed-off-by: Benny Halevy <bhalevy@tonian.com>
Signed-off-by: Jim Rees <rees@umich.edu>
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs/nfs')
-rw-r--r-- | fs/nfs/blocklayout/blocklayout.h | 3 | ||||
-rw-r--r-- | fs/nfs/blocklayout/extents.c | 47 |
2 files changed, 50 insertions, 0 deletions
diff --git a/fs/nfs/blocklayout/blocklayout.h b/fs/nfs/blocklayout/blocklayout.h index d645880f61a0..3e1b5fc152d7 100644 --- a/fs/nfs/blocklayout/blocklayout.h +++ b/fs/nfs/blocklayout/blocklayout.h | |||
@@ -153,6 +153,9 @@ int nfs4_blk_process_layoutget(struct pnfs_layout_hdr *lo, | |||
153 | void bl_free_block_dev(struct pnfs_block_dev *bdev); | 153 | void bl_free_block_dev(struct pnfs_block_dev *bdev); |
154 | 154 | ||
155 | /* extents.c */ | 155 | /* extents.c */ |
156 | struct pnfs_block_extent * | ||
157 | bl_find_get_extent(struct pnfs_block_layout *bl, sector_t isect, | ||
158 | struct pnfs_block_extent **cow_read); | ||
156 | void bl_put_extent(struct pnfs_block_extent *be); | 159 | void bl_put_extent(struct pnfs_block_extent *be); |
157 | struct pnfs_block_extent *bl_alloc_extent(void); | 160 | struct pnfs_block_extent *bl_alloc_extent(void); |
158 | int bl_add_merge_extent(struct pnfs_block_layout *bl, | 161 | int bl_add_merge_extent(struct pnfs_block_layout *bl, |
diff --git a/fs/nfs/blocklayout/extents.c b/fs/nfs/blocklayout/extents.c index ee4891f32492..8fa93e23cb24 100644 --- a/fs/nfs/blocklayout/extents.c +++ b/fs/nfs/blocklayout/extents.c | |||
@@ -193,3 +193,50 @@ bl_add_merge_extent(struct pnfs_block_layout *bl, | |||
193 | bl_put_extent(new); | 193 | bl_put_extent(new); |
194 | return -EIO; | 194 | return -EIO; |
195 | } | 195 | } |
196 | |||
197 | /* Returns extent, or NULL. If a second READ extent exists, it is returned | ||
198 | * in cow_read, if given. | ||
199 | * | ||
200 | * The extents are kept in two seperate ordered lists, one for READ and NONE, | ||
201 | * one for READWRITE and INVALID. Within each list, we assume: | ||
202 | * 1. Extents are ordered by file offset. | ||
203 | * 2. For any given isect, there is at most one extents that matches. | ||
204 | */ | ||
205 | struct pnfs_block_extent * | ||
206 | bl_find_get_extent(struct pnfs_block_layout *bl, sector_t isect, | ||
207 | struct pnfs_block_extent **cow_read) | ||
208 | { | ||
209 | struct pnfs_block_extent *be, *cow, *ret; | ||
210 | int i; | ||
211 | |||
212 | dprintk("%s enter with isect %llu\n", __func__, (u64)isect); | ||
213 | cow = ret = NULL; | ||
214 | spin_lock(&bl->bl_ext_lock); | ||
215 | for (i = 0; i < EXTENT_LISTS; i++) { | ||
216 | list_for_each_entry_reverse(be, &bl->bl_extents[i], be_node) { | ||
217 | if (isect >= be->be_f_offset + be->be_length) | ||
218 | break; | ||
219 | if (isect >= be->be_f_offset) { | ||
220 | /* We have found an extent */ | ||
221 | dprintk("%s Get %p (%i)\n", __func__, be, | ||
222 | atomic_read(&be->be_refcnt.refcount)); | ||
223 | kref_get(&be->be_refcnt); | ||
224 | if (!ret) | ||
225 | ret = be; | ||
226 | else if (be->be_state != PNFS_BLOCK_READ_DATA) | ||
227 | bl_put_extent(be); | ||
228 | else | ||
229 | cow = be; | ||
230 | break; | ||
231 | } | ||
232 | } | ||
233 | if (ret && | ||
234 | (!cow_read || ret->be_state != PNFS_BLOCK_INVALID_DATA)) | ||
235 | break; | ||
236 | } | ||
237 | spin_unlock(&bl->bl_ext_lock); | ||
238 | if (cow_read) | ||
239 | *cow_read = cow; | ||
240 | print_bl_extent(ret); | ||
241 | return ret; | ||
242 | } | ||