Commit fa33915c authored by Ryusuke Konishi's avatar Ryusuke Konishi Committed by Linus Torvalds

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: default avatarRyusuke Konishi <konishi.ryusuke@lab.ntt.co.jp>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 5b20384f
...@@ -260,6 +260,60 @@ int nilfs_mdt_get_block(struct inode *inode, unsigned long blkoff, int create, ...@@ -260,6 +260,60 @@ int nilfs_mdt_get_block(struct inode *inode, unsigned long blkoff, int create,
return ret; return ret;
} }
/**
* nilfs_mdt_find_block - find and get a buffer on meta data file.
* @inode: inode of the meta data file
* @start: start block offset (inclusive)
* @end: end block offset (inclusive)
* @blkoff: block offset
* @out_bh: place to store a pointer to buffer_head struct
*
* nilfs_mdt_find_block() looks up an existing block in range of
* [@start, @end] and stores pointer to a buffer head of the block to
* @out_bh, and block offset to @blkoff, respectively. @out_bh and
* @blkoff are substituted only when zero is returned.
*
* Return Value: On success, it returns 0. On error, the following negative
* error code is returned.
*
* %-ENOMEM - Insufficient memory available.
*
* %-EIO - I/O error
*
* %-ENOENT - no block was found in the range
*/
int nilfs_mdt_find_block(struct inode *inode, unsigned long start,
unsigned long end, unsigned long *blkoff,
struct buffer_head **out_bh)
{
__u64 next;
int ret;
if (unlikely(start > end))
return -ENOENT;
ret = nilfs_mdt_read_block(inode, start, true, out_bh);
if (!ret) {
*blkoff = start;
goto out;
}
if (unlikely(ret != -ENOENT || start == ULONG_MAX))
goto out;
ret = nilfs_bmap_seek_key(NILFS_I(inode)->i_bmap, start + 1, &next);
if (!ret) {
if (next <= end) {
ret = nilfs_mdt_read_block(inode, next, true, out_bh);
if (!ret)
*blkoff = next;
} else {
ret = -ENOENT;
}
}
out:
return ret;
}
/** /**
* nilfs_mdt_delete_block - make a hole on the meta data file. * nilfs_mdt_delete_block - make a hole on the meta data file.
* @inode: inode of the meta data file * @inode: inode of the meta data file
......
...@@ -78,6 +78,9 @@ int nilfs_mdt_get_block(struct inode *, unsigned long, int, ...@@ -78,6 +78,9 @@ int nilfs_mdt_get_block(struct inode *, unsigned long, int,
void (*init_block)(struct inode *, void (*init_block)(struct inode *,
struct buffer_head *, void *), struct buffer_head *, void *),
struct buffer_head **); struct buffer_head **);
int nilfs_mdt_find_block(struct inode *inode, unsigned long start,
unsigned long end, unsigned long *blkoff,
struct buffer_head **out_bh);
int nilfs_mdt_delete_block(struct inode *, unsigned long); int nilfs_mdt_delete_block(struct inode *, unsigned long);
int nilfs_mdt_forget_block(struct inode *, unsigned long); int nilfs_mdt_forget_block(struct inode *, unsigned long);
int nilfs_mdt_mark_block_dirty(struct inode *, unsigned long); int nilfs_mdt_mark_block_dirty(struct inode *, unsigned long);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment