/*
 * Copyright (C) 2016 David Sterba <dsterba@suse.cz>
 * Copyright (C) 2016 Stanislav Brabec <sbrabec@suse.cz>
 *
 * Based on kernel ctree.h, rbtree.h and btrfs-progs.
 *
 * This file may be redistributed under the terms of the
 * GNU Lesser General Public License.
 */
#include <dirent.h>
#include <sys/ioctl.h>
#include <stdlib.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 corresponds with 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);				\
}

/* 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:
 * @path: Path to mounted btrfs volume
 *
 * Searches for the btrfs default subvolume id.
 *
 * Returns: default subvolume id or UINT64_MAX (-1) in case of no
 * default subvolume or error. In case of error, errno is set
 * properly.
 */
uint64_t btrfs_get_default_subvol_id(const char *path)
{
	int iocret;
	int fd;
	DIR *dirstream;
	struct btrfs_ioctl_search_args args;
	struct btrfs_ioctl_search_key *sk = &args.key;
	struct btrfs_ioctl_search_header *sh;
	uint64_t found = UINT64_MAX;

	dirstream = opendir(path);
	if (!dirstream) {
		DBG(BTRFS, ul_debug("opendir() failed for \"%s\" [errno=%d %m]", path, errno));
		return UINT64_MAX;
	}
	fd = dirfd(dirstream);
	if (fd < 0) {
		DBG(BTRFS, ul_debug("dirfd(opendir()) failed for \"%s\" [errno=%d %m]", path, errno));
		goto out;
	}

	memset(&args, 0, sizeof(args));
	sk->tree_id = BTRFS_ROOT_TREE_OBJECTID;
	sk->min_objectid = BTRFS_ROOT_TREE_DIR_OBJECTID;
	sk->max_objectid = BTRFS_ROOT_TREE_DIR_OBJECTID;
	sk->min_type = BTRFS_DIR_ITEM_KEY;
	sk->max_type = BTRFS_DIR_ITEM_KEY;
	sk->max_offset = UINT64_MAX;
	sk->max_transid = UINT64_MAX;
	sk->nr_items = 1;

	iocret = ioctl(fd, BTRFS_IOC_TREE_SEARCH, &args);
	if (iocret < 0) {
		DBG(BTRFS, ul_debug("ioctl() failed for \"%s\" [errno=%d %m]", path, errno));
		goto out;
	}

	/* the ioctl returns the number of items it found in nr_items */
	if (sk->nr_items == 0) {
		DBG(BTRFS, ul_debug("root tree dir object id not found"));
		goto out;
	}
	DBG(BTRFS, ul_debug("found %d root tree dir object id items", sk->nr_items));

	sh = (struct btrfs_ioctl_search_header *)args.buf;

	if (sh->type == BTRFS_DIR_ITEM_KEY) {
		struct btrfs_dir_item *di;
		int name_len;
		char *name;

		di = (struct btrfs_dir_item *)(sh + 1);
		name_len = btrfs_stack_dir_name_len(di);
		name = (char *)(di + 1);

		if (!strncmp("default", name, name_len)) {
			found = btrfs_disk_key_objectid(&di->location);
			DBG(BTRFS, ul_debug("\"default\" id is %llu", (unsigned long long)found));
		} else {
			DBG(BTRFS, ul_debug("\"default\" id not found in tree root"));
			goto out;
		}
	} else {
		DBG(BTRFS, ul_debug("unexpected type found: %d", (int)sh->type));
		goto out;
	}

out:
	closedir(dirstream);
	return found;
}
