/*
 * Copyright (C) 2008-2010 Karel Zak <kzak@redhat.com>
 *
 * This file may be redistributed under the terms of the
 * GNU Lesser General Public License.
 */

/**
 * SECTION: table
 * @title: Table of filesystems
 * @short_description: container for entries from fstab, mtab or mountinfo
 *
 * Note that mnt_table_find_* functions are mount(8) compatible. These functions
 * try to find an entry in more iterations, where the first attempt is always
 * based on comparison with unmodified (non-canonicalized or un-evaluated)
 * paths or tags. For example a fstab with two entries:
 * <informalexample>
 *   <programlisting>
 *	LABEL=foo	/foo	auto   rw
 *	/dev/foo	/foo	auto   rw
 *  </programlisting>
 * </informalexample>
 *
 * where both lines are used for the *same* device, then
 * <informalexample>
 *  <programlisting>
 *	mnt_table_find_source(tb, "/dev/foo", &fs);
 *  </programlisting>
 * </informalexample>
 * will returns the second line, and
 * <informalexample>
 *  <programlisting>
 *	mnt_table_find_source(tb, "LABEL=foo", &fs);
 *  </programlisting>
 * </informalexample>
 * will returns the first entry, and
 * <informalexample>
 *  <programlisting>
 *	mnt_table_find_source(tb, "UUID=anyuuid", &fs);
 *  </programlisting>
 * </informalexample>
 * will return the first entry (if UUID matches with the device).
 */
#include <blkid.h>

#include "mountP.h"
#include "strutils.h"
#include "loopdev.h"
#include "fileutils.h"
#include "canonicalize.h"

int is_mountinfo(struct libmnt_table *tb)
{
	struct libmnt_fs *fs;

	if (!tb)
		return 0;

	fs = list_first_entry(&tb->ents, struct libmnt_fs, ents);
	if (fs && mnt_fs_is_kernel(fs) && mnt_fs_get_root(fs))
		return 1;

	return 0;
}

/**
 * mnt_new_table:
 *
 * The tab is a container for struct libmnt_fs entries that usually represents a fstab,
 * mtab or mountinfo file from your system.
 *
 * See also mnt_table_parse_file().
 *
 * Returns: newly allocated tab struct.
 */
struct libmnt_table *mnt_new_table(void)
{
	struct libmnt_table *tb = NULL;

	tb = calloc(1, sizeof(*tb));
	if (!tb)
		return NULL;

	DBG(TAB, ul_debugobj(tb, "alloc"));
	tb->refcount = 1;
	INIT_LIST_HEAD(&tb->ents);
	return tb;
}

/**
 * mnt_reset_table:
 * @tb: tab pointer
 *
 * Removes all entries (filesystems) from the table. The filesystems with zero
 * reference count will be deallocated.
 *
 * Returns: 0 on success or negative number in case of error.
 */
int mnt_reset_table(struct libmnt_table *tb)
{
	if (!tb)
		return -EINVAL;

	DBG(TAB, ul_debugobj(tb, "reset"));

	while (!list_empty(&tb->ents)) {
		struct libmnt_fs *fs = list_entry(tb->ents.next,
				                  struct libmnt_fs, ents);
		mnt_table_remove_fs(tb, fs);
	}

	tb->nents = 0;
	return 0;
}

/**
 * mnt_ref_table:
 * @tb: table pointer
 *
 * Increments reference counter.
 */
void mnt_ref_table(struct libmnt_table *tb)
{
	if (tb) {
		tb->refcount++;
		/*DBG(FS, ul_debugobj(tb, "ref=%d", tb->refcount));*/
	}
}

/**
 * mnt_unref_table:
 * @tb: table pointer
 *
 * De-increments reference counter, on zero the @tb is automatically
 * deallocated by mnt_free_table().
 */
void mnt_unref_table(struct libmnt_table *tb)
{
	if (tb) {
		tb->refcount--;
		/*DBG(FS, ul_debugobj(tb, "unref=%d", tb->refcount));*/
		if (tb->refcount <= 0)
			mnt_free_table(tb);
	}
}


/**
 * mnt_free_table:
 * @tb: tab pointer
 *
 * Deallocates the table. This function does not care about reference count. Don't
 * use this function directly -- it's better to use mnt_unref_table().
 *
 * The table entries (filesystems) are unreferenced by mnt_reset_table() and
 * cache by mnt_unref_cache().
 */
void mnt_free_table(struct libmnt_table *tb)
{
	if (!tb)
		return;

	mnt_reset_table(tb);
	DBG(TAB, ul_debugobj(tb, "free [refcount=%d]", tb->refcount));

	mnt_unref_cache(tb->cache);
	free(tb->comm_intro);
	free(tb->comm_tail);
	free(tb);
}

/**
 * mnt_table_get_nents:
 * @tb: pointer to tab
 *
 * Returns: number of entries in table.
 */
int mnt_table_get_nents(struct libmnt_table *tb)
{
	return tb ? tb->nents : 0;
}

/**
 * mnt_table_is_empty:
 * @tb: pointer to tab
 *
 * Returns: 1 if the table is without filesystems, or 0.
 */
int mnt_table_is_empty(struct libmnt_table *tb)
{
	return tb == NULL || list_empty(&tb->ents) ? 1 : 0;
}

/**
 * mnt_table_set_userdata:
 * @tb: pointer to tab
 * @data: pointer to user data
 *
 * Sets pointer to the private user data.
 *
 * Returns: 0 on success or negative number in case of error.
 */
int mnt_table_set_userdata(struct libmnt_table *tb, void *data)
{
	if (!tb)
		return -EINVAL;

	tb->userdata = data;
	return 0;
}

/**
 * mnt_table_get_userdata:
 * @tb: pointer to tab
 *
 * Returns: pointer to user's data.
 */
void *mnt_table_get_userdata(struct libmnt_table *tb)
{
	return tb ? tb->userdata : NULL;
}

/**
 * mnt_table_enable_comments:
 * @tb: pointer to tab
 * @enable: TRUE or FALSE
 *
 * Enables parsing of comments.
 *
 * The initial (intro) file comment is accessible by
 * mnt_table_get_intro_comment(). The intro and the comment of the first fstab
 * entry has to be separated by blank line.  The filesystem comments are
 * accessible by mnt_fs_get_comment(). The trailing fstab comment is accessible
 * by mnt_table_get_trailing_comment().
 *
 * <informalexample>
 *  <programlisting>
 *	#
 *	# Intro comment
 *	#
 *
 *	# this comments belongs to the first fs
 *	LABEL=foo /mnt/foo auto defaults 1 2
 *	# this comments belongs to the second fs
 *	LABEL=bar /mnt/bar auto defaults 1 2
 *	# tailing comment
 *  </programlisting>
 * </informalexample>
 */
void mnt_table_enable_comments(struct libmnt_table *tb, int enable)
{
	if (tb)
		tb->comms = enable;
}

/**
 * mnt_table_with_comments:
 * @tb: pointer to table
 *
 * Returns: 1 if comments parsing is enabled, or 0.
 */
int mnt_table_with_comments(struct libmnt_table *tb)
{
	assert(tb);
	return tb ? tb->comms : 0;
}

/**
 * mnt_table_get_intro_comment:
 * @tb: pointer to tab
 *
 * Returns: initial comment in tb
 */
const char *mnt_table_get_intro_comment(struct libmnt_table *tb)
{
	return tb ? tb->comm_intro : NULL;
}

/**
 * mnt_table_set_into_comment:
 * @tb: pointer to tab
 * @comm: comment or NULL
 *
 * Sets the initial comment in tb.
 *
 * Returns: 0 on success or negative number in case of error.
 */
int mnt_table_set_intro_comment(struct libmnt_table *tb, const char *comm)
{
	return strdup_to_struct_member(tb, comm_intro, comm);
}

/**
 * mnt_table_append_into_comment:
 * @tb: pointer to tab
 * @comm: comment of NULL
 *
 * Appends the initial comment in tb.
 *
 * Returns: 0 on success or negative number in case of error.
 */
int mnt_table_append_intro_comment(struct libmnt_table *tb, const char *comm)
{
	if (!tb)
		return -EINVAL;
	return append_string(&tb->comm_intro, comm);
}

/**
 * mnt_table_get_trailing_comment:
 * @tb: pointer to tab
 *
 * Returns: table trailing comment
 */
const char *mnt_table_get_trailing_comment(struct libmnt_table *tb)
{
	return tb ? tb->comm_tail : NULL;
}

/**
 * mnt_table_set_trailing_comment
 * @tb: pointer to tab
 * @comm: comment string
 *
 * Sets the trailing comment in table.
 *
 * Returns: 0 on success or negative number in case of error.
 */
int mnt_table_set_trailing_comment(struct libmnt_table *tb, const char *comm)
{
	return strdup_to_struct_member(tb, comm_tail, comm);
}

/**
 * mnt_table_append_trailing_comment:
 * @tb: pointer to tab
 * @comm: comment of NULL
 *
 * Appends to the trailing table comment.
 *
 * Returns: 0 on success or negative number in case of error.
 */
int mnt_table_append_trailing_comment(struct libmnt_table *tb, const char *comm)
{
	if (!tb)
		return -EINVAL;
	return append_string(&tb->comm_tail, comm);
}

/**
 * mnt_table_set_cache:
 * @tb: pointer to tab
 * @mpc: pointer to struct libmnt_cache instance
 *
 * Sets up a cache for canonicalized paths and evaluated tags (LABEL/UUID). The
 * cache is recommended for mnt_table_find_*() functions.
 *
 * The cache could be shared between more tabs. Be careful when you share the
 * same cache between more threads -- currently the cache does not provide any
 * locking method.
 *
 * This function increments cache reference counter. It's recommended to use
 * mnt_unref_cache() after mnt_table_set_cache() if you want to keep the cache
 * referenced by @tb only.
 *
 * See also mnt_new_cache().
 *
 * Returns: 0 on success or negative number in case of error.
 */
int mnt_table_set_cache(struct libmnt_table *tb, struct libmnt_cache *mpc)
{
	if (!tb)
		return -EINVAL;

	mnt_ref_cache(mpc);			/* new */
	mnt_unref_cache(tb->cache);		/* old */
	tb->cache = mpc;
	return 0;
}

/**
 * mnt_table_get_cache:
 * @tb: pointer to tab
 *
 * Returns: pointer to struct libmnt_cache instance or NULL.
 */
struct libmnt_cache *mnt_table_get_cache(struct libmnt_table *tb)
{
	return tb ? tb->cache : NULL;
}

/**
 * mnt_table_add_fs:
 * @tb: tab pointer
 * @fs: new entry
 *
 * Adds a new entry to tab and increment @fs reference counter. Don't forget to
 * use mnt_unref_fs() after mnt_table_add_fs() you want to keep the @fs
 * referenced by the table only.
 *
 * Returns: 0 on success or negative number in case of error.
 */
int mnt_table_add_fs(struct libmnt_table *tb, struct libmnt_fs *fs)
{
	if (!tb || !fs)
		return -EINVAL;

	mnt_ref_fs(fs);
	list_add_tail(&fs->ents, &tb->ents);
	tb->nents++;

	DBG(TAB, ul_debugobj(tb, "add entry: %s %s",
			mnt_fs_get_source(fs), mnt_fs_get_target(fs)));
	return 0;
}

/**
 * mnt_table_remove_fs:
 * @tb: tab pointer
 * @fs: new entry
 *
 * Removes the @fs from the table and de-increment reference counter of the @fs. The
 * filesystem with zero reference counter will be deallocated. Don't forget to use
 * mnt_ref_fs() before call mnt_table_remove_fs() if you want to use @fs later.
 *
 * Returns: 0 on success or negative number in case of error.
 */
int mnt_table_remove_fs(struct libmnt_table *tb, struct libmnt_fs *fs)
{
	if (!tb || !fs)
		return -EINVAL;

	list_del(&fs->ents);
	INIT_LIST_HEAD(&fs->ents);	/* otherwise FS still points to the list */

	mnt_unref_fs(fs);
	tb->nents--;
	return 0;
}

static inline struct libmnt_fs *get_parent_fs(struct libmnt_table *tb, struct libmnt_fs *fs)
{
	struct libmnt_iter itr;
	struct libmnt_fs *x;
	int parent_id = mnt_fs_get_parent_id(fs);

	mnt_reset_iter(&itr, MNT_ITER_FORWARD);
	while (mnt_table_next_fs(tb, &itr, &x) == 0) {
		if (mnt_fs_get_id(x) == parent_id)
			return x;
	}

	return NULL;
}

/**
 * mnt_table_get_root_fs:
 * @tb: mountinfo file (/proc/self/mountinfo)
 * @root: returns pointer to the root filesystem (/)
 *
 * The function uses the parent ID from the mountinfo file to determine the
 * root filesystem (the filesystem with the smallest ID with parent ID missing
 * in the table). The function is designed mostly for applications where it is
 * necessary to sort mountpoints by IDs to get the tree of the mountpoints
 * (e.g. findmnt default output).
 *
 * If you're not sure, then use
 *
 *	mnt_table_find_target(tb, "/", MNT_ITER_BACKWARD);
 *
 * this is more robust and usable for arbitrary tab files (including fstab).
 *
 * Returns: 0 on success or negative number in case of error.
 */
int mnt_table_get_root_fs(struct libmnt_table *tb, struct libmnt_fs **root)
{
	struct libmnt_iter itr;
	struct libmnt_fs *fs;
	int root_id = 0;

	if (!tb || !root || !is_mountinfo(tb))
		return -EINVAL;

	DBG(TAB, ul_debugobj(tb, "lookup root fs"));

	*root = NULL;

	/* get smallest possible ID from the table */
	mnt_reset_iter(&itr, MNT_ITER_FORWARD);
	while(mnt_table_next_fs(tb, &itr, &fs) == 0) {
		int id = mnt_fs_get_parent_id(fs);

		if (!*root || id < root_id) {
			*root = fs;
			root_id = id;
		}
	}

	/* go to the root node by "parent_id -> id" relation */
	while (*root) {
		struct libmnt_fs *x = get_parent_fs(tb, *root);
		if (!x || x == *root)
			break;
		DBG(TAB, ul_debugobj(tb, " messy mountinfo, walk to %s", mnt_fs_get_target(x)));
		*root = x;
	}

	return *root ? 0 : -EINVAL;
}

/**
 * mnt_table_next_child_fs:
 * @tb: mountinfo file (/proc/self/mountinfo)
 * @itr: iterator
 * @parent: parental FS
 * @chld: returns the next child filesystem
 *
 * Note that filesystems are returned in the order of mounting (according to
 * IDs in /proc/self/mountinfo).
 *
 * Returns: 0 on success, negative number in case of error or 1 at the end of list.
 */
int mnt_table_next_child_fs(struct libmnt_table *tb, struct libmnt_iter *itr,
			struct libmnt_fs *parent, struct libmnt_fs **chld)
{
	struct libmnt_fs *fs;
	int parent_id, lastchld_id = 0, chld_id = 0;

	if (!tb || !itr || !parent || !is_mountinfo(tb))
		return -EINVAL;

	DBG(TAB, ul_debugobj(tb, "lookup next child of '%s'",
				mnt_fs_get_target(parent)));

	parent_id = mnt_fs_get_id(parent);

	/* get ID of the previously returned child */
	if (itr->head && itr->p != itr->head) {
		MNT_ITER_ITERATE(itr, fs, struct libmnt_fs, ents);
		lastchld_id = mnt_fs_get_id(fs);
	}

