diff options
| author | Chris Mason <chris.mason@oracle.com> | 2012-03-03 07:40:03 -0500 | 
|---|---|---|
| committer | Chris Mason <chris.mason@oracle.com> | 2012-03-26 17:04:23 -0400 | 
| commit | cfed81a04eb555f5606d1b6a54bdbabab0ee1ac3 (patch) | |
| tree | 2a763276869693b21c0e3a14f725f642c1f27fd3 /fs/btrfs/struct-funcs.c | |
| parent | 0b32f4bbb423f02acee6d43cd442f5f0775db7e0 (diff) | |
| download | olio-linux-3.10-cfed81a04eb555f5606d1b6a54bdbabab0ee1ac3.tar.xz olio-linux-3.10-cfed81a04eb555f5606d1b6a54bdbabab0ee1ac3.zip  | |
Btrfs: add the ability to cache a pointer into the eb
This cuts down on the CPU time used by map_private_extent_buffer
Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs/struct-funcs.c')
| -rw-r--r-- | fs/btrfs/struct-funcs.c | 53 | 
1 files changed, 46 insertions, 7 deletions
diff --git a/fs/btrfs/struct-funcs.c b/fs/btrfs/struct-funcs.c index bc1f6ad1844..c6ffa581241 100644 --- a/fs/btrfs/struct-funcs.c +++ b/fs/btrfs/struct-funcs.c @@ -44,8 +44,9 @@  #define BTRFS_SETGET_FUNCS(name, type, member, bits)			\  u##bits btrfs_##name(struct extent_buffer *eb, type *s);		\  void btrfs_set_##name(struct extent_buffer *eb, type *s, u##bits val);	\ -u##bits btrfs_##name(struct extent_buffer *eb,				\ -				   type *s)				\ +void btrfs_set_token_##name(struct extent_buffer *eb, type *s, u##bits val, struct btrfs_map_token *token);	\ +u##bits btrfs_token_##name(struct extent_buffer *eb,				\ +			   type *s, struct btrfs_map_token *token)	\  {									\  	unsigned long part_offset = (unsigned long)s;			\  	unsigned long offset = part_offset + offsetof(type, member);	\ @@ -54,9 +55,18 @@ u##bits btrfs_##name(struct extent_buffer *eb,				\  	char *kaddr;						\  	unsigned long map_start;				\  	unsigned long map_len;					\ +	unsigned long mem_len = sizeof(((type *)0)->member);	\  	u##bits res;						\ +	if (token && token->kaddr && token->offset <= offset &&	\ +	    token->eb == eb &&					\ +	   (token->offset + PAGE_CACHE_SIZE >= offset + mem_len)) { \ +		kaddr = token->kaddr;				\ +		p = (type *)(kaddr + part_offset - token->offset);  \ +		res = le##bits##_to_cpu(p->member);		\ +		return res;					\ +	}							\  	err = map_private_extent_buffer(eb, offset,		\ -			sizeof(((type *)0)->member),		\ +			mem_len,				\  			&kaddr, &map_start, &map_len);		\  	if (err) {						\  		__le##bits leres;				\ @@ -65,10 +75,15 @@ u##bits btrfs_##name(struct extent_buffer *eb,				\  	}							\  	p = (type *)(kaddr + part_offset - map_start);		\  	res = le##bits##_to_cpu(p->member);			\ +	if (token) {						\ +		token->kaddr = kaddr;				\ +		token->offset = map_start;			\ +		token->eb = eb;					\ +	}							\  	return res;						\  }									\ -void btrfs_set_##name(struct extent_buffer *eb,				\ -				    type *s, u##bits val)		\ +void btrfs_set_token_##name(struct extent_buffer *eb,				\ +			    type *s, u##bits val, struct btrfs_map_token *token)		\  {									\  	unsigned long part_offset = (unsigned long)s;			\  	unsigned long offset = part_offset + offsetof(type, member);	\ @@ -77,8 +92,17 @@ void btrfs_set_##name(struct extent_buffer *eb,				\  	char *kaddr;						\  	unsigned long map_start;				\  	unsigned long map_len;					\ +	unsigned long mem_len = sizeof(((type *)0)->member);	\ +	if (token && token->kaddr && token->offset <= offset &&	\ +	    token->eb == eb &&					\ +	   (token->offset + PAGE_CACHE_SIZE >= offset + mem_len)) { \ +		kaddr = token->kaddr;				\ +		p = (type *)(kaddr + part_offset - token->offset);  \ +		p->member = cpu_to_le##bits(val);		\ +		return;						\ +	}							\  	err = map_private_extent_buffer(eb, offset,		\ -			sizeof(((type *)0)->member),		\ +			mem_len,				\  			&kaddr, &map_start, &map_len);		\  	if (err) {						\  		__le##bits val2;				\ @@ -88,7 +112,22 @@ void btrfs_set_##name(struct extent_buffer *eb,				\  	}							\  	p = (type *)(kaddr + part_offset - map_start);		\  	p->member = cpu_to_le##bits(val);			\ -} +	if (token) {						\ +		token->kaddr = kaddr;				\ +		token->offset = map_start;			\ +		token->eb = eb;					\ +	}							\ +}								\ +void btrfs_set_##name(struct extent_buffer *eb,			\ +		      type *s, u##bits val)			\ +{								\ +	btrfs_set_token_##name(eb, s, val, NULL);		\ +}								\ +u##bits btrfs_##name(struct extent_buffer *eb,			\ +		      type *s)					\ +{								\ +	return btrfs_token_##name(eb, s, NULL);			\ +}								\  #include "ctree.h"  |