lkml.org 
[lkml]   [2001]   [Oct]   [3]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
Date
From
Subject[PATCH] Re: bug? in using generic read/write functions to read/write block devices in 2.4.11-pre2


On Wed, 3 Oct 2001, Vladimir V. Saveliev wrote:

> Hi
>
> It looks like something wrong happens with writing/reading to block
> device using generic read/write functions when one does:
>
> mke2fs /dev/hda1 (blocksize is 4096)
> mount /dev/hda1
> umount /dev/hda1
> mke2fs /dev/hda1 - FAILS with
> Warning: could not write 8 blocks in inode table starting at 492004:
> Attempt to write block from filesystem resulted in short write
>
> (note that /dev/hda1 should be big enough - 3gb is enogh for example)

Ehh... Linus, both blkdev_get() and blkdev_open() should set ->i_blkbits.
Vladimir, see if the patch below helps:

--- S11-pre2/fs/block_dev.c Mon Oct 1 17:56:00 2001
+++ /tmp/block_dev.c Wed Oct 3 09:12:31 2001
@@ -549,36 +549,23 @@
return res;
}

-int blkdev_get(struct block_device *bdev, mode_t mode, unsigned flags, int kind)
+static int do_open(struct block_device *bdev, struct inode *inode, struct file *file)
{
- int ret = -ENODEV;
- kdev_t rdev = to_kdev_t(bdev->bd_dev); /* this should become bdev */
- down(&bdev->bd_sem);
+ int ret = -ENXIO;
+ kdev_t dev = to_kdev_t(bdev->bd_dev);

+ down(&bdev->bd_sem);
lock_kernel();
if (!bdev->bd_op)
- bdev->bd_op = get_blkfops(MAJOR(rdev));
+ bdev->bd_op = get_blkfops(MAJOR(dev));
if (bdev->bd_op) {
- /*
- * This crockload is due to bad choice of ->open() type.
- * It will go away.
- * For now, block device ->open() routine must _not_
- * examine anything in 'inode' argument except ->i_rdev.
- */
- struct file fake_file = {};
- struct dentry fake_dentry = {};
- ret = -ENOMEM;
- fake_file.f_mode = mode;
- fake_file.f_flags = flags;
- fake_file.f_dentry = &fake_dentry;
- fake_dentry.d_inode = bdev->bd_inode;
ret = 0;
if (bdev->bd_op->open)
- ret = bdev->bd_op->open(bdev->bd_inode, &fake_file);
+ ret = bdev->bd_op->open(inode, file);
if (!ret) {
bdev->bd_openers++;
- bdev->bd_inode->i_size = blkdev_size(rdev);
- bdev->bd_inode->i_blkbits = blksize_bits(block_size(rdev));
+ bdev->bd_inode->i_size = blkdev_size(dev);
+ bdev->bd_inode->i_blkbits = blksize_bits(block_size(dev));
} else if (!bdev->bd_openers)
bdev->bd_op = NULL;
}
@@ -589,9 +576,26 @@
return ret;
}

+int blkdev_get(struct block_device *bdev, mode_t mode, unsigned flags, int kind)
+{
+ /*
+ * This crockload is due to bad choice of ->open() type.
+ * It will go away.
+ * For now, block device ->open() routine must _not_
+ * examine anything in 'inode' argument except ->i_rdev.
+ */
+ struct file fake_file = {};
+ struct dentry fake_dentry = {};
+ fake_file.f_mode = mode;
+ fake_file.f_flags = flags;
+ fake_file.f_dentry = &fake_dentry;
+ fake_dentry.d_inode = bdev->bd_inode;
+
+ return do_open(bdev, bdev->bd_inode, &fake_file);
+}
+
int blkdev_open(struct inode * inode, struct file * filp)
{
- int ret;
struct block_device *bdev;

/*
@@ -604,29 +608,8 @@

bd_acquire(inode);
bdev = inode->i_bdev;
- down(&bdev->bd_sem);
-
- ret = -ENXIO;
- lock_kernel();
- if (!bdev->bd_op)
- bdev->bd_op = get_blkfops(MAJOR(inode->i_rdev));

- if (bdev->bd_op) {
- ret = 0;
- if (bdev->bd_op->open)
- ret = bdev->bd_op->open(inode,filp);
- if (!ret) {
- bdev->bd_openers++;
- bdev->bd_inode->i_size = blkdev_size(inode->i_rdev);
- } else if (!bdev->bd_openers)
- bdev->bd_op = NULL;
- }
-
- unlock_kernel();
- up(&bdev->bd_sem);
- if (ret)
- bdput(bdev);
- return ret;
+ return do_open(bdev, inode, filp);
}

int blkdev_put(struct block_device *bdev, int kind)
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/

\
 
 \ /
  Last update: 2005-03-22 13:03    [W:0.087 / U:0.728 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site