From 0f82731fc56448c2733f58e1f5db6c2cbfc90652 Mon Sep 17 00:00:00 2001 From: Chris Mason Date: Mon, 15 Oct 2007 16:18:56 -0400 Subject: Breakout BTRFS_SETGET_FUNCS into a separate C file, the inlines were too big. Signed-off-by: Chris Mason --- fs/btrfs/struct-funcs.c | 97 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 97 insertions(+) create mode 100644 fs/btrfs/struct-funcs.c (limited to 'fs/btrfs/struct-funcs.c') diff --git a/fs/btrfs/struct-funcs.c b/fs/btrfs/struct-funcs.c new file mode 100644 index 000000000000..cf68fcf9b552 --- /dev/null +++ b/fs/btrfs/struct-funcs.c @@ -0,0 +1,97 @@ +/* + * 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 +#define BTRFS_SETGET_FUNCS(name, type, member, bits) \ +u##bits btrfs_##name(struct extent_buffer *eb, \ + type *s) \ +{ \ + unsigned long offset = (unsigned long)s + \ + offsetof(type, member); \ + __le##bits *tmp; \ + /* 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) { \ + tmp = (__le##bits *)(eb->kaddr + offset - \ + eb->map_start); \ + return le##bits##_to_cpu(*tmp); \ + } \ + { \ + int err; \ + char *map_token; \ + char *kaddr; \ + int unmap_on_exit = (eb->map_token == NULL); \ + unsigned long map_start; \ + unsigned long map_len; \ + __le##bits res; \ + err = map_extent_buffer(eb, offset, \ + sizeof(((type *)0)->member), \ + &map_token, &kaddr, \ + &map_start, &map_len, KM_USER1); \ + if (err) { \ + read_eb_member(eb, s, type, member, &res); \ + return le##bits##_to_cpu(res); \ + } \ + tmp = (__le##bits *)(kaddr + offset - map_start); \ + res = le##bits##_to_cpu(*tmp); \ + 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 offset = (unsigned long)s + \ + offsetof(type, member); \ + __le##bits *tmp; \ + /* 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) { \ + tmp = (__le##bits *)(eb->kaddr + offset - \ + eb->map_start); \ + *tmp = 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) { \ + val = cpu_to_le##bits(val); \ + write_eb_member(eb, s, type, member, &val); \ + return; \ + } \ + tmp = (__le##bits *)(kaddr + offset - map_start); \ + *tmp = cpu_to_le##bits(val); \ + if (unmap_on_exit) \ + unmap_extent_buffer(eb, map_token, KM_USER1); \ + } \ +} + +#include "ctree.h" + -- cgit v1.2.2 From e644d021e328d3902559e5db687383f2da85993c Mon Sep 17 00:00:00 2001 From: Chris Mason Date: Tue, 6 Nov 2007 15:09:29 -0500 Subject: Fix recursive KM_USER1 usage in btrfs_realloc_node Signed-off-by: Chris Mason --- fs/btrfs/struct-funcs.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'fs/btrfs/struct-funcs.c') diff --git a/fs/btrfs/struct-funcs.c b/fs/btrfs/struct-funcs.c index cf68fcf9b552..c5715a60554c 100644 --- a/fs/btrfs/struct-funcs.c +++ b/fs/btrfs/struct-funcs.c @@ -95,3 +95,19 @@ void btrfs_set_##name(struct extent_buffer *eb, \ #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); +} -- cgit v1.2.2 From df68b8a7ad4a18c9e63f1c12015a59c3b7031adb Mon Sep 17 00:00:00 2001 From: David Miller Date: Fri, 15 Feb 2008 10:40:52 -0500 Subject: Btrfs: unaligned access fixes Btrfs set/get macros lose type information needed to avoid unaligned accesses on sparc64. ere is a patch for the kernel bits which fixes most of the unaligned accesses on sparc64. btrfs_name_hash is modified to return the hash value instead of getting a return location via a (potentially unaligned) pointer. Signed-off-by: Chris Mason --- fs/btrfs/struct-funcs.c | 30 ++++++++++++++---------------- 1 file changed, 14 insertions(+), 16 deletions(-) (limited to 'fs/btrfs/struct-funcs.c') diff --git a/fs/btrfs/struct-funcs.c b/fs/btrfs/struct-funcs.c index c5715a60554c..ad03a32d1116 100644 --- a/fs/btrfs/struct-funcs.c +++ b/fs/btrfs/struct-funcs.c @@ -21,16 +21,15 @@ u##bits btrfs_##name(struct extent_buffer *eb, \ type *s) \ { \ - unsigned long offset = (unsigned long)s + \ - offsetof(type, member); \ - __le##bits *tmp; \ + 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) { \ - tmp = (__le##bits *)(eb->kaddr + offset - \ - eb->map_start); \ - return le##bits##_to_cpu(*tmp); \ + p = (type *)(eb->kaddr + part_offset - eb->map_start); \ + return le##bits##_to_cpu(p->member); \ } \ { \ int err; \ @@ -48,8 +47,8 @@ u##bits btrfs_##name(struct extent_buffer *eb, \ read_eb_member(eb, s, type, member, &res); \ return le##bits##_to_cpu(res); \ } \ - tmp = (__le##bits *)(kaddr + offset - map_start); \ - res = le##bits##_to_cpu(*tmp); \ + 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; \ @@ -58,16 +57,15 @@ u##bits btrfs_##name(struct extent_buffer *eb, \ void btrfs_set_##name(struct extent_buffer *eb, \ type *s, u##bits val) \ { \ - unsigned long offset = (unsigned long)s + \ - offsetof(type, member); \ - __le##bits *tmp; \ + 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) { \ - tmp = (__le##bits *)(eb->kaddr + offset - \ - eb->map_start); \ - *tmp = cpu_to_le##bits(val); \ + p = (type *)(eb->kaddr + part_offset - eb->map_start); \ + p->member = cpu_to_le##bits(val); \ return; \ } \ { \ @@ -86,8 +84,8 @@ void btrfs_set_##name(struct extent_buffer *eb, \ write_eb_member(eb, s, type, member, &val); \ return; \ } \ - tmp = (__le##bits *)(kaddr + offset - map_start); \ - *tmp = cpu_to_le##bits(val); \ + 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); \ } \ -- cgit v1.2.2