From 5a9713293d5f0e20230646fc403ec4a5bf8c1a1f Mon Sep 17 00:00:00 2001
From: Karel Zak <kzak@redhat.com>
Date: Tue, 26 Jan 2016 14:39:13 +0100
Subject: [PATCH 1/2] libmount: consolidate btrfs stuff, make it more portable

- add --with-btrfs (enabled by default)
- check for linux/btrfs.h
- add "btrfs" to libmount features list (see mount -V)
- #ifdef HAVE_BTRFS_SUPPORT for all btrfs stuff in libmount

Signed-off-by: Karel Zak <kzak@redhat.com>
---
 configure.ac               |  22 ++++++++
 libmount/src/Makemodule.am |   7 ++-
 libmount/src/btrfs.c       |  90 +++++++++++++++++++++++++++++----
 libmount/src/btrfs.h       | 122 ---------------------------------------------
 libmount/src/tab.c         |   3 ++
 libmount/src/version.c     |   3 ++
 6 files changed, 114 insertions(+), 133 deletions(-)
 delete mode 100644 libmount/src/btrfs.h

Index: util-linux-2.25/configure.ac
===================================================================
--- util-linux-2.25.orig/configure.ac
+++ util-linux-2.25/configure.ac
@@ -174,6 +174,7 @@ AC_CHECK_HEADERS([ \
 	fcntl.h \
 	getopt.h \
 	inttypes.h \
+	linux/btrfs.h \
 	linux/cdrom.h \
 	linux/falloc.h \
 	linux/watchdog.h \
@@ -224,6 +225,7 @@ AC_CHECK_HEADERS([langinfo.h],
 
 dnl Convert some ac_cv_header_* variables to have_*
 dnl
+have_linux_btrfs_h=$ac_cv_header_linux_btrfs_h
 have_linux_raw_h=$ac_cv_header_linux_raw_h
 have_linux_securebits_h=$ac_cv_header_linux_securebits_h
 have_linux_watchdog_h=$ac_cv_header_linux_watchdog_h
@@ -1588,6 +1590,25 @@ UL_BUILD_INIT([write])
 AM_CONDITIONAL([BUILD_WRITE], [test "x$build_write" = xyes])
 
 
+AC_ARG_WITH([btrfs],
+  AS_HELP_STRING([--with-btrfs], [build with support for btrfs]),
+  [], [with_btrfs=check]
+)
+have_btrfs=no
+AS_IF([test "x$with_btrfs" != xno], [
+  AS_CASE([$with_btrfs:$have_linux_btrfs_h],
+    [yes:no],
+    [AC_MSG_ERROR([btrfs selected but linux/btrfs.h not found])],
+    [check:no],
+       [AC_MSG_WARN([linux/btrfs.h not found, do not build with btrfs support])],
+    [*:yes],
+       [have_btrfs=yes
+	AC_DEFINE([HAVE_BTRFS_SUPPORT], [1], [Define if btrfs stuff is available])]
+  )
+])
+AM_CONDITIONAL([HAVE_BTRFS], [test "x$have_btrfs" = xyes])
+
+
 AC_ARG_WITH([systemd],
   AS_HELP_STRING([--with-systemd], [build with support for systemd]),
   [], [with_systemd=check]
@@ -1835,6 +1856,7 @@ AC_MSG_RESULT([
 
 	Bash completions:  ${with_bashcompletiondir}
 	Systemd support:   ${have_systemd}
+	Btrfs support:     ${have_btrfs}
 
 	warnings:
 
Index: util-linux-2.25/libmount/src/btrfs.c
===================================================================
--- util-linux-2.25.orig/libmount/src/btrfs.c
+++ util-linux-2.25/libmount/src/btrfs.c
@@ -1,4 +1,5 @@
 /*
+ * Copyright (C) 1999 Andrea Arcangeli <andrea@suse.de>
  * Copyright (C) 2016 David Sterba <dsterba@suse.cz>
  * Copyright (C) 2016 Stanislav Brabec <sbrabec@suse.cz>
  *
@@ -6,17 +7,89 @@
  * GNU Lesser General Public License.
  */
 
+#include <dirent.h>
+#include <sys/ioctl.h>
+#include <libio.h>
+#include <stdint.h>
+#include <linux/btrfs.h>
+
+#include "mountP.h"
+#include "bitops.h"
+
+
+/* linux/btrfs.h lacks large parts of stuff needed for getting default
+ * sub-volume. Suppose that if BTRFS_DIR_ITEM_KEY is not defined, all
+ * declarations are still missing.
+ */
+#ifndef BTRFS_DIR_ITEM_KEY
+
+/*
+ * dir items are the name -> inode pointers in a directory.  There is one
+ * for every name in a directory.
+ */
+#define BTRFS_DIR_ITEM_KEY	84
+
+/* holds pointers to all of the tree roots */
+#define BTRFS_ROOT_TREE_OBJECTID 1ULL
+
+/* directory objectid inside the root tree */
+#define BTRFS_ROOT_TREE_DIR_OBJECTID 6ULL
+
 /*
- * SECTION: btrfs
- * @title: btrfs
- * @short_description: special function for btrfs
+ * the key defines the order in the tree, and so it also defines (optimal)
+ * block layout.  objectid corresonds to the inode number.  The flags
+ * tells us things about the object, and is a kind of stream selector.
+ * so for a given inode, keys with flags of 1 might refer to the inode
+ * data, flags of 2 may point to file data in the btree and flags == 3
+ * may point to extents.
+ *
+ * offset is the starting byte offset for this key in the stream.
  *
- * btrfs contains function needed for manipulation with btrfs.
+ * btrfs_disk_key is in disk byte order.  struct btrfs_key is always
+ * in cpu native order.  Otherwise they are identical and their sizes
+ * should be the same (ie both packed)
  */
-#include <dirent.h>
-#include <sys/ioctl.h>
-#include <linux/magic.h>
-#include "btrfs.h"
+struct btrfs_disk_key {
+	uint64_t objectid; /* little endian */
+	uint8_t type;
+	uint64_t offset; /* little endian */
+} __attribute__ ((__packed__));
+
+struct btrfs_dir_item {
+	struct btrfs_disk_key location;
+	uint64_t transid; /* little endian */
+	uint16_t data_len; /* little endian */
+	uint16_t name_len; /* little endian */
+	uint8_t type;
+} __attribute__ ((__packed__));
+
+#define BTRFS_SETGET_STACK_FUNCS(name, type, member, bits)		\
+static inline uint##bits##_t btrfs_##name(const type *s)		\
+{									\
+	return le##bits##_to_cpu(s->member);				\
+}									\
+static inline void btrfs_set_##name(type *s, uint##bits##_t val)	\
+{									\
+	s->member = cpu_to_le##bits(val);				\
+}
+
+/* struct btrfs_disk_key */
+BTRFS_SETGET_STACK_FUNCS(disk_key_objectid, struct btrfs_disk_key,
+			 objectid, 64);
+
+BTRFS_SETGET_STACK_FUNCS(stack_dir_name_len, struct btrfs_dir_item, name_len, 16);
+
+/*
+  Red Black Trees
+*/
+struct rb_node {
+	unsigned long  __rb_parent_color;
+	struct rb_node *rb_right;
+	struct rb_node *rb_left;
+} __attribute__((aligned(sizeof(long))));
+    /* The alignment might seem pointless, but allegedly CRIS needs it */
+
+#endif /* BTRFS_DIR_ITEM_KEY */
 
 /*
  * btrfs_get_default_subvol_id:
@@ -97,6 +170,5 @@ uint64_t btrfs_get_default_subvol_id(con
 
 out:
 	closedir(dirstream);
-
 	return found;
 }
Index: util-linux-2.25/libmount/src/btrfs.h
===================================================================
--- util-linux-2.25.orig/libmount/src/btrfs.h
+++ /dev/null
@@ -1,122 +0,0 @@
-/* This is an excerpt from btrfs-progs-v4.3.1
- * All kernel types are converted to stdint.h types. */
-
-/*
- * 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 <libio.h>
-#include <stdint.h>
-#include <linux/btrfs.h>
-#include "mountP.h"
-#include "bitops.h"
-
-
-/* linux/btrfs.h lacks large parts of stuff needed for getting default
- * sub-volume. Suppose that if BTRFS_DIR_ITEM_KEY is not defined, all
- * declarations are still missing.
- */
-#ifndef BTRFS_DIR_ITEM_KEY
-
-
-/* from ctree.h */
-
-/*
- * dir items are the name -> inode pointers in a directory.  There is one
- * for every name in a directory.
- */
-#define BTRFS_DIR_ITEM_KEY	84
-
-/* holds pointers to all of the tree roots */
-#define BTRFS_ROOT_TREE_OBJECTID 1ULL
-
-/* directory objectid inside the root tree */
-#define BTRFS_ROOT_TREE_DIR_OBJECTID 6ULL
-
-/*
- * the key defines the order in the tree, and so it also defines (optimal)
- * block layout.  objectid corresonds to the inode number.  The flags
- * tells us things about the object, and is a kind of stream selector.
- * so for a given inode, keys with flags of 1 might refer to the inode
- * data, flags of 2 may point to file data in the btree and flags == 3
- * may point to extents.
- *
- * offset is the starting byte offset for this key in the stream.
- *
- * btrfs_disk_key is in disk byte order.  struct btrfs_key is always
- * in cpu native order.  Otherwise they are identical and their sizes
- * should be the same (ie both packed)
- */
-struct btrfs_disk_key {
-	uint64_t objectid; /* little endian */
-	uint8_t type;
-	uint64_t offset; /* little endian */
-} __attribute__ ((__packed__));
-
-struct btrfs_dir_item {
-	struct btrfs_disk_key location;
-	uint64_t transid; /* little endian */
-	uint16_t data_len; /* little endian */
-	uint16_t name_len; /* little endian */
-	uint8_t type;
-} __attribute__ ((__packed__));
-
-#define BTRFS_SETGET_STACK_FUNCS(name, type, member, bits)		\
-static inline uint##bits##_t btrfs_##name(const type *s)		\
-{									\
-	return le##bits##_to_cpu(s->member);				\
-}									\
-static inline void btrfs_set_##name(type *s, uint##bits##_t val)	\
-{									\
-	s->member = cpu_to_le##bits(val);				\
-}
-
-/* struct btrfs_disk_key */
-BTRFS_SETGET_STACK_FUNCS(disk_key_objectid, struct btrfs_disk_key,
-			 objectid, 64);
-
-BTRFS_SETGET_STACK_FUNCS(stack_dir_name_len, struct btrfs_dir_item, name_len, 16);
-
-
-/* from rbtree.h */
-
-/*
-  Red Black Trees
-  (C) 1999  Andrea Arcangeli <andrea@suse.de>
-
-  This program is free software; you can redistribute it and/or modify
-  it under the terms of the GNU General Public License as published by
-  the Free Software Foundation; either version 2 of the License, or
-  (at your option) any later version.
-
-  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  02111-1307  USA
-*/
-struct rb_node {
-	unsigned long  __rb_parent_color;
-	struct rb_node *rb_right;
-	struct rb_node *rb_left;
-} __attribute__((aligned(sizeof(long))));
-    /* The alignment might seem pointless, but allegedly CRIS needs it */
-
-#endif
Index: util-linux-2.25/libmount/src/tab.c
===================================================================
--- util-linux-2.25.orig/libmount/src/tab.c
+++ util-linux-2.25/libmount/src/tab.c
@@ -1370,6 +1370,7 @@ struct libmnt_fs *mnt_table_get_fs_root(
 		}
 	}
 
+#ifdef HAVE_BTRFS_SUPPORT
 	/*
 	 * btrfs-subvolume mount -- get subvolume name and use it as a root-fs path
 	 */
@@ -1436,6 +1437,8 @@ struct libmnt_fs *mnt_table_get_fs_root(
 		memcpy(p, vol, volsz);
 		*(root + sz) = '\0';
 	}
+#endif /* HAVE_BTRFS_SUPPORT */
+
 dflt:
 	if (!root) {
 		root = strdup("/");
