diff options
author | Ryusuke Konishi <konishi.ryusuke@lab.ntt.co.jp> | 2015-04-16 15:46:39 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2015-04-17 09:04:04 -0400 |
commit | fa33915c92b43f5a4e95649f81303cc089b10dc6 (patch) | |
tree | e448cc995e87f394865e62b2c36605c169bb05c1 | |
parent | 5b20384fb32cc3f93857f44fb84736d6d62a9917 (diff) |
nilfs2: add helper to find existent block on metadata file
Add a new metadata file function, nilfs_mdt_find_block(), which finds
an existent block on a metadata file in a given range of blocks. This
function skips continuous hole blocks efficiently by using
nilfs_bmap_seek_key().
Signed-off-by: Ryusuke Konishi <konishi.ryusuke@lab.ntt.co.jp>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r-- | fs/nilfs2/mdt.c | 54 | ||||
-rw-r--r-- | fs/nilfs2/mdt.h | 3 |
2 files changed, 57 insertions, 0 deletions
diff --git a/fs/nilfs2/mdt.c b/fs/nilfs2/mdt.c index 892cf5ffdb8e..dee34d990281 100644 --- a/fs/nilfs2/mdt.c +++ b/fs/nilfs2/mdt.c | |||
@@ -261,6 +261,60 @@ int nilfs_mdt_get_block(struct inode *inode, unsigned long blkoff, int create, | |||
261 | } | 261 | } |
262 | 262 | ||
263 | /** | 263 | /** |
264 | * nilfs_mdt_find_block - find and get a buffer on meta data file. | ||
265 | * @inode: inode of the meta data file | ||
266 | * @start: start block offset (inclusive) | ||
267 | * @end: end block offset (inclusive) | ||
268 | * @blkoff: block offset | ||
269 | * @out_bh: place to store a pointer to buffer_head struct | ||
270 | * | ||
271 | * nilfs_mdt_find_block() looks up an existing block in range of | ||
272 | * [@start, @end] and stores pointer to a buffer head of the block to | ||
273 | * @out_bh, and block offset to @blkoff, respectively. @out_bh and | ||
274 | * @blkoff are substituted only when zero is returned. | ||
275 | * | ||
276 | * Return Value: On success, it returns 0. On error, the following negative | ||
277 | * error code is returned. | ||
278 | * | ||
279 | * %-ENOMEM - Insufficient memory available. | ||
280 | * | ||
281 | * %-EIO - I/O error | ||
282 | * | ||
283 | * %-ENOENT - no block was found in the range | ||
284 | */ | ||
285 | int nilfs_mdt_find_block(struct inode *inode, unsigned long start, | ||
286 | unsigned long end, unsigned long *blkoff, | ||
287 | struct buffer_head **out_bh) | ||
288 | { | ||
289 | __u64 next; | ||
290 | int ret; | ||
291 | |||
292 | if (unlikely(start > end)) | ||
293 | return -ENOENT; | ||
294 | |||
295 | ret = nilfs_mdt_read_block(inode, start, true, out_bh); | ||
296 | if (!ret) { | ||
297 | *blkoff = start; | ||
298 | goto out; | ||
299 | } | ||
300 | if (unlikely(ret != -ENOENT || start == ULONG_MAX)) | ||
301 | goto out; | ||
302 | |||
303 | ret = nilfs_bmap_seek_key(NILFS_I(inode)->i_bmap, start + 1, &next); | ||
304 | if (!ret) { | ||
305 | if (next <= end) { | ||
306 | ret = nilfs_mdt_read_block(inode, next, true, out_bh); | ||
307 | if (!ret) | ||
308 | *blkoff = next; | ||
309 | } else { | ||
310 | ret = -ENOENT; | ||
311 | } | ||
312 | } | ||
313 | out: | ||
314 | return ret; | ||
315 | } | ||
316 | |||
317 | /** | ||
264 | * nilfs_mdt_delete_block - make a hole on the meta data file. | 318 | * nilfs_mdt_delete_block - make a hole on the meta data file. |
265 | * @inode: inode of the meta data file | 319 | * @inode: inode of the meta data file |
266 | * @block: block offset | 320 | * @block: block offset |
diff --git a/fs/nilfs2/mdt.h b/fs/nilfs2/mdt.h index a294ea38e4c7..fe529a87a208 100644 --- a/fs/nilfs2/mdt.h +++ b/fs/nilfs2/mdt.h | |||
@@ -78,6 +78,9 @@ int nilfs_mdt_get_block(struct inode *, unsigned long, int, | |||
78 | void (*init_block)(struct inode *, | 78 | void (*init_block)(struct inode *, |
79 | struct buffer_head *, void *), | 79 | struct buffer_head *, void *), |
80 | struct buffer_head **); | 80 | struct buffer_head **); |
81 | int nilfs_mdt_find_block(struct inode *inode, unsigned long start, | ||
82 | unsigned long end, unsigned long *blkoff, | ||
83 | struct buffer_head **out_bh); | ||
81 | int nilfs_mdt_delete_block(struct inode *, unsigned long); | 84 | int nilfs_mdt_delete_block(struct inode *, unsigned long); |
82 | int nilfs_mdt_forget_block(struct inode *, unsigned long); | 85 | int nilfs_mdt_forget_block(struct inode *, unsigned long); |
83 | int nilfs_mdt_mark_block_dirty(struct inode *, unsigned long); | 86 | int nilfs_mdt_mark_block_dirty(struct inode *, unsigned long); |