	*chld = NULL;

	mnt_reset_iter(itr, MNT_ITER_FORWARD);
	while(mnt_table_next_fs(tb, itr, &fs) == 0) {
		int id;

		if (mnt_fs_get_parent_id(fs) != parent_id)
			continue;

		id = mnt_fs_get_id(fs);

		/* avoid an infinite loop. This only happens in rare cases
		 * such as in early userspace when the rootfs is its own parent */
		if (id == parent_id)
			continue;

		if ((!lastchld_id || id > lastchld_id) &&
		    (!*chld || id < chld_id)) {
			*chld = fs;
			chld_id = id;
		}
	}

	if (!*chld)
		return 1;	/* end of iterator */

	/* set the iterator to the @chld for the next call */
	mnt_table_set_iter(tb, itr, *chld);

	return 0;
}

/**
 * mnt_table_next_fs:
 * @tb: tab pointer
 * @itr: iterator
 * @fs: returns the next tab entry
 *
 * Returns: 0 on success, negative number in case of error or 1 at the end of list.
 *
 * Example:
 * <informalexample>
 *   <programlisting>
 *	while(mnt_table_next_fs(tb, itr, &fs) == 0) {
 *		const char *dir = mnt_fs_get_target(fs);
 *		printf("mount point: %s\n", dir);
 *	}
 *   </programlisting>
 * </informalexample>
 *
 * lists all mountpoints from fstab in reverse order.
 */
int mnt_table_next_fs(struct libmnt_table *tb, struct libmnt_iter *itr, struct libmnt_fs **fs)
{
	int rc = 1;

	if (!tb || !itr || !fs)
		return -EINVAL;
	*fs = NULL;

	if (!itr->head)
		MNT_ITER_INIT(itr, &tb->ents);
	if (itr->p != itr->head) {
		MNT_ITER_ITERATE(itr, *fs, struct libmnt_fs, ents);
		rc = 0;
	}

	return rc;
}

/**
 * mnt_table_first_fs:
 * @tb: tab pointer
 * @fs: returns the first tab entry
 *
 * Returns: 0 on success, negative number in case of error or 1 at the end of list.
 */
int mnt_table_first_fs(struct libmnt_table *tb, struct libmnt_fs **fs)
{
	if (!tb || !fs)
		return -EINVAL;
	if (list_empty(&tb->ents))
		return 1;
	*fs = list_first_entry(&tb->ents, struct libmnt_fs, ents);
	return 0;
}

/**
 * mnt_table_last_fs:
 * @tb: tab pointer
 * @fs: returns the last tab entry
 *
 * Returns: 0 on success, negative number in case of error or 1 at the end of list.
 */
int mnt_table_last_fs(struct libmnt_table *tb, struct libmnt_fs **fs)
{
	if (!tb || !fs)
		return -EINVAL;
	if (list_empty(&tb->ents))
		return 1;
	*fs = list_last_entry(&tb->ents, struct libmnt_fs, ents);
	return 0;
}

/**
 * mnt_table_find_next_fs:
 * @tb: table
 * @itr: iterator
 * @match_func: function returning 1 or 0
 * @userdata: extra data for match_func
 * @fs: returns pointer to the next matching table entry
 *
 * This function allows searching in @tb.
 *
 * Returns: negative number in case of error, 1 at end of table or 0 o success.
 */
int mnt_table_find_next_fs(struct libmnt_table *tb, struct libmnt_iter *itr,
		int (*match_func)(struct libmnt_fs *, void *), void *userdata,
		struct libmnt_fs **fs)
{
	if (!tb || !itr || !fs || !match_func)
		return -EINVAL;

	DBG(TAB, ul_debugobj(tb, "lookup next fs"));

	if (!itr->head)
		MNT_ITER_INIT(itr, &tb->ents);

	do {
		if (itr->p != itr->head)
			MNT_ITER_ITERATE(itr, *fs, struct libmnt_fs, ents);
		else
			break;			/* end */

		if (match_func(*fs, userdata))
			return 0;
	} while(1);

	*fs = NULL;
	return 1;
}

static int mnt_table_move_parent(struct libmnt_table *tb, int oldid, int newid)
{
	struct libmnt_iter itr;
	struct libmnt_fs *fs;

	if (!tb)
		return -EINVAL;
	if (list_empty(&tb->ents))
		return 0;

	DBG(TAB, ul_debugobj(tb, "moving parent ID from %d -> %d", oldid, newid));
	mnt_reset_iter(&itr, MNT_ITER_FORWARD);

	while (mnt_table_next_fs(tb, &itr, &fs) == 0) {
		if (fs->parent == oldid)
			fs->parent = newid;
	}
	return 0;
}

/**
 * mnt_table_uniq_fs:
 * @tb: table
 * @flags: MNT_UNIQ_*
 * @cmp: function to compare filesystems
 *
 * This function de-duplicate the @tb, but does not change order of the
 * filesystems. The @cmp function has to return 0 if the filesystems are
 * equal, otherwise non-zero.
 *
 * The default is to keep in the table later mounted filesystems (function uses
 * backward mode iterator).
 *
 * @MNT_UNIQ_FORWARD:  remove later mounted filesystems
 * @MNT_UNIQ_KEEPTREE: keep parent->id relationship still valid
 *
 * Returns: negative number in case of error, or 0 o success.
 */
int mnt_table_uniq_fs(struct libmnt_table *tb, int flags,
				int (*cmp)(struct libmnt_table *,
					   struct libmnt_fs *,
					   struct libmnt_fs *))
{
	struct libmnt_iter itr;
	struct libmnt_fs *fs;
	int direction = MNT_ITER_BACKWARD;

	if (!tb || !cmp)
		return -EINVAL;
	if (list_empty(&tb->ents))
		return 0;

	if (flags & MNT_UNIQ_FORWARD)
		direction = MNT_ITER_FORWARD;

	DBG(TAB, ul_debugobj(tb, "de-duplicate"));
	mnt_reset_iter(&itr, direction);

	if ((flags & MNT_UNIQ_KEEPTREE) && !is_mountinfo(tb))
		flags &= ~MNT_UNIQ_KEEPTREE;

	while (mnt_table_next_fs(tb, &itr, &fs) == 0) {
		int want = 1;
		struct libmnt_iter xtr;
		struct libmnt_fs *x;

		mnt_reset_iter(&xtr, direction);
		while (want && mnt_table_next_fs(tb, &xtr, &x) == 0) {
			if (fs == x)
				break;
			want = cmp(tb, x, fs) != 0;
		}

		if (!want) {
			if (flags & MNT_UNIQ_KEEPTREE)
				mnt_table_move_parent(tb, mnt_fs_get_id(fs),
							  mnt_fs_get_parent_id(fs));

			DBG(TAB, ul_debugobj(tb, "remove duplicate %s",
						mnt_fs_get_target(fs)));
			mnt_table_remove_fs(tb, fs);
		}
	}

	return 0;
}

/**
 * mnt_table_set_iter:
 * @tb: tab pointer
 * @itr: iterator
 * @fs: tab entry
 *
 * Sets @iter to the position of @fs in the file @tb.
 *
 * Returns: 0 on success, negative number in case of error.
 */
int mnt_table_set_iter(struct libmnt_table *tb, struct libmnt_iter *itr, struct libmnt_fs *fs)
{
	if (!tb || !itr || !fs)
		return -EINVAL;

	MNT_ITER_INIT(itr, &tb->ents);
	itr->p = &fs->ents;

	return 0;
}

/**
 * mnt_table_find_mountpoint:
 * @tb: tab pointer
 * @path: directory
 * @direction: MNT_ITER_{FORWARD,BACKWARD}
 *
 * Same as mnt_get_mountpoint(), except this function does not rely on
 * st_dev numbers.
 *
 * Returns: a tab entry or NULL.
 */
