Commit be401363 authored by Zheng Liu's avatar Zheng Liu Committed by Theodore Ts'o

ext4: rename and improbe ext4_es_find_extent()

This commit renames ext4_es_find_extent with ext4_es_find_delayed_extent
and improve this function.  First, we split input and output parameter.
Second, this function never return the first block of the next delayed
extent after 'es'.
Signed-off-by: default avatarZheng Liu <wenqing.lz@taobao.com>
Signed-off-by: default avatar"Theodore Ts'o" <tytso@mit.edu>
Cc: Jan kara <jack@suse.cz>
parent fdc0212e
...@@ -3528,8 +3528,7 @@ static int ext4_find_delalloc_range(struct inode *inode, ...@@ -3528,8 +3528,7 @@ static int ext4_find_delalloc_range(struct inode *inode,
{ {
struct extent_status es; struct extent_status es;
es.es_lblk = lblk_start; ext4_es_find_delayed_extent(inode, lblk_start, &es);
(void)ext4_es_find_extent(inode, &es);
if (es.es_len == 0) if (es.es_len == 0)
return 0; /* there is no delay extent in this tree */ return 0; /* there is no delay extent in this tree */
else if (es.es_lblk <= lblk_start && else if (es.es_lblk <= lblk_start &&
...@@ -4568,10 +4567,9 @@ static int ext4_find_delayed_extent(struct inode *inode, ...@@ -4568,10 +4567,9 @@ static int ext4_find_delayed_extent(struct inode *inode,
struct ext4_ext_cache *newex) struct ext4_ext_cache *newex)
{ {
struct extent_status es; struct extent_status es;
ext4_lblk_t next_del; ext4_lblk_t block, next_del;
es.es_lblk = newex->ec_block; ext4_es_find_delayed_extent(inode, newex->ec_block, &es);
next_del = ext4_es_find_extent(inode, &es);
if (newex->ec_start == 0) { if (newex->ec_start == 0) {
/* /*
...@@ -4592,6 +4590,13 @@ static int ext4_find_delayed_extent(struct inode *inode, ...@@ -4592,6 +4590,13 @@ static int ext4_find_delayed_extent(struct inode *inode,
newex->ec_len = es.es_lblk + es.es_len - newex->ec_block; newex->ec_len = es.es_lblk + es.es_len - newex->ec_block;
} }
block = newex->ec_block + newex->ec_len;
ext4_es_find_delayed_extent(inode, block, &es);
if (es.es_len == 0)
next_del = EXT_MAX_BLOCKS;
else
next_del = es.es_lblk;
return next_del; return next_del;
} }
/* fiemap flags we can handle specified here */ /* fiemap flags we can handle specified here */
......
...@@ -229,59 +229,59 @@ static struct extent_status *__es_tree_search(struct rb_root *root, ...@@ -229,59 +229,59 @@ static struct extent_status *__es_tree_search(struct rb_root *root,
} }
/* /*
* ext4_es_find_extent: find the 1st delayed extent covering @es->lblk * ext4_es_find_delayed_extent: find the 1st delayed extent covering @es->lblk
* if it exists, otherwise, the next extent after @es->lblk. * if it exists, otherwise, the next extent after @es->lblk.
* *
* @inode: the inode which owns delayed extents * @inode: the inode which owns delayed extents
* @lblk: the offset where we start to search
* @es: delayed extent that we found * @es: delayed extent that we found
*
* Returns the first block of the next extent after es, otherwise
* EXT_MAX_BLOCKS if no extent is found.
* Delayed extent is returned via @es.
*/ */
ext4_lblk_t ext4_es_find_extent(struct inode *inode, struct extent_status *es) void ext4_es_find_delayed_extent(struct inode *inode, ext4_lblk_t lblk,
struct extent_status *es)
{ {
struct ext4_es_tree *tree = NULL; struct ext4_es_tree *tree = NULL;
struct extent_status *es1 = NULL; struct extent_status *es1 = NULL;
struct rb_node *node; struct rb_node *node;
ext4_lblk_t ret = EXT_MAX_BLOCKS;
trace_ext4_es_find_extent_enter(inode, es->es_lblk); BUG_ON(es == NULL);
trace_ext4_es_find_delayed_extent_enter(inode, lblk);
read_lock(&EXT4_I(inode)->i_es_lock); read_lock(&EXT4_I(inode)->i_es_lock);
tree = &EXT4_I(inode)->i_es_tree; tree = &EXT4_I(inode)->i_es_tree;
/* find extent in cache firstly */ /* find extent in cache firstly */
es->es_len = es->es_pblk = 0; es->es_lblk = es->es_len = es->es_pblk = 0;
if (tree->cache_es) { if (tree->cache_es) {
es1 = tree->cache_es; es1 = tree->cache_es;
if (in_range(es->es_lblk, es1->es_lblk, es1->es_len)) { if (in_range(lblk, es1->es_lblk, es1->es_len)) {
es_debug("%u cached by [%u/%u) %llu %llx\n", es_debug("%u cached by [%u/%u) %llu %llx\n",
es->es_lblk, es1->es_lblk, es1->es_len, lblk, es1->es_lblk, es1->es_len,
ext4_es_pblock(es1), ext4_es_status(es1)); ext4_es_pblock(es1), ext4_es_status(es1));
goto out; goto out;
} }
} }
es1 = __es_tree_search(&tree->root, es->es_lblk); es1 = __es_tree_search(&tree->root, lblk);
out: out:
if (es1) { if (es1 && !ext4_es_is_delayed(es1)) {
while ((node = rb_next(&es1->rb_node)) != NULL) {
es1 = rb_entry(node, struct extent_status, rb_node);
if (ext4_es_is_delayed(es1))
break;
}
}
if (es1 && ext4_es_is_delayed(es1)) {
tree->cache_es = es1; tree->cache_es = es1;
es->es_lblk = es1->es_lblk; es->es_lblk = es1->es_lblk;
es->es_len = es1->es_len; es->es_len = es1->es_len;
es->es_pblk = es1->es_pblk; es->es_pblk = es1->es_pblk;
node = rb_next(&es1->rb_node);
if (node) {
es1 = rb_entry(node, struct extent_status, rb_node);
ret = es1->es_lblk;
}
} }
read_unlock(&EXT4_I(inode)->i_es_lock); read_unlock(&EXT4_I(inode)->i_es_lock);
trace_ext4_es_find_extent_exit(inode, es, ret); trace_ext4_es_find_delayed_extent_exit(inode, es);
return ret;
} }
static struct extent_status * static struct extent_status *
......
...@@ -51,8 +51,8 @@ extern int ext4_es_insert_extent(struct inode *inode, ext4_lblk_t lblk, ...@@ -51,8 +51,8 @@ extern int ext4_es_insert_extent(struct inode *inode, ext4_lblk_t lblk,
unsigned long long status); unsigned long long status);
extern int ext4_es_remove_extent(struct inode *inode, ext4_lblk_t lblk, extern int ext4_es_remove_extent(struct inode *inode, ext4_lblk_t lblk,
ext4_lblk_t len); ext4_lblk_t len);
extern ext4_lblk_t ext4_es_find_extent(struct inode *inode, extern void ext4_es_find_delayed_extent(struct inode *inode, ext4_lblk_t lblk,
struct extent_status *es); struct extent_status *es);
static inline int ext4_es_is_written(struct extent_status *es) static inline int ext4_es_is_written(struct extent_status *es)
{ {
......
...@@ -464,8 +464,7 @@ static loff_t ext4_seek_data(struct file *file, loff_t offset, loff_t maxsize) ...@@ -464,8 +464,7 @@ static loff_t ext4_seek_data(struct file *file, loff_t offset, loff_t maxsize)
* If there is a delay extent at this offset, * If there is a delay extent at this offset,
* it will be as a data. * it will be as a data.
*/ */
es.es_lblk = last; ext4_es_find_delayed_extent(inode, last, &es);
(void)ext4_es_find_extent(inode, &es);
if (es.es_len != 0 && in_range(last, es.es_lblk, es.es_len)) { if (es.es_len != 0 && in_range(last, es.es_lblk, es.es_len)) {
if (last != start) if (last != start)
dataoff = last << blkbits; dataoff = last << blkbits;
...@@ -548,8 +547,7 @@ static loff_t ext4_seek_hole(struct file *file, loff_t offset, loff_t maxsize) ...@@ -548,8 +547,7 @@ static loff_t ext4_seek_hole(struct file *file, loff_t offset, loff_t maxsize)
* If there is a delay extent at this offset, * If there is a delay extent at this offset,
* we will skip this extent. * we will skip this extent.
*/ */
es.es_lblk = last; ext4_es_find_delayed_extent(inode, last, &es);
(void)ext4_es_find_extent(inode, &es);
if (es.es_len != 0 && in_range(last, es.es_lblk, es.es_len)) { if (es.es_len != 0 && in_range(last, es.es_lblk, es.es_len)) {
last = es.es_lblk + es.es_len; last = es.es_lblk + es.es_len;
holeoff = last << blkbits; holeoff = last << blkbits;
......
...@@ -2147,7 +2147,7 @@ TRACE_EVENT(ext4_es_remove_extent, ...@@ -2147,7 +2147,7 @@ TRACE_EVENT(ext4_es_remove_extent,
__entry->lblk, __entry->len) __entry->lblk, __entry->len)
); );
TRACE_EVENT(ext4_es_find_extent_enter, TRACE_EVENT(ext4_es_find_delayed_extent_enter,
TP_PROTO(struct inode *inode, ext4_lblk_t lblk), TP_PROTO(struct inode *inode, ext4_lblk_t lblk),
TP_ARGS(inode, lblk), TP_ARGS(inode, lblk),
...@@ -2169,11 +2169,10 @@ TRACE_EVENT(ext4_es_find_extent_enter, ...@@ -2169,11 +2169,10 @@ TRACE_EVENT(ext4_es_find_extent_enter,
(unsigned long) __entry->ino, __entry->lblk) (unsigned long) __entry->ino, __entry->lblk)
); );
TRACE_EVENT(ext4_es_find_extent_exit, TRACE_EVENT(ext4_es_find_delayed_extent_exit,
TP_PROTO(struct inode *inode, struct extent_status *es, TP_PROTO(struct inode *inode, struct extent_status *es),
ext4_lblk_t ret),
TP_ARGS(inode, es, ret), TP_ARGS(inode, es),
TP_STRUCT__entry( TP_STRUCT__entry(
__field( dev_t, dev ) __field( dev_t, dev )
...@@ -2182,7 +2181,6 @@ TRACE_EVENT(ext4_es_find_extent_exit, ...@@ -2182,7 +2181,6 @@ TRACE_EVENT(ext4_es_find_extent_exit,
__field( ext4_lblk_t, len ) __field( ext4_lblk_t, len )
__field( ext4_fsblk_t, pblk ) __field( ext4_fsblk_t, pblk )
__field( unsigned long long, status ) __field( unsigned long long, status )
__field( ext4_lblk_t, ret )
), ),
TP_fast_assign( TP_fast_assign(
...@@ -2192,14 +2190,13 @@ TRACE_EVENT(ext4_es_find_extent_exit, ...@@ -2192,14 +2190,13 @@ TRACE_EVENT(ext4_es_find_extent_exit,
__entry->len = es->es_len; __entry->len = es->es_len;
__entry->pblk = ext4_es_pblock(es); __entry->pblk = ext4_es_pblock(es);
__entry->status = ext4_es_status(es); __entry->status = ext4_es_status(es);
__entry->ret = ret;
), ),
TP_printk("dev %d,%d ino %lu es [%u/%u) mapped %llu status %llx ret %u", TP_printk("dev %d,%d ino %lu es [%u/%u) mapped %llu status %llx",
MAJOR(__entry->dev), MINOR(__entry->dev), MAJOR(__entry->dev), MINOR(__entry->dev),
(unsigned long) __entry->ino, (unsigned long) __entry->ino,
__entry->lblk, __entry->len, __entry->lblk, __entry->len,
__entry->pblk, __entry->status, __entry->ret) __entry->pblk, __entry->status)
); );
#endif /* _TRACE_EXT4_H */ #endif /* _TRACE_EXT4_H */
......
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