/*
 * GPL HEADER START
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 only,
 * as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License version 2 for more details (a copy is included
 * in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU General Public License
 * version 2 along with this program; If not, see
 * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
 *
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
 * CA 95054 USA or visit www.sun.com if you need additional information or
 * have any questions.
 *
 * GPL HEADER END
 */
/*
 * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
 * Use is subject to license terms.
 *
 * Copyright (c) 2011, 2012, Intel Corporation.
 */
/*
 * This file is part of Lustre, http://www.lustre.org/
 * Lustre is a trademark of Sun Microsystems, Inc.
 */

/*
 *  linux/drivers/block/loop.c
 *
 *  Written by Theodore Ts'o, 3/29/93
 *
 * Copyright 1993 by Theodore Ts'o.  Redistribution of this file is
 * permitted under the GNU General Public License.
 *
 * Modularized and updated for 1.1.16 kernel - Mitch Dsouza 28th May 1994
 * Adapted for 1.3.59 kernel - Andries Brouwer, 1 Feb 1996
 *
 * Fixed do_loop_request() re-entrancy - Vincent.Renardias@waw.com Mar 20, 1997
 *
 * Added devfs support - Richard Gooch <rgooch@atnf.csiro.au> 16-Jan-1998
 *
 * Handle sparse backing files correctly - Kenn Humborg, Jun 28, 1998
 *
 * Loadable modules and other fixes by AK, 1998
 *
 * Maximum number of loop devices now dynamic via max_loop module parameter.
 * Russell Kroll <rkroll@exploits.org> 19990701
 *
 * Maximum number of loop devices when compiled-in now selectable by passing
 * max_loop=<1-255> to the kernel on boot.
 * Erik I. Bols?, <eriki@himolde.no>, Oct 31, 1999
 *
 * Completely rewrite request handling to be make_request_fn style and
 * non blocking, pushing work to a helper thread. Lots of fixes from
 * Al Viro too.
 * Jens Axboe <axboe@suse.de>, Nov 2000
 *
 * Support up to 256 loop devices
 * Heinz Mauelshagen <mge@sistina.com>, Feb 2002
 *
 * Support for falling back on the write file operation when the address space
 * operations prepare_write and/or commit_write are not available on the
 * backing filesystem.
 * Anton Altaparmakov, 16 Feb 2005
 *
 * Still To Fix:
 * - Advisory locking is ignored here.
 * - Should use an own CAP_* category instead of CAP_SYS_ADMIN
 *
 */

#include <linux/module.h>

#include <linux/sched.h>
#include <linux/fs.h>
#include <linux/file.h>
#include <linux/stat.h>
#include <linux/errno.h>
#include <linux/major.h>
#include <linux/wait.h>
#include <linux/blkdev.h>
#include <linux/blkpg.h>
#include <linux/init.h>
#include <linux/swap.h>
#include <linux/slab.h>
#include <linux/suspend.h>
#include <linux/writeback.h>
#include <linux/buffer_head.h>		/* for invalidate_bdev() */
#include <linux/completion.h>
#include <linux/highmem.h>
#include <linux/gfp.h>
#include <linux/pagevec.h>
#include <linux/uaccess.h>

#include "../include/lustre_lib.h"
#include "../include/lustre_lite.h"
#include "llite_internal.h"

#define LLOOP_MAX_SEGMENTS	LNET_MAX_IOV

/* Possible states of device */
enum {
	LLOOP_UNBOUND,
	LLOOP_BOUND,
	LLOOP_RUNDOWN,
};

struct lloop_device {
	int		  lo_number;
	int		  lo_refcnt;
	loff_t	       lo_offset;
	loff_t	       lo_sizelimit;
	int		  lo_flags;
	struct file	 *lo_backing_file;
	struct block_device *lo_device;
	unsigned	     lo_blocksize;

	gfp_t		  old_gfp_mask;

