Blame view

fs/btrfs/struct-funcs.c 3.6 KB
0f82731fc   Chris Mason   Breakout BTRFS_SE...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
  /*
   * Copyright (C) 2007 Oracle.  All rights reserved.
   *
   * This program is free software; you can redistribute it and/or
   * modify it under the terms of the GNU General Public
   * License v2 as published by the Free Software Foundation.
   *
   * This program is distributed in the hope that it will be useful,
   * but WITHOUT ANY WARRANTY; without even the implied warranty of
   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   * General Public License for more details.
   *
   * You should have received a copy of the GNU General Public
   * License along with this program; if not, write to the
   * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
   * Boston, MA 021110-1307, USA.
   */
  
  #include <linux/highmem.h>
d352ac681   Chris Mason   Btrfs: add and im...
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
  
  /* this is some deeply nasty code.  ctree.h has a different
   * definition for this BTRFS_SETGET_FUNCS macro, behind a #ifndef
   *
   * The end result is that anyone who #includes ctree.h gets a
   * declaration for the btrfs_set_foo functions and btrfs_foo functions
   *
   * This file declares the macros and then #includes ctree.h, which results
   * in cpp creating the function here based on the template below.
   *
   * These setget functions do all the extent_buffer related mapping
   * required to efficiently read and write specific fields in the extent
   * buffers.  Every pointer to metadata items in btrfs is really just
   * an unsigned long offset into the extent buffer which has been
   * cast to a specific type.  This gives us all the gcc type checking.
   *
   * The extent buffer api is used to do all the kmapping and page
   * spanning work required to get extent buffers in highmem and have
   * a metadata blocksize different from the page size.
c99e905c9   Chris Mason   Btrfs: Fix sparse...
39
40
41
   *
   * The macro starts with a simple function prototype declaration so that
   * sparse won't complain about it being static.
d352ac681   Chris Mason   Btrfs: add and im...
42
   */
0f82731fc   Chris Mason   Breakout BTRFS_SE...
43
  #define BTRFS_SETGET_FUNCS(name, type, member, bits)			\
c99e905c9   Chris Mason   Btrfs: Fix sparse...
44
45
  u##bits btrfs_##name(struct extent_buffer *eb, type *s);		\
  void btrfs_set_##name(struct extent_buffer *eb, type *s, u##bits val);	\
0f82731fc   Chris Mason   Breakout BTRFS_SE...
46
47
48
  u##bits btrfs_##name(struct extent_buffer *eb,				\
  				   type *s)				\
  {									\
df68b8a7a   David Miller   Btrfs: unaligned ...
49
50
51
  	unsigned long part_offset = (unsigned long)s;			\
  	unsigned long offset = part_offset + offsetof(type, member);	\
  	type *p;							\
a65917156   Chris Mason   Btrfs: stop using...
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
  	int err;						\
  	char *kaddr;						\
  	unsigned long map_start;				\
  	unsigned long map_len;					\
  	u##bits res;						\
  	err = map_private_extent_buffer(eb, offset,		\
  			sizeof(((type *)0)->member),		\
  			&kaddr, &map_start, &map_len);		\
  	if (err) {						\
  		__le##bits leres;				\
  		read_eb_member(eb, s, type, member, &leres);	\
  		return le##bits##_to_cpu(leres);		\
  	}							\
  	p = (type *)(kaddr + part_offset - map_start);		\
  	res = le##bits##_to_cpu(p->member);			\
  	return res;						\
0f82731fc   Chris Mason   Breakout BTRFS_SE...
68
69
70
71
  }									\
  void btrfs_set_##name(struct extent_buffer *eb,				\
  				    type *s, u##bits val)		\
  {									\
df68b8a7a   David Miller   Btrfs: unaligned ...
72
73
74
  	unsigned long part_offset = (unsigned long)s;			\
  	unsigned long offset = part_offset + offsetof(type, member);	\
  	type *p;							\
a65917156   Chris Mason   Btrfs: stop using...
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
  	int err;						\
  	char *kaddr;						\
  	unsigned long map_start;				\
  	unsigned long map_len;					\
  	err = map_private_extent_buffer(eb, offset,		\
  			sizeof(((type *)0)->member),		\
  			&kaddr, &map_start, &map_len);		\
  	if (err) {						\
  		__le##bits val2;				\
  		val2 = cpu_to_le##bits(val);			\
  		write_eb_member(eb, s, type, member, &val2);	\
  		return;						\
  	}							\
  	p = (type *)(kaddr + part_offset - map_start);		\
  	p->member = cpu_to_le##bits(val);			\
0f82731fc   Chris Mason   Breakout BTRFS_SE...
90
91
92
  }
  
  #include "ctree.h"
e644d021e   Chris Mason   Fix recursive KM_...
93
94
95
96
  void btrfs_node_key(struct extent_buffer *eb,
  		    struct btrfs_disk_key *disk_key, int nr)
  {
  	unsigned long ptr = btrfs_node_key_ptr_offset(nr);
e644d021e   Chris Mason   Fix recursive KM_...
97
98
99
  	read_eb_member(eb, (struct btrfs_key_ptr *)ptr,
  		       struct btrfs_key_ptr, key, disk_key);
  }