aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/ext4/extents.c15
-rw-r--r--fs/ext4/extents_status.c40
-rw-r--r--fs/ext4/extents_status.h4
-rw-r--r--fs/ext4/file.c6
-rw-r--r--include/trace/events/ext4.h15
5 files changed, 40 insertions, 40 deletions
diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
index 37f94a751ad7..895c19595ecf 100644
--- a/fs/ext4/extents.c
+++ b/fs/ext4/extents.c
@@ -3528,8 +3528,7 @@ static int ext4_find_delalloc_range(struct inode *inode,
3528{ 3528{
3529 struct extent_status es; 3529 struct extent_status es;
3530 3530
3531 es.es_lblk = lblk_start; 3531 ext4_es_find_delayed_extent(inode, lblk_start, &es);
3532 (void)ext4_es_find_extent(inode, &es);
3533 if (es.es_len == 0) 3532 if (es.es_len == 0)
3534 return 0; /* there is no delay extent in this tree */ 3533 return 0; /* there is no delay extent in this tree */
3535 else if (es.es_lblk <= lblk_start && 3534 else if (es.es_lblk <= lblk_start &&
@@ -4568,10 +4567,9 @@ static int ext4_find_delayed_extent(struct inode *inode,
4568 struct ext4_ext_cache *newex) 4567 struct ext4_ext_cache *newex)
4569{ 4568{
4570 struct extent_status es; 4569 struct extent_status es;
4571 ext4_lblk_t next_del; 4570 ext4_lblk_t block, next_del;
4572 4571
4573 es.es_lblk = newex->ec_block; 4572 ext4_es_find_delayed_extent(inode, newex->ec_block, &es);
4574 next_del = ext4_es_find_extent(inode, &es);
4575 4573
4576 if (newex->ec_start == 0) { 4574 if (newex->ec_start == 0) {
4577 /* 4575 /*
@@ -4592,6 +4590,13 @@ static int ext4_find_delayed_extent(struct inode *inode,
4592 newex->ec_len = es.es_lblk + es.es_len - newex->ec_block; 4590 newex->ec_len = es.es_lblk + es.es_len - newex->ec_block;
4593 } 4591 }
4594 4592
4593 block = newex->ec_block + newex->ec_len;
4594 ext4_es_find_delayed_extent(inode, block, &es);
4595 if (es.es_len == 0)
4596 next_del = EXT_MAX_BLOCKS;
4597 else
4598 next_del = es.es_lblk;
4599
4595 return next_del; 4600 return next_del;
4596} 4601}
4597/* fiemap flags we can handle specified here */ 4602/* fiemap flags we can handle specified here */
diff --git a/fs/ext4/extents_status.c b/fs/ext4/extents_status.c
index 1f5fd44993e9..76f4351ea821 100644
--- a/fs/ext4/extents_status.c
+++ b/fs/ext4/extents_status.c
@@ -229,59 +229,59 @@ static struct extent_status *__es_tree_search(struct rb_root *root,
229} 229}
230 230
231/* 231/*
232 * ext4_es_find_extent: find the 1st delayed extent covering @es->lblk 232 * ext4_es_find_delayed_extent: find the 1st delayed extent covering @es->lblk
233 * if it exists, otherwise, the next extent after @es->lblk. 233 * if it exists, otherwise, the next extent after @es->lblk.
234 * 234 *
235 * @inode: the inode which owns delayed extents 235 * @inode: the inode which owns delayed extents
236 * @lblk: the offset where we start to search
236 * @es: delayed extent that we found 237 * @es: delayed extent that we found
237 *
238 * Returns the first block of the next extent after es, otherwise
239 * EXT_MAX_BLOCKS if no extent is found.
240 * Delayed extent is returned via @es.
241 */ 238 */
242ext4_lblk_t ext4_es_find_extent(struct inode *inode, struct extent_status *es) 239void ext4_es_find_delayed_extent(struct inode *inode, ext4_lblk_t lblk,
240 struct extent_status *es)
243{ 241{
244 struct ext4_es_tree *tree = NULL; 242 struct ext4_es_tree *tree = NULL;
245 struct extent_status *es1 = NULL; 243 struct extent_status *es1 = NULL;
246 struct rb_node *node; 244 struct rb_node *node;
247 ext4_lblk_t ret = EXT_MAX_BLOCKS;
248 245
249 trace_ext4_es_find_extent_enter(inode, es->es_lblk); 246 BUG_ON(es == NULL);
247 trace_ext4_es_find_delayed_extent_enter(inode, lblk);
250 248
251 read_lock(&EXT4_I(inode)->i_es_lock); 249 read_lock(&EXT4_I(inode)->i_es_lock);
252 tree = &EXT4_I(inode)->i_es_tree; 250 tree = &EXT4_I(inode)->i_es_tree;
253 251
254 /* find extent in cache firstly */ 252 /* find extent in cache firstly */
255 es->es_len = es->es_pblk = 0; 253 es->es_lblk = es->es_len = es->es_pblk = 0;
256 if (tree->cache_es) { 254 if (tree->cache_es) {
257 es1 = tree->cache_es; 255 es1 = tree->cache_es;
258 if (in_range(es->es_lblk, es1->es_lblk, es1->es_len)) { 256 if (in_range(lblk, es1->es_lblk, es1->es_len)) {
259 es_debug("%u cached by [%u/%u) %llu %llx\n", 257 es_debug("%u cached by [%u/%u) %llu %llx\n",
260 es->es_lblk, es1->es_lblk, es1->es_len, 258 lblk, es1->es_lblk, es1->es_len,
261 ext4_es_pblock(es1), ext4_es_status(es1)); 259 ext4_es_pblock(es1), ext4_es_status(es1));
262 goto out; 260 goto out;
263 } 261 }
264 } 262 }
265 263
266 es1 = __es_tree_search(&tree->root, es->es_lblk); 264 es1 = __es_tree_search(&tree->root, lblk);
267 265
268out: 266out:
269 if (es1) { 267 if (es1 && !ext4_es_is_delayed(es1)) {
268 while ((node = rb_next(&es1->rb_node)) != NULL) {
269 es1 = rb_entry(node, struct extent_status, rb_node);
270 if (ext4_es_is_delayed(es1))
271 break;
272 }
273 }
274
275 if (es1 && ext4_es_is_delayed(es1)) {
270 tree->cache_es = es1; 276 tree->cache_es = es1;
271 es->es_lblk = es1->es_lblk; 277 es->es_lblk = es1->es_lblk;
272 es->es_len = es1->es_len; 278 es->es_len = es1->es_len;
273 es->es_pblk = es1->es_pblk; 279 es->es_pblk = es1->es_pblk;
274 node = rb_next(&es1->rb_node);
275 if (node) {
276 es1 = rb_entry(node, struct extent_status, rb_node);
277 ret = es1->es_lblk;
278 }
279 } 280 }
280 281
281 read_unlock(&EXT4_I(inode)->i_es_lock); 282 read_unlock(&EXT4_I(inode)->i_es_lock);
282 283
283 trace_ext4_es_find_extent_exit(inode, es, ret); 284 trace_ext4_es_find_delayed_extent_exit(inode, es);
284 return ret;
285} 285}
286 286
287static struct extent_status * 287static struct extent_status *
diff --git a/fs/ext4/extents_status.h b/fs/ext4/extents_status.h
index 3cad83303adb..3f69d097c6e7 100644
--- a/fs/ext4/extents_status.h
+++ b/fs/ext4/extents_status.h
@@ -51,8 +51,8 @@ extern int ext4_es_insert_extent(struct inode *inode, ext4_lblk_t lblk,
51 unsigned long long status); 51 unsigned long long status);
52extern int ext4_es_remove_extent(struct inode *inode, ext4_lblk_t lblk, 52extern int ext4_es_remove_extent(struct inode *inode, ext4_lblk_t lblk,
53 ext4_lblk_t len); 53 ext4_lblk_t len);
54extern ext4_lblk_t ext4_es_find_extent(struct inode *inode, 54extern void ext4_es_find_delayed_extent(struct inode *inode, ext4_lblk_t lblk,
55 struct extent_status *es); 55 struct extent_status *es);
56 56
57static inline int ext4_es_is_written(struct extent_status *es) 57static inline int ext4_es_is_written(struct extent_status *es)
58{ 58{
diff --git a/fs/ext4/file.c b/fs/ext4/file.c
index 2df9354b105e..7e85a10a6f4f 100644
--- a/fs/ext4/file.c
+++ b/fs/ext4/file.c
@@ -464,8 +464,7 @@ static loff_t ext4_seek_data(struct file *file, loff_t offset, loff_t maxsize)
464 * If there is a delay extent at this offset, 464 * If there is a delay extent at this offset,
465 * it will be as a data. 465 * it will be as a data.
466 */ 466 */
467 es.es_lblk = last; 467 ext4_es_find_delayed_extent(inode, last, &es);
468 (void)ext4_es_find_extent(inode, &es);
469 if (es.es_len != 0 && in_range(last, es.es_lblk, es.es_len)) { 468 if (es.es_len != 0 && in_range(last, es.es_lblk, es.es_len)) {
470 if (last != start) 469 if (last != start)
471 dataoff = last << blkbits; 470 dataoff = last << blkbits;
@@ -548,8 +547,7 @@ static loff_t ext4_seek_hole(struct file *file, loff_t offset, loff_t maxsize)
548 * If there is a delay extent at this offset, 547 * If there is a delay extent at this offset,
549 * we will skip this extent. 548 * we will skip this extent.
550 */ 549 */
551 es.es_lblk = last; 550 ext4_es_find_delayed_extent(inode, last, &es);
552 (void)ext4_es_find_extent(inode, &es);
553 if (es.es_len != 0 && in_range(last, es.es_lblk, es.es_len)) { 551 if (es.es_len != 0 && in_range(last, es.es_lblk, es.es_len)) {
554 last = es.es_lblk + es.es_len; 552 last = es.es_lblk + es.es_len;
555 holeoff = last << blkbits; 553 holeoff = last << blkbits;
diff --git a/include/trace/events/ext4.h b/include/trace/events/ext4.h
index 0ee507ff216d..c121cdf55ab3 100644
--- a/include/trace/events/ext4.h
+++ b/include/trace/events/ext4.h
@@ -2147,7 +2147,7 @@ TRACE_EVENT(ext4_es_remove_extent,
2147 __entry->lblk, __entry->len) 2147 __entry->lblk, __entry->len)
2148); 2148);
2149 2149
2150TRACE_EVENT(ext4_es_find_extent_enter, 2150TRACE_EVENT(ext4_es_find_delayed_extent_enter,
2151 TP_PROTO(struct inode *inode, ext4_lblk_t lblk), 2151 TP_PROTO(struct inode *inode, ext4_lblk_t lblk),
2152 2152
2153 TP_ARGS(inode, lblk), 2153 TP_ARGS(inode, lblk),
@@ -2169,11 +2169,10 @@ TRACE_EVENT(ext4_es_find_extent_enter,
2169 (unsigned long) __entry->ino, __entry->lblk) 2169 (unsigned long) __entry->ino, __entry->lblk)
2170); 2170);
2171 2171
2172TRACE_EVENT(ext4_es_find_extent_exit, 2172TRACE_EVENT(ext4_es_find_delayed_extent_exit,
2173 TP_PROTO(struct inode *inode, struct extent_status *es, 2173 TP_PROTO(struct inode *inode, struct extent_status *es),
2174 ext4_lblk_t ret),
2175 2174
2176 TP_ARGS(inode, es, ret), 2175 TP_ARGS(inode, es),
2177 2176
2178 TP_STRUCT__entry( 2177 TP_STRUCT__entry(
2179 __field( dev_t, dev ) 2178 __field( dev_t, dev )
@@ -2182,7 +2181,6 @@ TRACE_EVENT(ext4_es_find_extent_exit,
2182 __field( ext4_lblk_t, len ) 2181 __field( ext4_lblk_t, len )
2183 __field( ext4_fsblk_t, pblk ) 2182 __field( ext4_fsblk_t, pblk )
2184 __field( unsigned long long, status ) 2183 __field( unsigned long long, status )
2185 __field( ext4_lblk_t, ret )
2186 ), 2184 ),
2187 2185
2188 TP_fast_assign( 2186 TP_fast_assign(
@@ -2192,14 +2190,13 @@ TRACE_EVENT(ext4_es_find_extent_exit,
2192 __entry->len = es->es_len; 2190 __entry->len = es->es_len;
2193 __entry->pblk = ext4_es_pblock(es); 2191 __entry->pblk = ext4_es_pblock(es);
2194 __entry->status = ext4_es_status(es); 2192 __entry->status = ext4_es_status(es);
2195 __entry->ret = ret;
2196 ), 2193 ),
2197 2194
2198 TP_printk("dev %d,%d ino %lu es [%u/%u) mapped %llu status %llx ret %u", 2195 TP_printk("dev %d,%d ino %lu es [%u/%u) mapped %llu status %llx",
2199 MAJOR(__entry->dev), MINOR(__entry->dev), 2196 MAJOR(__entry->dev), MINOR(__entry->dev),
2200 (unsigned long) __entry->ino, 2197 (unsigned long) __entry->ino,
2201 __entry->lblk, __entry->len, 2198 __entry->lblk, __entry->len,
2202 __entry->pblk, __entry->status, __entry->ret) 2199 __entry->pblk, __entry->status)
2203); 2200);
2204 2201
2205#endif /* _TRACE_EXT4_H */ 2202#endif /* _TRACE_EXT4_H */