diff options
| author | Steven Rostedt <srostedt@redhat.com> | 2010-09-10 11:47:43 -0400 |
|---|---|---|
| committer | Steven Rostedt <rostedt@goodmis.org> | 2010-09-14 14:46:01 -0400 |
| commit | 98c4fd046f07156ca6055677e8f03d4280be16c1 (patch) | |
| tree | bf461479713dbbaf79b0bf1a50a3ba0f30a2f17c | |
| parent | 4aeb69672d011fac5c8df671f3ca89f7987c104e (diff) | |
tracing: Keep track of set_ftrace_filter position and allow lseek again
This patch keeps track of the index within the elements of
set_ftrace_filter and if the position goes backwards, it nicely
resets and starts from the beginning again.
This allows for lseek and pread to work properly now.
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
| -rw-r--r-- | kernel/trace/ftrace.c | 34 |
1 files changed, 26 insertions, 8 deletions
diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c index c8db0dbb984e..2d51166b93fe 100644 --- a/kernel/trace/ftrace.c +++ b/kernel/trace/ftrace.c | |||
| @@ -1368,6 +1368,7 @@ enum { | |||
| 1368 | #define FTRACE_BUFF_MAX (KSYM_SYMBOL_LEN+4) /* room for wildcards */ | 1368 | #define FTRACE_BUFF_MAX (KSYM_SYMBOL_LEN+4) /* room for wildcards */ |
| 1369 | 1369 | ||
| 1370 | struct ftrace_iterator { | 1370 | struct ftrace_iterator { |
| 1371 | loff_t pos; | ||
| 1371 | loff_t func_pos; | 1372 | loff_t func_pos; |
| 1372 | struct ftrace_page *pg; | 1373 | struct ftrace_page *pg; |
| 1373 | struct dyn_ftrace *func; | 1374 | struct dyn_ftrace *func; |
| @@ -1385,9 +1386,8 @@ t_hash_next(struct seq_file *m, loff_t *pos) | |||
| 1385 | struct hlist_node *hnd = NULL; | 1386 | struct hlist_node *hnd = NULL; |
| 1386 | struct hlist_head *hhd; | 1387 | struct hlist_head *hhd; |
| 1387 | 1388 | ||
| 1388 | WARN_ON(!(iter->flags & FTRACE_ITER_HASH)); | ||
| 1389 | |||
| 1390 | (*pos)++; | 1389 | (*pos)++; |
| 1390 | iter->pos = *pos; | ||
| 1391 | 1391 | ||
| 1392 | if (iter->probe) | 1392 | if (iter->probe) |
| 1393 | hnd = &iter->probe->node; | 1393 | hnd = &iter->probe->node; |
| @@ -1427,14 +1427,9 @@ static void *t_hash_start(struct seq_file *m, loff_t *pos) | |||
| 1427 | void *p = NULL; | 1427 | void *p = NULL; |
| 1428 | loff_t l; | 1428 | loff_t l; |
| 1429 | 1429 | ||
| 1430 | if (!(iter->flags & FTRACE_ITER_HASH)) | ||
| 1431 | iter->func_pos = *pos; | ||
| 1432 | |||
| 1433 | if (iter->func_pos > *pos) | 1430 | if (iter->func_pos > *pos) |
| 1434 | return NULL; | 1431 | return NULL; |
| 1435 | 1432 | ||
| 1436 | iter->flags |= FTRACE_ITER_HASH; | ||
| 1437 | |||
| 1438 | iter->hidx = 0; | 1433 | iter->hidx = 0; |
| 1439 | for (l = 0; l <= (*pos - iter->func_pos); ) { | 1434 | for (l = 0; l <= (*pos - iter->func_pos); ) { |
| 1440 | p = t_hash_next(m, &l); | 1435 | p = t_hash_next(m, &l); |
| @@ -1444,6 +1439,9 @@ static void *t_hash_start(struct seq_file *m, loff_t *pos) | |||
| 1444 | if (!p) | 1439 | if (!p) |
| 1445 | return NULL; | 1440 | return NULL; |
| 1446 | 1441 | ||
| 1442 | /* Only set this if we have an item */ | ||
| 1443 | iter->flags |= FTRACE_ITER_HASH; | ||
| 1444 | |||
| 1447 | return iter; | 1445 | return iter; |
| 1448 | } | 1446 | } |
| 1449 | 1447 | ||
| @@ -1478,6 +1476,8 @@ t_next(struct seq_file *m, void *v, loff_t *pos) | |||
| 1478 | return t_hash_next(m, pos); | 1476 | return t_hash_next(m, pos); |
| 1479 | 1477 | ||
| 1480 | (*pos)++; | 1478 | (*pos)++; |
| 1479 | iter->pos = *pos; | ||
| 1480 | iter->func_pos = *pos; | ||
| 1481 | 1481 | ||
| 1482 | if (iter->flags & FTRACE_ITER_PRINTALL) | 1482 | if (iter->flags & FTRACE_ITER_PRINTALL) |
| 1483 | return NULL; | 1483 | return NULL; |
| @@ -1517,6 +1517,13 @@ t_next(struct seq_file *m, void *v, loff_t *pos) | |||
| 1517 | return iter; | 1517 | return iter; |
| 1518 | } | 1518 | } |
| 1519 | 1519 | ||
| 1520 | static void reset_iter_read(struct ftrace_iterator *iter) | ||
| 1521 | { | ||
| 1522 | iter->pos = 0; | ||
| 1523 | iter->func_pos = 0; | ||
| 1524 | iter->flags &= ~(FTRACE_ITER_PRINTALL & FTRACE_ITER_HASH); | ||
| 1525 | } | ||
| 1526 | |||
| 1520 | static void *t_start(struct seq_file *m, loff_t *pos) | 1527 | static void *t_start(struct seq_file *m, loff_t *pos) |
| 1521 | { | 1528 | { |
| 1522 | struct ftrace_iterator *iter = m->private; | 1529 | struct ftrace_iterator *iter = m->private; |
| @@ -1525,6 +1532,12 @@ static void *t_start(struct seq_file *m, loff_t *pos) | |||
| 1525 | 1532 | ||
| 1526 | mutex_lock(&ftrace_lock); | 1533 | mutex_lock(&ftrace_lock); |
| 1527 | /* | 1534 | /* |
| 1535 | * If an lseek was done, then reset and start from beginning. | ||
| 1536 | */ | ||
| 1537 | if (*pos < iter->pos) | ||
| 1538 | reset_iter_read(iter); | ||
| 1539 | |||
| 1540 | /* | ||
| 1528 | * For set_ftrace_filter reading, if we have the filter | 1541 | * For set_ftrace_filter reading, if we have the filter |
| 1529 | * off, we can short cut and just print out that all | 1542 | * off, we can short cut and just print out that all |
| 1530 | * functions are enabled. | 1543 | * functions are enabled. |
| @@ -1541,6 +1554,11 @@ static void *t_start(struct seq_file *m, loff_t *pos) | |||
| 1541 | if (iter->flags & FTRACE_ITER_HASH) | 1554 | if (iter->flags & FTRACE_ITER_HASH) |
| 1542 | return t_hash_start(m, pos); | 1555 | return t_hash_start(m, pos); |
| 1543 | 1556 | ||
| 1557 | /* | ||
| 1558 | * Unfortunately, we need to restart at ftrace_pages_start | ||
| 1559 | * every time we let go of the ftrace_mutex. This is because | ||
| 1560 | * those pointers can change without the lock. | ||
| 1561 | */ | ||
| 1544 | iter->pg = ftrace_pages_start; | 1562 | iter->pg = ftrace_pages_start; |
| 1545 | iter->idx = 0; | 1563 | iter->idx = 0; |
| 1546 | for (l = 0; l <= *pos; ) { | 1564 | for (l = 0; l <= *pos; ) { |
| @@ -2447,7 +2465,7 @@ static const struct file_operations ftrace_filter_fops = { | |||
| 2447 | .open = ftrace_filter_open, | 2465 | .open = ftrace_filter_open, |
| 2448 | .read = seq_read, | 2466 | .read = seq_read, |
| 2449 | .write = ftrace_filter_write, | 2467 | .write = ftrace_filter_write, |
| 2450 | .llseek = no_llseek, | 2468 | .llseek = ftrace_regex_lseek, |
| 2451 | .release = ftrace_filter_release, | 2469 | .release = ftrace_filter_release, |
| 2452 | }; | 2470 | }; |
| 2453 | 2471 | ||
