<feed xmlns='http://www.w3.org/2005/Atom'>
<title>linux.git/drivers/block/loop.c, branch v2.6.31</title>
<subtitle>Linux kernel source tree</subtitle>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux.git/'/>
<entry>
<title>headers: smp_lock.h redux</title>
<updated>2009-07-12T19:22:34+00:00</updated>
<author>
<name>Alexey Dobriyan</name>
<email>adobriyan@gmail.com</email>
</author>
<published>2009-07-11T18:08:37+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux.git/commit/?id=405f55712dfe464b3240d7816cc4fe4174831be2'/>
<id>405f55712dfe464b3240d7816cc4fe4174831be2</id>
<content type='text'>
* Remove smp_lock.h from files which don't need it (including some headers!)
* Add smp_lock.h to files which do need it
* Make smp_lock.h include conditional in hardirq.h
  It's needed only for one kernel_locked() usage which is under CONFIG_PREEMPT

  This will make hardirq.h inclusion cheaper for every PREEMPT=n config
  (which includes allmodconfig/allyesconfig, BTW)

Signed-off-by: Alexey Dobriyan &lt;adobriyan@gmail.com&gt;
Signed-off-by: Linus Torvalds &lt;torvalds@linux-foundation.org&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
* Remove smp_lock.h from files which don't need it (including some headers!)
* Add smp_lock.h to files which do need it
* Make smp_lock.h include conditional in hardirq.h
  It's needed only for one kernel_locked() usage which is under CONFIG_PREEMPT

  This will make hardirq.h inclusion cheaper for every PREEMPT=n config
  (which includes allmodconfig/allyesconfig, BTW)

Signed-off-by: Alexey Dobriyan &lt;adobriyan@gmail.com&gt;
Signed-off-by: Linus Torvalds &lt;torvalds@linux-foundation.org&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>splice: implement default splice_read method</title>
<updated>2009-05-11T12:13:10+00:00</updated>
<author>
<name>Miklos Szeredi</name>
<email>miklos@szeredi.hu</email>
</author>
<published>2009-05-07T13:37:36+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux.git/commit/?id=6818173bd658439b83896a2a7586f64ab51bf29c'/>
<id>6818173bd658439b83896a2a7586f64ab51bf29c</id>
<content type='text'>
If f_op-&gt;splice_read() is not implemented, fall back to a plain read.
Use vfs_readv() to read into previously allocated pages.

This will allow splice and functions using splice, such as the loop
device, to work on all filesystems.  This includes "direct_io" files
in fuse which bypass the page cache.

Signed-off-by: Miklos Szeredi &lt;mszeredi@suse.cz&gt;
Signed-off-by: Jens Axboe &lt;jens.axboe@oracle.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
If f_op-&gt;splice_read() is not implemented, fall back to a plain read.
Use vfs_readv() to read into previously allocated pages.

This will allow splice and functions using splice, such as the loop
device, to work on all filesystems.  This includes "direct_io" files
in fuse which bypass the page cache.

Signed-off-by: Miklos Szeredi &lt;mszeredi@suse.cz&gt;
Signed-off-by: Jens Axboe &lt;jens.axboe@oracle.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>loop: use BIO list management functions</title>
<updated>2009-04-28T05:37:28+00:00</updated>
<author>
<name>Akinobu Mita</name>
<email>akinobu.mita@gmail.com</email>
</author>
<published>2009-04-17T06:41:21+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux.git/commit/?id=e686307fdc84f249490e6c9da92fcb2424491f14'/>
<id>e686307fdc84f249490e6c9da92fcb2424491f14</id>
<content type='text'>
Now that the bio list management stuff is generic, convert loop to use
bio lists instead of its own private bio list implementation.

Cc:  Jens Axboe &lt;axboe@kernel.dk&gt;
Cc: Christoph Hellwig &lt;hch@infradead.org&gt;
Signed-off-by: Akinobu Mita &lt;akinobu.mita@gmail.com&gt;
Signed-off-by: Jens Axboe &lt;jens.axboe@oracle.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Now that the bio list management stuff is generic, convert loop to use
bio lists instead of its own private bio list implementation.

