LCOV - code coverage report
Current view: top level - fs/btrfs - struct-funcs.c (source / functions) Hit Total Coverage
Test: btrfstest.info Lines: 9 9 100.0 %
Date: 2014-11-28 Functions: 9 9 100.0 %

          Line data    Source code
       1             : /*
       2             :  * Copyright (C) 2007 Oracle.  All rights reserved.
       3             :  *
       4             :  * This program is free software; you can redistribute it and/or
       5             :  * modify it under the terms of the GNU General Public
       6             :  * License v2 as published by the Free Software Foundation.
       7             :  *
       8             :  * This program is distributed in the hope that it will be useful,
       9             :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      10             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      11             :  * General Public License for more details.
      12             :  *
      13             :  * You should have received a copy of the GNU General Public
      14             :  * License along with this program; if not, write to the
      15             :  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
      16             :  * Boston, MA 021110-1307, USA.
      17             :  */
      18             : 
      19             : #include <linux/highmem.h>
      20             : #include <asm/unaligned.h>
      21             : 
      22             : #include "ctree.h"
      23             : 
      24             : static inline u8 get_unaligned_le8(const void *p)
      25             : {
      26     3661589 :        return *(u8 *)p;
      27             : }
      28             : 
      29             : static inline void put_unaligned_le8(u8 val, void *p)
      30             : {
      31      408497 :        *(u8 *)p = val;
      32             : }
      33             : 
      34             : /*
      35             :  * this is some deeply nasty code.
      36             :  *
      37             :  * The end result is that anyone who #includes ctree.h gets a
      38             :  * declaration for the btrfs_set_foo functions and btrfs_foo functions,
      39             :  * which are wappers of btrfs_set_token_#bits functions and
      40             :  * btrfs_get_token_#bits functions, which are defined in this file.
      41             :  *
      42             :  * These setget functions do all the extent_buffer related mapping
      43             :  * required to efficiently read and write specific fields in the extent
      44             :  * buffers.  Every pointer to metadata items in btrfs is really just
      45             :  * an unsigned long offset into the extent buffer which has been
      46             :  * cast to a specific type.  This gives us all the gcc type checking.
      47             :  *
      48             :  * The extent buffer api is used to do the page spanning work required to
      49             :  * have a metadata blocksize different from the page size.
      50             :  */
      51             : 
      52             : #define DEFINE_BTRFS_SETGET_BITS(bits)                                  \
      53             : u##bits btrfs_get_token_##bits(struct extent_buffer *eb, void *ptr,     \
      54             :                                unsigned long off,                       \
      55             :                                struct btrfs_map_token *token)           \
      56             : {                                                                       \
      57             :         unsigned long part_offset = (unsigned long)ptr;                 \
      58             :         unsigned long offset = part_offset + off;                       \
      59             :         void *p;                                                        \
      60             :         int err;                                                        \
      61             :         char *kaddr;                                                    \
      62             :         unsigned long map_start;                                        \
      63             :         unsigned long map_len;                                          \
      64             :         int size = sizeof(u##bits);                                     \
      65             :         u##bits res;                                                    \
      66             :                                                                         \
      67             :         if (token && token->kaddr && token->offset <= offset &&                \
      68             :             token->eb == eb &&                                               \
      69             :            (token->offset + PAGE_CACHE_SIZE >= offset + size)) {  \
      70             :                 kaddr = token->kaddr;                                        \
      71             :                 p = kaddr + part_offset - token->offset;             \
      72             :                 res = get_unaligned_le##bits(p + off);                  \
      73             :                 return res;                                             \
      74             :         }                                                               \
      75             :         err = map_private_extent_buffer(eb, offset, size,               \
      76             :                                         &kaddr, &map_start, &map_len);      \
      77             :         if (err) {                                                      \
      78             :                 __le##bits leres;                                       \
      79             :                                                                         \
      80             :                 read_extent_buffer(eb, &leres, offset, size);               \
      81             :                 return le##bits##_to_cpu(leres);                        \
      82             :         }                                                               \
      83             :         p = kaddr + part_offset - map_start;                            \
      84             :         res = get_unaligned_le##bits(p + off);                          \
      85             :         if (token) {                                                    \
      86             :                 token->kaddr = kaddr;                                        \
      87             :                 token->offset = map_start;                           \
      88             :                 token->eb = eb;                                              \
      89             :         }                                                               \
      90             :         return res;                                                     \
      91             : }                                                                       \
      92             : void btrfs_set_token_##bits(struct extent_buffer *eb,                   \
      93             :                             void *ptr, unsigned long off, u##bits val,  \
      94             :                             struct btrfs_map_token *token)              \
      95             : {                                                                       \
      96             :         unsigned long part_offset = (unsigned long)ptr;                 \
      97             :         unsigned long offset = part_offset + off;                       \
      98             :         void *p;                                                        \
      99             :         int err;                                                        \
     100             :         char *kaddr;                                                    \
     101             :         unsigned long map_start;                                        \
     102             :         unsigned long map_len;                                          \
     103             :         int size = sizeof(u##bits);                                     \
     104             :                                                                         \
     105             :         if (token && token->kaddr && token->offset <= offset &&                \
     106             :             token->eb == eb &&                                               \
     107             :            (token->offset + PAGE_CACHE_SIZE >= offset + size)) {  \
     108             :                 kaddr = token->kaddr;                                        \
     109             :                 p = kaddr + part_offset - token->offset;             \
     110             :                 put_unaligned_le##bits(val, p + off);                   \
     111             :                 return;                                                 \
     112             :         }                                                               \
     113             :         err = map_private_extent_buffer(eb, offset, size,               \
     114             :                         &kaddr, &map_start, &map_len);                      \
     115             :         if (err) {                                                      \
     116             :                 __le##bits val2;                                        \
     117             :                                                                         \
     118             :                 val2 = cpu_to_le##bits(val);                            \
     119             :                 write_extent_buffer(eb, &val2, offset, size);               \
     120             :                 return;                                                 \
     121             :         }                                                               \
     122             :         p = kaddr + part_offset - map_start;                            \
     123             :         put_unaligned_le##bits(val, p + off);                           \
     124             :         if (token) {                                                    \
     125             :                 token->kaddr = kaddr;                                        \
     126             :                 token->offset = map_start;                           \
     127             :                 token->eb = eb;                                              \
     128             :         }                                                               \
     129             : }
     130             : 
     131     8534272 : DEFINE_BTRFS_SETGET_BITS(8)
     132     3062988 : DEFINE_BTRFS_SETGET_BITS(16)
     133    95799120 : DEFINE_BTRFS_SETGET_BITS(32)
     134    33053371 : DEFINE_BTRFS_SETGET_BITS(64)
     135             : 
     136     1247331 : void btrfs_node_key(struct extent_buffer *eb,
     137             :                     struct btrfs_disk_key *disk_key, int nr)
     138             : {
     139             :         unsigned long ptr = btrfs_node_key_ptr_offset(nr);
     140     1247331 :         read_eb_member(eb, (struct btrfs_key_ptr *)ptr,
     141             :                        struct btrfs_key_ptr, key, disk_key);
     142     1248596 : }

Generated by: LCOV version 1.10