Btrfs: Avoid memcpy where possible in extent_buffers
authorChris Mason <chris.mason@oracle.com>
Mon, 15 Oct 2007 20:14:37 +0000 (16:14 -0400)
committerChris Mason <chris.mason@oracle.com>
Thu, 25 Sep 2008 15:03:56 +0000 (11:03 -0400)
Signed-off-by: Chris Mason <chris.mason@oracle.com>
fs/btrfs/ctree.h
fs/btrfs/disk-io.c
fs/btrfs/extent_map.c
fs/btrfs/extent_map.h

index 30fbbd7..aed0861 100644 (file)
@@ -483,15 +483,50 @@ static inline void btrfs_set_##name(struct extent_buffer *eb,             \
 #define BTRFS_SETGET_HEADER_FUNCS(name, type, member, bits)            \
 static inline u##bits btrfs_##name(struct extent_buffer *eb)           \
 {                                                                      \
-       __le##bits res;                                                 \
-       read_eb_member(eb, NULL, type, member, &res);                   \
-       return le##bits##_to_cpu(res);                                  \
+       int err;                                                        \
+       char *map_token;                                                \
+       char *kaddr;                                                    \
+       unsigned long map_start;                                        \
+       unsigned long map_len;                                          \
+       unsigned long offset = offsetof(type, member);                  \
+       err = map_extent_buffer(eb, offset,                             \
+                               sizeof(((type *)0)->member),            \
+                               &map_token, &kaddr,                     \
+                               &map_start, &map_len, KM_USER0);        \
+       if (!err) {                                                     \
+               __le##bits *tmp = (__le##bits *)(kaddr + offset -       \
+                                              map_start);              \
+               u##bits res = le##bits##_to_cpu(*tmp);                  \
+               unmap_extent_buffer(eb, map_token, KM_USER0);           \
+               return res;                                             \
+       } else {                                                        \
+               __le##bits res;                                         \
+               read_eb_member(eb, NULL, type, member, &res);           \
+               return le##bits##_to_cpu(res);                          \
+       }                                                               \
 }                                                                      \
 static inline void btrfs_set_##name(struct extent_buffer *eb,          \
                                    u##bits val)                        \
 {                                                                      \
-       val = cpu_to_le##bits(val);                                     \
-       write_eb_member(eb, NULL, type, member, &val);                  \
+       int err;                                                        \
+       char *map_token;                                                \
+       char *kaddr;                                                    \
+       unsigned long map_start;                                        \
+       unsigned long map_len;                                          \
+       unsigned long offset = offsetof(type, member);                  \
+       err = map_extent_buffer(eb, offset,                             \
+                               sizeof(((type *)0)->member),            \
+                               &map_token, &kaddr,                     \
+                               &map_start, &map_len, KM_USER0);        \
+       if (!err) {                                                     \
+               __le##bits *tmp = (__le##bits *)(kaddr + offset -       \
+                                              map_start);              \
+               *tmp = cpu_to_le##bits(val);                            \
+               unmap_extent_buffer(eb, map_token, KM_USER0);           \
+       } else {                                                        \
+               val = cpu_to_le##bits(val);                             \
+               write_eb_member(eb, NULL, type, member, &val);          \
+       }                                                               \
 }
 
 #define BTRFS_SETGET_STACK_FUNCS(name, type, member, bits)             \
index 0c1f90c..8242933 100644 (file)
@@ -609,20 +609,20 @@ int close_ctree(struct btrfs_root *root)
 
 int btrfs_buffer_uptodate(struct extent_buffer *buf)
 {
-       struct inode *btree_inode = buf->pages[0]->mapping->host;
+       struct inode *btree_inode = buf->first_page->mapping->host;
        return extent_buffer_uptodate(&BTRFS_I(btree_inode)->extent_tree, buf);
 }
 
 int btrfs_set_buffer_uptodate(struct extent_buffer *buf)
 {
-       struct inode *btree_inode = buf->pages[0]->mapping->host;
+       struct inode *btree_inode = buf->first_page->mapping->host;
        return set_extent_buffer_uptodate(&BTRFS_I(btree_inode)->extent_tree,
                                          buf);
 }
 
 void btrfs_mark_buffer_dirty(struct extent_buffer *buf)
 {
-       struct btrfs_root *root = BTRFS_I(buf->pages[0]->mapping->host)->root;
+       struct btrfs_root *root = BTRFS_I(buf->first_page->mapping->host)->root;
        u64 transid = btrfs_header_generation(buf);
        struct inode *btree_inode = root->fs_info->btree_inode;
 
Simple merge
Simple merge