Cc:  Jens Axboe &lt;axboe@kernel.dk&gt;
Cc: Christoph Hellwig &lt;hch@infradead.org&gt;
Signed-off-by: Akinobu Mita &lt;akinobu.mita@gmail.com&gt;
Signed-off-by: Jens Axboe &lt;jens.axboe@oracle.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>loop: mutex already unlocked in loop_clr_fd()</title>
<updated>2009-04-07T11:48:21+00:00</updated>
<author>
<name>Alexander Beregalov</name>
<email>a.beregalov@gmail.com</email>
</author>
<published>2009-04-07T11:48:21+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux.git/commit/?id=ffcd7dca3ab78f9f425971756e5e90024157f6be'/>
<id>ffcd7dca3ab78f9f425971756e5e90024157f6be</id>
<content type='text'>
mount/1865 is trying to release lock (&amp;lo-&gt;lo_ctl_mutex) at:
but there are no more locks to release!

mutex is already unlocked in loop_clr_fd(), we should not
try to unlock it in lo_release() again.

Signed-off-by: Alexander Beregalov &lt;a.beregalov@gmail.com&gt;
Signed-off-by: Jens Axboe &lt;jens.axboe@oracle.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
mount/1865 is trying to release lock (&amp;lo-&gt;lo_ctl_mutex) at:
but there are no more locks to release!

mutex is already unlocked in loop_clr_fd(), we should not
try to unlock it in lo_release() again.

Signed-off-by: Alexander Beregalov &lt;a.beregalov@gmail.com&gt;
Signed-off-by: Jens Axboe &lt;jens.axboe@oracle.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>loop: add ioctl to resize a loop device</title>
<updated>2009-04-01T15:59:17+00:00</updated>
<author>
<name>J. R. Okajima</name>
<email>hooanon05@yahoo.co.jp</email>
</author>
<published>2009-03-31T22:23:43+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux.git/commit/?id=53d6660836f233df66490707365ab177e5fb2bb4'/>
<id>53d6660836f233df66490707365ab177e5fb2bb4</id>
<content type='text'>
Add the ability to 'resize' the loop device on the fly.

One practical application is a loop file with XFS filesystem, already
mounted: You can easily enlarge the file (append some bytes) and then call
ioctl(fd, LOOP_SET_CAPACITY, new); The loop driver will learn about the
new size and you can use xfs_growfs later on, which will allow you to use
full capacity of the loop file without the need to unmount.

Test app:

#include &lt;linux/fs.h&gt;
#include &lt;linux/loop.h&gt;
#include &lt;sys/ioctl.h&gt;
#include &lt;sys/stat.h&gt;
#include &lt;sys/types.h&gt;
#include &lt;assert.h&gt;
#include &lt;errno.h&gt;
#include &lt;fcntl.h&gt;
#include &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;
#include &lt;unistd.h&gt;

#define _GNU_SOURCE
#include &lt;getopt.h&gt;

char *me;

void usage(FILE *f)
{
	fprintf(f, "%s [options] loop_dev [backend_file]\n"
		"-s, --set new_size_in_bytes\n"
		"\twhen backend_file is given, "
		"it will be expanded too while keeping the original contents\n",
		me);
}

struct option opts[] = {
	{
		.name		= "set",
		.has_arg	= 1,
		.flag		= NULL,
		.val		= 's'
	},
	{
		.name		= "help",
		.has_arg	= 0,
		.flag		= NULL,
		.val		= 'h'
	}
};

void err_size(char *name, __u64 old)
{
	fprintf(stderr, "size must be larger than current %s (%llu)\n",
		name, old);
}

