Commit 836d901c authored by Alexander Viro's avatar Alexander Viro Committed by James Bottomley

[PATCH] nftl

	* switched to private queues
	* set ->queue and ->private_data
	* switched to use of ->bd_disk and ->rq_disk
	* fixed the problem with request_module() from open()
	* cleaned up
parent e8782ed7
...@@ -49,6 +49,8 @@ ...@@ -49,6 +49,8 @@
struct NFTLrecord *NFTLs[MAX_NFTLS]; struct NFTLrecord *NFTLs[MAX_NFTLS];
static struct request_queue nftl_queue;
static void NFTL_setup(struct mtd_info *mtd) static void NFTL_setup(struct mtd_info *mtd)
{ {
int i; int i;
...@@ -134,6 +136,8 @@ static void NFTL_setup(struct mtd_info *mtd) ...@@ -134,6 +136,8 @@ static void NFTL_setup(struct mtd_info *mtd)
gd->first_minor = firstfree << NFTL_PARTN_BITS; gd->first_minor = firstfree << NFTL_PARTN_BITS;
set_capacity(gd, nftl->nr_sects); set_capacity(gd, nftl->nr_sects);
nftl->disk = gd; nftl->disk = gd;
gd->private_data = nftl;
gd->queue = &nftl_queue;
add_disk(gd); add_disk(gd);
} }
...@@ -752,13 +756,7 @@ static int NFTL_readblock(struct NFTLrecord *nftl, unsigned block, char *buffer) ...@@ -752,13 +756,7 @@ static int NFTL_readblock(struct NFTLrecord *nftl, unsigned block, char *buffer)
static int nftl_ioctl(struct inode * inode, struct file * file, unsigned int cmd, unsigned long arg) static int nftl_ioctl(struct inode * inode, struct file * file, unsigned int cmd, unsigned long arg)
{ {
struct NFTLrecord *nftl; struct NFTLrecord *nftl = inode->i_bdev->bd_disk->private_data;
int res;
nftl = NFTLs[minor(inode->i_rdev) >> NFTL_PARTN_BITS];
if (!nftl) return -EINVAL;
switch (cmd) { switch (cmd) {
case HDIO_GETGEO: { case HDIO_GETGEO: {
struct hd_geometry g; struct hd_geometry g;
...@@ -780,23 +778,19 @@ static int nftl_ioctl(struct inode * inode, struct file * file, unsigned int cmd ...@@ -780,23 +778,19 @@ static int nftl_ioctl(struct inode * inode, struct file * file, unsigned int cmd
} }
} }
void nftl_request(RQFUNC_ARG) void nftl_request(struct request_queue *q)
{ {
unsigned int dev, unit, block, nsect; while (!blk_queue_empty(q)) {
struct NFTLrecord *nftl; struct request *req = elv_next_request(q);
char *buffer; unsigned block = req->sector;
struct request *req; unsigned nsect = req->current_nr_sectors;
int res; char *buffer = req->buffer;
struct NFTLrecord *nftl = req->rq_disk->private_data;
while (1) { int res = 1; /* succeed */
if (blk_queue_empty(QUEUE))
return;
req = CURRENT;
/* We can do this because the generic code knows not to /* We can do this because the generic code knows not to
touch the request at the head of the queue */ touch the request at the head of the queue */
spin_unlock_irq(QUEUE->queue_lock); spin_unlock_irq(q->queue_lock);
DEBUG(MTD_DEBUG_LEVEL2, "NFTL_request\n"); DEBUG(MTD_DEBUG_LEVEL2, "NFTL_request\n");
DEBUG(MTD_DEBUG_LEVEL3, DEBUG(MTD_DEBUG_LEVEL3,
...@@ -804,29 +798,14 @@ void nftl_request(RQFUNC_ARG) ...@@ -804,29 +798,14 @@ void nftl_request(RQFUNC_ARG)
(req->cmd == READ) ? "Read " : "Write", (req->cmd == READ) ? "Read " : "Write",
(unsigned long long)req->sector, req->current_nr_sectors); (unsigned long long)req->sector, req->current_nr_sectors);
dev = minor(req->rq_dev);
block = req->sector;
nsect = req->current_nr_sectors;
buffer = req->buffer;
res = 1; /* succeed */
unit = dev >> NFTL_PARTN_BITS;
if (unit >= MAX_NFTLS || dev != (unit << NFTL_PARTN_BITS)) {
printk("nftl: bad minor number: device = %s\n",
kdevname(req->rq_dev));
res = 0; /* fail */
goto repeat;
}
nftl = NFTLs[dev / (1<<NFTL_PARTN_BITS)];
DEBUG(MTD_DEBUG_LEVEL3, "Waiting for mutex\n"); DEBUG(MTD_DEBUG_LEVEL3, "Waiting for mutex\n");
down(&nftl->mutex); down(&nftl->mutex);
DEBUG(MTD_DEBUG_LEVEL3, "Got mutex\n"); DEBUG(MTD_DEBUG_LEVEL3, "Got mutex\n");
if (block + nsect > get_capacity(nftl->disk)) { if (block + nsect > get_capacity(nftl->disk)) {
/* access past the end of device */ /* access past the end of device */
printk("nftl%c%d: bad access: block = %d, count = %d\n", printk("%s: bad access: block = %d, count = %d\n",
unit+'a', dev & 0xf, block, nsect); nftl->disk->disk_name, block, nsect);
up(&nftl->mutex); up(&nftl->mutex);
res = 0; /* fail */ res = 0; /* fail */
goto repeat; goto repeat;
...@@ -877,30 +856,24 @@ void nftl_request(RQFUNC_ARG) ...@@ -877,30 +856,24 @@ void nftl_request(RQFUNC_ARG)
} }
repeat: repeat:
DEBUG(MTD_DEBUG_LEVEL3, "end_request(%d)\n", res); DEBUG(MTD_DEBUG_LEVEL3, "end_request(%d)\n", res);
spin_lock_irq(QUEUE->queue_lock); spin_lock_irq(q->queue_lock);
end_request(CURRENT, res); end_request(req, res);
} }
} }
static struct gendisk *nftl_probe(dev_t dev, int *part, void *data)
{
request_module("docprobe");
return NULL;
}
static int nftl_open(struct inode *ip, struct file *fp) static int nftl_open(struct inode *ip, struct file *fp)
{ {
int nftlnum = minor(ip->i_rdev) >> NFTL_PARTN_BITS; struct NFTLrecord *thisNFTL = ip->i_bdev->bd_disk->private_data;
struct NFTLrecord *thisNFTL;
thisNFTL = NFTLs[nftlnum];
DEBUG(MTD_DEBUG_LEVEL2,"NFTL_open\n"); DEBUG(MTD_DEBUG_LEVEL2,"NFTL_open\n");
if (!thisNFTL)
#ifdef CONFIG_KMOD
if (!thisNFTL && nftlnum == 0) {
request_module("docprobe");
thisNFTL = NFTLs[nftlnum];
}
#endif
if (!thisNFTL) {
DEBUG(MTD_DEBUG_LEVEL2,"ENODEV: thisNFTL = %d, minor = %d, ip = %p, fp = %p\n",
nftlnum, minor(ip->i_rdev), ip, fp);
return -ENODEV; return -ENODEV;
}
#ifndef CONFIG_NFTL_RW #ifndef CONFIG_NFTL_RW
if (fp->f_mode & FMODE_WRITE) if (fp->f_mode & FMODE_WRITE)
...@@ -915,9 +888,7 @@ static int nftl_open(struct inode *ip, struct file *fp) ...@@ -915,9 +888,7 @@ static int nftl_open(struct inode *ip, struct file *fp)
static int nftl_release(struct inode *inode, struct file *fp) static int nftl_release(struct inode *inode, struct file *fp)
{ {
struct NFTLrecord *thisNFTL; struct NFTLrecord *thisNFTL = inode->i_bdev->bd_disk->private_data;
thisNFTL = NFTLs[minor(inode->i_rdev) / 16];
DEBUG(MTD_DEBUG_LEVEL2, "NFTL_release\n"); DEBUG(MTD_DEBUG_LEVEL2, "NFTL_release\n");
...@@ -930,10 +901,10 @@ static int nftl_release(struct inode *inode, struct file *fp) ...@@ -930,10 +901,10 @@ static int nftl_release(struct inode *inode, struct file *fp)
} }
static struct block_device_operations nftl_fops = static struct block_device_operations nftl_fops =
{ {
owner: THIS_MODULE, .owner = THIS_MODULE,
open: nftl_open, .open = nftl_open,
release: nftl_release, .release = nftl_release,
ioctl: nftl_ioctl .ioctl = nftl_ioctl
}; };
/**************************************************************************** /****************************************************************************
...@@ -957,11 +928,15 @@ int __init init_nftl(void) ...@@ -957,11 +928,15 @@ int __init init_nftl(void)
printk(KERN_INFO "NFTL driver: nftlcore.c $Revision: 1.82 $, nftlmount.c %s\n", nftlmountrev); printk(KERN_INFO "NFTL driver: nftlcore.c $Revision: 1.82 $, nftlmount.c %s\n", nftlmountrev);
#endif #endif
if (register_blkdev(MAJOR_NR, "nftl", &nftl_fops)){ if (register_blkdev(MAJOR_NR, "nftl", &nftl_fops)) {
printk("unable to register NFTL block device on major %d\n", MAJOR_NR); printk("unable to register NFTL block device on major %d\n", MAJOR_NR);
return -EBUSY; return -EBUSY;
} }
blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), &nftl_request, &nftl_lock);
blk_register_region(MKDEV(MAJOR_NR, 0), 256,
THIS_MODULE, nftl_probe, NULL, NULL);
blk_init_queue(&nftl_queue, &nftl_request, &nftl_lock);
register_mtd_user(&nftl_notifier); register_mtd_user(&nftl_notifier);
...@@ -971,8 +946,9 @@ int __init init_nftl(void) ...@@ -971,8 +946,9 @@ int __init init_nftl(void)
static void __exit cleanup_nftl(void) static void __exit cleanup_nftl(void)
{ {
unregister_mtd_user(&nftl_notifier); unregister_mtd_user(&nftl_notifier);
blk_unregister_region(MKDEV(MAJOR_NR, 0), 256);
unregister_blkdev(MAJOR_NR, "nftl"); unregister_blkdev(MAJOR_NR, "nftl");
blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR)); blk_cleanup_queue(&nftl_queue);
} }
module_init(init_nftl); module_init(init_nftl);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment