/*
 * 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);	\
u##bits btrfs_##name(struct extent_buffer *eb,				\
				   type *s)				\
{									\
	unsigned long part_offset = (unsigned long)s;			\
	unsigned long offset = part_offset + offsetof(type, member);	\
	type *p;							\
	/* ugly, but we want the fast path here */			\
	if (eb->map_token && offset >= eb->map_start &&			\
	    offset + sizeof(((type *)0)->member) <= eb->map_start +	\
	    eb->map_len) {						\
		p = (type *)(eb->kaddr + part_offset - eb->map_start);	\
		return le##bits##_to_cpu(p->member);			\
	}								\
	{								\
		int err;						\
		char *map_token;					\
		char *kaddr;						\
		int unmap_on_exit = (eb->map_token == NULL);		\
		unsigned long map_start;				\
		unsigned long map_len;					\
		u##bits res;						\
		err = map_extent_buffer(eb, offset,			\
				sizeof(((type *)0)->member),		\
				&map_token, &kaddr,			\
				&map_start, &map_len, KM_USER1);	\
		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 (unmap_on_exit)					\
			unmap_extent_buffer(eb, map_token, KM_USER1);	\
		return res;						\
	}								\
}									\
void btrfs_set_##name(struct extent_buffer *eb,				\
				    type *s, u##bits val)		\
{									\
	unsigned long part_offset = (unsigned long)s;			\
	unsigned long offset = part_offset + offsetof(type, member);	\
	type *p;							\
	/* ugly, but we want the fast path here */			\
	if (eb->map_token && offset >= eb->map_start &&			\
	    offset + sizeof(((type *)0)->member) <= eb->map_start +	\
	    eb->map_len) {						\
		p = (type *)(eb->kaddr + part_offset - eb->map_start);	\
		p->member = cpu_to_le##bits(val);			\
		return;							\
	}								\
	{								\
		int err;						\
		char *map_token;					\
		char *kaddr;						\
		int unmap_on_exit = (eb->map_token == NULL);		\
		unsigned long map_start;				\
		unsigned long map_len;					\
		err = map_extent_buffer(eb, offset,			\
				sizeof(((type *)0)->member),		\
				&map_token, &kaddr,			\
				&map_start, &map_len, KM_USER1);	\
		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 (unmap_on_exit)					\
			unmap_extent_buffer(eb, map_token, KM_USER1);	\
	}								\
}

#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);
	if (eb->map_token && ptr >= eb->map_start &&
	    ptr + sizeof(*disk_key) <= eb->map_start + eb->map_len) {
		memcpy(disk_key, eb->kaddr + ptr - eb->map_start,
			sizeof(*disk_key));
		return;
	} else if (eb->map_token) {
		unmap_extent_buffer(eb, eb->map_token, KM_USER1);
		eb->map_token = NULL;
	}
	read_eb_member(eb, (struct btrfs_key_ptr *)ptr,
		       struct btrfs_key_ptr, key, disk_key);
}