struct libmnt_fs *mnt_table_find_mountpoint(struct libmnt_table *tb,
					    const char *path,
					    int direction)
{
	char *mnt;
	struct stat st;

	if (!tb || !path || !*path)
		return NULL;
	if (direction != MNT_ITER_FORWARD && direction != MNT_ITER_BACKWARD)
		return NULL;

	DBG(TAB, ul_debugobj(tb, "lookup MOUNTPOINT: '%s'", path));

	if (mnt_stat_mountpoint(path, &st))
		return NULL;

	mnt = strdup(path);
	if (!mnt)
		return NULL;

	do {
		char *p;
		struct libmnt_fs *fs;

		fs = mnt_table_find_target(tb, mnt, direction);
		if (fs) {
			free(mnt);
			return fs;
		}

		p = stripoff_last_component(mnt);
		if (!p)
			break;
	} while (mnt && *(mnt + 1) != '\0');

	free(mnt);
	return mnt_table_find_target(tb, "/", direction);
}

/**
 * mnt_table_find_target:
 * @tb: tab pointer
 * @path: mountpoint directory
 * @direction: MNT_ITER_{FORWARD,BACKWARD}
 *
 * Try to lookup an entry in the given tab, three iterations are possible, the first
 * with @path, the second with realpath(@path) and the third with realpath(@path)
 * against realpath(fs->target). The 2nd and 3rd iterations are not performed when
 * the @tb cache is not set (see mnt_table_set_cache()). If
 * mnt_cache_set_targets(cache, mtab) was called, the 3rd iteration skips any
 * @fs->target found in @mtab (see mnt_resolve_target()).
 *
 * Returns: a tab entry or NULL.
 */
struct libmnt_fs *mnt_table_find_target(struct libmnt_table *tb, const char *path, int direction)
{
	struct libmnt_iter itr;
	struct libmnt_fs *fs = NULL;
	char *cn;

	if (!tb || !path || !*path)
		return NULL;
	if (direction != MNT_ITER_FORWARD && direction != MNT_ITER_BACKWARD)
		return NULL;

	DBG(TAB, ul_debugobj(tb, "lookup TARGET: '%s'", path));

	/* native @target */
	mnt_reset_iter(&itr, direction);
	while(mnt_table_next_fs(tb, &itr, &fs) == 0) {
		if (mnt_fs_streq_target(fs, path))
			return fs;
	}

	/* try absolute path */
	if (is_relative_path(path) && (cn = absolute_path(path))) {
		DBG(TAB, ul_debugobj(tb, "lookup absolute TARGET: '%s'", cn));
		mnt_reset_iter(&itr, direction);
		while (mnt_table_next_fs(tb, &itr, &fs) == 0) {
			if (mnt_fs_streq_target(fs, cn)) {
				free(cn);
				return fs;
			}
		}
		free(cn);
	}

	if (!tb->cache || !(cn = mnt_resolve_path(path, tb->cache)))
		return NULL;

	DBG(TAB, ul_debugobj(tb, "lookup canonical TARGET: '%s'", cn));

	/* canonicalized paths in struct libmnt_table */
	mnt_reset_iter(&itr, direction);
	while(mnt_table_next_fs(tb, &itr, &fs) == 0) {
		if (mnt_fs_streq_target(fs, cn))
			return fs;
	}

	/* non-canonical path in struct libmnt_table
	 * -- note that mountpoint in /proc/self/mountinfo is already
	 *    canonicalized by the kernel
	 */
	mnt_reset_iter(&itr, direction);
	while(mnt_table_next_fs(tb, &itr, &fs) == 0) {
		char *p;

		if (!fs->target
		    || mnt_fs_is_swaparea(fs)
		    || mnt_fs_is_kernel(fs)
		    || (*fs->target == '/' && *(fs->target + 1) == '\0'))
		       continue;

		p = mnt_resolve_target(fs->target, tb->cache);
		/* both canonicalized, strcmp() is fine here */
		if (p && strcmp(cn, p) == 0)
			return fs;
	}
	return NULL;
}

/**
 * mnt_table_find_srcpath:
 * @tb: tab pointer
 * @path: source path (devname or dirname) or NULL
 * @direction: MNT_ITER_{FORWARD,BACKWARD}
 *
 * Try to lookup an entry in the given tab, four iterations are possible, the first
 * with @path, the second with realpath(@path), the third with tags (LABEL, UUID, ..)
 * from @path and the fourth with realpath(@path) against realpath(entry->srcpath).
 *
 * The 2nd, 3rd and 4th iterations are not performed when the @tb cache is not
 * set (see mnt_table_set_cache()).
 *
 * For btrfs returns tab entry for default id.
 *
 * Note that NULL is a valid source path; it will be replaced with "none". The
 * "none" is used in /proc/{mounts,self/mountinfo} for pseudo filesystems.
 *
 * Returns: a tab entry or NULL.
 */
struct libmnt_fs *mnt_table_find_srcpath(struct libmnt_table *tb, const char *path, int direction)
{
	struct libmnt_iter itr;
	struct libmnt_fs *fs = NULL;
	int ntags = 0, nents;
	char *cn;
	const char *p;

	if (!tb || !path || !*path)
		return NULL;
	if (direction != MNT_ITER_FORWARD && direction != MNT_ITER_BACKWARD)
		return NULL;

	DBG(TAB, ul_debugobj(tb, "lookup SRCPATH: '%s'", path));

	/* native paths */
	mnt_reset_iter(&itr, direction);

	while(mnt_table_next_fs(tb, &itr, &fs) == 0) {

		if (mnt_fs_streq_srcpath(fs, path)) {
#ifdef HAVE_BTRFS_SUPPORT
			if (fs->fstype && !strcmp(fs->fstype, "btrfs")) {
				uint64_t default_id = btrfs_get_default_subvol_id(mnt_fs_get_target(fs));
				char *val;
				size_t len;

				if (default_id == UINT64_MAX)
					DBG(TAB, ul_debug("not found btrfs volume setting"));

				else if (mnt_fs_get_option(fs, "subvolid", &val, &len) == 0) {
					uint64_t subvol_id;

					if (mnt_parse_offset(val, len, &subvol_id)) {
						DBG(TAB, ul_debugobj(tb, "failed to parse subvolid="));
						continue;
					}
					if (subvol_id != default_id)
						continue;
				}
			}
#endif /* HAVE_BTRFS_SUPPORT */
			return fs;
		}
		if (mnt_fs_get_tag(fs, NULL, NULL) == 0)
			ntags++;
	}

	if (!path || !tb->cache || !(cn = mnt_resolve_path(path, tb->cache)))
		return NULL;

	DBG(TAB, ul_debugobj(tb, "lookup canonical SRCPATH: '%s'", cn));

	nents = mnt_table_get_nents(tb);

	/* canonicalized paths in struct libmnt_table */
	if (ntags < nents) {
		mnt_reset_iter(&itr, direction);
		while(mnt_table_next_fs(tb, &itr, &fs) == 0) {
			if (mnt_fs_streq_srcpath(fs, cn))
				return fs;
		}
	}

	/* evaluated tag */
	if (ntags) {
		int rc = mnt_cache_read_tags(tb->cache, cn);

		mnt_reset_iter(&itr, direction);

		if (rc == 0) {
			/* @path's TAGs are in the cache */
			while(mnt_table_next_fs(tb, &itr, &fs) == 0) {
				const char *t, *v;

				if (mnt_fs_get_tag(fs, &t, &v))
					continue;

				if (mnt_cache_device_has_tag(tb->cache, cn, t, v))
					return fs;
			}
		} else if (rc < 0 && errno == EACCES) {
			/* @path is inaccessible, try evaluating all TAGs in @tb
			 * by udev symlinks -- this could be expensive on systems
			 * with a huge fstab/mtab */
			 while(mnt_table_next_fs(tb, &itr, &fs) == 0) {
				 const char *t, *v, *x;
				 if (mnt_fs_get_tag(fs, &t, &v))
					 continue;
				 x = mnt_resolve_tag(t, v, tb->cache);

				 /* both canonicalized, strcmp() is fine here */
				 if (x && strcmp(x, cn) == 0)
					 return fs;
			 }
		}
	}

