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>
This commit is contained in:
Karel Zak 2016-01-26 14:39:13 +01:00
parent bb7803e971
commit 5a9713293d
6 changed files with 115 additions and 134 deletions

View File

@ -197,6 +197,7 @@ AC_CHECK_HEADERS([ \
fcntl.h \
getopt.h \
inttypes.h \
linux/btrfs.h \
linux/cdrom.h \
linux/falloc.h \
linux/watchdog.h \
@ -264,6 +265,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
@ -1786,6 +1788,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]
@ -2061,6 +2082,7 @@ AC_MSG_RESULT([
Bash completions: ${with_bashcompletiondir}
Systemd support: ${have_systemd}
Btrfs support: ${have_btrfs}
warnings:

View File

@ -27,15 +27,18 @@ libmount_la_SOURCES = \
if LINUX
libmount_la_SOURCES += \
libmount/src/btrfs.c \
libmount/src/btrfs.h \
libmount/src/context.c \
libmount/src/context_loopdev.c \
libmount/src/context_mount.c \
libmount/src/context_umount.c \
libmount/src/monitor.c
if HAVE_BTRFS
libmount_la_SOURCES += libmount/src/btrfs.c
endif
endif # LINUX
nodist_libmount_la_SOURCES = libmount/src/mountP.h
libmount_la_LIBADD = \

View File

@ -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.
*/
/*
* SECTION: btrfs
* @title: btrfs
* @short_description: special function for btrfs
*
* btrfs contains function needed for manipulation with btrfs.
*/
#include <dirent.h>
#include <sys/ioctl.h>
#include <linux/magic.h>
#include "btrfs.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
/*
* 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);
/*
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(const char *path)
out:
closedir(dirstream);
return found;
}

View File

@ -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

View File

@ -1315,6 +1315,7 @@ struct libmnt_fs *mnt_table_get_fs_root(struct libmnt_table *tb,
}
}
#ifdef HAVE_BTRFS_SUPPORT
/*
* btrfs-subvolume mount -- get subvolume name and use it as a root-fs path
*/
@ -1381,6 +1382,8 @@ struct libmnt_fs *mnt_table_get_fs_root(struct libmnt_table *tb,
memcpy(p, vol, volsz);
*(root + sz) = '\0';
}
#endif /* HAVE_BTRFS_SUPPORT */
dflt:
if (!root) {
root = strdup("/");

View File

@ -25,6 +25,9 @@ static const char *lib_features[] = {
#ifdef HAVE_SMACK
"smack",
#endif
#ifdef HAVE_BTRFS_SUPPORT
"btrfs",
#endif
#if !defined(NDEBUG)
"assert", /* libc assert.h stuff */
#endif