int main(int argc, char *argv[])
{
	int fd, err, c, i, bfd;
	ssize_t ssz;
	size_t sz;
	__u64 old, new, append;
	char a[BUFSIZ];
	struct stat st;
	FILE *out;
	char *backend, *dev;

	err = EINVAL;
	out = stderr;
	me = argv[0];
	new = 0;
	while ((c = getopt_long(argc, argv, "s:h", opts, &amp;i)) != -1) {
		switch (c) {
		case 's':
			errno = 0;
			new = strtoull(optarg, NULL, 0);
			if (errno) {
				err = errno;
				perror(argv[i]);
				goto out;
			}
			break;

		case 'h':
			err = 0;
			out = stdout;
			goto err;

		default:
			perror(argv[i]);
			goto err;
		}
	}

	if (optind &lt; argc)
		dev = argv[optind++];
	else
		goto err;

	fd = open(dev, O_RDONLY);
	if (fd &lt; 0) {
		err = errno;
		perror(dev);
		goto out;
	}

	err = ioctl(fd, BLKGETSIZE64, &amp;old);
	if (err) {
		err = errno;
		perror("ioctl BLKGETSIZE64");
		goto out;
	}

	if (!new) {
		printf("%llu\n", old);
		goto out;
	}

	if (new &lt; old) {
		err = EINVAL;
		err_size(dev, old);
		goto out;
	}

	if (optind &lt; argc) {
		backend = argv[optind++];
		bfd = open(backend, O_WRONLY|O_APPEND);
		if (bfd &lt; 0) {
			err = errno;
			perror(backend);
			goto out;
		}
		err = fstat(bfd, &amp;st);
		if (err) {
			err = errno;
			perror(backend);
			goto out;
		}
		if (new &lt; st.st_size) {
			err = EINVAL;
			err_size(backend, st.st_size);
			goto out;
		}
		append = new - st.st_size;
		sz = sizeof(a);
		while (append &gt; 0) {
			if (append &lt; sz)
				sz = append;
			ssz = write(bfd, a, sz);
			if (ssz != sz) {
				err = errno;
				perror(backend);
				goto out;
			}
			append -= sz;
		}
		err = fsync(bfd);
		if (err) {
			err = errno;
			perror(backend);
			goto out;
		}
	}

	err = ioctl(fd, LOOP_SET_CAPACITY, new);
	if (err) {
		err = errno;
		perror("ioctl LOOP_SET_CAPACITY");
	}
	goto out;

 err:
	usage(out);
 out:
	return err;
}

Signed-off-by: J. R. Okajima &lt;hooanon05@yahoo.co.jp&gt;
Signed-off-by: Tomas Matejicek &lt;tomas@slax.org&gt;
Cc: &lt;util-linux-ng@vger.kernel.org&gt;
Cc: Karel Zak &lt;kzak@redhat.com&gt;
Cc: Jens Axboe &lt;jens.axboe@oracle.com&gt;
Cc: Al Viro &lt;viro@zeniv.linux.org.uk&gt;
Cc: Christoph Hellwig &lt;hch@lst.de&gt;
Cc: Akinobu Mita &lt;akinobu.mita@gmail.com&gt;
Cc: &lt;linux-api@vger.kernel.org&gt;
Signed-off-by: Andrew Morton &lt;akpm@linux-foundation.org&gt;
Signed-off-by: Linus Torvalds &lt;torvalds@linux-foundation.org&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Add the ability to 'resize' the loop device on the fly.

One practical application is a loop file with XFS filesystem, already
mounted: You can easily enlarge the file (append some bytes) and then call
ioctl(fd, LOOP_SET_CAPACITY, new); The loop driver will learn about the
new size and you can use xfs_growfs later on, which will allow you to use
full capacity of the loop file without the need to unmount.

Test app:

#include &lt;linux/fs.h&gt;
#include &lt;linux/loop.h&gt;
#include &lt;sys/ioctl.h&gt;
#include &lt;sys/stat.h&gt;
#include &lt;sys/types.h&gt;
#include &lt;assert.h&gt;
#include &lt;errno.h&gt;
#include &lt;fcntl.h&gt;
#include &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;
#include &lt;unistd.h&gt;

#define _GNU_SOURCE
#include &lt;getopt.h&gt;

char *me;

void usage(FILE *f)
{
	fprintf(f, "%s [options] loop_dev [backend_file]\n"
		"-s, --set new_size_in_bytes\n"
		"\twhen backend_file is given, "
		"it will be expanded too while keeping the original contents\n",
		me);
}

struct option opts[] = {
	{
		.name		= "set",
		.has_arg	= 1,
		.flag		= NULL,
		.val		= 's'
	},
	{
		.name		= "help",
		.has_arg	= 0,
		.flag		= NULL,
		.val		= 'h'
	}
};

void err_size(char *name, __u64 old)
{
	fprintf(stderr, "size must be larger than current %s (%llu)\n",
		name, old);
}

int main(int argc, char *argv[])
{
	int fd, err, c, i, bfd;
	ssize_t ssz;
	size_t sz;
	__u64 old, new, append;
	char a[BUFSIZ];
	struct stat st;
	FILE *out;
	char *backend, *dev;

	err = EINVAL;
	out = stderr;
	me = argv[0];
	new = 0;
	while ((c = getopt_long(argc, argv, "s:h", opts, &amp;i)) != -1) {
		switch (c) {
		case 's':
			errno = 0;
			new = strtoull(optarg, NULL, 0);
			if (errno) {
				err = errno;
				perror(argv[i]);
				goto out;
			}
			break;

		case 'h':
			err = 0;
			out = stdout;
			goto err;

		default:
			perror(argv[i]);
			goto err;
		}
	}

	if (optind &lt; argc)
		dev = argv[optind++];
	else
		goto err;

	fd = open(dev, O_RDONLY);
	if (fd &lt; 0) {
		err = errno;
		perror(dev);
		goto out;
	}

	err = ioctl(fd, BLKGETSIZE64, &amp;old);
	if (err) {
		err = errno;
		perror("ioctl BLKGETSIZE64");
		goto out;
	}

	if (!new) {
		printf("%llu\n", old);
		goto out;
	}

	if (new &lt; old) {
		err = EINVAL;
		err_size(dev, old);
		goto out;
	}

	if (optind &lt; argc) {
		backend = argv[optind++];
		bfd = open(backend, O_WRONLY|O_APPEND);
		if (bfd &lt; 0) {
			err = errno;
			perror(backend);
			goto out;
		}
		err = fstat(bfd, &amp;st);
		if (err) {
			err = errno;
			perror(backend);
			goto out;
		}
		if (new &lt; st.st_size) {
			err = EINVAL;
			err_size(backend, st.st_size);
			goto out;
		}
		append = new - st.st_size;
		sz = sizeof(a);
		while (append &gt; 0) {
			if (append &lt; sz)
				sz = append;
			ssz = write(bfd, a, sz);
			if (ssz != sz) {
				err = errno;
				perror(backend);
				goto out;
			}
			append -= sz;
		}
		err = fsync(bfd);
		if (err) {
			err = errno;
			perror(backend);
			goto out;
		}
	}

	err = ioctl(fd, LOOP_SET_CAPACITY, new);
	if (err) {
		err = errno;
		perror("ioctl LOOP_SET_CAPACITY");
	}
	goto out;

 err:
	usage(out);
 out:
	return err;
}

Signed-off-by: J. R. Okajima &lt;hooanon05@yahoo.co.jp&gt;
Signed-off-by: Tomas Matejicek &lt;tomas@slax.org&gt;
Cc: &lt;util-linux-ng@vger.kernel.org&gt;
Cc: Karel Zak &lt;kzak@redhat.com&gt;
Cc: Jens Axboe &lt;jens.axboe@oracle.com&gt;
Cc: Al Viro &lt;viro@zeniv.linux.org.uk&gt;
Cc: Christoph Hellwig &lt;hch@lst.de&gt;
Cc: Akinobu Mita &lt;akinobu.mita@gmail.com&gt;
Cc: &lt;linux-api@vger.kernel.org&gt;
Signed-off-by: Andrew Morton &lt;akpm@linux-foundation.org&gt;
Signed-off-by: Linus Torvalds &lt;torvalds@linux-foundation.org&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>loop: fix circular locking in loop_clr_fd()</title>
<updated>2009-03-26T10:01:19+00:00</updated>
<author>
<name>Nikanth Karthikesan</name>
<email>knikanth@suse.de</email>
</author>
<published>2009-03-24T11:33:41+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux.git/commit/?id=f028f3b2f987ebc61cef382ab7a5c449917b728e'/>
<id>f028f3b2f987ebc61cef382ab7a5c449917b728e</id>
<content type='text'>
With CONFIG_PROVE_LOCKING enabled

$ losetup /dev/loop0 file
$ losetup -o 32256 /dev/loop1 /dev/loop0

$ losetup -d /dev/loop1
$ losetup -d /dev/loop0

triggers a [ INFO: possible circular locking dependency detected ]

I think this warning is a false positive.

Open/close on a loop device acquires bd_mutex of the device before
acquiring lo_ctl_mutex of the same device. For ioctl(LOOP_CLR_FD) after
acquiring lo_ctl_mutex, fput on the backing_file might acquire the bd_mutex of
a device, if backing file is a device and this is the last reference to the
file being dropped . But it is guaranteed that it is impossible to have a
circular list of backing devices.(say loop2-&gt;loop1-&gt;loop0-&gt;loop2 is not
possible), which guarantees that this can never deadlock.

