aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRyusuke Konishi <konishi.ryusuke@lab.ntt.co.jp>2015-04-16 15:46:39 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2015-04-17 09:04:04 -0400
commitfa33915c92b43f5a4e95649f81303cc089b10dc6 (patch)
treee448cc995e87f394865e62b2c36605c169bb05c1
parent5b20384fb32cc3f93857f44fb84736d6d62a9917 (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.c54
-rw-r--r--fs/nilfs2/mdt.h3
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 */
285int 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 }
313out:
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 **);
81int nilfs_mdt_find_block(struct inode *inode, unsigned long start,
82 unsigned long end, unsigned long *blkoff,
83 struct buffer_head **out_bh);
81int nilfs_mdt_delete_block(struct inode *, unsigned long); 84int nilfs_mdt_delete_block(struct inode *, unsigned long);
82int nilfs_mdt_forget_block(struct inode *, unsigned long); 85int nilfs_mdt_forget_block(struct inode *, unsigned long);
83int nilfs_mdt_mark_block_dirty(struct inode *, unsigned long); 86int nilfs_mdt_mark_block_dirty(struct inode *, unsigned long);