	/* non-canonicalized paths in struct libmnt_table */
	if (ntags <= nents) {
		mnt_reset_iter(&itr, direction);
		while(mnt_table_next_fs(tb, &itr, &fs) == 0) {
			if (mnt_fs_is_netfs(fs) || mnt_fs_is_pseudofs(fs))
				continue;
			p = mnt_fs_get_srcpath(fs);
			if (p)
				p = mnt_resolve_path(p, tb->cache);

			/* both canonicalized, strcmp() is fine here */
			if (p && strcmp(p, cn) == 0)
				return fs;
		}
	}

	return NULL;
}


/**
 * mnt_table_find_tag:
 * @tb: tab pointer
 * @tag: tag name (e.g "LABEL", "UUID", ...)
 * @val: tag value
 * @direction: MNT_ITER_{FORWARD,BACKWARD}
 *
 * Try to lookup an entry in the given tab, the first attempt is to lookup by @tag and
 * @val, for the second attempt the tag is evaluated (converted to the device
 * name) and mnt_table_find_srcpath() is performed. The second attempt is not
 * performed when @tb cache is not set (see mnt_table_set_cache()).

 * Returns: a tab entry or NULL.
 */
struct libmnt_fs *mnt_table_find_tag(struct libmnt_table *tb, const char *tag,
			const char *val, int direction)
{
	struct libmnt_iter itr;
	struct libmnt_fs *fs = NULL;

	if (!tb || !tag || !*tag || !val)
		return NULL;
	if (direction != MNT_ITER_FORWARD && direction != MNT_ITER_BACKWARD)
		return NULL;

	DBG(TAB, ul_debugobj(tb, "lookup by TAG: %s %s", tag, val));

	/* look up by TAG */
	mnt_reset_iter(&itr, direction);
	while(mnt_table_next_fs(tb, &itr, &fs) == 0) {
		if (fs->tagname && fs->tagval &&
		    strcmp(fs->tagname, tag) == 0 &&
		    strcmp(fs->tagval, val) == 0)
			return fs;
	}

	if (tb->cache) {
		/* look up by device name */
		char *cn = mnt_resolve_tag(tag, val, tb->cache);
		if (cn)
			return mnt_table_find_srcpath(tb, cn, direction);
	}
	return NULL;
}

/**
 * mnt_table_find_target_with_option:
 * @tb: tab pointer
 * @path: mountpoint directory
 * @option: option name (e.g "subvol", "subvolid", ...)
 * @val: option value or NULL
 * @direction: MNT_ITER_{FORWARD,BACKWARD}
 *
 * Try to lookup an entry in the given tab that matches combination of @path
 * and @option. In difference to mnt_table_find_target(), only @path iteration
 * is done. No lookup by device name, no canonicalization.
 *
 * Returns: a tab entry or NULL.
 *
 * Since: 2.28
 */
struct libmnt_fs *mnt_table_find_target_with_option(
			struct libmnt_table *tb, const char *path,
			const char *option, const char *val, int direction)
{
	struct libmnt_iter itr;
	struct libmnt_fs *fs = NULL;
	char *optval = NULL;
	size_t optvalsz = 0, valsz = val ? strlen(val) : 0;

	if (!tb || !path || !*path || !option || !*option || !val)
		return NULL;
	if (direction != MNT_ITER_FORWARD && direction != MNT_ITER_BACKWARD)
		return NULL;

	DBG(TAB, ul_debugobj(tb, "lookup TARGET: '%s' with OPTION %s %s", path, option, val));

	/* look up by native @target with OPTION */
	mnt_reset_iter(&itr, direction);
	while (mnt_table_next_fs(tb, &itr, &fs) == 0) {
		if (mnt_fs_streq_target(fs, path)
		    && mnt_fs_get_option(fs, option, &optval, &optvalsz) == 0
		    && (!val || (optvalsz == valsz
				 && strncmp(optval, val, optvalsz) == 0)))
			return fs;
	}
	return NULL;
}

/**
 * mnt_table_find_source:
 * @tb: tab pointer
 * @source: TAG or path
 * @direction: MNT_ITER_{FORWARD,BACKWARD}
 *
 * This is a high-level API for mnt_table_find_{srcpath,tag}. You needn't care
 * about the @source format (device, LABEL, UUID, ...). This function parses
 * the @source and calls mnt_table_find_tag() or mnt_table_find_srcpath().
 *
 * Returns: a tab entry or NULL.
 */
struct libmnt_fs *mnt_table_find_source(struct libmnt_table *tb,
					const char *source, int direction)
{
	struct libmnt_fs *fs;
	char *t = NULL, *v = NULL;

	if (!tb)
		return NULL;
	if (direction != MNT_ITER_FORWARD && direction != MNT_ITER_BACKWARD)
		return NULL;

	DBG(TAB, ul_debugobj(tb, "lookup SOURCE: '%s'", source));

	if (blkid_parse_tag_string(source, &t, &v) || !mnt_valid_tagname(t))
		fs = mnt_table_find_srcpath(tb, source, direction);
	else
		fs = mnt_table_find_tag(tb, t, v, direction);

	free(t);
	free(v);

	return fs;
}

/**
 * mnt_table_find_pair
 * @tb: tab pointer
 * @source: TAG or path
 * @target: mountpoint
 * @direction: MNT_ITER_{FORWARD,BACKWARD}
 *
 * This function is implemented by mnt_fs_match_source() and
 * mnt_fs_match_target() functions. It means that this is more expensive than
 * others mnt_table_find_* function, because every @tab entry is fully evaluated.
 *
 * Returns: a tab entry or NULL.
 */
struct libmnt_fs *mnt_table_find_pair(struct libmnt_table *tb, const char *source,
				      const char *target, int direction)
{
	struct libmnt_fs *fs = NULL;
	struct libmnt_iter itr;

	if (!tb || !target || !*target || !source || !*source)
		return NULL;
	if (direction != MNT_ITER_FORWARD && direction != MNT_ITER_BACKWARD)
		return NULL;

	DBG(TAB, ul_debugobj(tb, "lookup SOURCE: %s TARGET: %s", source, target));

	mnt_reset_iter(&itr, direction);
	while(mnt_table_next_fs(tb, &itr, &fs) == 0) {

		if (mnt_fs_match_target(fs, target, tb->cache) &&
		    mnt_fs_match_source(fs, source, tb->cache))
			return fs;
	}

	return NULL;
}

/**
 * mnt_table_find_devno
 * @tb: /proc/self/mountinfo
 * @devno: device number
 * @direction: MNT_ITER_{FORWARD,BACKWARD}
 *
 * Note that zero could be a valid device number for the root pseudo filesystem (e.g.
 * tmpfs).
 *
 * Returns: a tab entry or NULL.
 */
struct libmnt_fs *mnt_table_find_devno(struct libmnt_table *tb,
				       dev_t devno, int direction)
{
	struct libmnt_fs *fs = NULL;
	struct libmnt_iter itr;

	if (!tb)
		return NULL;
	if (direction != MNT_ITER_FORWARD && direction != MNT_ITER_BACKWARD)
		return NULL;

	DBG(TAB, ul_debugobj(tb, "lookup DEVNO: %d", (int) devno));

	mnt_reset_iter(&itr, direction);

	while(mnt_table_next_fs(tb, &itr, &fs) == 0) {
		if (mnt_fs_get_devno(fs) == devno)
			return fs;
	}

	return NULL;
}

