linux-btrfs.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/3] Btrfs-progs: fix unaligned acces for ioctl search header
@ 2016-05-03 16:12 David Sterba
  2016-05-03 16:12 ` [PATCH 1/3] btrfs-progs: kerncompat: introduce get_unaligned helpers David Sterba
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: David Sterba @ 2016-05-03 16:12 UTC (permalink / raw)
  To: linux-btrfs; +Cc: David Sterba

A user reports that some commands fail with SIGBUS on SPARC, due to unaligned
access. We should really use the helpers as the search header data are read
from a random position in the buffer that's returned from the TREE_SEARCH
ioctl.

David Sterba (3):
  btrfs-progs: kerncompat: introduce get_unaligned helpers
  btrfs-progs: add getters for ioctl search_header
  btrfs-progs: use ioctl search headers everywhere

 btrfs-fragments.c | 62 ++++++++++++++++++++++++++++++++++---------------------
 btrfs-list.c      | 21 ++++++++++---------
 cmds-fi-usage.c   |  8 +++----
 cmds-inspect.c    | 23 +++++++++++----------
 cmds-subvolume.c  | 13 ++++++------
 ctree.h           | 26 +++++++++++++++++++++++
 kerncompat.h      |  4 ++++
 qgroup.c          | 44 +++++++++++++++++++++++----------------
 send-utils.c      | 60 ++++++++++++++++++++++++++++++-----------------------
 uuid-tree.c       |  2 +-
 10 files changed, 163 insertions(+), 100 deletions(-)

-- 
2.7.1


^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH 1/3] btrfs-progs: kerncompat: introduce get_unaligned helpers
  2016-05-03 16:12 [PATCH 0/3] Btrfs-progs: fix unaligned acces for ioctl search header David Sterba
@ 2016-05-03 16:12 ` David Sterba
  2016-05-03 16:12 ` [PATCH 2/3] btrfs-progs: add getters for ioctl search_header David Sterba
  2016-05-03 16:12 ` [PATCH 3/3] btrfs-progs: use ioctl search headers everywhere David Sterba
  2 siblings, 0 replies; 4+ messages in thread
From: David Sterba @ 2016-05-03 16:12 UTC (permalink / raw)
  To: linux-btrfs; +Cc: David Sterba

Signed-off-by: David Sterba <dsterba@suse.com>
---
 kerncompat.h | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/kerncompat.h b/kerncompat.h
index ee65aa72ad6d..574f468226c2 100644
--- a/kerncompat.h
+++ b/kerncompat.h
@@ -334,12 +334,16 @@ struct __una_u32 { __le32 x; } __attribute__((__packed__));
 struct __una_u64 { __le64 x; } __attribute__((__packed__));
 
 #define get_unaligned_le8(p) (*((u8 *)(p)))
+#define get_unaligned_8(p) (*((u8 *)(p)))
 #define put_unaligned_le8(val,p) ((*((u8 *)(p))) = (val))
 #define get_unaligned_le16(p) le16_to_cpu(((const struct __una_u16 *)(p))->x)
+#define get_unaligned_16(p) (((const struct __una_u16 *)(p))->x)
 #define put_unaligned_le16(val,p) (((struct __una_u16 *)(p))->x = cpu_to_le16(val))
 #define get_unaligned_le32(p) le32_to_cpu(((const struct __una_u32 *)(p))->x)
+#define get_unaligned_32(p) (((const struct __una_u32 *)(p))->x)
 #define put_unaligned_le32(val,p) (((struct __una_u32 *)(p))->x = cpu_to_le32(val))
 #define get_unaligned_le64(p) le64_to_cpu(((const struct __una_u64 *)(p))->x)
+#define get_unaligned_64(p) (((const struct __una_u64 *)(p))->x)
 #define put_unaligned_le64(val,p) (((struct __una_u64 *)(p))->x = cpu_to_le64(val))
 
 #ifndef true