	spinlock_t		lo_lock;
	struct bio		*lo_bio;
	struct bio		*lo_biotail;
	int			lo_state;
	struct semaphore	lo_sem;
	struct mutex		lo_ctl_mutex;
	atomic_t	 lo_pending;
	wait_queue_head_t	  lo_bh_wait;

	struct request_queue *lo_queue;

	const struct lu_env *lo_env;
	struct cl_io	 lo_io;
	struct ll_dio_pages  lo_pvec;

	/* data to handle bio for lustre. */
	struct lo_request_data {
		struct page *lrd_pages[LLOOP_MAX_SEGMENTS];
		loff_t       lrd_offsets[LLOOP_MAX_SEGMENTS];
	} lo_requests[1];
};

/*
 * Loop flags
 */
enum {
	LO_FLAGS_READ_ONLY       = 1,
};

static int lloop_major;
#define MAX_LOOP_DEFAULT  16
static int max_loop = MAX_LOOP_DEFAULT;
static struct lloop_device *loop_dev;
static struct gendisk **disks;
static struct mutex lloop_mutex;
static void *ll_iocontrol_magic;

static loff_t get_loop_size(struct lloop_device *lo, struct file *file)
{
	loff_t size, offset, loopsize;

	/* Compute loopsize in bytes */
	size = i_size_read(file->f_mapping->host);
	offset = lo->lo_offset;
	loopsize = size - offset;
	if (lo->lo_sizelimit > 0 && lo->lo_sizelimit < loopsize)
		loopsize = lo->lo_sizelimit;

	/*
	 * Unfortunately, if we want to do I/O on the device,
	 * the number of 512-byte sectors has to fit into a sector_t.
	 */
	return loopsize >> 9;
}

static int do_bio_lustrebacked(struct lloop_device *lo, struct bio *head)
{
	const struct lu_env  *env   = lo->lo_env;
	struct cl_io	 *io    = &lo->lo_io;
	struct inode	 *inode = file_inode(lo->lo_backing_file);
	struct cl_object     *obj = ll_i2info(inode)->lli_clob;
	pgoff_t	       offset;
	int		   ret;
	int		   rw;
	u32		   page_count = 0;
	struct bio_vec       bvec;
	struct bvec_iter   iter;
	struct bio	   *bio;
	ssize_t	       bytes;

	struct ll_dio_pages  *pvec = &lo->lo_pvec;
	struct page	 **pages = pvec->ldp_pages;
	loff_t	       *offsets = pvec->ldp_offsets;

	truncate_inode_pages(inode->i_mapping, 0);

	/* initialize the IO */
	memset(io, 0, sizeof(*io));
	io->ci_obj = obj;
	ret = cl_io_init(env, io, CIT_MISC, obj);
	if (ret)
		return io->ci_result;
	io->ci_lockreq = CILR_NEVER;

	rw = head->bi_rw;
	for (bio = head; bio ; bio = bio->bi_next) {
		LASSERT(rw == bio->bi_rw);

		offset = (pgoff_t)(bio->bi_iter.bi_sector << 9) + lo->lo_offset;
		bio_for_each_segment(bvec, bio, iter) {
			BUG_ON(bvec.bv_offset != 0);
			BUG_ON(bvec.bv_len != PAGE_SIZE);

			pages[page_count] = bvec.bv_page;
			offsets[page_count] = offset;
			page_count++;
			offset += bvec.bv_len;
		}
		LASSERT(page_count <= LLOOP_MAX_SEGMENTS);
	}

	ll_stats_ops_tally(ll_i2sbi(inode),
			(rw == WRITE) ? LPROC_LL_BRW_WRITE : LPROC_LL_BRW_READ,
			page_count);

	pvec->ldp_size = page_count << PAGE_SHIFT;
	pvec->ldp_nr = page_count;

	/* FIXME: in ll_direct_rw_pages, it has to allocate many cl_page{}s to
	 * write those pages into OST. Even worse case is that more pages
	 * would be asked to write out to swap space, and then finally get here
	 * again.
	 * Unfortunately this is NOT easy to fix.
	 * Thoughts on solution:
	 * 0. Define a reserved pool for cl_pages, which could be a list of
	 *    pre-allocated cl_pages;
	 * 1. Define a new operation in cl_object_operations{}, says clo_depth,
	 *    which measures how many layers for this lustre object. Generally
	 *    speaking, the depth would be 2, one for llite, and one for lovsub.
	 *    However, for SNS, there will be more since we need additional page
	 *    to store parity;
	 * 2. Reserve the # of (page_count * depth) cl_pages from the reserved
	 *    pool. Afterwards, the clio would allocate the pages from reserved
	 *    pool, this guarantees we needn't allocate the cl_pages from
	 *    generic cl_page slab cache.
	 *    Of course, if there is NOT enough pages in the pool, we might
	 *    be asked to write less pages once, this purely depends on
	 *    implementation. Anyway, we should be careful to avoid deadlocking.
	 */
	inode_lock(inode);
	bytes = ll_direct_rw_pages(env, io, rw, inode, pvec);
	inode_unlock(inode);
	cl_io_fini(env, io);
	return (bytes == pvec->ldp_size) ? 0 : (int)bytes;
}

