All of lore.kernel.org
 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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.