-- 
2.7.1


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH 2/3] btrfs-progs: add getters for ioctl search_header
  2016-05-03 16:12 [PATCH 0/3] Btrfs-progs: fix unaligned acces for ioctl search header David Sterba
  2016-05-03 16:12 ` [PATCH 1/3] btrfs-progs: kerncompat: introduce get_unaligned helpers David Sterba
@ 2016-05-03 16:12 ` David Sterba
  2016-05-03 16:12 ` [PATCH 3/3] btrfs-progs: use ioctl search headers everywhere David Sterba
  2 siblings, 0 replies; 4+ messages in thread
From: David Sterba @ 2016-05-03 16:12 UTC (permalink / raw)
  To: linux-btrfs; +Cc: David Sterba

The search header is usually accessed in an unaligned way, we could
trigger errors (SIGBUS) on architectures that do not support that.

Signed-off-by: David Sterba <dsterba@suse.com>
---
 ctree.h | 26 ++++++++++++++++++++++++++
 1 file changed, 26 insertions(+)

diff --git a/ctree.h b/ctree.h
index 2da6f7786a78..13ed05052301 100644
--- a/ctree.h
+++ b/ctree.h
@@ -2196,6 +2196,32 @@ static inline u32 btrfs_file_extent_inline_item_len(struct extent_buffer *eb,
        return btrfs_item_size(eb, e) - offset;
 }
 
+/* struct btrfs_ioctl_search_header */
+static inline u64 btrfs_search_header_transid(struct btrfs_ioctl_search_header *sh)
+{
+	return get_unaligned_64(&sh->transid);
+}
+
+static inline u64 btrfs_search_header_objectid(struct btrfs_ioctl_search_header *sh)
+{
+	return get_unaligned_64(&sh->objectid);
+}
+
+static inline u64 btrfs_search_header_offset(struct btrfs_ioctl_search_header *sh)
+{
+	return get_unaligned_64(&sh->offset);
+}
+
+static inline u32 btrfs_search_header_type(struct btrfs_ioctl_search_header *sh)
+{
+	return get_unaligned_32(&sh->type);
+}
+
+static inline u32 btrfs_search_header_len(struct btrfs_ioctl_search_header *sh)
+{
+	return get_unaligned_32(&sh->len);
+}
+
 /* this returns the number of file bytes represented by the inline item.
  * If an item is compressed, this is the uncompressed size
  */
-- 
2.7.1


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH 3/3] btrfs-progs: use ioctl search headers everywhere
  2016-05-03 16:12 [PATCH 0/3] Btrfs-progs: fix unaligned acces for ioctl search header David Sterba
  2016-05-03 16:12 ` [PATCH 1/3] btrfs-progs: kerncompat: introduce get_unaligned helpers David Sterba
  2016-05-03 16:12 ` [PATCH 2/3] btrfs-progs: add getters for ioctl search_header David Sterba
@ 2016-05-03 16:12 ` David Sterba
  2 siblings, 0 replies; 4+ messages in thread
From: David Sterba @ 2016-05-03 16:12 UTC (permalink / raw)
  To: linux-btrfs; +Cc: David Sterba

Generated by following semantic patch and manually tweaked.

<SmPL>
@@
struct btrfs_ioctl_search_header *SH;
@@
(
- SH->objectid
+ btrfs_search_header_objectid(SH)
|
- SH->offset
+ btrfs_search_header_offset(SH)
|
- SH->transid
+ btrfs_search_header_transid(SH)
|
- SH->len
+ btrfs_search_header_len(SH)
|
- SH->type
+ btrfs_search_header_type(SH)
)
</SmPL>

Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=112131
Reported-and-tested-by: Anatoly Pugachev <matorola@gmail.com>
Signed-off-by: David Sterba <dsterba@suse.com>
---
 btrfs-fragments.c | 62 ++++++++++++++++++++++++++++++++++---------------------
 btrfs-list.c      | 21 ++++++++++---------
 cmds-fi-usage.c   |  8 +++----
 cmds-inspect.c    | 23 +++++++++++----------
 cmds-subvolume.c  | 13 ++++++------
 qgroup.c          | 44 +++++++++++++++++++++++----------------
 send-utils.c      | 60 ++++++++++++++++++++++++++++++-----------------------
 uuid-tree.c       |  2 +-
 8 files changed, 133 insertions(+), 100 deletions(-)