/*
 * Add bio to back of pending list
 */
static void loop_add_bio(struct lloop_device *lo, struct bio *bio)
{
	unsigned long flags;

	spin_lock_irqsave(&lo->lo_lock, flags);
	if (lo->lo_biotail) {
		lo->lo_biotail->bi_next = bio;
		lo->lo_biotail = bio;
	} else
		lo->lo_bio = lo->lo_biotail = bio;
	spin_unlock_irqrestore(&lo->lo_lock, flags);

	atomic_inc(&lo->lo_pending);
	if (waitqueue_active(&lo->lo_bh_wait))
		wake_up(&lo->lo_bh_wait);
}

/*
 * Grab first pending buffer
 */
static unsigned int loop_get_bio(struct lloop_device *lo, struct bio **req)
{
	struct bio *first;
	struct bio **bio;
	unsigned int count = 0;
	unsigned int page_count = 0;
	int rw;

	spin_lock_irq(&lo->lo_lock);
	first = lo->lo_bio;
	if (unlikely(!first)) {
		spin_unlock_irq(&lo->lo_lock);
		return 0;
	}

	/* TODO: need to split the bio, too bad. */
	LASSERT(first->bi_vcnt <= LLOOP_MAX_SEGMENTS);

	rw = first->bi_rw;
	bio = &lo->lo_bio;
	while (*bio && (*bio)->bi_rw == rw) {
		CDEBUG(D_INFO, "bio sector %llu size %u count %u vcnt%u\n",
		       (unsigned long long)(*bio)->bi_iter.bi_sector,
		       (*bio)->bi_iter.bi_size,
		       page_count, (*bio)->bi_vcnt);
		if (page_count + (*bio)->bi_vcnt > LLOOP_MAX_SEGMENTS)
			break;

		page_count += (*bio)->bi_vcnt;
		count++;
		bio = &(*bio)->bi_next;
	}
	if (*bio) {
		/* Some of bios can't be mergeable. */
		lo->lo_bio = *bio;
		*bio = NULL;
	} else {
		/* Hit the end of queue */
		lo->lo_biotail = NULL;
		lo->lo_bio = NULL;
	}
	*req = first;
	spin_unlock_irq(&lo->lo_lock);
	return count;
}

static blk_qc_t loop_make_request(struct request_queue *q, struct bio *old_bio)
{
	struct lloop_device *lo = q->queuedata;
	int rw = bio_rw(old_bio);
	int inactive;

	blk_queue_split(q, &old_bio, q->bio_split);

	if (!lo)
		goto err;

	CDEBUG(D_INFO, "submit bio sector %llu size %u\n",
	       (unsigned long long)old_bio->bi_iter.bi_sector,
	       old_bio->bi_iter.bi_size);

	spin_lock_irq(&lo->lo_lock);
	inactive = lo->lo_state != LLOOP_BOUND;
	spin_unlock_irq(&lo->lo_lock);
	if (inactive)
		goto err;

	if (rw == WRITE) {
		if (lo->lo_flags & LO_FLAGS_READ_ONLY)
			goto err;
	} else if (rw == READA) {
		rw = READ;
	} else if (rw != READ) {
		CERROR("lloop: unknown command (%x)\n", rw);
		goto err;
	}
	loop_add_bio(lo, old_bio);
	return BLK_QC_T_NONE;
err:
	bio_io_error(old_bio);
	return BLK_QC_T_NONE;
}