static char *remove_mountpoint_from_path(const char *path, const char *mnt)
{
        char *res;
	const char *p;
	size_t sz;

	sz = strlen(mnt);
	p = sz > 1 ? path + sz : path;

	res = *p ? strdup(p) : strdup("/");
	DBG(UTILS, ul_debug("%s fs-root is %s", path, res));
	return res;
}

#ifdef HAVE_BTRFS_SUPPORT
static int get_btrfs_fs_root(struct libmnt_table *tb, struct libmnt_fs *fs, char **root)
{
	char *vol = NULL, *p;
	size_t sz, volsz = 0;

	DBG(BTRFS, ul_debug("lookup for btrfs FS root"));
	*root = NULL;

	if (mnt_fs_get_option(fs, "subvolid", &vol, &volsz) == 0) {
		char *target;
		struct libmnt_fs *f;
		char subvolidstr[sizeof(stringify_value(UINT64_MAX))];

		DBG(BTRFS, ul_debug(" found subvolid=%s, checking", vol));

		assert (volsz + 1 < sizeof(stringify_value(UINT64_MAX)));
		memcpy(subvolidstr, vol, volsz);
		subvolidstr[volsz] = '\0';

		target = mnt_resolve_target(mnt_fs_get_target(fs), tb->cache);
		if (!target)
			goto err;

		DBG(BTRFS, ul_debug(" trying target=%s subvolid=%s", target, subvolidstr));
		f = mnt_table_find_target_with_option(tb, target,
					"subvolid", subvolidstr,
					MNT_ITER_BACKWARD);
		if (!tb->cache)
			free(target);
		if (!f)
			goto not_found;

		/* Instead of set of BACKREF queries constructing subvol path
		 * corresponding to a particular subvolid, use the one in
		 * mountinfo. Kernel keeps subvol path up to date.
		 */
		if (mnt_fs_get_option(f, "subvol", &vol, &volsz) != 0)
			goto not_found;

	} else if (mnt_fs_get_option(fs, "subvol", &vol, &volsz) != 0) {
		/* If fstab entry does not contain "subvol", we have to
		 * check, whether btrfs has default subvolume defined.
		 */
		uint64_t default_id;
		char *target;
		struct libmnt_fs *f;
		char default_id_str[sizeof(stringify_value(UINT64_MAX))];

		DBG(BTRFS, ul_debug(" subvolid/subvol not found, checking default"));

		default_id = btrfs_get_default_subvol_id(mnt_fs_get_target(fs));
		if (default_id == UINT64_MAX)
			goto not_found;

		/* Volume has default subvolume. Check if it matches to
		 * the one in mountinfo.
		 *
		 * Only kernel >= 4.2 reports subvolid. On older
		 * kernels, there is no reasonable way to detect which
		 * subvolume was mounted.
		 */
		target = mnt_resolve_target(mnt_fs_get_target(fs), tb->cache);
		if (!target)
			goto err;

		snprintf(default_id_str, sizeof(default_id_str), "%llu",
				(unsigned long long int) default_id);

		DBG(BTRFS, ul_debug(" trying target=%s default subvolid=%s",
					target, default_id_str));

		f = mnt_table_find_target_with_option(tb, target,
					"subvolid", default_id_str,
					MNT_ITER_BACKWARD);
		if (!tb->cache)
			free(target);
		if (!f)
			goto not_found;

		/* Instead of set of BACKREF queries constructing
		 * subvol path, use the one in mountinfo. Kernel does
		 * the evaluation for us.
		 */
		DBG(BTRFS, ul_debug("setting FS root: btrfs default subvolid = %s",
					default_id_str));

		if (mnt_fs_get_option(f, "subvol", &vol, &volsz) != 0)
			goto not_found;
	}

	DBG(BTRFS, ul_debug(" using subvol=%s", vol));
	sz = volsz;
	if (*vol != '/')
		sz++;
	*root = malloc(sz + 1);
	if (!*root)
		goto err;
	p = *root;
	if (*vol != '/')
		*p++ = '/';
	memcpy(p, vol, volsz);
	*(*root + sz) = '\0';
	return 0;

not_found:
	DBG(BTRFS, ul_debug(" not found btrfs volume setting"));
	return 1;
err:
	DBG(BTRFS, ul_debug(" error on btrfs volume setting evaluation"));
	return errno ? -errno : -1;
}
#endif /* HAVE_BTRFS_SUPPORT */

static const char *get_cifs_unc_subdir_path (const char *unc)
{
	/*
	 *  1 or more slash:     %*[/]
	 *  1 or more non-slash: %*[^/]
	 *  number of byte read: %n
	 */
	int share_end = 0;
	int r = sscanf(unc, "%*[/]%*[^/]%*[/]%*[^/]%n", &share_end);
	if (r == EOF || share_end == 0)
		return NULL;
	return unc + share_end;
}

/*
 * tb: /proc/self/mountinfo
 * fs: filesystem
 * mountflags: MS_BIND or 0
 * fsroot: fs-root that will probably be used in the mountinfo file
 *          for @fs after mount(2)
 *
 * For btrfs subvolumes this function returns NULL, but @fsroot properly set.
 *
 * If @tb is NULL then defaults to '/'.
 *
 * Returns: entry from @tb that will be used as a source for @fs if the @fs is
 *          bindmount.
 *
 * Don't export to library API!
 */
struct libmnt_fs *mnt_table_get_fs_root(struct libmnt_table *tb,
					struct libmnt_fs *fs,
					unsigned long mountflags,
					char **fsroot)
{
	char *root = NULL;
	const char *mnt = NULL;
	struct libmnt_fs *src_fs = NULL;

	assert(fs);
	assert(fsroot);

	DBG(TAB, ul_debug("lookup fs-root for '%s'", mnt_fs_get_source(fs)));

	if (tb && (mountflags & MS_BIND)) {
		const char *src, *src_root;
		char *xsrc = NULL;

		DBG(TAB, ul_debug("fs-root for bind"));

		src = xsrc = mnt_resolve_spec(mnt_fs_get_source(fs), tb->cache);
		if (src) {
			struct libmnt_fs *f = mnt_table_find_mountpoint(tb,
							src, MNT_ITER_BACKWARD);
			if (f)
				mnt = mnt_fs_get_target(f);
		}
		if (mnt)
			root = remove_mountpoint_from_path(src, mnt);

		if (xsrc && !tb->cache) {
			free(xsrc);
			src = NULL;
		}
		if (!mnt)
			goto err;

		src_fs = mnt_table_find_target(tb, mnt, MNT_ITER_BACKWARD);
		if (!src_fs)  {
			DBG(TAB, ul_debug("not found '%s' in mountinfo -- using default", mnt));
			goto dflt;
		}

		/* It's possible that fstab_fs source is subdirectory on btrfs
		 * subvolume or another bind mount. For example:
		 *
		 * /dev/sdc        /mnt/test       btrfs   subvol=/anydir
		 * /dev/sdc        /mnt/test       btrfs   defaults
		 * /mnt/test/foo   /mnt/test2      auto    bind
		 *
		 * in this case, the root for /mnt/test2 will be /anydir/foo on
		 * /dev/sdc. It means we have to compose the final root from
		 * root and src_root.
		 */
		src_root = mnt_fs_get_root(src_fs);

		DBG(FS, ul_debugobj(fs, "source root: %s, source FS root: %s", root, src_root));

		if (src_root && !startswith(root, src_root)) {
			if (strcmp(root, "/") == 0) {
				free(root);
				root = strdup(src_root);
				if (!root)
					goto err;
			} else {
				char *tmp;
				if (asprintf(&tmp, "%s%s", src_root, root) < 0)
					goto err;
				free(root);
				root = tmp;
			}
		}
	}

#ifdef HAVE_BTRFS_SUPPORT
	/*
	 * btrfs-subvolume mount -- get subvolume name and use it as a root-fs path
	 */
	else if (tb && fs->fstype &&
		 (!strcmp(fs->fstype, "btrfs") || !strcmp(fs->fstype, "auto"))) {
		if (get_btrfs_fs_root(tb, fs, &root) < 0)
			goto err;
	}
#endif /* HAVE_BTRFS_SUPPORT */

dflt:
	if (!root) {
		root = strdup("/");
		if (!root)
			goto err;
	}
	*fsroot = root;

	DBG(TAB, ul_debug("FS root result: %s", root));

	return src_fs;
err:
	free(root);
	return NULL;
}