diff --git a/btrfs-fragments.c b/btrfs-fragments.c
index 9db1861e9c7b..eb75eb7a7704 100644
--- a/btrfs-fragments.c
+++ b/btrfs-fragments.c
@@ -245,7 +245,8 @@ list_fragments(int fd, u64 flags, char *dir)
 			sh = (struct btrfs_ioctl_search_header *)(args.buf +
 								  off);
 			off += sizeof(*sh);
-			if (sh->type == BTRFS_BLOCK_GROUP_ITEM_KEY) {
+			if (btrfs_search_header_type(sh)
+			    == BTRFS_BLOCK_GROUP_ITEM_KEY) {
 				struct btrfs_block_group_item *bg;
 
 				if (im) {
@@ -262,20 +263,24 @@ list_fragments(int fd, u64 flags, char *dir)
 						(args.buf + off);
 				bgflags = btrfs_block_group_flags(bg);
 				bgused = btrfs_block_group_used(bg);
-				
+
 				printf("found block group %lld len %lld "
-					"flags %lld\n", sh->objectid,
-					sh->offset, bgflags);
+					"flags %lld\n",
+					btrfs_search_header_objectid(sh),
+					btrfs_search_header_offset(sh),
+					bgflags);
 				if (!(bgflags & flags)) {
 					/* skip this block group */
-					sk->min_objectid = sh->objectid +
-							   sh->offset;
+					sk->min_objectid =
+					    btrfs_search_header_objectid(sh) +
+					    btrfs_search_header_offset(sh);
 					sk->min_type = 0;
 					sk->min_offset = 0;
 					break;
 				}
 				im = gdImageCreate(width,
-					(sh->offset / 4096 + 799) / width);
+					(btrfs_search_header_offset(sh)
+					 / 4096 + 799) / width);
 
 				black = gdImageColorAllocate(im, 0, 0, 0);  
 
@@ -283,8 +288,8 @@ list_fragments(int fd, u64 flags, char *dir)
 					colors[j] = black;
 
 				init_colors(im, colors);
-				bgstart = sh->objectid;
-				bglen = sh->offset;
+				bgstart = btrfs_search_header_objectid(sh);
+				bglen = btrfs_search_header_offset(sh);
 				bgend = bgstart + bglen;
 
 				snprintf(name, sizeof(name), "bg%d.png", bgnum);
@@ -303,7 +308,8 @@ list_fragments(int fd, u64 flags, char *dir)
 				areas = 0;
 				saved_len = 0;
 			}
