login
Header Space

 
 

BTRFS only works with PAGE_SIZE <= 4K

Score:
Previous message: [thread] [date] [author]
Next message: [thread] [date] [author]
To: <chris.mason@...>
Cc: <linux-kernel@...>, <linux-fsdevel@...>, <btrfs-devel@...>
Date: Tuesday, February 12, 2008 - 5:55 pm

From: Chris Mason <chris.mason@oracle.com>
Date: Wed, 6 Feb 2008 12:00:13 -0500


Any page size larger than 4K will not work with btrfs.  All of the
extent stuff assumes that PAGE_SIZE <= sectorsize.

I confirmed this by forcing mkfs.btrfs to use an 8K sectorsize on
sparc64 and I was finally able to successfully mount a partition.

With 4K there are zero's in the root tree node header, because it's
extent's location on disk is at a sub-PAGE_SIZE multiple and the
extent code doesn't handle that.

You really need to start validating this stuff on other platforms.
Something that isn't little endian and something that doesn't use 4K
pages.  I'm sure you have some powerpc parts around somewhere. :)

Anyways, here is a patch for the kernel bits which fixes most of the
unaligned accesses on sparc64.

diff -u --recursive --new-file vanilla/btrfs-0.12/ctree.h btrfs-0.12/ctree.h
--- vanilla/btrfs-0.12/ctree.h	2008-02-06 08:37:39.000000000 -0800
+++ btrfs-0.12/ctree.h	2008-02-10 17:17:49.000000000 -0800
@@ -495,22 +495,17 @@
 #define BTRFS_SETGET_HEADER_FUNCS(name, type, member, bits)		\
 static inline u##bits btrfs_##name(struct extent_buffer *eb)		\
 {									\
-	char *kaddr = kmap_atomic(eb->first_page, KM_USER0);		\
-	unsigned long offset = offsetof(type, member);			\
-	u##bits res;							\
-	__le##bits *tmp = (__le##bits *)(kaddr + offset);		\
-	res = le##bits##_to_cpu(*tmp);					\
-	kunmap_atomic(kaddr, KM_USER0);					\
+	type *p = kmap_atomic(eb->first_page, KM_USER0);		\
+	u##bits res = le##bits##_to_cpu(p->member);			\
+	kunmap_atomic(p, KM_USER0);					\
 	return res;							\
 }									\
 static inline void btrfs_set_##name(struct extent_buffer *eb,		\
 				    u##bits val)			\
 {									\
-	char *kaddr = kmap_atomic(eb->first_page, KM_USER0);		\
-	unsigned long offset = offsetof(type, member);			\
-	__le##bits *tmp = (__le##bits *)(kaddr + offset);		\
-	*tmp = cpu_to_le##bits(val);					\
-	kunmap_atomic(kaddr, KM_USER0);					\
+	type *p = kmap_atomic(eb->first_page, KM_USER0);		\
+	p->member = cpu_to_le##bits(val);				\
+	kunmap_atomic(p, KM_USER0);					\
 }
 
 #define BTRFS_SETGET_STACK_FUNCS(name, type, member, bits)		\
diff -u --recursive --new-file vanilla/btrfs-0.12/dir-item.c btrfs-0.12/dir-item.c
--- vanilla/btrfs-0.12/dir-item.c	2008-02-06 08:37:39.000000000 -0800
+++ btrfs-0.12/dir-item.c	2008-02-10 17:20:00.000000000 -0800
@@ -71,8 +71,7 @@
 
 	key.objectid = dir;
 	btrfs_set_key_type(&key, BTRFS_XATTR_ITEM_KEY);
-	ret = btrfs_name_hash(name, name_len, &key.offset);
-	BUG_ON(ret);
+	key.offset = btrfs_name_hash(name, name_len);
 	path = btrfs_alloc_path();
 	if (!path)
 		return -ENOMEM;
@@ -125,8 +124,7 @@
 
 	key.objectid = dir;
 	btrfs_set_key_type(&key, BTRFS_DIR_ITEM_KEY);
-	ret = btrfs_name_hash(name, name_len, &key.offset);
-	BUG_ON(ret);
+	key.offset = btrfs_name_hash(name, name_len);
 	path = btrfs_alloc_path();
 	data_size = sizeof(*dir_item) + name_len;
 	dir_item = insert_with_overflow(trans, root, path, &key, data_size,
@@ -199,8 +197,7 @@
 	key.objectid = dir;
 	btrfs_set_key_type(&key, BTRFS_DIR_ITEM_KEY);
 
-	ret = btrfs_name_hash(name, name_len, &key.offset);
-	BUG_ON(ret);
+	key.offset = btrfs_name_hash(name, name_len);
 
 	ret = btrfs_search_slot(trans, root, &key, path, ins_len, cow);
 	if (ret < 0)
@@ -261,8 +258,7 @@
 
 	key.objectid = dir;
 	btrfs_set_key_type(&key, BTRFS_XATTR_ITEM_KEY);
-	ret = btrfs_name_hash(name, name_len, &key.offset);
-	BUG_ON(ret);
+	key.offset = btrfs_name_hash(name, name_len);
 	ret = btrfs_search_slot(trans, root, &key, path, ins_len, cow);
 	if (ret < 0)
 		return ERR_PTR(ret);
diff -u --recursive --new-file vanilla/btrfs-0.12/hash.c btrfs-0.12/hash.c
--- vanilla/btrfs-0.12/hash.c	2008-02-06 08:37:39.000000000 -0800
+++ btrfs-0.12/hash.c	2008-02-10 17:19:19.000000000 -0800
@@ -76,19 +76,18 @@
 		*buf++ = pad;
 }
 