static inline void loop_handle_bio(struct lloop_device *lo, struct bio *bio)
{
	int ret;

	ret = do_bio_lustrebacked(lo, bio);
	while (bio) {
		struct bio *tmp = bio->bi_next;

		bio->bi_next = NULL;
		bio->bi_error = ret;
		bio_endio(bio);
		bio = tmp;
	}
}

static inline int loop_active(struct lloop_device *lo)
{
	return atomic_read(&lo->lo_pending) ||
		(lo->lo_state == LLOOP_RUNDOWN);
}

/*
 * worker thread that handles reads/writes to file backed loop devices,
 * to avoid blocking in our make_request_fn.
 */
static int loop_thread(void *data)
{
	struct lloop_device *lo = data;
	struct bio *bio;
	unsigned int count;
	unsigned long times = 0;
	unsigned long total_count = 0;

	struct lu_env *env;
	int refcheck;
	int ret = 0;

	set_user_nice(current, MIN_NICE);

	lo->lo_state = LLOOP_BOUND;

	env = cl_env_get(&refcheck);
	if (IS_ERR(env)) {
		ret = PTR_ERR(env);
		goto out;
	}

	lo->lo_env = env;
	memset(&lo->lo_pvec, 0, sizeof(lo->lo_pvec));
	lo->lo_pvec.ldp_pages   = lo->lo_requests[0].lrd_pages;
	lo->lo_pvec.ldp_offsets = lo->lo_requests[0].lrd_offsets;

	/*
	 * up sem, we are running
	 */
	up(&lo->lo_sem);

	for (;;) {
		wait_event(lo->lo_bh_wait, loop_active(lo));
		if (!atomic_read(&lo->lo_pending)) {
			int exiting = 0;

			spin_lock_irq(&lo->lo_lock);
			exiting = (lo->lo_state == LLOOP_RUNDOWN);
			spin_unlock_irq(&lo->lo_lock);
			if (exiting)
				break;
		}

		bio = NULL;
		count = loop_get_bio(lo, &bio);
		if (!count) {
			CWARN("lloop(minor: %d): missing bio\n", lo->lo_number);
			continue;
		}

		total_count += count;
		if (total_count < count) {     /* overflow */
			total_count = count;
			times = 1;
		} else {
			times++;
		}
		if ((times & 127) == 0) {
			CDEBUG(D_INFO, "total: %lu, count: %lu, avg: %lu\n",
			       total_count, times, total_count / times);
		}

		LASSERT(bio);
		LASSERT(count <= atomic_read(&lo->lo_pending));
		loop_handle_bio(lo, bio);
		atomic_sub(count, &lo->lo_pending);
	}
	cl_env_put(env, &refcheck);

out:
	up(&lo->lo_sem);
	return ret;
}

static int loop_set_fd(struct lloop_device *lo, struct file *unused,
		       struct block_device *bdev, struct file *file)
{
	struct inode	 *inode;
	struct address_space *mapping;
	int		   lo_flags = 0;
	int		   error;
	loff_t		size;

	if (!try_module_get(THIS_MODULE))
		return -ENODEV;

	error = -EBUSY;
	if (lo->lo_state != LLOOP_UNBOUND)
		goto out;

	mapping = file->f_mapping;
	inode = mapping->host;

	error = -EINVAL;
	if (!S_ISREG(inode->i_mode) || inode->i_sb->s_magic != LL_SUPER_MAGIC)
		goto out;