/**
 * mnt_table_is_fs_mounted:
 * @tb: /proc/self/mountinfo file
 * @fstab_fs: /etc/fstab entry
 *
 * Checks if the @fstab_fs entry is already in the @tb table. The "swap" is
 * ignored. This function explicitly compares the source, target and root of the
 * filesystems.
 *
 * Note that source and target are canonicalized only if a cache for @tb is
 * defined (see mnt_table_set_cache()). The target canonicalization may
 * trigger automount on autofs mountpoints!
 *
 * Don't use it if you want to know if a device is mounted, just use
 * mnt_table_find_source() on the device.
 *
 * This function is designed mostly for "mount -a".
 *
 * Returns: 0 or 1
 */
int mnt_table_is_fs_mounted(struct libmnt_table *tb, struct libmnt_fs *fstab_fs)
{
	struct libmnt_iter itr;
	struct libmnt_fs *fs;

	char *root = NULL;
	char *src2 = NULL;
	const char *src = NULL, *tgt = NULL;
	char *xtgt = NULL;
	int rc = 0;
	dev_t devno = 0;

	DBG(FS, ul_debugobj(fstab_fs, "mnt_table_is_fs_mounted: target=%s, source=%s",
				mnt_fs_get_target(fstab_fs),
				mnt_fs_get_source(fstab_fs)));

	if (mnt_fs_is_swaparea(fstab_fs) || mnt_table_is_empty(tb)) {
		DBG(FS, ul_debugobj(fstab_fs, "- ignore (swap or no data)"));
		return 0;
	}

	if (is_mountinfo(tb)) {
		/* @tb is mountinfo, so we can try to use fs-roots */
		struct libmnt_fs *rootfs;
		int flags = 0;

		if (mnt_fs_get_option(fstab_fs, "bind", NULL, NULL) == 0 ||
		    mnt_fs_get_option(fstab_fs, "rbind", NULL, NULL) == 0)
			flags = MS_BIND;

		rootfs = mnt_table_get_fs_root(tb, fstab_fs, flags, &root);
		if (rootfs) {
			const char *fstype = mnt_fs_get_fstype(rootfs);

			src = mnt_fs_get_srcpath(rootfs);
			if (fstype && strncmp(fstype, "nfs", 3) == 0 && root) {
				/* NFS stores the root at the end of the source */
				src = src2 = strappend(src, root);
				free(root);
				root = NULL;
			}
		}
	}

	if (!src)
		src = mnt_fs_get_source(fstab_fs);

	if (src && tb->cache && !mnt_fs_is_pseudofs(fstab_fs))
		src = mnt_resolve_spec(src, tb->cache);

	if (src && root) {
		struct stat st;

		devno = mnt_fs_get_devno(fstab_fs);
		if (!devno && stat(src, &st) == 0 && S_ISBLK(st.st_mode))
			devno = st.st_rdev;
	}

	tgt = mnt_fs_get_target(fstab_fs);

	if (!tgt || !src) {
		DBG(FS, ul_debugobj(fstab_fs, "- ignore (no source/target)"));
		goto done;
	}
	mnt_reset_iter(&itr, MNT_ITER_FORWARD);

	DBG(FS, ul_debugobj(fstab_fs, "mnt_table_is_fs_mounted: src=%s, tgt=%s, root=%s", src, tgt, root));

	while (mnt_table_next_fs(tb, &itr, &fs) == 0) {

		int eq = mnt_fs_streq_srcpath(fs, src);

		if (!eq && devno && mnt_fs_get_devno(fs) == devno)
			eq = 1;

		if (!eq) {
			/* The source does not match. Maybe the source is a loop
			 * device backing file.
			 */
			uint64_t offset = 0;
			char *val;
			size_t len;
			int flags = 0;

			if (!mnt_fs_get_srcpath(fs) ||
			    !startswith(mnt_fs_get_srcpath(fs), "/dev/loop"))
				continue;	/* does not look like loopdev */

			if (mnt_fs_get_option(fstab_fs, "offset", &val, &len) == 0) {
				if (mnt_parse_offset(val, len, &offset)) {
					DBG(FS, ul_debugobj(fstab_fs, "failed to parse offset="));
					continue;
				}
				flags = LOOPDEV_FL_OFFSET;
			}

			DBG(FS, ul_debugobj(fs, "checking for loop: src=%s", mnt_fs_get_srcpath(fs)));
#if __linux__
			if (!loopdev_is_used(mnt_fs_get_srcpath(fs), src, offset, 0, flags))
				continue;

			DBG(FS, ul_debugobj(fs, "used loop"));
#endif
		}

		if (root) {
			const char *fstype = mnt_fs_get_fstype(fs);

			if (fstype && strcmp(fstype, "cifs") == 0) {
				const char *unc_subdir = get_cifs_unc_subdir_path(src);
				const char *path_on_fs = mnt_fs_get_root(fs);
				if (!unc_subdir || !path_on_fs || !streq_paths(unc_subdir, path_on_fs))
					continue;
			} else {
				const char *r = mnt_fs_get_root(fs);
				if (!r || strcmp(r, root) != 0)
					continue;
			}
		}

		/*
		 * Compare target, try to minimize the number of situations when we
		 * need to canonicalize the path to avoid readlink() on
		 * mountpoints.
		 */
		if (!xtgt) {
			if (mnt_fs_streq_target(fs, tgt))
				break;
			if (tb->cache)
				xtgt = mnt_resolve_path(tgt, tb->cache);
		}
		if (xtgt && mnt_fs_streq_target(fs, xtgt))
			break;
	}

	if (fs)
		rc = 1;		/* success */
done:
	free(root);

	DBG(TAB, ul_debugobj(tb, "mnt_table_is_fs_mounted: %s [rc=%d]", src, rc));
	free(src2);
	return rc;
}

#ifdef TEST_PROGRAM
#include "pathnames.h"

static int parser_errcb(struct libmnt_table *tb, const char *filename, int line)
{
	fprintf(stderr, "%s:%d: parse error\n", filename, line);

	return 1;	/* all errors are recoverable -- this is the default */
}

static struct libmnt_table *create_table(const char *file, int comments)
{
	struct libmnt_table *tb;

	if (!file)
		return NULL;
	tb = mnt_new_table();
	if (!tb)
		goto err;

	mnt_table_enable_comments(tb, comments);
	mnt_table_set_parser_errcb(tb, parser_errcb);

	if (mnt_table_parse_file(tb, file) != 0)
		goto err;
	return tb;
err:
	fprintf(stderr, "%s: parsing failed\n", file);
	mnt_unref_table(tb);
	return NULL;
}

static int test_copy_fs(struct libmnt_test *ts, int argc, char *argv[])
{
	struct libmnt_table *tb;
	struct libmnt_fs *fs;
	int rc = -1;

	tb = create_table(argv[1], FALSE);
	if (!tb)
		return -1;

	fs = mnt_table_find_target(tb, "/", MNT_ITER_FORWARD);
	if (!fs)
		goto done;

	printf("ORIGINAL:\n");
	mnt_fs_print_debug(fs, stdout);

	fs = mnt_copy_fs(NULL, fs);
	if (!fs)
		goto done;

	printf("COPY:\n");
	mnt_fs_print_debug(fs, stdout);
	mnt_unref_fs(fs);
	rc = 0;
done:
	mnt_unref_table(tb);
	return rc;
}