-			if (im && sh->type == BTRFS_EXTENT_ITEM_KEY) {
+			if (im && btrfs_search_header_type(sh)
+					== BTRFS_EXTENT_ITEM_KEY) {
 				int c;
 				struct btrfs_extent_item *item;
 
@@ -311,40 +317,48 @@ list_fragments(int fd, u64 flags, char *dir)
 						(args.buf + off);
 
 				if (use_color)
-					c = colors[get_color(item, sh->len)];
+					c = colors[get_color(item,
+						btrfs_search_header_len(sh))];
 				else
 					c = black;
-				if (sh->objectid > bgend) {
+				if (btrfs_search_header_objectid(sh) > bgend) {
 					printf("WARN: extent %lld is without "
-						"block group\n", sh->objectid);
+						"block group\n",
+						btrfs_search_header_objectid(sh));
 					goto skip;
 				}
-				if (sh->objectid == bgend) {
-					saved_extent = sh->objectid;
-					saved_len = sh->offset;
+				if (btrfs_search_header_objectid(sh) == bgend) {
+					saved_extent =
+						btrfs_search_header_objectid(sh);
+					saved_len =
+						btrfs_search_header_offset(sh);
 					saved_color = c;
 					goto skip;
 				}
-				px = (sh->objectid - bgstart) / 4096;
-				for (j = 0; j < sh->offset / 4096; ++j) {
+				px = (btrfs_search_header_objectid(sh)
+					- bgstart) / 4096;
+				for (j = 0;
+				     j < btrfs_search_header_offset(sh) / 4096;
+				     ++j) {
 					int x = (px + j) % width;
 					int y = (px + j) / width;
 					gdImageSetPixel(im, x, y, c);
 				}
-				if (sh->objectid != last_end)
+				if (btrfs_search_header_objectid(sh) != last_end)
 					++areas;
-				last_end = sh->objectid + sh->offset;
+				last_end = btrfs_search_header_objectid(sh)
+					+ btrfs_search_header_offset(sh);
 skip:;
 			}
-			off += sh->len;
+			off += btrfs_search_header_len(sh);
 
 			/*
 			 * record the mins in sk so we can make sure the
 			 * next search doesn't repeat this root
 			 */
-			sk->min_objectid = sh->objectid;
-			sk->min_type = sh->type;
-			sk->min_offset = sh->offset;
+			sk->min_objectid = btrfs_search_header_objectid(sh);
+			sk->min_type = btrfs_search_header_type(sh);
+			sk->min_offset = btrfs_search_header_offset(sh);
 		}
 		sk->nr_items = 4096;
 
diff --git a/btrfs-list.c b/btrfs-list.c
index 2da54bf706f3..27b23721b6c1 100644
--- a/btrfs-list.c
+++ b/btrfs-list.c
@@ -876,9 +876,9 @@ static char *ino_resolve(int fd, u64 ino, u64 *cache_dirid, char **cache_name)
 	off = 0;
 	sh = (struct btrfs_ioctl_search_header *)(args.buf + off);
 
-	if (sh->type == BTRFS_INODE_REF_KEY) {
+	if (btrfs_search_header_type(sh) == BTRFS_INODE_REF_KEY) {
 		struct btrfs_inode_ref *ref;
-		dirid = sh->offset;
+		dirid = btrfs_search_header_offset(sh);
 
 		ref = (struct btrfs_inode_ref *)(sh + 1);
 		namelen = btrfs_stack_inode_ref_name_len(ref);
@@ -947,7 +947,7 @@ int btrfs_list_get_default_subvolume(int fd, u64 *default_id)
 
 	sh = (struct btrfs_ioctl_search_header *)args.buf;
 
-	if (sh->type == BTRFS_DIR_ITEM_KEY) {
+	if (btrfs_search_header_type(sh) == BTRFS_DIR_ITEM_KEY) {
 		struct btrfs_dir_item *di;
 		int name_len;
 		char *name;
@@ -1602,17 +1602,18 @@ static int print_one_extent(int fd, struct btrfs_ioctl_search_header *sh,
 	int flags = 0;
 	char *name = NULL;
 
-	if (sh->objectid == *cache_ino) {
+	if (btrfs_search_header_objectid(sh) == *cache_ino) {
 		name = *cache_full_name;
 	} else if (*cache_full_name) {
 		free(*cache_full_name);
 		*cache_full_name = NULL;
 	}
 	if (!name) {
-		name = ino_resolve(fd, sh->objectid, cache_dirid,
+		name = ino_resolve(fd, btrfs_search_header_objectid(sh),
+				   cache_dirid,
 				   cache_dir_name);
 		*cache_full_name = name;
-		*cache_ino = sh->objectid;
+		*cache_ino = btrfs_search_header_objectid(sh);
 	}
 	if (!name)
 		return -EIO;
@@ -1633,16 +1634,16 @@ static int print_one_extent(int fd, struct btrfs_ioctl_search_header *sh,
 		printf("unhandled extent type %d for inode %llu "
 		       "file offset %llu gen %llu\n",
 			type,
-			(unsigned long long)sh->objectid,
-			(unsigned long long)sh->offset,
+			(unsigned long long)btrfs_search_header_objectid(sh),
+			(unsigned long long)btrfs_search_header_offset(sh),
 			(unsigned long long)found_gen);
 
 		return -EIO;
 	}
 	printf("inode %llu file offset %llu len %llu disk start %llu "
 	       "offset %llu gen %llu flags ",
-	       (unsigned long long)sh->objectid,
-	       (unsigned long long)sh->offset,
+	       (unsigned long long)btrfs_search_header_objectid(sh),
+	       (unsigned long long)btrfs_search_header_offset(sh),
 	       (unsigned long long)len,
 	       (unsigned long long)disk_start,
 	       (unsigned long long)disk_offset,
diff --git a/cmds-fi-usage.c b/cmds-fi-usage.c
index 33bf403af569..32000ea0683b 100644
--- a/cmds-fi-usage.c
+++ b/cmds-fi-usage.c
@@ -185,11 +185,11 @@ static int load_chunk_info(int fd, struct chunk_info **info_ptr, int *info_count
 				return 1;
 			}
 
-			off += sh->len;
+			off += btrfs_search_header_len(sh);
 
-			sk->min_objectid = sh->objectid;
-			sk->min_type = sh->type;
-			sk->min_offset = sh->offset+1;
+			sk->min_objectid = btrfs_search_header_objectid(sh);
+			sk->min_type = btrfs_search_header_type(sh);
+			sk->min_offset = btrfs_search_header_offset(sh)+1;
 
 		}
 		if (!sk->min_offset)	/* overflow */
diff --git a/cmds-inspect.c b/cmds-inspect.c
index abe4edf10f70..25e8c016136f 100644
--- a/cmds-inspect.c
+++ b/cmds-inspect.c
@@ -537,32 +537,33 @@ static int print_min_dev_size(int fd, u64 devid)
 								  off);
 			off += sizeof(*sh);
 			extent = (struct btrfs_dev_extent *)(args.buf + off);
-			off += sh->len;
+			off += btrfs_search_header_len(sh);
 
-			sk->min_objectid = sh->objectid;
-			sk->min_type = sh->type;
-			sk->min_offset = sh->offset + 1;
+			sk->min_objectid = btrfs_search_header_objectid(sh);
+			sk->min_type = btrfs_search_header_type(sh);
+			sk->min_offset = btrfs_search_header_offset(sh) + 1;
 
-			if (sh->objectid != devid ||
-			    sh->type != BTRFS_DEV_EXTENT_KEY)
+			if (btrfs_search_header_objectid(sh) != devid ||
+			    btrfs_search_header_type(sh) != BTRFS_DEV_EXTENT_KEY)
 				continue;
 
 			len = btrfs_stack_dev_extent_length(extent);
 			min_size += len;
-			ret = add_dev_extent(&extents, sh->offset,
-					     sh->offset + len - 1, 0);
+			ret = add_dev_extent(&extents,
+				btrfs_search_header_offset(sh),
+				btrfs_search_header_offset(sh) + len - 1, 0);
 
 			if (!ret && last_pos != (u64)-1 &&
-			    last_pos != sh->offset)
+			    last_pos != btrfs_search_header_offset(sh))
 				ret = add_dev_extent(&holes, last_pos,
-						     sh->offset - 1, 1);
+					btrfs_search_header_offset(sh) - 1, 1);
 			if (ret) {
 				error("add device extent: %s", strerror(-ret));
 				ret = 1;
 				goto out;
 			}
 
-			last_pos = sh->offset + len;
+			last_pos = btrfs_search_header_offset(sh) + len;
 		}
 
 		if (sk->min_type != BTRFS_DEV_EXTENT_KEY ||
diff --git a/cmds-subvolume.c b/cmds-subvolume.c
index 2319684e1500..7c8ab8f21d0c 100644
--- a/cmds-subvolume.c
+++ b/cmds-subvolume.c
@@ -1142,7 +1142,8 @@ static int enumerate_dead_subvols(int fd, u64 **ids)
 			sh = (struct btrfs_ioctl_search_header*)(args.buf + off);
 			off += sizeof(*sh);
 
-			if (sh->type == BTRFS_ORPHAN_ITEM_KEY) {
+			if (btrfs_search_header_type(sh)
+			    == BTRFS_ORPHAN_ITEM_KEY) {
 				if (idx >= count) {
 					u64 *newids;
 
@@ -1153,14 +1154,14 @@ static int enumerate_dead_subvols(int fd, u64 **ids)
 						return -ENOMEM;
 					*ids = newids;
 				}
-				(*ids)[idx] = sh->offset;
+				(*ids)[idx] = btrfs_search_header_offset(sh);
 				idx++;
 			}
-			off += sh->len;
+			off += btrfs_search_header_len(sh);
 
-			sk->min_objectid = sh->objectid;
-			sk->min_type = sh->type;
-			sk->min_offset = sh->offset;
+			sk->min_objectid = btrfs_search_header_objectid(sh);
+			sk->min_type = btrfs_search_header_type(sh);
+			sk->min_offset = btrfs_search_header_offset(sh);
 		}
 		if (sk->min_offset < (u64)-1)
 			sk->min_offset++;
diff --git a/qgroup.c b/qgroup.c
index a672ac049a50..f17fdaeeb986 100644
--- a/qgroup.c
+++ b/qgroup.c
@@ -1094,7 +1094,8 @@ static int __qgroups_search(int fd, struct qgroup_lookup *qgroup_lookup)
 								  off);
 			off += sizeof(*sh);
 
-			if (sh->type == BTRFS_QGROUP_STATUS_KEY) {
+			if (btrfs_search_header_type(sh)
+			    == BTRFS_QGROUP_STATUS_KEY) {
 				struct btrfs_qgroup_status_item *si;
 				u64 flags;
 
@@ -1102,7 +1103,8 @@ static int __qgroups_search(int fd, struct qgroup_lookup *qgroup_lookup)
 				     (args.buf + off);
 				flags = btrfs_stack_qgroup_status_flags(si);
 				print_status_flag_warning(flags);
-			} else if (sh->type == BTRFS_QGROUP_INFO_KEY) {
+			} else if (btrfs_search_header_type(sh)
+				   == BTRFS_QGROUP_INFO_KEY) {
 				info = (struct btrfs_qgroup_info_item *)
 				       (args.buf + off);
 				a1 = btrfs_stack_qgroup_info_generation(info);
@@ -1114,10 +1116,12 @@ static int __qgroups_search(int fd, struct qgroup_lookup *qgroup_lookup)
 				a5 =
 				  btrfs_stack_qgroup_info_exclusive_compressed
 				  (info);
-				add_qgroup(qgroup_lookup, sh->offset, a1, a2,
-					   a3, a4, a5, 0, 0, 0, 0, 0,
-					   NULL, NULL);
-			} else if (sh->type == BTRFS_QGROUP_LIMIT_KEY) {
+				add_qgroup(qgroup_lookup,
+					btrfs_search_header_offset(sh), a1,
+					a2, a3, a4, a5, 0, 0, 0, 0, 0, NULL,
+					NULL);
+			} else if (btrfs_search_header_type(sh)
+				   == BTRFS_QGROUP_LIMIT_KEY) {
 				limit = (struct btrfs_qgroup_limit_item *)
 				    (args.buf + off);
 
@@ -1130,34 +1134,38 @@ static int __qgroups_search(int fd, struct qgroup_lookup *qgroup_lookup)
 				     (limit);
 				a5 = btrfs_stack_qgroup_limit_rsv_exclusive
 				     (limit);
-				add_qgroup(qgroup_lookup, sh->offset, 0, 0,
-					   0, 0, 0, a1, a2, a3, a4, a5,
+				add_qgroup(qgroup_lookup,
+					   btrfs_search_header_offset(sh), 0,
+					   0, 0, 0, 0, a1, a2, a3, a4, a5,
 					   NULL, NULL);
-			} else if (sh->type == BTRFS_QGROUP_RELATION_KEY) {
-				if (sh->offset < sh->objectid)
+			} else if (btrfs_search_header_type(sh)
+				   == BTRFS_QGROUP_RELATION_KEY) {
+				if (btrfs_search_header_offset(sh)
+				    < btrfs_search_header_objectid(sh))
 					goto skip;
 				bq = qgroup_tree_search(qgroup_lookup,
-							sh->offset);
+					btrfs_search_header_offset(sh));
 				if (!bq)
 					goto skip;
 				bq1 = qgroup_tree_search(qgroup_lookup,
-							 sh->objectid);
+					 btrfs_search_header_objectid(sh));
 				if (!bq1)
 					goto skip;
-				add_qgroup(qgroup_lookup, sh->offset, 0, 0,
-					   0, 0, 0, 0, 0, 0, 0, 0, bq, bq1);
+				add_qgroup(qgroup_lookup,
+					   btrfs_search_header_offset(sh), 0,
+					   0, 0, 0, 0, 0, 0, 0, 0, 0, bq, bq1);
 			} else
 				goto done;
 skip:
-			off += sh->len;
+			off += btrfs_search_header_len(sh);
 
 			/*
 			 * record the mins in sk so we can make sure the
 			 * next search doesn't repeat this root
 			 */
-			sk->min_type = sh->type;
-			sk->min_offset = sh->offset;
-			sk->min_objectid = sh->objectid;
+			sk->min_type = btrfs_search_header_type(sh);
+			sk->min_offset = btrfs_search_header_offset(sh);
+			sk->min_objectid = btrfs_search_header_objectid(sh);
 		}
 		sk->nr_items = 4096;
 		/*
diff --git a/send-utils.c b/send-utils.c
index 3c369b86c237..2e3ffd76caaa 100644
--- a/send-utils.c
+++ b/send-utils.c
@@ -99,25 +99,25 @@ static int btrfs_read_root_item_raw(int mnt_fd, u64 root_id, size_t buf_len,
 
 			off += sizeof(*sh);
 			item = (struct btrfs_root_item *)(args.buf + off);
-			off += sh->len;
+			off += btrfs_search_header_len(sh);
 
-			sk->min_objectid = sh->objectid;
-			sk->min_type = sh->type;
-			sk->min_offset = sh->offset;
+			sk->min_objectid = btrfs_search_header_objectid(sh);
+			sk->min_type = btrfs_search_header_type(sh);
+			sk->min_offset = btrfs_search_header_offset(sh);
 
-			if (sh->objectid > root_id)
+			if (btrfs_search_header_objectid(sh) > root_id)
 				break;
 
-			if (sh->objectid == root_id &&
-			    sh->type == BTRFS_ROOT_ITEM_KEY) {
-				if (sh->len > buf_len) {
+			if (btrfs_search_header_objectid(sh) == root_id &&
+			    btrfs_search_header_type(sh) == BTRFS_ROOT_ITEM_KEY) {
+				if (btrfs_search_header_len(sh) > buf_len) {
 					/* btrfs-progs is too old for kernel */
 					fprintf(stderr,
 						"ERROR: buf for read_root_item_raw() is too small, get newer btrfs tools!\n");
 					return -EOVERFLOW;
 				}
-				memcpy(buf, item, sh->len);
-				*read_len = sh->len;
+				memcpy(buf, item, btrfs_search_header_len(sh));
+				*read_len = btrfs_search_header_len(sh);
 				found = 1;
 			}
 		}
@@ -280,11 +280,12 @@ static int btrfs_subvolid_resolve_sub(int fd, char *path, size_t *path_len,
 	}
 	search_header = (struct btrfs_ioctl_search_header *)search_arg.buf;
 	backref_item = (struct btrfs_root_ref *)(search_header + 1);
-	if (search_header->offset != BTRFS_FS_TREE_OBJECTID) {
+	if (btrfs_search_header_offset(search_header)
+	    != BTRFS_FS_TREE_OBJECTID) {
 		int sub_ret;
 
 		sub_ret = btrfs_subvolid_resolve_sub(fd, path, path_len,
-						     search_header->offset);
+				btrfs_search_header_offset(search_header));
 		if (sub_ret)
 			return sub_ret;
 		if (*path_len < 1)
@@ -298,7 +299,8 @@ static int btrfs_subvolid_resolve_sub(int fd, char *path, size_t *path_len,
 		int len;
 
 		memset(&ino_lookup_arg, 0, sizeof(ino_lookup_arg));
-		ino_lookup_arg.treeid = search_header->offset;
+		ino_lookup_arg.treeid =
+			btrfs_search_header_offset(search_header);
 		ino_lookup_arg.objectid =
 			btrfs_stack_root_ref_dirid(backref_item);
 		ret = ioctl(fd, BTRFS_IOC_INO_LOOKUP, &ino_lookup_arg);
@@ -593,14 +595,19 @@ int subvol_uuid_search_init(int mnt_fd, struct subvol_uuid_search *s)
 								  off);
 			off += sizeof(*sh);
 
-			if ((sh->objectid != 5 &&
-			    sh->objectid < BTRFS_FIRST_FREE_OBJECTID) ||
-			    sh->objectid > BTRFS_LAST_FREE_OBJECTID)
+			if ((btrfs_search_header_objectid(sh) != 5 &&
+			     btrfs_search_header_objectid(sh)
+			     < BTRFS_FIRST_FREE_OBJECTID) ||
+			    btrfs_search_header_objectid(sh)
+			    > BTRFS_LAST_FREE_OBJECTID) {
 				goto skip;
+			}
 
-			if (sh->type == BTRFS_ROOT_ITEM_KEY) {
+			if (btrfs_search_header_type(sh)
+			    == BTRFS_ROOT_ITEM_KEY) {
 				/* older kernels don't have uuids+times */
-				if (sh->len < sizeof(root_item)) {
+				if (btrfs_search_header_len(sh)
+				    < sizeof(root_item)) {
 					root_item_valid = 0;
 					goto skip;
 				}
@@ -609,13 +616,14 @@ int subvol_uuid_search_init(int mnt_fd, struct subvol_uuid_search *s)
 				memcpy(&root_item, root_item_ptr,
 						sizeof(root_item));
 				root_item_valid = 1;
-			} else if (sh->type == BTRFS_ROOT_BACKREF_KEY ||
+			} else if (btrfs_search_header_type(sh)
+				   == BTRFS_ROOT_BACKREF_KEY ||
 				   root_item_valid) {
 				if (!root_item_valid)
 					goto skip;
 
 				path = btrfs_list_path_for_root(mnt_fd,
-								sh->objectid);
+					btrfs_search_header_objectid(sh));
 				if (!path)
 					path = strdup("");
 				if (IS_ERR(path)) {
@@ -623,12 +631,12 @@ int subvol_uuid_search_init(int mnt_fd, struct subvol_uuid_search *s)
 					fprintf(stderr, "ERROR: unable to "
 							"resolve path "
 							"for root %llu\n",
-							sh->objectid);
+						btrfs_search_header_objectid(sh));
 					goto out;
 				}
 
 				si = calloc(1, sizeof(*si));
-				si->root_id = sh->objectid;
+				si->root_id = btrfs_search_header_objectid(sh);
 				memcpy(si->uuid, root_item.uuid,
 						BTRFS_UUID_SIZE);
 				memcpy(si->parent_uuid, root_item.parent_uuid,
@@ -648,15 +656,15 @@ int subvol_uuid_search_init(int mnt_fd, struct subvol_uuid_search *s)
 			}
 
 skip:
-			off += sh->len;
+			off += btrfs_search_header_len(sh);
 
 			/*
 			 * record the mins in sk so we can make sure the
 			 * next search doesn't repeat this root
 			 */
-			sk->min_objectid = sh->objectid;
-			sk->min_offset = sh->offset;
-			sk->min_type = sh->type;
+			sk->min_objectid = btrfs_search_header_objectid(sh);
+			sk->min_offset = btrfs_search_header_offset(sh);
+			sk->min_type = btrfs_search_header_type(sh);
 		}
 		sk->nr_items = 4096;
 		if (sk->min_offset < (u64)-1)
diff --git a/uuid-tree.c b/uuid-tree.c
index 39c3f3fd21e6..8d0b9173238d 100644
--- a/uuid-tree.c
+++ b/uuid-tree.c
@@ -72,7 +72,7 @@ static int btrfs_uuid_tree_lookup_any(int fd, const u8 *uuid, u8 type,
 		goto out;
 	}
 	search_header = (struct btrfs_ioctl_search_header *)(search_arg.buf);
-	item_size = search_header->len;
+	item_size = btrfs_search_header_len(search_header);
 	if ((item_size & (sizeof(u64) - 1)) || item_size == 0) {
 		printf("btrfs: uuid item with illegal size %lu!\n",
 		       (unsigned long)item_size);
-- 
2.7.1


^ permalink raw reply related	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2016-05-03 16:13 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-05-03 16:12 [PATCH 0/3] Btrfs-progs: fix unaligned acces for ioctl search header David Sterba
2016-05-03 16:12 ` [PATCH 1/3] btrfs-progs: kerncompat: introduce get_unaligned helpers David Sterba
2016-05-03 16:12 ` [PATCH 2/3] btrfs-progs: add getters for ioctl search_header David Sterba
2016-05-03 16:12 ` [PATCH 3/3] btrfs-progs: use ioctl search headers everywhere David Sterba

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).