	if (!(file->f_mode & FMODE_WRITE))
		lo_flags |= LO_FLAGS_READ_ONLY;

	size = get_loop_size(lo, file);

	if ((loff_t)(sector_t)size != size) {
		error = -EFBIG;
		goto out;
	}

	/* remove all pages in cache so as dirty pages not to be existent. */
	truncate_inode_pages(mapping, 0);

	set_device_ro(bdev, (lo_flags & LO_FLAGS_READ_ONLY) != 0);

	lo->lo_blocksize = PAGE_SIZE;
	lo->lo_device = bdev;
	lo->lo_flags = lo_flags;
	lo->lo_backing_file = file;
	lo->lo_sizelimit = 0;
	lo->old_gfp_mask = mapping_gfp_mask(mapping);
	mapping_set_gfp_mask(mapping, lo->old_gfp_mask & ~(__GFP_IO|__GFP_FS));

	lo->lo_bio = lo->lo_biotail = NULL;

	/*
	 * set queue make_request_fn, and add limits based on lower level
	 * device
	 */
	blk_queue_make_request(lo->lo_queue, loop_make_request);
	lo->lo_queue->queuedata = lo;

	/* queue parameters */
	CLASSERT(PAGE_SIZE < (1 << (sizeof(unsigned short) * 8)));
	blk_queue_logical_block_size(lo->lo_queue,
				     (unsigned short)PAGE_SIZE);
	blk_queue_max_hw_sectors(lo->lo_queue,
				 LLOOP_MAX_SEGMENTS << (PAGE_SHIFT - 9));
	blk_queue_max_segments(lo->lo_queue, LLOOP_MAX_SEGMENTS);

	set_capacity(disks[lo->lo_number], size);
	bd_set_size(bdev, size << 9);

	set_blocksize(bdev, lo->lo_blocksize);

	kthread_run(loop_thread, lo, "lloop%d", lo->lo_number);
	down(&lo->lo_sem);
	return 0;

out:
	/* This is safe: open() is still holding a reference. */
	module_put(THIS_MODULE);
	return error;
}

static int loop_clr_fd(struct lloop_device *lo, struct block_device *bdev,
		       int count)
{
	struct file *filp = lo->lo_backing_file;
	gfp_t gfp = lo->old_gfp_mask;

	if (lo->lo_state != LLOOP_BOUND)
		return -ENXIO;

	if (lo->lo_refcnt > count)	/* we needed one fd for the ioctl */
		return -EBUSY;

	if (!filp)
		return -EINVAL;

	spin_lock_irq(&lo->lo_lock);
	lo->lo_state = LLOOP_RUNDOWN;
	spin_unlock_irq(&lo->lo_lock);
	wake_up(&lo->lo_bh_wait);

	down(&lo->lo_sem);
	lo->lo_backing_file = NULL;
	lo->lo_device = NULL;
	lo->lo_offset = 0;
	lo->lo_sizelimit = 0;
	lo->lo_flags = 0;
	invalidate_bdev(bdev);
	set_capacity(disks[lo->lo_number], 0);
	bd_set_size(bdev, 0);
	mapping_set_gfp_mask(filp->f_mapping, gfp);
	lo->lo_state = LLOOP_UNBOUND;
	fput(filp);
	/* This is safe: open() is still holding a reference. */
	module_put(THIS_MODULE);
	return 0;
}

static int lo_open(struct block_device *bdev, fmode_t mode)
{
	struct lloop_device *lo = bdev->bd_disk->private_data;

	mutex_lock(&lo->lo_ctl_mutex);
	lo->lo_refcnt++;
	mutex_unlock(&lo->lo_ctl_mutex);

	return 0;
}

static void lo_release(struct gendisk *disk, fmode_t mode)
{
	struct lloop_device *lo = disk->private_data;

	mutex_lock(&lo->lo_ctl_mutex);
	--lo->lo_refcnt;
	mutex_unlock(&lo->lo_ctl_mutex);
}