static int test_parse(struct libmnt_test *ts, int argc, char *argv[])
{
	struct libmnt_table *tb = NULL;
	struct libmnt_iter *itr = NULL;
	struct libmnt_fs *fs;
	int rc = -1;
	int parse_comments = FALSE;

	if (argc == 3 && !strcmp(argv[2], "--comments"))
		parse_comments = TRUE;

	tb = create_table(argv[1], parse_comments);
	if (!tb)
		return -1;

	itr = mnt_new_iter(MNT_ITER_FORWARD);
	if (!itr)
		goto done;

	if (mnt_table_get_intro_comment(tb))
		fprintf(stdout, "Initial comment:\n\"%s\"\n",
				mnt_table_get_intro_comment(tb));

	while(mnt_table_next_fs(tb, itr, &fs) == 0)
		mnt_fs_print_debug(fs, stdout);

	if (mnt_table_get_trailing_comment(tb))
		fprintf(stdout, "Trailing comment:\n\"%s\"\n",
				mnt_table_get_trailing_comment(tb));
	rc = 0;
done:
	mnt_free_iter(itr);
	mnt_unref_table(tb);
	return rc;
}

static int test_find(struct libmnt_test *ts, int argc, char *argv[], int dr)
{
	struct libmnt_table *tb;
	struct libmnt_fs *fs = NULL;
	struct libmnt_cache *mpc = NULL;
	const char *file, *find, *what;
	int rc = -1;

	if (argc != 4) {
		fprintf(stderr, "try --help\n");
		return -EINVAL;
	}

	file = argv[1], find = argv[2], what = argv[3];

	tb = create_table(file, FALSE);
	if (!tb)
		goto done;

	/* create a cache for canonicalized paths */
	mpc = mnt_new_cache();
	if (!mpc)
		goto done;
	mnt_table_set_cache(tb, mpc);
	mnt_unref_cache(mpc);

	if (strcasecmp(find, "source") == 0)
		fs = mnt_table_find_source(tb, what, dr);
	else if (strcasecmp(find, "target") == 0)
		fs = mnt_table_find_target(tb, what, dr);

	if (!fs)
		fprintf(stderr, "%s: not found %s '%s'\n", file, find, what);
	else {
		mnt_fs_print_debug(fs, stdout);
		rc = 0;
	}
done:
	mnt_unref_table(tb);
	return rc;
}

static int test_find_bw(struct libmnt_test *ts, int argc, char *argv[])
{
	return test_find(ts, argc, argv, MNT_ITER_BACKWARD);
}

static int test_find_fw(struct libmnt_test *ts, int argc, char *argv[])
{
	return test_find(ts, argc, argv, MNT_ITER_FORWARD);
}

static int test_find_pair(struct libmnt_test *ts, int argc, char *argv[])
{
	struct libmnt_table *tb;
	struct libmnt_fs *fs;
	struct libmnt_cache *mpc = NULL;
	int rc = -1;

	tb = create_table(argv[1], FALSE);
	if (!tb)
		return -1;
	mpc = mnt_new_cache();
	if (!mpc)
		goto done;
	mnt_table_set_cache(tb, mpc);
	mnt_unref_cache(mpc);

	fs = mnt_table_find_pair(tb, argv[2], argv[3], MNT_ITER_FORWARD);
	if (!fs)
		goto done;

	mnt_fs_print_debug(fs, stdout);
	rc = 0;
done:
	mnt_unref_table(tb);
	return rc;
}

static int test_find_mountpoint(struct libmnt_test *ts, int argc, char *argv[])
{
	struct libmnt_table *tb;
	struct libmnt_fs *fs;
	struct libmnt_cache *mpc = NULL;
	int rc = -1;

	tb = mnt_new_table_from_file(_PATH_PROC_MOUNTINFO);
	if (!tb)
		return -1;
	mpc = mnt_new_cache();
	if (!mpc)
		goto done;
	mnt_table_set_cache(tb, mpc);
	mnt_unref_cache(mpc);

	fs = mnt_table_find_mountpoint(tb, argv[1], MNT_ITER_BACKWARD);
	if (!fs)
		goto done;

	mnt_fs_print_debug(fs, stdout);
	rc = 0;
done:
	mnt_unref_table(tb);
	return rc;
}

static int test_is_mounted(struct libmnt_test *ts, int argc, char *argv[])
{
	struct libmnt_table *tb = NULL, *fstab = NULL;
	struct libmnt_fs *fs;
	struct libmnt_iter *itr = NULL;
	struct libmnt_cache *mpc = NULL;
	int writable = 0;
	const char *path = NULL;

	if (mnt_has_regular_mtab(&path, &writable) == 1 && writable == 0)
		tb = mnt_new_table_from_file(path);
	else
		tb = mnt_new_table_from_file("/proc/self/mountinfo");

	if (!tb) {
		fprintf(stderr, "failed to parse mountinfo\n");
		return -1;
	}

	fstab = create_table(argv[1], FALSE);
	if (!fstab)
		goto done;

	itr = mnt_new_iter(MNT_ITER_FORWARD);
	if (!itr)
		goto done;

	mpc = mnt_new_cache();
	if (!mpc)
		goto done;
	mnt_table_set_cache(tb, mpc);
	mnt_unref_cache(mpc);

	while (mnt_table_next_fs(fstab, itr, &fs) == 0) {
		if (mnt_table_is_fs_mounted(tb, fs))
			printf("%s already mounted on %s\n",
					mnt_fs_get_source(fs),
					mnt_fs_get_target(fs));
		else
			printf("%s not mounted on %s\n",
					mnt_fs_get_source(fs),
					mnt_fs_get_target(fs));
	}

done:
	mnt_unref_table(tb);
	mnt_unref_table(fstab);
	mnt_free_iter(itr);
	return 0;
}

/* returns 0 if @a and @b targets are the same */
static int test_uniq_cmp(struct libmnt_table *tb __attribute__((__unused__)),
			 struct libmnt_fs *a,
			 struct libmnt_fs *b)
{
	assert(a);
	assert(b);

	return mnt_fs_streq_target(a, mnt_fs_get_target(b)) ? 0 : 1;
}

static int test_uniq(struct libmnt_test *ts, int argc, char *argv[])
{
	struct libmnt_table *tb;
	int rc = -1;

	if (argc != 2) {
		fprintf(stderr, "try --help\n");
		return -EINVAL;
	}

	tb = create_table(argv[1], FALSE);
	if (!tb)
		goto done;

	if (mnt_table_uniq_fs(tb, 0, test_uniq_cmp) == 0) {
		struct libmnt_iter *itr = mnt_new_iter(MNT_ITER_FORWARD);
		struct libmnt_fs *fs;
		if (!itr)
			goto done;
		while (mnt_table_next_fs(tb, itr, &fs) == 0)
			mnt_fs_print_debug(fs, stdout);
		mnt_free_iter(itr);
		rc = 0;
	}
done:
	mnt_unref_table(tb);
	return rc;
}


int main(int argc, char *argv[])
{
	struct libmnt_test tss[] = {
	{ "--parse",    test_parse,        "<file> [--comments] parse and print tab" },
	{ "--find-forward",  test_find_fw, "<file> <source|target> <string>" },
	{ "--find-backward", test_find_bw, "<file> <source|target> <string>" },
	{ "--uniq-target",   test_uniq,    "<file>" },
	{ "--find-pair",     test_find_pair, "<file> <source> <target>" },
	{ "--find-mountpoint", test_find_mountpoint, "<path>" },
	{ "--copy-fs",       test_copy_fs, "<file>  copy root FS from the file" },
	{ "--is-mounted",    test_is_mounted, "<fstab> check what from fstab is already mounted" },
	{ NULL }
	};

	return mnt_run_test(tss, argc, argv);
}

#endif /* TEST_PROGRAM */