So this warning should be suppressed. It is very difficult to annotate lockdep
not to warn here in the correct way. A simple way to silence lockdep could be
to mark the lo_ctl_mutex in ioctl to be a sub class, but this might mask some
other real bugs.

@@ -1164,7 +1164,7 @@ static int lo_ioctl(struct block_device *bdev, fmode_t mode,
 	struct loop_device *lo = bdev-&gt;bd_disk-&gt;private_data;
 	int err;

-	mutex_lock(&amp;lo-&gt;lo_ctl_mutex);
+	mutex_lock_nested(&amp;lo-&gt;lo_ctl_mutex, 1);
 	switch (cmd) {
 	case LOOP_SET_FD:
 		err = loop_set_fd(lo, mode, bdev, arg);

Or actually marking the bd_mutex after lo_ctl_mutex as a sub class could be
a better solution.

Luckily it is easy to avoid calling fput on backing file with lo_ctl_mutex
held, so no lockdep annotation is required.

If you do not like the special handling of the lo_ctl_mutex just for the
LOOP_CLR_FD ioctl in lo_ioctl(), the mutex handling could be moved inside
each of the individual ioctl handlers and I could send you another patch.

Signed-off-by: Jens Axboe &lt;jens.axboe@oracle.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
With CONFIG_PROVE_LOCKING enabled

$ losetup /dev/loop0 file
$ losetup -o 32256 /dev/loop1 /dev/loop0

$ losetup -d /dev/loop1
$ losetup -d /dev/loop0

triggers a [ INFO: possible circular locking dependency detected ]

I think this warning is a false positive.

Open/close on a loop device acquires bd_mutex of the device before
acquiring lo_ctl_mutex of the same device. For ioctl(LOOP_CLR_FD) after
acquiring lo_ctl_mutex, fput on the backing_file might acquire the bd_mutex of
a device, if backing file is a device and this is the last reference to the
file being dropped . But it is guaranteed that it is impossible to have a
circular list of backing devices.(say loop2-&gt;loop1-&gt;loop0-&gt;loop2 is not
possible), which guarantees that this can never deadlock.

So this warning should be suppressed. It is very difficult to annotate lockdep
not to warn here in the correct way. A simple way to silence lockdep could be
to mark the lo_ctl_mutex in ioctl to be a sub class, but this might mask some
other real bugs.

@@ -1164,7 +1164,7 @@ static int lo_ioctl(struct block_device *bdev, fmode_t mode,
 	struct loop_device *lo = bdev-&gt;bd_disk-&gt;private_data;
 	int err;

-	mutex_lock(&amp;lo-&gt;lo_ctl_mutex);
+	mutex_lock_nested(&amp;lo-&gt;lo_ctl_mutex, 1);
 	switch (cmd) {
 	case LOOP_SET_FD:
 		err = loop_set_fd(lo, mode, bdev, arg);

Or actually marking the bd_mutex after lo_ctl_mutex as a sub class could be
a better solution.

Luckily it is easy to avoid calling fput on backing file with lo_ctl_mutex
held, so no lockdep annotation is required.

If you do not like the special handling of the lo_ctl_mutex just for the
LOOP_CLR_FD ioctl in lo_ioctl(), the mutex handling could be moved inside
each of the individual ioctl handlers and I could send you another patch.

Signed-off-by: Jens Axboe &lt;jens.axboe@oracle.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>loop: support barrier writes</title>
<updated>2009-03-24T11:35:18+00:00</updated>
<author>
<name>Nikanth Karthikesan</name>
<email>knikanth@suse.de</email>
</author>
<published>2009-03-24T11:29:54+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux.git/commit/?id=68db1961bbf4e16c220ccec4a780e966bc1fece3'/>
<id>68db1961bbf4e16c220ccec4a780e966bc1fece3</id>
<content type='text'>
Honour barrier requests in the loop back block device driver.
In case of barrier bios, flush the backing file once before processing the
barrier and once after to guarantee ordering. In case of filesystems that
does not support fsync, barrier bios would be failed with -EOPNOTSUPP.

Signed-off-by: Nikanth Karthikesan &lt;knikanth@suse.de&gt;
Signed-off-by: Jens Axboe &lt;jens.axboe@oracle.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Honour barrier requests in the loop back block device driver.
In case of barrier bios, flush the backing file once before processing the
barrier and once after to guarantee ordering. In case of filesystems that
does not support fsync, barrier bios would be failed with -EOPNOTSUPP.

Signed-off-by: Nikanth Karthikesan &lt;knikanth@suse.de&gt;
Signed-off-by: Jens Axboe &lt;jens.axboe@oracle.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>loop: don't increment p-&gt;offset with (size_t) -EINVAL</title>
<updated>2009-03-05T11:04:57+00:00</updated>
<author>
<name>Roel Kluin</name>
<email>roel.kluin@gmail.com</email>
</author>
<published>2009-03-05T07:03:53+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux.git/commit/?id=a3941ec101a5ec54c1e929730afeb196441a171e'/>
<id>a3941ec101a5ec54c1e929730afeb196441a171e</id>
<content type='text'>
Upon a 'transfer error block' size is set to -EINVAL, but this becomes positive
since size is unsigned: p-&gt;offset still gets incremented.

Signed-off-by: Roel Kluin &lt;roel.kluin@gmail.com&gt;
Signed-off-by: Jens Axboe &lt;jens.axboe@oracle.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Upon a 'transfer error block' size is set to -EINVAL, but this becomes positive
since size is unsigned: p-&gt;offset still gets incremented.

Signed-off-by: Roel Kluin &lt;roel.kluin@gmail.com&gt;
Signed-off-by: Jens Axboe &lt;jens.axboe@oracle.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>loop: Do not call loop_unplug for not configured loop device.</title>
<updated>2008-12-29T07:29:52+00:00</updated>
<author>
<name>Milan Broz</name>
<email>mbroz@redhat.com</email>
</author>
<published>2008-12-12T13:50:49+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux.git/commit/?id=8ae30b895805a6e2bb725b1d78b12daabd7eadfe'/>
<id>8ae30b895805a6e2bb725b1d78b12daabd7eadfe</id>
<content type='text'>
In loop_unplug() function is expected that mapping is set
and lo-&gt;lo_backing_file is not NULL.

Unfortunately loop_set_fd() set the request queue unplug function,
but loop_clr_fd() doesn't clear that.

Loop device allows open of non-configured loop in some situations.
If the unplug on request queue is called, loop module oopses because
of missing lo_backing_file.

Simple reproducer:
	losetup /dev/loop0 /xxx
	losetup -d /dev/loop0
	dmsetup create x --table "0 1 linear /dev/loop0 0"

 EIP is at loop_unplug+0x1d/0x3b
 ...
  Call Trace:
   blk_unplug+0x57/0x5e
   dm_table_unplug_all+0x34/0x77 [dm_mod]
   destroy_inode+0x27/0x38
   generic_delete_inode+0xd5/0xd9
   iput+0x4b/0x4e
   dm_resume+0xca/0xfe [dm_mod]
   dev_suspend+0x143/0x165 [dm_mod]
   dm_ctl_ioctl+0x18e/0x1cf [dm_mod]
   dev_suspend+0x0/0x165 [dm_mod]
   dm_ctl_ioctl+0x0/0x1cf [dm_mod]
   vfs_ioctl+0x22/0x69
   do_vfs_ioctl+0x39d/0x3c7
   trace_hardirqs_on+0xb/0xd
   remove_vma+0x50/0x56
   do_munmap+0x21c/0x237
   sys_ioctl+0x2c/0x45
   sysenter_do_call+0x12/0x31

Several reports here
http://www.kerneloops.org/search.php?search=loop_unplug

Fix it by simply clear unplug function together with
removing of backing file.

Signed-off-by: Milan Broz &lt;mbroz@redhat.com&gt;
Signed-off-by: Jens Axboe &lt;jens.axboe@oracle.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
In loop_unplug() function is expected that mapping is set
and lo-&gt;lo_backing_file is not NULL.

Unfortunately loop_set_fd() set the request queue unplug function,
but loop_clr_fd() doesn't clear that.

Loop device allows open of non-configured loop in some situations.
If the unplug on request queue is called, loop module oopses because
of missing lo_backing_file.

Simple reproducer:
	losetup /dev/loop0 /xxx
	losetup -d /dev/loop0
	dmsetup create x --table "0 1 linear /dev/loop0 0"

 EIP is at loop_unplug+0x1d/0x3b
 ...
  Call Trace:
   blk_unplug+0x57/0x5e
   dm_table_unplug_all+0x34/0x77 [dm_mod]
   destroy_inode+0x27/0x38
   generic_delete_inode+0xd5/0xd9
   iput+0x4b/0x4e
   dm_resume+0xca/0xfe [dm_mod]
   dev_suspend+0x143/0x165 [dm_mod]
   dm_ctl_ioctl+0x18e/0x1cf [dm_mod]
   dev_suspend+0x0/0x165 [dm_mod]
   dm_ctl_ioctl+0x0/0x1cf [dm_mod]
   vfs_ioctl+0x22/0x69
   do_vfs_ioctl+0x39d/0x3c7
   trace_hardirqs_on+0xb/0xd
   remove_vma+0x50/0x56
   do_munmap+0x21c/0x237
   sys_ioctl+0x2c/0x45
   sysenter_do_call+0x12/0x31

Several reports here
http://www.kerneloops.org/search.php?search=loop_unplug

Fix it by simply clear unplug function together with
removing of backing file.

Signed-off-by: Milan Broz &lt;mbroz@redhat.com&gt;
Signed-off-by: Jens Axboe &lt;jens.axboe@oracle.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>loop: Flush possible running bios when loop device is released.</title>
<updated>2008-12-29T07:29:52+00:00</updated>
<author>
<name>Milan Broz</name>
<email>mbroz@redhat.com</email>
</author>
<published>2008-12-12T13:48:27+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux.git/commit/?id=14f2793958bd7878db2dc0309ed4525d6b7f1b72'/>
<id>14f2793958bd7878db2dc0309ed4525d6b7f1b72</id>
<content type='text'>
When there are still queued bios and reference count
drops to zero, loop device must flush all queued bios.

Otherwise it can lead to situation that caller
closes the device, but some bios are still running
and endio() function call later OOpses when uses
unallocated mempool.

This happens for example when running dm-crypt over loop,
here is typical oops backtrace:

 Oops: 0000 [#1] PREEMPT SMP
 EIP is at mempool_free+0x12/0x6b
...
 crypt_dec_pending+0x50/0x54 [dm_crypt]
 crypt_endio+0x9f/0xa7 [dm_crypt]
 crypt_endio+0x0/0xa7 [dm_crypt]
 bio_endio+0x2b/0x2e
 loop_thread+0x37a/0x3b1
 do_lo_send_aops+0x0/0x165
 autoremove_wake_function+0x0/0x33
 loop_thread+0x0/0x3b1
 kthread+0x3b/0x61
 kthread+0x0/0x61
 kernel_thread_helper+0x7/0x10

(But crash is reproducible with different dm targets
running over loop device too.)

Patch fixes it by flushing the bios in release call,
reusing the flush mechanism for switching backing store.

Signed-off-by: Milan Broz &lt;mbroz@redhat.com&gt;
Signed-off-by: Jens Axboe &lt;jens.axboe@oracle.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
When there are still queued bios and reference count
drops to zero, loop device must flush all queued bios.

Otherwise it can lead to situation that caller
closes the device, but some bios are still running
and endio() function call later OOpses when uses
unallocated mempool.

This happens for example when running dm-crypt over loop,
here is typical oops backtrace:

 Oops: 0000 [#1] PREEMPT SMP
 EIP is at mempool_free+0x12/0x6b
...
 crypt_dec_pending+0x50/0x54 [dm_crypt]
 crypt_endio+0x9f/0xa7 [dm_crypt]
 crypt_endio+0x0/0xa7 [dm_crypt]
 bio_endio+0x2b/0x2e
 loop_thread+0x37a/0x3b1
 do_lo_send_aops+0x0/0x165
 autoremove_wake_function+0x0/0x33
 loop_thread+0x0/0x3b1
 kthread+0x3b/0x61
 kthread+0x0/0x61
 kernel_thread_helper+0x7/0x10

(But crash is reproducible with different dm targets
running over loop device too.)

Patch fixes it by flushing the bios in release call,
reusing the flush mechanism for switching backing store.

Signed-off-by: Milan Broz &lt;mbroz@redhat.com&gt;
Signed-off-by: Jens Axboe &lt;jens.axboe@oracle.com&gt;
</pre>
</div>
</content>
</entry>
</feed>