/* lloop device node's ioctl function. */
static int lo_ioctl(struct block_device *bdev, fmode_t mode,
		    unsigned int cmd, unsigned long arg)
{
	struct lloop_device *lo = bdev->bd_disk->private_data;
	struct inode *inode = NULL;
	int err = 0;

	mutex_lock(&lloop_mutex);
	switch (cmd) {
	case LL_IOC_LLOOP_DETACH: {
		err = loop_clr_fd(lo, bdev, 2);
		if (err == 0)
			blkdev_put(bdev, 0); /* grabbed in LLOOP_ATTACH */
		break;
	}

	case LL_IOC_LLOOP_INFO: {
		struct lu_fid fid;

		if (!lo->lo_backing_file) {
			err = -ENOENT;
			break;
		}
		if (!inode)
			inode = file_inode(lo->lo_backing_file);
		if (lo->lo_state == LLOOP_BOUND)
			fid = ll_i2info(inode)->lli_fid;
		else
			fid_zero(&fid);

		if (copy_to_user((void __user *)arg, &fid, sizeof(fid)))
			err = -EFAULT;
		break;
	}

	default:
		err = -EINVAL;
		break;
	}
	mutex_unlock(&lloop_mutex);

	return err;
}

static struct block_device_operations lo_fops = {
	.owner =	THIS_MODULE,
	.open =	 lo_open,
	.release =      lo_release,
	.ioctl =	lo_ioctl,
};

/* dynamic iocontrol callback.
 * This callback is registered in lloop_init and will be called by
 * ll_iocontrol_call.
 *
 * This is a llite regular file ioctl function. It takes the responsibility
 * of attaching or detaching a file by a lloop's device number.
 */
static enum llioc_iter lloop_ioctl(struct inode *unused, struct file *file,
				   unsigned int cmd, unsigned long arg,
				   void *magic, int *rcp)
{
	struct lloop_device *lo = NULL;
	struct block_device *bdev = NULL;
	int err = 0;
	dev_t dev;

	if (magic != ll_iocontrol_magic)
		return LLIOC_CONT;

	if (!disks) {
		err = -ENODEV;
		goto out1;
	}

	CWARN("Enter llop_ioctl\n");

	mutex_lock(&lloop_mutex);
	switch (cmd) {
	case LL_IOC_LLOOP_ATTACH: {
		struct lloop_device *lo_free = NULL;
		int i;

		for (i = 0; i < max_loop; i++, lo = NULL) {
			lo = &loop_dev[i];
			if (lo->lo_state == LLOOP_UNBOUND) {
				if (!lo_free)
					lo_free = lo;
				continue;
			}
			if (file_inode(lo->lo_backing_file) == file_inode(file))
				break;
		}
		if (lo || !lo_free) {
			err = -EBUSY;
			goto out;
		}

		lo = lo_free;
		dev = MKDEV(lloop_major, lo->lo_number);

		/* quit if the used pointer is writable */
		if (put_user((long)old_encode_dev(dev), (long __user *)arg)) {
			err = -EFAULT;
			goto out;
		}

		bdev = blkdev_get_by_dev(dev, file->f_mode, NULL);
		if (IS_ERR(bdev)) {
			err = PTR_ERR(bdev);
			goto out;
		}

		get_file(file);
		err = loop_set_fd(lo, NULL, bdev, file);
		if (err) {
			fput(file);
			blkdev_put(bdev, 0);
		}

		break;
	}

	case LL_IOC_LLOOP_DETACH_BYDEV: {
		int minor;

		dev = old_decode_dev(arg);
		if (MAJOR(dev) != lloop_major) {
			err = -EINVAL;
			goto out;
		}

		minor = MINOR(dev);
		if (minor > max_loop - 1) {
			err = -EINVAL;
			goto out;
		}

		lo = &loop_dev[minor];
		if (lo->lo_state != LLOOP_BOUND) {
			err = -EINVAL;
			goto out;
		}

		bdev = lo->lo_device;
		err = loop_clr_fd(lo, bdev, 1);
		if (err == 0)
			blkdev_put(bdev, 0); /* grabbed in LLOOP_ATTACH */

		break;
	}

	default:
		err = -EINVAL;
		break;
	}

out:
	mutex_unlock(&lloop_mutex);
out1:
	if (rcp)
		*rcp = err;
	return LLIOC_STOP;
}

