#include <linux/module.h>
#include <linux/major.h>
#include <linux/smp.h>
+#include <linux/hdreg.h>
#define DEBUG_SUBSYSTEM S_PTLBD
-#include <linux/lustre_lite.h>
#include <linux/lustre_ha.h>
#include <linux/obd_support.h>
#include <linux/lustre_idl.h>
struct ptlbd_obd *ptlbd = ptlbd_get_inode(inode);
ENTRY;
+
if ( IS_ERR(ptlbd) )
RETURN(PTR_ERR(ptlbd));
- if ( ptlbd->bd_import.imp_connection == NULL )
- RETURN(-ENODEV);
+
+ if (! ptlbd->bd_import->imp_remote_handle.cookie)
+ if (ptlbd_do_connect(ptlbd))
+ RETURN(-ENOTCONN);
ptlbd->refcount++;
RETURN(0);
}
+
static int ptlbd_ioctl(struct inode *inode, struct file *file,
unsigned int cmd, unsigned long arg)
{
struct ptlbd_obd *ptlbd;
int ret;
+ __u16 major, minor, dev;
+ struct hd_geometry geo;
if ( ! capable(CAP_SYS_ADMIN) )
RETURN(-EPERM);
if ( IS_ERR(ptlbd) )
RETURN( PTR_ERR(ptlbd) );
+ major = MAJOR(inode->i_rdev);
+ minor = MINOR(inode->i_rdev);
+ dev = inode->i_rdev;
+
switch(cmd) {
+ case HDIO_GETGEO:
+ geo.heads = 64;
+ geo.sectors = 32;
+ geo.start = 4;
+ geo.cylinders = blk_size[major][minor]/
+ (geo.heads * geo.sectors);
+ if (copy_to_user((void *) arg, &geo, sizeof(geo)))
+ ret = -EFAULT;
+ else
+ ret = 0;
+ break;
+
+ case BLKSECTGET:
+ ret = copy_to_user((void *) arg,
+ & max_sectors[major][minor], sizeof(arg));
+ break;
+
case BLKFLSBUF:
- ret = blk_ioctl(inode->i_rdev, cmd, arg);
+ ret = blk_ioctl(dev, cmd, arg);
+ ptlbd_send_flush_req(ptlbd, PTLBD_FLUSH);
break;
+
+ case BLKGETSIZE:
+ case BLKGETSIZE64:
+ case BLKROSET:
+ case BLKROGET:
+ case BLKRASET:
+ case BLKRAGET:
+ case BLKSSZGET:
+ case BLKELVGET:
+ case BLKELVSET:
default:
+ ret = blk_ioctl(dev, cmd, arg);
+ break;
+
+ case BLKSECTSET: /* don't allow setting of max_sectors */
+
+ case BLKRRPART: /* not a partitionable device */
+ case BLKPG: /* "" */
ret = -EINVAL;
break;
}
if ( IS_ERR(ptlbd) )
RETURN( PTR_ERR(ptlbd) );
- ptlbd->refcount--;
+ if (--ptlbd->refcount == 0)
+ ptlbd_do_disconnect(ptlbd);
+
RETURN(0);
}
struct ptlbd_obd *ptlbd;
struct request *req;
ptlbd_cmd_t cmd;
+ int errors = 0;
ENTRY;
while ( !QUEUE_EMPTY ) {
spin_unlock_irq(&io_request_lock);
- /* XXX dunno if we're supposed to get this or not.. */
- LASSERT(req->cmd != READA);
-
if ( req->cmd == READ )
cmd = PTLBD_READ;
else
cmd = PTLBD_WRITE;
- ptlbd_send_req(ptlbd, cmd, req->bh);
+ errors = ptlbd_send_rw_req(ptlbd, cmd, req->bh);
spin_lock_irq(&io_request_lock);
+ if (errors)
+ req->errors += errors;
+
ptlbd_end_request_havelock(req);
}
}
static struct block_device_operations ptlbd_ops = {
- .owner = THIS_MODULE,
- .open = ptlbd_open,
+ .owner = THIS_MODULE,
+ .open = ptlbd_open,
+ .ioctl = ptlbd_ioctl,
.release = ptlbd_release,
- .ioctl = ptlbd_ioctl,
};
int ptlbd_blk_init(void)
blksize_size[PTLBD_MAJOR] = ptlbd_size_size;
hardsect_size[PTLBD_MAJOR] = ptlbd_hardsect_size;
max_sectors[PTLBD_MAJOR] = ptlbd_max_sectors;
- //RHism blkdev_varyio[PTLBD_MAJOR] = ptlbd_dev_varyio;
blk_init_queue(BLK_DEFAULT_QUEUE(PTLBD_MAJOR), ptlbd_request);
blk_queue_headactive(BLK_DEFAULT_QUEUE(MAJOR_NR), 0);
for ( i = 0 ; i < PTLBD_MAX_MINOR ; i++) {
ptlbd_size_size[i] = 4096;
- ptlbd_size[i] = (4096*2048) >> BLOCK_SIZE_BITS;
+ /* avoid integer overflow */
+ ptlbd_size[i] = (16*1024*((1024*1024) >> BLOCK_SIZE_BITS));
ptlbd_hardsect_size[i] = 4096;
- ptlbd_max_sectors[i] = 2;
- //RHism ptlbd_dev_varyio[i] = 0;
- /* XXX register_disk? */
+ ptlbd_max_sectors[i] = PTLRPC_MAX_BRW_PAGES * (4096/512);
}
return 0;
void ptlbd_blk_exit(void)
{
- int ret;
ENTRY;
blk_cleanup_queue(BLK_DEFAULT_QUEUE(PTLBD_MAJOR));
- ret = unregister_blkdev(PTLBD_MAJOR, "ptlbd");
- if ( ret ) /* XXX */
- printk("unregister_blkdev() failed: %d\n", ret);
+ unregister_blkdev(PTLBD_MAJOR, "ptlbd");
}
#undef MAJOR_NR