/*
 * 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"
#include "blkdev.h"
#include "debug.h"

/*
 * Debug stuff (based on include/debug.h)
 */
UL_DEBUG_DEFINE_MASK(loopdev);
UL_DEBUG_DEFINE_MASKNAMES(loopdev) = UL_DEBUG_EMPTY_MASKNAMES;

#define LOOPDEV_DEBUG_INIT	(1 << 1)
#define LOOPDEV_DEBUG_CXT	(1 << 2)
#define LOOPDEV_DEBUG_ITER	(1 << 3)
#define LOOPDEV_DEBUG_SETUP	(1 << 4)
#define SFDISKPROG_DEBUG_ALL	0xFFFF

#define DBG(m, x)       __UL_DBG(loopdev, LOOPDEV_DEBUG_, m, x)
#define ON_DBG(m, x)    __UL_DBG_CALL(loopdev, LOOPDEV_DEBUG_, m, x)

static void loopdev_init_debug(void)
{
	if (loopdev_debug_mask)
		return;
	__UL_INIT_DEBUG(loopdev, LOOPDEV_DEBUG_, 0, LOOPDEV_DEBUG);
}

/*
 * 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>)
 *
 * This sets the device name, but does not check if the device exists!
 *
 * 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(CXT, ul_debugobj(lc, "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(CXT, ul_debugobj(lc, "%s name 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;

	loopdev_init_debug();
	DBG(CXT, ul_debugobj(lc, "initialize context"));

	memcpy(lc, &dummy, sizeof(dummy));
	lc->flags = flags;

	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(CXT, ul_debugobj(lc, "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(CXT, ul_debugobj(lc, "init: ignore ioctls"));
	}

	if (!(lc->flags & LOOPDEV_FL_CONTROL) && !stat(_PATH_DEV_LOOPCTL, &st)) {
		lc->flags |= LOOPDEV_FL_CONTROL;
		DBG(CXT, ul_debugobj(lc, "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(CXT, ul_debugobj(lc, "de-initialize"));

	free(lc->filename);
	lc->filename = NULL;

	ignore_result( loopcxt_set_device(lc, NULL) );
	loopcxt_deinit_iterator(lc);

	errno = errsv;
}

/*
 * @lc: context
 *
 * Returns newly allocated device path.
 */
char *loopcxt_strdup_device(struct loopdev_cxt *lc)
{
	if (!lc || !*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 : 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(CXT, ul_debugobj(lc, "sysfs: failed devname to devno"));
			return NULL;
		}
		if (sysfs_init(&lc->sysfs, devno, NULL)) {
			DBG(CXT, ul_debugobj(lc, "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 | O_CLOEXEC);
		DBG(CXT, ul_debugobj(lc, "open %s [%s]: %m", lc->device,
				lc->flags & LOOPDEV_FL_RDWR ? "rw" : "ro"));
	}
	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;


	iter = &lc->iter;
	DBG(ITER, ul_debugobj(iter, "initialize"));

	/* 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;

	iter = &lc->iter;
	DBG(ITER, ul_debugobj(iter, "de-initialize"));

	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 */

	if (!is_loopdev(lc->device)) {
		DBG(ITER, ul_debugobj(&lc->iter, "%s does not exist", lc->device));
		return -errno;
	}

	DBG(ITER, ul_debugobj(&lc->iter, "%s exist", lc->device));

	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(ITER, ul_debugobj(&lc->iter, "failed to use %s device", lc->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;

	DBG(ITER, ul_debug("scan dir: %s", dirname));

	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;

			errno = 0;
			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(ITER, ul_debugobj(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(ITER, ul_debugobj(iter, "checking %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(ITER, ul_debugobj(iter, "scanning /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(ITER, ul_debugobj(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;


	iter = &lc->iter;
	if (iter->done)
		return 1;

	DBG(ITER, ul_debugobj(iter, "next"));

	/* 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(ITER, ul_debugobj(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(ITER, ul_debugobj(iter, "next: scanning /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) {
		errno = EINVAL;
		return NULL;
	}
	errno = 0;
	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(CXT, ul_debugobj(lc, "reading loop_info64 OK"));
		return &lc->info;
	}

	lc->info_failed = 1;
	DBG(CXT, ul_debugobj(lc, "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(CXT, ul_debugobj(lc, "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;
		} else
			rc = -errno;
	}

	DBG(CXT, ul_debugobj(lc, "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;
		} else
			rc = -errno;
	}

	DBG(CXT, ul_debugobj(lc, "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;

	/* not provided by sysfs */
	if (lo) {
		if (type)
			*type = lo->lo_encrypt_type;
		rc = 0;
	} else
		rc = -errno;

	DBG(CXT, ul_debugobj(lc, "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(CXT, ul_debugobj(lc, "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;

	if (lo) {
		if (devno)
			*devno = lo->lo_device;
		rc = 0;
	} else
		rc = -errno;

	DBG(CXT, ul_debugobj(lc, "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;

	if (lo) {
		if (ino)
			*ino = lo->lo_inode;
		rc = 0;
	} else
		rc = -errno;

	DBG(CXT, ul_debugobj(lc, "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(CXT, ul_debugobj(lc, "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(CXT, ul_debugobj(lc, "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(CXT, ul_debugobj(lc, "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(CXT, ul_debugobj(lc, "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(CXT, ul_debugobj(lc, "set backing file=%s", lc->info.lo_file_name));
	return 0;
}

/*
 * In kernels prior to v3.9, if the offset or sizelimit options
 * are used, the block device's size won't be synced automatically.
 * blockdev --getsize64 and filesystems will use the backing
 * file size until the block device has been re-opened or the
 * LOOP_SET_CAPACITY ioctl is called to sync the sizes.
 *
 * Since mount -oloop uses the LO_FLAGS_AUTOCLEAR option and passes
 * the open file descriptor to the mount system call, we need to use
 * the ioctl. Calling losetup directly doesn't have this problem since
 * it closes the device when it exits and whatever consumes the device
 * next will re-open it, causing the resync.
 */
static int loopcxt_check_size(struct loopdev_cxt *lc, int file_fd)
{
	uint64_t size, expected_size;
	int dev_fd;
	struct stat st;

	if (!lc->info.lo_offset && !lc->info.lo_sizelimit)
		return 0;

	if (fstat(file_fd, &st)) {
		DBG(CXT, ul_debugobj(lc, "failed to fstat backing file"));
		return -errno;
	}
	if (S_ISBLK(st.st_mode)) {
		if (blkdev_get_size(file_fd,
				(unsigned long long *) &expected_size)) {
			DBG(CXT, ul_debugobj(lc, "failed to determine device size"));
			return -errno;
		}
	} else
		expected_size = st.st_size;

	if (expected_size == 0 || expected_size <= lc->info.lo_offset) {
		DBG(CXT, ul_debugobj(lc, "failed to determine expected size"));
		return 0;	/* ignore this error */
	}

	if (lc->info.lo_offset > 0)
		expected_size -= lc->info.lo_offset;

	if (lc->info.lo_sizelimit > 0 && lc->info.lo_sizelimit < expected_size)
		expected_size = lc->info.lo_sizelimit;

	dev_fd = loopcxt_get_fd(lc);
	if (dev_fd < 0) {
		DBG(CXT, ul_debugobj(lc, "failed to get loop FD"));
		return -errno;
	}

	if (blkdev_get_size(dev_fd, (unsigned long long *) &size)) {
		DBG(CXT, ul_debugobj(lc, "failed to determine loopdev size"));
		return -errno;
	}

	/* It's block device, so, align to 512-byte sectors */
	if (expected_size % 512) {
		DBG(CXT, ul_debugobj(lc, "expected size misaligned to 512-byte sectors"));
		expected_size = (expected_size >> 9) << 9;
	}

	if (expected_size != size) {
		DBG(CXT, ul_debugobj(lc, "warning: loopdev and expected "
				      "size dismatch (%ju/%ju)",
				      size, expected_size));

		if (loopcxt_set_capacity(lc)) {
			/* ioctl not available */
			if (errno == ENOTTY || errno == EINVAL)
				errno = ERANGE;
			return -errno;
		}

		if (blkdev_get_size(dev_fd, (unsigned long long *) &size))
			return -errno;

		if (expected_size != size) {
			errno = ERANGE;
			DBG(CXT, ul_debugobj(lc, "failed to set loopdev size, "
					"size: %ju, expected: %ju",
					size, expected_size));
			return -errno;
		}
	}

	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, cnt = 0;

	if (!lc || !*lc->device || !lc->filename)
		return -EINVAL;

	DBG(SETUP, ul_debugobj(lc, "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 | O_CLOEXEC)) < 0) {
		if (mode != O_RDONLY && (errno == EROFS || errno == EACCES))
			file_fd = open(lc->filename, mode = O_RDONLY);

		if (file_fd < 0) {
			DBG(SETUP, ul_debugobj(lc, "open backing file failed: %m"));
			return -errno;
		}
	}
	DBG(SETUP, ul_debugobj(lc, "backing file open: OK"));

	if (lc->fd != -1 && lc->mode != mode) {
		DBG(SETUP, ul_debugobj(lc, "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;
	}

	do {
		errno = 0;
		dev_fd = loopcxt_get_fd(lc);
		if (dev_fd >= 0 || lc->control_ok == 0)
			break;
		if (errno != EACCES && errno != ENOENT)
			break;
		/* We have permissions to open /dev/loop-control, but open
		 * /dev/loopN failed with EACCES, it's probably because udevd
		 * does not applied chown yet. Let's wait a moment. */
		usleep(25000);
	} while (cnt++ < 16);

	if (dev_fd < 0) {
		rc = -errno;
		goto err;
	}

	DBG(SETUP, ul_debugobj(lc, "device open: OK"));

	/*
	 * Set FD
	 */
	if (ioctl(dev_fd, LOOP_SET_FD, file_fd) < 0) {
		rc = -errno;
		DBG(SETUP, ul_debugobj(lc, "LOOP_SET_FD failed: %m"));
		goto err;
	}

	DBG(SETUP, ul_debugobj(lc, "LOOP_SET_FD: OK"));

	if (ioctl(dev_fd, LOOP_SET_STATUS64, &lc->info)) {
		DBG(SETUP, ul_debugobj(lc, "LOOP_SET_STATUS64 failed: %m"));
		goto err;
	}

	DBG(SETUP, ul_debugobj(lc, "LOOP_SET_STATUS64: OK"));

	if ((rc = loopcxt_check_size(lc, file_fd)))
		goto err;

	close(file_fd);

	memset(&lc->info, 0, sizeof(lc->info));
	lc->has_info = 0;
	lc->info_failed = 0;

	DBG(SETUP, ul_debugobj(lc, "success [rc=0]"));
	return 0;
err:
	if (file_fd >= 0)
		close(file_fd);
	if (dev_fd >= 0 && rc != -EBUSY)
		ioctl(dev_fd, LOOP_CLR_FD, 0);

	DBG(SETUP, ul_debugobj(lc, "failed [rc=%d]", rc));
	return rc;
}

int loopcxt_set_capacity(struct loopdev_cxt *lc)
{
	int fd = loopcxt_get_fd(lc);

	if (fd < 0)
		return -EINVAL;

	/* Kernels prior to v2.6.30 don't support this ioctl */
	if (ioctl(fd, LOOP_SET_CAPACITY, 0) < 0) {
		int rc = -errno;
		DBG(CXT, ul_debugobj(lc, "LOOP_SET_CAPACITY failed: %m"));
		return rc;
	}

	DBG(CXT, ul_debugobj(lc, "capacity set"));
	return 0;
}

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(CXT, ul_debugobj(lc, "LOOP_CLR_FD failed: %m"));
		return -errno;
	}

	DBG(CXT, ul_debugobj(lc, "device removed"));
	return 0;
}

int loopcxt_add_device(struct loopdev_cxt *lc)
{
	int rc = -EINVAL;
	int ctl, nr = -1;
	const char *p, *dev = loopcxt_get_device(lc);

	if (!dev)
		goto done;

	if (!(lc->flags & LOOPDEV_FL_CONTROL)) {
		rc = -ENOSYS;
		goto done;
	}

	p = strrchr(dev, '/');
	if (!p || (sscanf(p, "/loop%d", &nr) != 1 && sscanf(p, "/%d", &nr) != 1)
	       || nr < 0)
		goto done;

	ctl = open(_PATH_DEV_LOOPCTL, O_RDWR|O_CLOEXEC);
	if (ctl >= 0) {
		DBG(CXT, ul_debugobj(lc, "add_device %d", nr));
		rc = ioctl(ctl, LOOP_CTL_ADD, nr);
		close(ctl);
	}
	lc->control_ok = rc >= 0 ? 1 : 0;
done:
	DBG(CXT, ul_debugobj(lc, "add_device done [rc=%d]", rc));
	return rc;
}

/*
 * 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(CXT, ul_debugobj(lc, "find_unused requested"));

	if (lc->flags & LOOPDEV_FL_CONTROL) {
		int ctl = open(_PATH_DEV_LOOPCTL, O_RDWR|O_CLOEXEC);

		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);
		}
		lc->control_ok = ctl >= 0 && rc == 0 ? 1 : 0;
		if (ctl >= 0)
			close(ctl);
		DBG(CXT, ul_debugobj(lc, "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(CXT, ul_debugobj(lc, "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;
}