static int __init lloop_init(void)
{
	int	i;
	unsigned int cmdlist[] = {
		LL_IOC_LLOOP_ATTACH,
		LL_IOC_LLOOP_DETACH_BYDEV,
	};

	if (max_loop < 1 || max_loop > 256) {
		max_loop = MAX_LOOP_DEFAULT;
		CWARN("lloop: invalid max_loop (must be between 1 and 256), using default (%u)\n",
		      max_loop);
	}

	lloop_major = register_blkdev(0, "lloop");
	if (lloop_major < 0)
		return -EIO;

	CDEBUG(D_CONFIG, "registered lloop major %d with %u minors\n",
	       lloop_major, max_loop);

	ll_iocontrol_magic = ll_iocontrol_register(lloop_ioctl, 2, cmdlist);
	if (!ll_iocontrol_magic)
		goto out_mem1;

	loop_dev = kcalloc(max_loop, sizeof(*loop_dev), GFP_KERNEL);
	if (!loop_dev)
		goto out_mem1;

	disks = kcalloc(max_loop, sizeof(*disks), GFP_KERNEL);
	if (!disks)
		goto out_mem2;

	for (i = 0; i < max_loop; i++) {
		disks[i] = alloc_disk(1);
		if (!disks[i])
			goto out_mem3;
	}

	mutex_init(&lloop_mutex);

	for (i = 0; i < max_loop; i++) {
		struct lloop_device *lo = &loop_dev[i];
		struct gendisk *disk = disks[i];

		lo->lo_queue = blk_alloc_queue(GFP_KERNEL);
		if (!lo->lo_queue)
			goto out_mem4;

		mutex_init(&lo->lo_ctl_mutex);
		sema_init(&lo->lo_sem, 0);
		init_waitqueue_head(&lo->lo_bh_wait);
		lo->lo_number = i;
		spin_lock_init(&lo->lo_lock);
		disk->major = lloop_major;
		disk->first_minor = i;
		disk->fops = &lo_fops;
		sprintf(disk->disk_name, "lloop%d", i);
		disk->private_data = lo;
		disk->queue = lo->lo_queue;
	}

	/* We cannot fail after we call this, so another loop!*/
	for (i = 0; i < max_loop; i++)
		add_disk(disks[i]);
	return 0;

out_mem4:
	while (i--)
		blk_cleanup_queue(loop_dev[i].lo_queue);
	i = max_loop;
out_mem3:
	while (i--)
		put_disk(disks[i]);
	kfree(disks);
out_mem2:
	kfree(loop_dev);
out_mem1:
	unregister_blkdev(lloop_major, "lloop");
	ll_iocontrol_unregister(ll_iocontrol_magic);
	CERROR("lloop: ran out of memory\n");
	return -ENOMEM;
}

static void lloop_exit(void)
{
	int i;

	ll_iocontrol_unregister(ll_iocontrol_magic);
	for (i = 0; i < max_loop; i++) {
		del_gendisk(disks[i]);
		blk_cleanup_queue(loop_dev[i].lo_queue);
		put_disk(disks[i]);
	}

	unregister_blkdev(lloop_major, "lloop");

	kfree(disks);
	kfree(loop_dev);
}

module_param(max_loop, int, 0444);
MODULE_PARM_DESC(max_loop, "maximum of lloop_device");
MODULE_AUTHOR("OpenSFS, Inc. <http://www.lustre.org/>");
MODULE_DESCRIPTION("Lustre virtual block device");
MODULE_VERSION(LUSTRE_VERSION_STRING);
MODULE_LICENSE("GPL");

module_init(lloop_init);
module_exit(lloop_exit);