-int btrfs_name_hash(const char *name, int len, u64 *hash_result)
+u64 btrfs_name_hash(const char *name, int len)
 {
 	__u32	hash;
 	__u32	minor_hash = 0;
 	const char	*p;
 	__u32		in[8], buf[2];
+	u64		hash_result;
 
 	if (len == 1 && *name == '.') {
-		*hash_result = 1;
-		return 0;
+		return 1;
 	} else if (len == 2 && name[0] == '.' && name[1] == '.') {
-		*hash_result = 2;
-		return 0;
+		return 2;
 	}
 
 	/* Initialize the default seed for the hash checksum functions */
@@ -106,8 +105,8 @@
 	}
 	hash = buf[0];
 	minor_hash = buf[1];
-	*hash_result = buf[0];
-	*hash_result <<= 32;
-	*hash_result |= buf[1];
-	return 0;
+	hash_result = buf[0];
+	hash_result <<= 32;
+	hash_result |= buf[1];
+	return hash_result;
 }
diff -u --recursive --new-file vanilla/btrfs-0.12/hash.h btrfs-0.12/hash.h
--- vanilla/btrfs-0.12/hash.h	2008-02-06 08:37:39.000000000 -0800
+++ btrfs-0.12/hash.h	2008-02-10 17:19:25.000000000 -0800
@@ -18,5 +18,5 @@
 
 #ifndef __HASH__
 #define __HASH__
-int btrfs_name_hash(const char *name, int len, u64 *hash_result);
+u64 btrfs_name_hash(const char *name, int len);
 #endif
diff -u --recursive --new-file vanilla/btrfs-0.12/struct-funcs.c btrfs-0.12/struct-funcs.c
--- vanilla/btrfs-0.12/struct-funcs.c	2008-02-06 08:37:39.000000000 -0800
+++ btrfs-0.12/struct-funcs.c	2008-02-11 22:50:46.000000000 -0800
@@ -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 @@
 			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 @@
 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 @@
 			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);	\
 	}								\
-
To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Previous message: [thread] [date] [author]
Next message: [thread] [date] [author]

Messages in current thread:
[ANNOUNCE] Btrfs v0.12 released, Chris Mason, (Wed Feb 6, 1:00 pm)
BTRFS only works with PAGE_SIZE <= 4K, David Miller, (Tue Feb 12, 5:55 pm)
Re: BTRFS only works with PAGE_SIZE &lt;= 4K, Chris Mason, (Tue Feb 12, 6:03 pm)
CRC32C big endian bugs..., David Miller, (Tue Feb 12, 5:23 am)
BTRFS partition usage..., David Miller, (Tue Feb 12, 3:21 am)
Re: BTRFS partition usage..., David Miller, (Tue Feb 12, 4:11 am)
Re: BTRFS partition usage..., Chris Mason, (Tue Feb 12, 9:49 am)
Re: BTRFS partition usage..., David Miller, (Tue Feb 12, 4:50 pm)
Re: BTRFS partition usage..., Jan Engelhardt, (Tue Feb 12, 10:00 am)
Re: BTRFS partition usage..., David Miller, (Tue Feb 12, 7:28 pm)
Re: BTRFS partition usage..., Theodore Tso, (Tue Feb 12, 8:45 pm)
Re: BTRFS partition usage..., David Miller, (Tue Feb 12, 7:26 pm)
Re: BTRFS partition usage..., Bryan Henderson, (Tue Feb 12, 9:25 pm)
Re: BTRFS partition usage..., Jan Engelhardt, (Tue Feb 12, 7:39 pm)
Re: BTRFS partition usage..., David Miller, (Tue Feb 12, 9:08 pm)
Re: BTRFS partition usage..., Chris Mason, (Tue Feb 12, 10:08 am)
Re: BTRFS partition usage..., David Miller, (Tue Feb 12, 7:33 pm)
Re: BTRFS partition usage..., Jeff Garzik, (Tue Feb 12, 10:10 pm)
Re: BTRFS partition usage..., Szabolcs Szakacsits, (Wed Feb 13, 8:51 pm)
Re: BTRFS partition usage..., Jan Engelhardt, (Tue Feb 12, 10:21 am)
Re: BTRFS partition usage..., David Miller, (Tue Feb 12, 7:34 pm)
Re: BTRFS partition usage..., Chris Mason, (Tue Feb 12, 10:35 am)
Re: BTRFS partition usage..., David Miller, (Tue Feb 12, 7:35 pm)
Re: BTRFS partition usage..., Christoph Hellwig, (Wed Feb 13, 3:02 am)
Re: BTRFS partition usage..., Jan Engelhardt, (Tue Feb 12, 11:04 am)
Re: BTRFS partition usage..., David Miller, (Tue Feb 12, 7:38 pm)
Re: BTRFS partition usage..., Jan Engelhardt, (Tue Feb 12, 7:42 pm)
Re: BTRFS partition usage..., Rene Herman, (Tue Feb 12, 9:22 pm)
Re: BTRFS partition usage..., David Miller, (Tue Feb 12, 9:09 pm)
Re: BTRFS partition usage..., Chris Mason, (Tue Feb 12, 12:17 pm)
Re: [ANNOUNCE] Btrfs v0.12 released, David Miller, (Sun Feb 10, 9:12 pm)
Re: [ANNOUNCE] Btrfs v0.12 released, Chris Mason, (Mon Feb 11, 9:42 am)
Re: [ANNOUNCE] Btrfs v0.12 released, David Miller, (Tue Feb 12, 2:43 am)
Re: [ANNOUNCE] Btrfs v0.12 released, Chris Mason, (Tue Feb 12, 9:43 am)
speck-geostationary