diff options
author | Chris Mason <chris.mason@oracle.com> | 2007-10-15 16:18:55 -0400 |
---|---|---|
committer | Chris Mason <chris.mason@oracle.com> | 2008-09-25 11:03:56 -0400 |
commit | 810191ff3087e8143b41a944fcf4fd8c693f00e3 (patch) | |
tree | 9d23dd51458623eaac41bc8c89dd2998a2eda7ae /fs/btrfs/ctree.h | |
parent | 3326d1b07c0cb6a2ff5b835b7a2cffa54124d074 (diff) |
Btrfs: extent_map optimizations to cut down on CPU usage
Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs/ctree.h')
-rw-r--r-- | fs/btrfs/ctree.h | 74 |
1 files changed, 14 insertions, 60 deletions
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index 18994c53106c..a942a2427228 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h | |||
@@ -19,6 +19,8 @@ | |||
19 | #ifndef __BTRFS__ | 19 | #ifndef __BTRFS__ |
20 | #define __BTRFS__ | 20 | #define __BTRFS__ |
21 | 21 | ||
22 | #include <linux/mm.h> | ||
23 | #include <linux/highmem.h> | ||
22 | #include <linux/fs.h> | 24 | #include <linux/fs.h> |
23 | #include <linux/workqueue.h> | 25 | #include <linux/workqueue.h> |
24 | #include <linux/completion.h> | 26 | #include <linux/completion.h> |
@@ -499,70 +501,22 @@ static inline void btrfs_set_##name(struct extent_buffer *eb, \ | |||
499 | #define BTRFS_SETGET_HEADER_FUNCS(name, type, member, bits) \ | 501 | #define BTRFS_SETGET_HEADER_FUNCS(name, type, member, bits) \ |
500 | static inline u##bits btrfs_##name(struct extent_buffer *eb) \ | 502 | static inline u##bits btrfs_##name(struct extent_buffer *eb) \ |
501 | { \ | 503 | { \ |
502 | int err; \ | 504 | char *kaddr = kmap_atomic(eb->first_page, KM_USER0); \ |
503 | char *map_token; \ | ||
504 | char *kaddr; \ | ||
505 | unsigned long map_start; \ | ||
506 | unsigned long map_len; \ | ||
507 | unsigned long offset = offsetof(type, member); \ | 505 | unsigned long offset = offsetof(type, member); \ |
508 | int unmap_on_exit = (eb->map_token == NULL); \ | 506 | u##bits res; \ |
509 | if (eb->map_token && offset >= eb->map_start && \ | 507 | __le##bits *tmp = (__le##bits *)(kaddr + offset); \ |
510 | offset + sizeof(((type *)0)->member) <= eb->map_start + \ | 508 | res = le##bits##_to_cpu(*tmp); \ |
511 | eb->map_len) { \ | 509 | kunmap_atomic(kaddr, KM_USER0); \ |
512 | kaddr = eb->kaddr; \ | 510 | return res; \ |
513 | map_start = eb->map_start; \ | ||
514 | err = 0; \ | ||
515 | } else { \ | ||
516 | err = map_extent_buffer(eb, offset, \ | ||
517 | sizeof(((type *)0)->member), \ | ||
518 | &map_token, &kaddr, \ | ||
519 | &map_start, &map_len, KM_USER1); \ | ||
520 | } \ | ||
521 | if (!err) { \ | ||
522 | __le##bits *tmp = (__le##bits *)(kaddr + offset - \ | ||
523 | map_start); \ | ||
524 | u##bits res = le##bits##_to_cpu(*tmp); \ | ||
525 | if (unmap_on_exit) \ | ||
526 | unmap_extent_buffer(eb, map_token, KM_USER1); \ | ||
527 | return res; \ | ||
528 | } else { \ | ||
529 | __le##bits res; \ | ||
530 | read_eb_member(eb, NULL, type, member, &res); \ | ||
531 | return le##bits##_to_cpu(res); \ | ||
532 | } \ | ||
533 | } \ | 511 | } \ |
534 | static inline void btrfs_set_##name(struct extent_buffer *eb, \ | 512 | static inline void btrfs_set_##name(struct extent_buffer *eb, \ |
535 | u##bits val) \ | 513 | u##bits val) \ |
536 | { \ | 514 | { \ |
537 | int err; \ | 515 | char *kaddr = kmap_atomic(eb->first_page, KM_USER0); \ |
538 | char *map_token; \ | ||
539 | char *kaddr; \ | ||
540 | unsigned long map_start; \ | ||
541 | unsigned long map_len; \ | ||
542 | unsigned long offset = offsetof(type, member); \ | 516 | unsigned long offset = offsetof(type, member); \ |
543 | int unmap_on_exit = (eb->map_token == NULL); \ | 517 | __le##bits *tmp = (__le##bits *)(kaddr + offset); \ |
544 | if (eb->map_token && offset >= eb->map_start && \ | 518 | *tmp = cpu_to_le##bits(val); \ |
545 | offset + sizeof(((type *)0)->member) <= eb->map_start + \ | 519 | kunmap_atomic(kaddr, KM_USER0); \ |
546 | eb->map_len) { \ | ||
547 | kaddr = eb->kaddr; \ | ||
548 | map_start = eb->map_start; \ | ||
549 | err = 0; \ | ||
550 | } else { \ | ||
551 | err = map_extent_buffer(eb, offset, \ | ||
552 | sizeof(((type *)0)->member), \ | ||
553 | &map_token, &kaddr, \ | ||
554 | &map_start, &map_len, KM_USER1); \ | ||
555 | } \ | ||
556 | if (!err) { \ | ||
557 | __le##bits *tmp = (__le##bits *)(kaddr + offset - \ | ||
558 | map_start); \ | ||
559 | *tmp = cpu_to_le##bits(val); \ | ||
560 | if (unmap_on_exit) \ | ||
561 | unmap_extent_buffer(eb, map_token, KM_USER1); \ | ||
562 | } else { \ | ||
563 | val = cpu_to_le##bits(val); \ | ||
564 | write_eb_member(eb, NULL, type, member, &val); \ | ||
565 | } \ | ||
566 | } | 520 | } |
567 | 521 | ||
568 | #define BTRFS_SETGET_STACK_FUNCS(name, type, member, bits) \ | 522 | #define BTRFS_SETGET_STACK_FUNCS(name, type, member, bits) \ |
@@ -659,13 +613,13 @@ static inline void btrfs_set_node_blockptr(struct extent_buffer *eb, | |||
659 | btrfs_set_key_blockptr(eb, (struct btrfs_key_ptr *)ptr, val); | 613 | btrfs_set_key_blockptr(eb, (struct btrfs_key_ptr *)ptr, val); |
660 | } | 614 | } |
661 | 615 | ||
662 | static unsigned long btrfs_node_key_ptr_offset(int nr) | 616 | static inline unsigned long btrfs_node_key_ptr_offset(int nr) |
663 | { | 617 | { |
664 | return offsetof(struct btrfs_node, ptrs) + | 618 | return offsetof(struct btrfs_node, ptrs) + |
665 | sizeof(struct btrfs_key_ptr) * nr; | 619 | sizeof(struct btrfs_key_ptr) * nr; |
666 | } | 620 | } |
667 | 621 | ||
668 | static void btrfs_node_key(struct extent_buffer *eb, | 622 | static inline void btrfs_node_key(struct extent_buffer *eb, |
669 | struct btrfs_disk_key *disk_key, int nr) | 623 | struct btrfs_disk_key *disk_key, int nr) |
670 | { | 624 | { |
671 | unsigned long ptr; | 625 | unsigned long ptr; |