/*
 * 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>

/* 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.
 *
 * The macro starts with a simple function prototype declaration so that
 * sparse won't complain about it being static.
 */

#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);	\
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);	\
	type *p;							\
	int err;						\
	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,		\
			mem_len,				\
			&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);			\
	if (token) {						\
		token->kaddr = kaddr;				\
		token->offset = map_start;			\
		token->eb = eb;					\
	}							\
	return res;						\
}									\
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);	\
	type *p;							\
	int err;						\
	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,		\
			mem_len,				\
			&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);			\
	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"

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);
	read_eb_member(eb, (struct btrfs_key_ptr *)ptr,
		       struct btrfs_key_ptr, key, disk_key);
}
