diff --git a/libblkid/loopdev.c b/libblkid/loopdev.c
new file mode 100644
index 0000000..a25a2fa
--- /dev/null
+++ b/libblkid/loopdev.c
@@ -0,0 +1,1559 @@
+/*
+ * No copyright is claimed.  This code is in the public domain; do with
+ * it what you wish.
+ *
+ * Written by Karel Zak <kzak@redhat.com>
+ *
+ * -- based on mount/losetup.c
+ *
+ * Simple library for work with loop devices.
+ *
+ *  - requires kernel 2.6.x
+ *  - reads info from /sys/block/loop<N>/loop/<attr> (new kernels)
+ *  - reads info by ioctl
+ *  - supports *unlimited* number of loop devices
+ *  - supports /dev/loop<N> as well as /dev/loop/<N>
+ *  - minimize overhead (fd, loopinfo, ... are shared for all operations)
+ *  - setup (associate device and backing file)
+ *  - delete (dis-associate file)
+ *  - old LOOP_{SET,GET}_STATUS (32bit) ioctls are unsupported
+ *  - extendible
+ */
+#include <stdio.h>
+#include <stdint.h>
+#include <string.h>
+#include <ctype.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/ioctl.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+#include <sys/sysmacros.h>
+#include <inttypes.h>
+#include <dirent.h>
+#include <linux/posix_types.h>
+
+#include "linux_version.h"
+#include "c.h"
+#include "sysfs.h"
+#include "pathnames.h"
+#include "loopdev.h"
+#include "canonicalize.h"
+#include "at.h"
+
+#define CONFIG_LOOPDEV_DEBUG
+
+#ifdef CONFIG_LOOPDEV_DEBUG
+# include <stdarg.h>
+
+# define DBG(l,x)	do { \
+				if ((l)->debug) {\
+					fprintf(stderr, "loopdev:  [%p]: ", (l)); \
+					x; \
+				} \
+			} while(0)
+
+static inline void __attribute__ ((__format__ (__printf__, 1, 2)))
+loopdev_debug(const char *mesg, ...)
+{
+	va_list ap;
+	va_start(ap, mesg);
+	vfprintf(stderr, mesg, ap);
+	va_end(ap);
+	fputc('\n', stderr);
+}
+
+#else /* !CONFIG_LOOPDEV_DEBUG */
+# define DBG(m,x) do { ; } while(0)
+#endif
+
+/*
+ * see loopcxt_init()
+ */
+#define loopcxt_ioctl_enabled(_lc)	(!((_lc)->flags & LOOPDEV_FL_NOIOCTL))
+#define loopcxt_sysfs_available(_lc)	(!((_lc)->flags & LOOPDEV_FL_NOSYSFS)) \
+					 && !loopcxt_ioctl_enabled(_lc)
+
+/*
+ * @lc: context
+ * @device: device name, absolute device path or NULL to reset the current setting
+ *
+ * Sets device, absolute paths (e.g. "/dev/loop<N>") are unchanged, device
+ * names ("loop<N>") are converted to the path (/dev/loop<N> or to
+ * /dev/loop/<N>)
+ *
+ * Returns: <0 on error, 0 on success
+ */
+int loopcxt_set_device(struct loopdev_cxt *lc, const char *device)
+{
+	if (!lc)
+		return -EINVAL;
+
+	if (lc->fd >= 0) {
+		close(lc->fd);
+		DBG(lc, loopdev_debug("closing old open fd"));
+	}
+	lc->fd = -1;
+	lc->mode = 0;
+	lc->has_info = 0;
+	lc->info_failed = 0;
+	*lc->device = '\0';
+	memset(&lc->info, 0, sizeof(lc->info));
+
+	/* set new */
+	if (device) {
+		if (*device != '/') {
+			const char *dir = _PATH_DEV;
+
+			/* compose device name for /dev/loop<n> or /dev/loop/<n> */
+			if (lc->flags & LOOPDEV_FL_DEVSUBDIR) {
+				if (strlen(device) < 5)
+					return -1;
+				device += 4;
+				dir = _PATH_DEV_LOOP "/";	/* _PATH_DEV uses tailing slash */
+			}
+			snprintf(lc->device, sizeof(lc->device), "%s%s",
+				dir, device);
+		} else {
+			strncpy(lc->device, device, sizeof(lc->device));
+			lc->device[sizeof(lc->device) - 1] = '\0';
+		}
+		DBG(lc, loopdev_debug("%s successfully assigned", device));
+	}
+
+	sysfs_deinit(&lc->sysfs);
+	return 0;
+}
+
+int loopcxt_has_device(struct loopdev_cxt *lc)
+{
+	return lc && *lc->device;
+}
+
+/*
+ * @lc: context
+ * @flags: LOOPDEV_FL_* flags
+ *
+ * Initilize loop handler.
+ *
+ * We have two sets of the flags:
+ *
+ *	* LOOPDEV_FL_* flags control loopcxt_* API behavior
+ *
+ *	* LO_FLAGS_* are kernel flags used for LOOP_{SET,GET}_STAT64 ioctls
+ *
+ * Note about LOOPDEV_FL_{RDONLY,RDWR} flags. These flags are used for open(2)
+ * syscall to open loop device. By default is the device open read-only.
+ *
+ * The expection is loopcxt_setup_device(), where the device is open read-write
+ * if LO_FLAGS_READ_ONLY flags is not set (see loopcxt_set_flags()).
+ *
+ * Returns: <0 on error, 0 on success.
+ */
+int loopcxt_init(struct loopdev_cxt *lc, int flags)
+{
+	int rc;
+	struct stat st;
+	struct loopdev_cxt dummy = UL_LOOPDEVCXT_EMPTY;
+
+	if (!lc)
+		return -EINVAL;
+
+	memcpy(lc, &dummy, sizeof(dummy));
+	lc->flags = flags;
+
+	if (getenv("LOOPDEV_DEBUG"))
+		loopcxt_enable_debug(lc, TRUE);
+
+	rc = loopcxt_set_device(lc, NULL);
+	if (rc)
+		return rc;
+
+	if (stat(_PATH_SYS_BLOCK, &st) || !S_ISDIR(st.st_mode)) {
+		lc->flags |= LOOPDEV_FL_NOSYSFS;
+		lc->flags &= ~LOOPDEV_FL_NOIOCTL;
+		DBG(lc, loopdev_debug("init: disable /sys usage"));
+	}
+
+	if (!(lc->flags & LOOPDEV_FL_NOSYSFS) &&
+	    get_linux_version() >= KERNEL_VERSION(2,6,37)) {
+		/*
+		 * Use only sysfs for basic information about loop devices
+		 */
+		lc->flags |= LOOPDEV_FL_NOIOCTL;
+		DBG(lc, loopdev_debug("init: ignore ioctls"));
+	}
+
+	if (!(lc->flags & LOOPDEV_FL_CONTROL) && !stat(_PATH_DEV_LOOPCTL, &st)) {
+		lc->flags |= LOOPDEV_FL_CONTROL;
+		DBG(lc, loopdev_debug("init: loop-control detected "));
+	}
+
+	return 0;
+}
+
+/*
+ * @lc: context
+ *
+ * Deinitialize loop context
+ */
+void loopcxt_deinit(struct loopdev_cxt *lc)
+{
+	int errsv = errno;
+
+	if (!lc)
+		return;
+
+	DBG(lc, loopdev_debug("de-initialize"));
+
+	free(lc->filename);
+	lc->filename = NULL;
+
+	ignore_result( loopcxt_set_device(lc, NULL) );
+	loopcxt_deinit_iterator(lc);
+
+	errno = errsv;
+}
+
+/*
+ * @lc: context
+ * @enable: TRUE/FALSE
+ *
+ * Enabled/disables debug messages
+ */
+void loopcxt_enable_debug(struct loopdev_cxt *lc, int enable)
+{
+	if (lc)
+		lc->debug = enable ? 1 : 0;
+}
+
+/*
+ * @lc: context
+ *
+ * Returns newly allocated device path.
+ */
+char *loopcxt_strdup_device(struct loopdev_cxt *lc)
+{
+	if (!lc || !lc->device || !*lc->device)
+		return NULL;
+	return strdup(lc->device);
+}
+
+/*
+ * @lc: context
+ *
+ * Returns pointer device name in the @lc struct.
+ */
+const char *loopcxt_get_device(struct loopdev_cxt *lc)
+{
+	return lc && lc->device && *lc->device ? lc->device : NULL;
+}
+
+/*
+ * @lc: context
+ *
+ * Returns pointer to the sysfs context (see lib/sysfs.c)
+ */
+struct sysfs_cxt *loopcxt_get_sysfs(struct loopdev_cxt *lc)
+{
+	if (!lc || !*lc->device || (lc->flags & LOOPDEV_FL_NOSYSFS))
+		return NULL;
+
+	if (!lc->sysfs.devno) {
+		dev_t devno = sysfs_devname_to_devno(lc->device, NULL);
+		if (!devno) {
+			DBG(lc, loopdev_debug("sysfs: failed devname to devno"));
+			return NULL;
+		}
+		if (sysfs_init(&lc->sysfs, devno, NULL)) {
+			DBG(lc, loopdev_debug("sysfs: init failed"));
+			return NULL;
+		}
+	}
+
+	return &lc->sysfs;
+}
+
+/*
+ * @lc: context
+ *
+ * Returns: file descriptor to the open loop device or <0 on error. The mode
+ *          depends on LOOPDEV_FL_{RDWR,RDONLY} context flags. Default is
+ *          read-only.
+ */
+int loopcxt_get_fd(struct loopdev_cxt *lc)
+{
+	if (!lc || !*lc->device)
+		return -EINVAL;
+
+	if (lc->fd < 0) {
+		lc->mode = lc->flags & LOOPDEV_FL_RDWR ? O_RDWR : O_RDONLY;
+		lc->fd = open(lc->device, lc->mode);
+		DBG(lc, loopdev_debug("open %s [%s]: %s", lc->device,
+				lc->flags & LOOPDEV_FL_RDWR ? "rw" : "ro",
+				lc->fd < 0 ? "failed" : "ok"));
+	}
+	return lc->fd;
+}
+
+int loopcxt_set_fd(struct loopdev_cxt *lc, int fd, int mode)
+{
+	if (!lc)
+		return -EINVAL;
+
+	lc->fd = fd;
+	lc->mode = mode;
+	return 0;
+}
+
+/*
+ * @lc: context
+ * @flags: LOOPITER_FL_* flags
+ *
+ * Iterator allows to scan list of the free or used loop devices.
+ *
+ * Returns: <0 on error, 0 on success
+ */
+int loopcxt_init_iterator(struct loopdev_cxt *lc, int flags)
+{
+	struct loopdev_iter *iter;
+	struct stat st;
+
+	if (!lc)
+		return -EINVAL;
+
+	DBG(lc, loopdev_debug("iter: initialize"));
+
+	iter = &lc->iter;
+
+	/* always zeroize
+	 */
+	memset(iter, 0, sizeof(*iter));
+	iter->ncur = -1;
+	iter->flags = flags;
+	iter->default_check = 1;
+
+	if (!lc->extra_check) {
+		/*
+		 * Check for /dev/loop/<N> subdirectory
+		 */
+		if (!(lc->flags & LOOPDEV_FL_DEVSUBDIR) &&
+		    stat(_PATH_DEV_LOOP, &st) == 0 && S_ISDIR(st.st_mode))
+			lc->flags |= LOOPDEV_FL_DEVSUBDIR;
+
+		lc->extra_check = 1;
+	}
+	return 0;
+}
+
+/*
+ * @lc: context
+ *
+ * Returns: <0 on error, 0 on success
+ */
+int loopcxt_deinit_iterator(struct loopdev_cxt *lc)
+{
+	struct loopdev_iter *iter;
+
+	if (!lc)
+		return -EINVAL;
+
+	DBG(lc, loopdev_debug("iter: de-initialize"));
+
+	iter = &lc->iter;
+
+	free(iter->minors);
+	if (iter->proc)
+		fclose(iter->proc);
+	if (iter->sysblock)
+		closedir(iter->sysblock);
+	iter->minors = NULL;
+	iter->proc = NULL;
+	iter->sysblock = NULL;
+	iter->done = 1;
+	return 0;
+}
+
+/*
+ * Same as loopcxt_set_device, but also checks if the device is
+ * associeted with any file.
+ *
+ * Returns: <0 on error, 0 on success, 1 device does not match with
+ *         LOOPITER_FL_{USED,FREE} flags.
+ */
+static int loopiter_set_device(struct loopdev_cxt *lc, const char *device)
+{
+	int rc = loopcxt_set_device(lc, device);
+	int used;
+
+	if (rc)
+		return rc;
+
+	if (!(lc->iter.flags & LOOPITER_FL_USED) &&
+	    !(lc->iter.flags & LOOPITER_FL_FREE))
+		return 0;	/* caller does not care about device status */
+
+	used = loopcxt_get_offset(lc, NULL) == 0;
+
+	if ((lc->iter.flags & LOOPITER_FL_USED) && used)
+		return 0;
+
+	if ((lc->iter.flags & LOOPITER_FL_FREE) && !used)
+		return 0;
+
+	DBG(lc, loopdev_debug("iter: unset device"));
+	ignore_result( loopcxt_set_device(lc, NULL) );
+	return 1;
+}
+
+static int cmpnum(const void *p1, const void *p2)
+{
+	return (((* (int *) p1) > (* (int *) p2)) -
+			((* (int *) p1) < (* (int *) p2)));
+}
+
+/*
+ * The classic scandir() is more expensive and less portable.
+ * We needn't full loop device names -- loop numbers (loop<N>)
+ * are enough.
+ */
+static int loop_scandir(const char *dirname, int **ary, int hasprefix)
+{
+	DIR *dir;
+	struct dirent *d;
+	unsigned int n, count = 0, arylen = 0;
+
+	if (!dirname || !ary)
+		return 0;
+	dir = opendir(dirname);
+	if (!dir)
+		return 0;
+	free(*ary);
+	*ary = NULL;
+
+	while((d = readdir(dir))) {
+#ifdef _DIRENT_HAVE_D_TYPE
+		if (d->d_type != DT_BLK && d->d_type != DT_UNKNOWN &&
+		    d->d_type != DT_LNK)
+			continue;
+#endif
+		if (!strcmp(d->d_name, ".") || !strcmp(d->d_name, ".."))
+			continue;
+
+		if (hasprefix) {
+			/* /dev/loop<N> */
+			if (sscanf(d->d_name, "loop%u", &n) != 1)
+				continue;
+		} else {
+			/* /dev/loop/<N> */
+			char *end = NULL;
+
+			n = strtol(d->d_name, &end, 10);
+			if (d->d_name == end || (end && *end) || errno)
+				continue;
+		}
+		if (n < LOOPDEV_DEFAULT_NNODES)
+			continue;			/* ignore loop<0..7> */
+
+		if (count + 1 > arylen) {
+			int *tmp;
+
+			arylen += 1;
+
+			tmp = realloc(*ary, arylen * sizeof(int));
+			if (!tmp) {
+				free(*ary);
+				closedir(dir);
+				return -1;
+			}
+			*ary = tmp;
+		}
+		if (*ary)
+			(*ary)[count++] = n;
+	}
+	if (count && *ary)
+		qsort(*ary, count, sizeof(int), cmpnum);
+
+	closedir(dir);
+	return count;
+}
+
+/*
+ * Set the next *used* loop device according to /proc/partitions.
+ *
+ * Loop devices smaller than 512 bytes are invisible for this function.
+ */
+static int loopcxt_next_from_proc(struct loopdev_cxt *lc)
+{
+	struct loopdev_iter *iter = &lc->iter;
+	char buf[BUFSIZ];
+
+	DBG(lc, loopdev_debug("iter: scan /proc/partitions"));
+
+	if (!iter->proc)
+		iter->proc = fopen(_PATH_PROC_PARTITIONS, "r");
+	if (!iter->proc)
+		return 1;
+
+	while (fgets(buf, sizeof(buf), iter->proc)) {
+		unsigned int m;
+		char name[128 + 1];
+
+
+		if (sscanf(buf, " %u %*s %*s %128[^\n ]",
+			   &m, name) != 2 || m != LOOPDEV_MAJOR)
+			continue;
+
+		DBG(lc, loopdev_debug("iter: check %s", name));
+
+		if (loopiter_set_device(lc, name) == 0)
+			return 0;
+	}
+
+	return 1;
+}
+
+/*
+ * Set the next *used* loop device according to
+ * /sys/block/loopN/loop/backing_file (kernel >= 2.6.37 is required).
+ *
+ * This is preferred method.
+ */
+static int loopcxt_next_from_sysfs(struct loopdev_cxt *lc)
+{
+	struct loopdev_iter *iter = &lc->iter;
+	struct dirent *d;
+	int fd;
+
+	DBG(lc, loopdev_debug("iter: scan /sys/block"));
+
+	if (!iter->sysblock)
+		iter->sysblock = opendir(_PATH_SYS_BLOCK);
+
+	if (!iter->sysblock)
+		return 1;
+
+	fd = dirfd(iter->sysblock);
+
+	while ((d = readdir(iter->sysblock))) {
+		char name[256];
+		struct stat st;
+
+		DBG(lc, loopdev_debug("iter: check %s", d->d_name));
+
+		if (strcmp(d->d_name, ".") == 0
+		    || strcmp(d->d_name, "..") == 0
+		    || strncmp(d->d_name, "loop", 4) != 0)
+			continue;
+
+		snprintf(name, sizeof(name), "%s/loop/backing_file", d->d_name);
+		if (fstat_at(fd, _PATH_SYS_BLOCK, name, &st, 0) != 0)
+			continue;
+
+		if (loopiter_set_device(lc, d->d_name) == 0)
+			return 0;
+	}
+
+	return 1;
+}
+
+/*
+ * @lc: context, has to initialized by loopcxt_init_iterator()
+ *
+ * Returns: 0 on success, -1 on error, 1 at the end of scanning. The details
+ *          about the current loop device are available by
+ *          loopcxt_get_{fd,backing_file,device,offset, ...} functions.
+ */
+int loopcxt_next(struct loopdev_cxt *lc)
+{
+	struct loopdev_iter *iter;
+
+	if (!lc)
+		return -EINVAL;
+
+	DBG(lc, loopdev_debug("iter: next"));
+
+	iter = &lc->iter;
+	if (iter->done)
+		return 1;
+
+	/* A) Look for used loop devices in /proc/partitions ("losetup -a" only)
+	 */
+	if (iter->flags & LOOPITER_FL_USED) {
+		int rc;
+
+		if (loopcxt_sysfs_available(lc))
+			rc = loopcxt_next_from_sysfs(lc);
+		else
+			rc = loopcxt_next_from_proc(lc);
+		if (rc == 0)
+			return 0;
+		goto done;
+	}
+
+	/* B) Classic way, try first eight loop devices (default number
+	 *    of loop devices). This is enough for 99% of all cases.
+	 */
+	if (iter->default_check) {
+		DBG(lc, loopdev_debug("iter: next: default check"));
+		for (++iter->ncur; iter->ncur < LOOPDEV_DEFAULT_NNODES;
+							iter->ncur++) {
+			char name[16];
+			snprintf(name, sizeof(name), "loop%d", iter->ncur);
+
+			if (loopiter_set_device(lc, name) == 0)
+				return 0;
+		}
+		iter->default_check = 0;
+	}
+
+	/* C) the worst possibility, scan whole /dev or /dev/loop/<N>
+	 */
+	if (!iter->minors) {
+		DBG(lc, loopdev_debug("iter: next: scan /dev"));
+		iter->nminors = (lc->flags & LOOPDEV_FL_DEVSUBDIR) ?
+			loop_scandir(_PATH_DEV_LOOP, &iter->minors, 0) :
+			loop_scandir(_PATH_DEV, &iter->minors, 1);
+		iter->ncur = -1;
+	}
+	for (++iter->ncur; iter->ncur < iter->nminors; iter->ncur++) {
+		char name[16];
+		snprintf(name, sizeof(name), "loop%d", iter->minors[iter->ncur]);
+
+		if (loopiter_set_device(lc, name) == 0)
+			return 0;
+	}
+done:
+	loopcxt_deinit_iterator(lc);
+	return 1;
+}
+
+/*
+ * @device: path to device
+ */
+int is_loopdev(const char *device)
+{
+	struct stat st;
+
+	if (!device)
+		return 0;
+
+	return (stat(device, &st) == 0 &&
+		S_ISBLK(st.st_mode) &&
+		major(st.st_rdev) == LOOPDEV_MAJOR);
+}
+
+/*
+ * @lc: context
+ *
+ * Returns result from LOOP_GET_STAT64 ioctl or NULL on error.
+ */
+struct loop_info64 *loopcxt_get_info(struct loopdev_cxt *lc)
+{
+	int fd;
+
+	if (!lc || lc->info_failed)
+		return NULL;
+	if (lc->has_info)
+		return &lc->info;
+
+	fd = loopcxt_get_fd(lc);
+	if (fd < 0)
+		return NULL;
+
+	if (ioctl(fd, LOOP_GET_STATUS64, &lc->info) == 0) {
+		lc->has_info = 1;
+		lc->info_failed = 0;
+		DBG(lc, loopdev_debug("reading loop_info64 OK"));
+		return &lc->info;
+	} else {
+		lc->info_failed = 1;
+		DBG(lc, loopdev_debug("reading loop_info64 FAILED"));
+	}
+
+	return NULL;
+}
+
+/*
+ * @lc: context
+ *
+ * Returns (allocated) string with path to the file assicieted
+ * with the current loop device.
+ */
+char *loopcxt_get_backing_file(struct loopdev_cxt *lc)
+{
+	struct sysfs_cxt *sysfs = loopcxt_get_sysfs(lc);
+	char *res = NULL;
+
+	if (sysfs)
+		/*
+		 * This is always preffered, the loop_info64
+		 * has too small buffer for the filename.
+		 */
+		res = sysfs_strdup(sysfs, "loop/backing_file");
+
+	if (!res && loopcxt_ioctl_enabled(lc)) {
+		struct loop_info64 *lo = loopcxt_get_info(lc);
+
+		if (lo) {
+			lo->lo_file_name[LO_NAME_SIZE - 2] = '*';
+			lo->lo_file_name[LO_NAME_SIZE - 1] = '\0';
+			res = strdup((char *) lo->lo_file_name);
+		}
+	}
+
+	DBG(lc, loopdev_debug("get_backing_file [%s]", res));
+	return res;
+}
+
+/*
+ * @lc: context
+ * @offset: returns offset number for the given device
+ *
+ * Returns: <0 on error, 0 on success
+ */
+int loopcxt_get_offset(struct loopdev_cxt *lc, uint64_t *offset)
+{
+	struct sysfs_cxt *sysfs = loopcxt_get_sysfs(lc);
+	int rc = -EINVAL;
+
+	if (sysfs)
+		rc = sysfs_read_u64(sysfs, "loop/offset", offset);
+
+	if (rc && loopcxt_ioctl_enabled(lc)) {
+		struct loop_info64 *lo = loopcxt_get_info(lc);
+		if (lo) {
+			if (offset)
+				*offset = lo->lo_offset;
+			rc = 0;
+		}
+	}
+
+	DBG(lc, loopdev_debug("get_offset [rc=%d]", rc));
+	return rc;
+}
+
+/*
+ * @lc: context
+ * @sizelimit: returns size limit for the given device
+ *
+ * Returns: <0 on error, 0 on success
+ */
+int loopcxt_get_sizelimit(struct loopdev_cxt *lc, uint64_t *size)
+{
+	struct sysfs_cxt *sysfs = loopcxt_get_sysfs(lc);
+	int rc = -EINVAL;
+
+	if (sysfs)
+		rc = sysfs_read_u64(sysfs, "loop/sizelimit", size);
+
+	if (rc && loopcxt_ioctl_enabled(lc)) {
+		struct loop_info64 *lo = loopcxt_get_info(lc);
+		if (lo) {
+			if (size)
+				*size = lo->lo_sizelimit;
+			rc = 0;
+		}
+	}
+
+	DBG(lc, loopdev_debug("get_sizelimit [rc=%d]", rc));
+	return rc;
+}
+
+/*
+ * @lc: context
+ * @devno: returns encryption type
+ *
+ * Cryptoloop is DEPRECATED!
+ *
+ * Returns: <0 on error, 0 on success
+ */
+int loopcxt_get_encrypt_type(struct loopdev_cxt *lc, uint32_t *type)
+{
+	struct loop_info64 *lo = loopcxt_get_info(lc);
+	int rc = -EINVAL;
+
+	if (lo) {
+		if (type)
+			*type = lo->lo_encrypt_type;
+		rc = 0;
+	}
+	DBG(lc, loopdev_debug("get_encrypt_type [rc=%d]", rc));
+	return rc;
+}
+
+/*
+ * @lc: context
+ * @devno: returns crypt name
+ *
+ * Cryptoloop is DEPRECATED!
+ *
+ * Returns: <0 on error, 0 on success
+ */
+const char *loopcxt_get_crypt_name(struct loopdev_cxt *lc)
+{
+	struct loop_info64 *lo = loopcxt_get_info(lc);
+
+	if (lo)
+		return (char *) lo->lo_crypt_name;
+
+	DBG(lc, loopdev_debug("get_crypt_name failed"));
+	return NULL;
+}
+
+/*
+ * @lc: context
+ * @devno: returns backing file devno
+ *
+ * Returns: <0 on error, 0 on success
+ */
+int loopcxt_get_backing_devno(struct loopdev_cxt *lc, dev_t *devno)
+{
+	struct loop_info64 *lo = loopcxt_get_info(lc);
+	int rc = -EINVAL;
+
+	if (lo) {
+		if (devno)
+			*devno = lo->lo_device;
+		rc = 0;
+	}
+	DBG(lc, loopdev_debug("get_backing_devno [rc=%d]", rc));
+	return rc;
+}
+
+/*
+ * @lc: context
+ * @ino: returns backing file inode
+ *
+ * Returns: <0 on error, 0 on success
+ */
+int loopcxt_get_backing_inode(struct loopdev_cxt *lc, ino_t *ino)
+{
+	struct loop_info64 *lo = loopcxt_get_info(lc);
+	int rc = -EINVAL;
+
+	if (lo) {
+		if (ino)
+			*ino = lo->lo_inode;
+		rc = 0;
+	}
+	DBG(lc, loopdev_debug("get_backing_inode [rc=%d]", rc));
+	return rc;
+}
+
+/*
+ * Check if the kernel supports partitioned loop devices.
+ *
+ * Notes:
+ *   - kernels < 3.2 support partitioned loop devices and PT scanning
+ *     only if max_part= module paremeter is non-zero
+ *
+ *   - kernels >= 3.2 always support partitioned loop devices
+ *
+ *   - kernels >= 3.2 always support BLKPG_{ADD,DEL}_PARTITION ioctls
+ *
+ *   - kernels >= 3.2 enable PT scanner only if max_part= is non-zero or if the
+ *     LO_FLAGS_PARTSCAN flag is set for the device. The PT scanner is disabled
+ *     by default.
+ *
+ *  See kernel commit e03c8dd14915fabc101aa495828d58598dc5af98.
+ */
+int loopmod_supports_partscan(void)
+{
+	int rc, ret = 0;
+	FILE *f;
+
+	if (get_linux_version() >= KERNEL_VERSION(3,2,0))
+		return 1;
+
+	f = fopen("/sys/module/loop/parameters/max_part", "r");
+	if (!f)
+		return 0;
+	rc = fscanf(f, "%d", &ret);
+	fclose(f);
+	return rc == 1 ? ret : 0;
+}
+
+/*
+ * @lc: context
+ *
+ * Returns: 1 if the partscan flags is set *or* (for old kernels) partitions
+ * scannig is enabled for all loop devices.
+ */
+int loopcxt_is_partscan(struct loopdev_cxt *lc)
+{
+	struct sysfs_cxt *sysfs = loopcxt_get_sysfs(lc);
+
+	if (sysfs) {
+		/* kernel >= 3.2 */
+		int fl;
+		if (sysfs_read_int(sysfs, "loop/partscan", &fl) == 0)
+			return fl;
+	}
+
+	/* old kernels (including kernels without loopN/loop/<flags> directory */
+	return loopmod_supports_partscan();
+}
+
+/*
+ * @lc: context
+ *
+ * Returns: 1 if the autoclear flags is set.
+ */
+int loopcxt_is_autoclear(struct loopdev_cxt *lc)
+{
+	struct sysfs_cxt *sysfs = loopcxt_get_sysfs(lc);
+
+	if (sysfs) {
+		int fl;
+		if (sysfs_read_int(sysfs, "loop/autoclear", &fl) == 0)
+			return fl;
+	}
+
+	if (loopcxt_ioctl_enabled(lc)) {
+		struct loop_info64 *lo = loopcxt_get_info(lc);
+		if (lo)
+			return lo->lo_flags & LO_FLAGS_AUTOCLEAR;
+	}
+	return 0;
+}
+
+/*
+ * @lc: context
+ *
+ * Returns: 1 if the readonly flags is set.
+ */
+int loopcxt_is_readonly(struct loopdev_cxt *lc)
+{
+	struct sysfs_cxt *sysfs = loopcxt_get_sysfs(lc);
+
+	if (sysfs) {
+		int fl;
+		if (sysfs_read_int(sysfs, "ro", &fl) == 0)
+			return fl;
+	}
+
+	if (loopcxt_ioctl_enabled(lc)) {
+		struct loop_info64 *lo = loopcxt_get_info(lc);
+		if (lo)
+			return lo->lo_flags & LO_FLAGS_READ_ONLY;
+	}
+	return 0;
+}
+
+/*
+ * @lc: context
+ * @st: backing file stat or NULL
+ * @backing_file: filename
+ * @offset: offset
+ * @flags: LOOPDEV_FL_OFFSET if @offset should not be ignored
+ *
+ * Returns 1 if the current @lc loopdev is associated with the given backing
+ * file. Note that the preferred way is to use devno and inode number rather
+ * than filename. The @backing_file filename is poor solution usable in case
+ * that you don't have rights to call stat().
+ *
+ * Don't forget that old kernels provide very restricted (in size) backing
+ * filename by LOOP_GET_STAT64 ioctl only.
+ */
+int loopcxt_is_used(struct loopdev_cxt *lc,
+		    struct stat *st,
+		    const char *backing_file,
+		    uint64_t offset,
+		    int flags)
+{
+	ino_t ino;
+	dev_t dev;
+
+	if (!lc)
+		return 0;
+
+	DBG(lc, loopdev_debug("checking %s vs. %s",
+				loopcxt_get_device(lc),
+				backing_file));
+
+	if (st && loopcxt_get_backing_inode(lc, &ino) == 0 &&
+		  loopcxt_get_backing_devno(lc, &dev) == 0) {
+
+		if (ino == st->st_ino && dev == st->st_dev)
+			goto found;
+
+		/* don't use filename if we have devno and inode */
+		return 0;
+	}
+
+	/* poor man's solution */
+	if (backing_file) {
+		char *name = loopcxt_get_backing_file(lc);
+		int rc = name && strcmp(name, backing_file) == 0;
+
+		free(name);
+		if (rc)
+			goto found;
+	}
+
+	return 0;
+found:
+	if (flags & LOOPDEV_FL_OFFSET) {
+		uint64_t off;
+
+		return loopcxt_get_offset(lc, &off) == 0 && off == offset;
+	}
+	return 1;
+}
+
+/*
+ * The setting is removed by loopcxt_set_device() loopcxt_next()!
+ */
+int loopcxt_set_offset(struct loopdev_cxt *lc, uint64_t offset)
+{
+	if (!lc)
+		return -EINVAL;
+	lc->info.lo_offset = offset;
+
+	DBG(lc, loopdev_debug("set offset=%jd", offset));
+	return 0;
+}
+
+/*
+ * The setting is removed by loopcxt_set_device() loopcxt_next()!
+ */
+int loopcxt_set_sizelimit(struct loopdev_cxt *lc, uint64_t sizelimit)
+{
+	if (!lc)
+		return -EINVAL;
+	lc->info.lo_sizelimit = sizelimit;
+
+	DBG(lc, loopdev_debug("set sizelimit=%jd", sizelimit));
+	return 0;
+}
+
+/*
+ * @lc: context
+ * @flags: kernel LO_FLAGS_{READ_ONLY,USE_AOPS,AUTOCLEAR} flags
+ *
+ * The setting is removed by loopcxt_set_device() loopcxt_next()!
+ *
+ * Returns: 0 on success, <0 on error.
+ */
+int loopcxt_set_flags(struct loopdev_cxt *lc, uint32_t flags)
+{
+	if (!lc)
+		return -EINVAL;
+	lc->info.lo_flags = flags;
+
+	DBG(lc, loopdev_debug("set flags=%u", (unsigned) flags));
+	return 0;
+}
+
+/*
+ * @lc: context
+ * @filename: backing file path (the path will be canonicalized)
+ *
+ * The setting is removed by loopcxt_set_device() loopcxt_next()!
+ *
+ * Returns: 0 on success, <0 on error.
+ */
+int loopcxt_set_backing_file(struct loopdev_cxt *lc, const char *filename)
+{
+	if (!lc)
+		return -EINVAL;
+
+	lc->filename = canonicalize_path(filename);
+	if (!lc->filename)
+		return -errno;
+
+	strncpy((char *)lc->info.lo_file_name, lc->filename, LO_NAME_SIZE);
+	lc->info.lo_file_name[LO_NAME_SIZE- 1] = '\0';
+
+	DBG(lc, loopdev_debug("set backing file=%s", lc->info.lo_file_name));
+	return 0;
+}
+
+/*
+ * @cl: context
+ *
+ * Associate the current device (see loopcxt_{set,get}_device()) with
+ * a file (see loopcxt_set_backing_file()).
+ *
+ * The device is initialized read-write by default. If you want read-only
+ * device then set LO_FLAGS_READ_ONLY by loopcxt_set_flags(). The LOOPDEV_FL_*
+ * flags are ignored and modified according to LO_FLAGS_*.
+ *
+ * If the device is already open by loopcxt_get_fd() then this setup device
+ * function will re-open the device to fix read/write mode.
+ *
+ * The device is also initialized read-only if the backing file is not
+ * possible to open read-write (e.g. read-only FS).
+ *
+ * Returns: <0 on error, 0 on success.
+ */
+int loopcxt_setup_device(struct loopdev_cxt *lc)
+{
+	int file_fd, dev_fd, mode = O_RDWR, rc = -1;
+
+	if (!lc || !*lc->device || !lc->filename)
+		return -EINVAL;
+
+	DBG(lc, loopdev_debug("device setup requested"));
+
+	/*
+	 * Open backing file and device
+	 */
+	if (lc->info.lo_flags & LO_FLAGS_READ_ONLY)
+		mode = O_RDONLY;
+
+	if ((file_fd = open(lc->filename, mode)) < 0) {
+		if (mode != O_RDONLY && (errno == EROFS || errno == EACCES))
+			file_fd = open(lc->filename, mode = O_RDONLY);
+
+		if (file_fd < 0) {
+			DBG(lc, loopdev_debug("open backing file failed: %m"));
+			return -errno;
+		}
+	}
+	DBG(lc, loopdev_debug("setup: backing file open: OK"));
+
+	if (lc->fd != -1 && lc->mode != mode) {
+		DBG(lc, loopdev_debug("closing already open device (mode mismatch)"));
+		close(lc->fd);
+		lc->fd = -1;
+		lc->mode = 0;
+	}
+
+	if (mode == O_RDONLY) {
+		lc->flags |= LOOPDEV_FL_RDONLY;			/* open() mode */
+		lc->info.lo_flags |= LO_FLAGS_READ_ONLY;	/* kernel loopdev mode */
+	} else {
+		lc->flags |= LOOPDEV_FL_RDWR;			/* open() mode */
+		lc->info.lo_flags &= ~LO_FLAGS_READ_ONLY;
+		lc->flags &= ~LOOPDEV_FL_RDONLY;
+	}
+
+	dev_fd = loopcxt_get_fd(lc);
+	if (dev_fd < 0) {
+		rc = -errno;
+		goto err;
+	}
+
+	DBG(lc, loopdev_debug("setup: device open: OK"));
+
+	/*
+	 * Set FD
+	 */
+	if (ioctl(dev_fd, LOOP_SET_FD, file_fd) < 0) {
+		rc = -errno;
+		DBG(lc, loopdev_debug("LOOP_SET_FD failed: %m"));
+		goto err;
+	}
+
+	DBG(lc, loopdev_debug("setup: LOOP_SET_FD: OK"));
+
+	close(file_fd);
+	file_fd = -1;
+
+	if (ioctl(dev_fd, LOOP_SET_STATUS64, &lc->info)) {
+		DBG(lc, loopdev_debug("LOOP_SET_STATUS64 failed: %m"));
+		goto err;
+	}
+
+	DBG(lc, loopdev_debug("setup: LOOP_SET_STATUS64: OK"));
+
+	memset(&lc->info, 0, sizeof(lc->info));
+	lc->has_info = 0;
+	lc->info_failed = 0;
+
+	DBG(lc, loopdev_debug("setup success [rc=0]"));
+	return 0;
+err:
+	if (file_fd >= 0)
+		close(file_fd);
+	if (dev_fd >= 0)
+		ioctl(dev_fd, LOOP_CLR_FD, 0);
+
+	DBG(lc, loopdev_debug("setup failed [rc=%d]", rc));
+	return rc;
+}
+
+int loopcxt_delete_device(struct loopdev_cxt *lc)
+{
+	int fd = loopcxt_get_fd(lc);
+
+	if (fd < 0)
+		return -EINVAL;
+
+	if (ioctl(fd, LOOP_CLR_FD, 0) < 0) {
+		DBG(lc, loopdev_debug("LOOP_CLR_FD failed: %m"));
+		return -errno;
+	}
+
+	DBG(lc, loopdev_debug("device removed"));
+	return 0;
+}
+
+/*
+ * Note that LOOP_CTL_GET_FREE ioctl is supported since kernel 3.1. In older
+ * kernels we have to check all loop devices to found unused one.
+ *
+ * See kernel commit 770fe30a46a12b6fb6b63fbe1737654d28e8484.
+ */
+int loopcxt_find_unused(struct loopdev_cxt *lc)
+{
+	int rc = -1;
+
+	DBG(lc, loopdev_debug("find_unused requested"));
+
+	if (lc->flags & LOOPDEV_FL_CONTROL) {
+		int ctl = open(_PATH_DEV_LOOPCTL, O_RDWR);
+
+		if (ctl >= 0)
+			rc = ioctl(ctl, LOOP_CTL_GET_FREE);
+		if (rc >= 0) {
+			char name[16];
+			snprintf(name, sizeof(name), "loop%d", rc);
+
+			rc = loopiter_set_device(lc, name);
+		}
+		if (ctl >= 0)
+			close(ctl);
+		DBG(lc, loopdev_debug("find_unused by loop-control [rc=%d]", rc));
+	}
+
+	if (rc < 0) {
+		rc = loopcxt_init_iterator(lc, LOOPITER_FL_FREE);
+		if (rc)
+			return rc;
+
+		rc = loopcxt_next(lc);
+		loopcxt_deinit_iterator(lc);
+		DBG(lc, loopdev_debug("find_unused by scan [rc=%d]", rc));
+	}
+	return rc;
+}
+
+
+
+/*
+ * Return: TRUE/FALSE
+ */
+int loopdev_is_autoclear(const char *device)
+{
+	struct loopdev_cxt lc;
+	int rc;
+
+	if (!device)
+		return 0;
+
+	rc = loopcxt_init(&lc, 0);
+	if (!rc)
+		rc = loopcxt_set_device(&lc, device);
+	if (!rc)
+		rc = loopcxt_is_autoclear(&lc);
+
+	loopcxt_deinit(&lc);
+	return rc;
+}
+
+char *loopdev_get_backing_file(const char *device)
+{
+	struct loopdev_cxt lc;
+	char *res = NULL;
+
+	if (!device)
+		return NULL;
+	if (loopcxt_init(&lc, 0))
+		return NULL;
+	if (loopcxt_set_device(&lc, device) == 0)
+		res = loopcxt_get_backing_file(&lc);
+
+	loopcxt_deinit(&lc);
+	return res;
+}
+
+/*
+ * Returns: TRUE/FALSE
+ */
+int loopdev_is_used(const char *device, const char *filename,
+		    uint64_t offset, int flags)
+{
+	struct loopdev_cxt lc;
+	struct stat st;
+	int rc = 0;
+
+	if (!device || !filename)
+		return 0;
+
+	rc = loopcxt_init(&lc, 0);
+	if (!rc)
+		rc = loopcxt_set_device(&lc, device);
+	if (rc)
+		return rc;
+
+	rc = !stat(filename, &st);
+	rc = loopcxt_is_used(&lc, rc ? &st : NULL, filename, offset, flags);
+
+	loopcxt_deinit(&lc);
+	return rc;
+}
+
+int loopdev_delete(const char *device)
+{
+	struct loopdev_cxt lc;
+	int rc;
+
+	if (!device)
+		return -EINVAL;
+
+	rc = loopcxt_init(&lc, 0);
+	if (!rc)
+		rc = loopcxt_set_device(&lc, device);
+	if (!rc)
+		rc = loopcxt_delete_device(&lc);
+	loopcxt_deinit(&lc);
+	return rc;
+}
+
+/*
+ * Returns: 0 = success, < 0 error, 1 not found
+ */
+int loopcxt_find_by_backing_file(struct loopdev_cxt *lc, const char *filename,
+				 uint64_t offset, int flags)
+{
+	int rc, hasst;
+	struct stat st;
+
+	if (!filename)
+		return -EINVAL;
+
+	hasst = !stat(filename, &st);
+
+	rc = loopcxt_init_iterator(lc, LOOPITER_FL_USED);
+	if (rc)
+		return rc;
+
+	while ((rc = loopcxt_next(lc)) == 0) {
+
+		if (loopcxt_is_used(lc, hasst ? &st : NULL,
+					filename, offset, flags))
+			break;
+	}
+
+	loopcxt_deinit_iterator(lc);
+	return rc;
+}
+
+/*
+ * Returns allocated string with device name
+ */
+char *loopdev_find_by_backing_file(const char *filename, uint64_t offset, int flags)
+{
+	struct loopdev_cxt lc;
+	char *res = NULL;
+
+	if (!filename)
+		return NULL;
+
+	if (loopcxt_init(&lc, 0))
+		return NULL;
+	if (loopcxt_find_by_backing_file(&lc, filename, offset, flags) == 0)
+		res = loopcxt_strdup_device(&lc);
+	loopcxt_deinit(&lc);
+
+	return res;
+}
+
+/*
+ * Returns number of loop devices associated with @file, if only one loop
+ * device is associeted with the given @filename and @loopdev is not NULL then
+ * @loopdev returns name of the device.
+ */
+int loopdev_count_by_backing_file(const char *filename, char **loopdev)
+{
+	struct loopdev_cxt lc;
+	int count = 0, rc;
+
+	if (!filename)
+		return -1;
+
+	rc = loopcxt_init(&lc, 0);
+	if (rc)
+		return rc;
+	if (loopcxt_init_iterator(&lc, LOOPITER_FL_USED))
+		return -1;
+
+	while(loopcxt_next(&lc) == 0) {
+		char *backing = loopcxt_get_backing_file(&lc);
+
+		if (!backing || strcmp(backing, filename)) {
+			free(backing);
+			continue;
+		}
+
+		free(backing);
+		if (loopdev && count == 0)
+			*loopdev = loopcxt_strdup_device(&lc);
+		count++;
+	}
+
+	loopcxt_deinit(&lc);
+
+	if (loopdev && count > 1) {
+		free(*loopdev);
+		*loopdev = NULL;
+	}
+	return count;
+}
+
+
+#ifdef TEST_PROGRAM_LOOPDEV
+#include <errno.h>
+#include <err.h>
+
+static void test_loop_info(const char *device, int flags, int debug)
+{
+	struct loopdev_cxt lc;
+	char *p;
+	uint64_t u64;
+
+	if (loopcxt_init(&lc, flags))
+		return;
+	loopcxt_enable_debug(&lc, debug);
+
+	if (loopcxt_set_device(&lc, device))
+		err(EXIT_FAILURE, "failed to set device");
+
+	p = loopcxt_get_backing_file(&lc);
+	printf("\tBACKING FILE: %s\n", p);
+	free(p);
+
+	if (loopcxt_get_offset(&lc, &u64) == 0)
+		printf("\tOFFSET: %jd\n", u64);
+
+	if (loopcxt_get_sizelimit(&lc, &u64) == 0)
+		printf("\tSIZE LIMIT: %jd\n", u64);
+
+	printf("\tAUTOCLEAR: %s\n", loopcxt_is_autoclear(&lc) ? "YES" : "NOT");
+
+	loopcxt_deinit(&lc);
+}
+
+static void test_loop_scan(int flags, int debug)
+{
+	struct loopdev_cxt lc;
+	int rc;
+
+	if (loopcxt_init(&lc, 0))
+		return;
+	loopcxt_enable_debug(&lc, debug);
+
+	if (loopcxt_init_iterator(&lc, flags))
+		err(EXIT_FAILURE, "iterator initlization failed");
+
+	while((rc = loopcxt_next(&lc)) == 0) {
+		const char *device = loopcxt_get_device(&lc);
+
+		if (flags & LOOPITER_FL_USED) {
+			char *backing = loopcxt_get_backing_file(&lc);
+			printf("\t%s: %s\n", device, backing);
+			free(backing);
+		} else
+			printf("\t%s\n", device);
+	}
+
+	if (rc < 0)
+		err(EXIT_FAILURE, "loopdevs scanning failed");
+
+	loopcxt_deinit(&lc);
+}
+
+static int test_loop_setup(const char *filename, const char *device, int debug)
+{
+	struct loopdev_cxt lc;
+	int rc;
+
+	rc = loopcxt_init(&lc, 0);
+	if (rc)
+		return rc;
+	loopcxt_enable_debug(&lc, debug);
+
+	if (device) {
+		rc = loopcxt_set_device(&lc, device);
+		if (rc)
+			err(EXIT_FAILURE, "failed to set device: %s", device);
+	}
+
+	do {
+		if (!device) {
+			rc = loopcxt_find_unused(&lc);
+			if (rc)
+				err(EXIT_FAILURE, "failed to find unused device");
+			printf("Trying to use '%s'\n", loopcxt_get_device(&lc));
+		}
+
+		if (loopcxt_set_backing_file(&lc, filename))
+			err(EXIT_FAILURE, "failed to set backing file");
+
+		rc = loopcxt_setup_device(&lc);
+		if (rc == 0)
+			break;		/* success */
+
+		if (device || rc != -EBUSY)
+			err(EXIT_FAILURE, "failed to setup device for %s",
+					lc.filename);
+
+		printf("device stolen...trying again\n");
+	} while (1);
+
+	loopcxt_deinit(&lc);
+
+	return 0;
+}
+
+int main(int argc, char *argv[])
+{
+	int dbg;
+
+	if (argc < 2)
+		goto usage;
+
+	dbg = getenv("LOOPDEV_DEBUG") == NULL ? 0 : 1;
+
+	if (argc == 3 && strcmp(argv[1], "--info") == 0) {
+		printf("---sysfs & ioctl:---\n");
+		test_loop_info(argv[2], 0, dbg);
+		printf("---sysfs only:---\n");
+		test_loop_info(argv[2], LOOPDEV_FL_NOIOCTL, dbg);
+		printf("---ioctl only:---\n");
+		test_loop_info(argv[2], LOOPDEV_FL_NOSYSFS, dbg);
+
+	} else if (argc == 2 && strcmp(argv[1], "--used") == 0) {
+		printf("---all used devices---\n");
+		test_loop_scan(LOOPITER_FL_USED, dbg);
+
+	} else if (argc == 2 && strcmp(argv[1], "--free") == 0) {
+		printf("---all free devices---\n");
+		test_loop_scan(LOOPITER_FL_FREE, dbg);
+
+	} else if (argc >= 3 && strcmp(argv[1], "--setup") == 0) {
+		test_loop_setup(argv[2], argv[3], dbg);
+
+	} else if (argc == 3 && strcmp(argv[1], "--delete") == 0) {
+		if (loopdev_delete(argv[2]))
+			errx(EXIT_FAILURE, "failed to deinitialize device %s", argv[2]);
+	} else
+		goto usage;
+
+	return EXIT_SUCCESS;
+
+usage:
+	errx(EXIT_FAILURE, "usage: \n"
+			   "  %1$s --info <device>\n"
+			   "  %1$s --free\n"
+			   "  %1$s --used\n"
+			   "  %1$s --setup <filename> [<device>]\n"
+			   "  %1$s --delete\n",
+			   argv[0]);
+}
+
+#endif /* TEST_PROGRAM */
