fix for loop device

Matthew Wilcox (willy@odie.barnet.ac.uk)
Wed, 24 Jun 1998 12:35:01 +0100 (BST)


This patch isn't intended to fix the lockups; it fixes the problem with
being able to unmount a device which has an open loop device on it.

P.S.
I haven't heard anything from linux-kernel for the last day.. should I
be worried?

Matthew Wilcox

diff -ur linux-2.1.105/drivers/block/loop.c linux/drivers/block/loop.c
--- linux-2.1.105/drivers/block/loop.c Wed Jun 24 10:35:12 1998
+++ linux/drivers/block/loop.c Wed Jun 24 10:26:21 1998
@@ -166,8 +166,8 @@
{
int size;

- if (S_ISREG(lo->lo_inode->i_mode))
- size = (lo->lo_inode->i_size - lo->lo_offset) / BLOCK_SIZE;
+ if (S_ISREG(lo->lo_dentry->d_inode->i_mode))
+ size = (lo->lo_dentry->d_inode->i_size - lo->lo_offset) / BLOCK_SIZE;
else {
kdev_t lodev = lo->lo_device;
if (blk_size[MAJOR(lodev)])
@@ -195,7 +195,7 @@
if (MINOR(current_request->rq_dev) >= MAX_LOOP)
goto error_out;
lo = &loop_dev[MINOR(current_request->rq_dev)];
- if (!lo->lo_inode || !lo->transfer)
+ if (!lo->lo_dentry || !lo->transfer)
goto error_out;

blksize = BLOCK_SIZE;
@@ -232,7 +232,7 @@
while (len > 0) {
real_block = block;
if (lo->lo_flags & LO_FLAGS_DO_BMAP) {
- real_block = bmap(lo->lo_inode, block);
+ real_block = bmap(lo->lo_dentry->d_inode, block);
if (!real_block) {
printk("loop: block %d not present\n", block);
goto error_out;
@@ -292,15 +292,16 @@
int error;

MOD_INC_USE_COUNT;
+
+ error = -EBUSY;
+ if (lo->lo_dentry)
+ goto out;
+
error = -EBADF;
file = fget(arg);
if (!file)
goto out;

- error = -EBUSY;
- if (lo->lo_inode)
- goto out_putf;
-
error = -EINVAL;
inode = file->f_dentry->d_inode;
if (!inode) {
@@ -328,9 +329,8 @@
set_device_ro(dev, 0);
}

- /* N.B. Should keep the file or dentry ... */
- inode->i_count++;
- lo->lo_inode = inode;
+ lo->lo_dentry = file->f_dentry;
+ lo->lo_dentry->d_count++;
lo->transfer = NULL;
figure_loop_size(lo);

@@ -344,17 +344,17 @@

static int loop_clr_fd(struct loop_device *lo, kdev_t dev)
{
- struct inode *inode = lo->lo_inode;
+ struct dentry *dentry = lo->lo_dentry;

- if (!inode)
+ if (!dentry)
return -ENXIO;
if (lo->lo_refcnt > 1) /* we needed one fd for the ioctl */
return -EBUSY;

- if (S_ISBLK(inode->i_mode))
- blkdev_release (inode);
- lo->lo_inode = NULL;
- iput(inode);
+ if (S_ISBLK(dentry->d_inode->i_mode))
+ blkdev_release (dentry->d_inode);
+ lo->lo_dentry = NULL;
+ dput(dentry);
lo->lo_device = 0;
lo->lo_encrypt_type = 0;
lo->lo_offset = 0;
@@ -372,7 +372,7 @@
struct loop_info info;
int err;

- if (!lo->lo_inode)
+ if (!lo->lo_dentry)
return -ENXIO;
if (!arg)
return -EINVAL;
@@ -432,7 +432,7 @@
struct loop_info info;
int err;

- if (!lo->lo_inode)
+ if (!lo->lo_dentry)
return -ENXIO;
if (!arg)
return -EINVAL;
@@ -441,8 +441,8 @@
return err;
memset(&info, 0, sizeof(info));
info.lo_number = lo->lo_number;
- info.lo_device = kdev_t_to_nr(lo->lo_inode->i_dev);
- info.lo_inode = lo->lo_inode->i_ino;
+ info.lo_device = kdev_t_to_nr(lo->lo_dentry->d_inode->i_dev);
+ info.lo_inode = lo->lo_dentry->d_inode->i_ino;
info.lo_rdevice = kdev_t_to_nr(lo->lo_device);
info.lo_offset = lo->lo_offset;
info.lo_flags = lo->lo_flags;
@@ -483,7 +483,7 @@
case LOOP_GET_STATUS:
return loop_get_status(lo, (struct loop_info *) arg);
case BLKGETSIZE: /* Return device size */
- if (!lo->lo_inode)
+ if (!lo->lo_dentry)
return -ENXIO;
if (!arg)
return -EINVAL;
diff -ur linux-2.1.105/include/linux/loop.h linux/include/linux/loop.h
--- linux-2.1.105/include/linux/loop.h Mon Jul 1 17:06:05 1996
+++ linux/include/linux/loop.h Wed Jun 24 10:07:33 1998
@@ -17,7 +17,7 @@

struct loop_device {
int lo_number;
- struct inode *lo_inode;
+ struct dentry *lo_dentry;
int lo_refcnt;
kdev_t lo_device;
int lo_offset;

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu