1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2 * vim:expandtab:shiftwidth=8:tabstop=8:
4 * Copyright (c) 2002 Cluster File Systems, Inc.
6 * This file is part of Lustre, http://www.lustre.org.
8 * Lustre is free software; you can redistribute it and/or
9 * modify it under the terms of version 2 of the GNU General Public
10 * License as published by the Free Software Foundation.
12 * Lustre is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with Lustre; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 #include <linux/module.h>
22 #include <linux/major.h>
23 #include <linux/smp.h>
25 #define DEBUG_SUBSYSTEM S_PTLBD
27 #include <linux/lustre_lite.h>
28 #include <linux/lustre_ha.h>
29 #include <linux/obd_support.h>
30 #include <linux/lustre_idl.h>
31 #include <linux/obd_ptlbd.h>
35 * assign proper major number
37 * discover actual block sizes?
38 * allow more than one sector per io
40 * restrict single ops to sequential block io
41 * ddn target addresses need to be 32 bit
42 * cant get to addresses after 0xFFFF0000
45 #define PTLBD_MAJOR 253
46 #define PTLBD_MAX_MINOR 1
48 #define MAJOR_NR PTLBD_MAJOR
49 #define LOCAL_END_REQUEST
50 #include <linux/blk.h>
51 #include <linux/blkdev.h>
52 #include <linux/devfs_fs_kernel.h>
54 static int ptlbd_size_size[PTLBD_MAX_MINOR];
55 static int ptlbd_size[PTLBD_MAX_MINOR];
56 static int ptlbd_hardsect_size[PTLBD_MAX_MINOR];
57 static int ptlbd_max_sectors[PTLBD_MAX_MINOR];
58 //RHism static char ptlbd_dev_varyio[PTLBD_MAX_MINOR];
61 * per minor state, indexed by minor.
64 static struct ptlbd_obd *one_for_now;
66 void ptlbd_blk_register(struct ptlbd_obd *ptlbd)
73 static struct ptlbd_obd * ptlbd_get_minor(int minor)
76 if ( minor >= PTLBD_MAX_MINOR )
77 RETURN( ERR_PTR(-ENODEV) );
81 static struct ptlbd_obd * ptlbd_get_inode(struct inode *inode)
85 if ( inode == NULL ) /* can this really happen? */
86 RETURN( ERR_PTR(-EINVAL) );
88 return ptlbd_get_minor(MINOR(inode->i_rdev));
91 static int ptlbd_open(struct inode *inode, struct file *file)
93 struct ptlbd_obd *ptlbd = ptlbd_get_inode(inode);
97 RETURN(PTR_ERR(ptlbd));
98 if ( ptlbd->bd_import.imp_connection == NULL )
105 static int ptlbd_ioctl(struct inode *inode, struct file *file,
106 unsigned int cmd, unsigned long arg)
108 struct ptlbd_obd *ptlbd;
110 if ( ! capable(CAP_SYS_ADMIN) )
113 ptlbd = ptlbd_get_inode(inode);
115 RETURN( PTR_ERR(ptlbd) );
117 /* XXX getattr{,64} */
122 static int ptlbd_release(struct inode *inode, struct file *file)
124 struct ptlbd_obd *ptlbd = ptlbd_get_inode(inode);
128 RETURN( PTR_ERR(ptlbd) );
134 static void ptlbd_end_request_havelock(struct request *req)
136 struct buffer_head *bh;
142 while( (bh = req->bh) != NULL ) {
143 blk_finished_io(bh->b_size >> 9);
144 req->bh = bh->b_reqnext;
145 bh->b_reqnext = NULL;
146 bh->b_end_io(bh, uptodate);
148 blkdev_release_request(req);
152 static void ptlbd_end_request_getlock(struct request *req)
156 spin_lock_irqsave(&io_request_lock, flags);
157 ptlbd_end_request_havelock(req);
158 spin_unlock_irqrestore(&io_request_lock, flags);
162 static void ptlbd_request(request_queue_t *q)
164 struct ptlbd_obd *ptlbd;
169 while ( !QUEUE_EMPTY ) {
171 ptlbd = ptlbd_get_minor(MINOR(req->rq_dev));
173 blkdev_dequeue_request(req);
175 if ( ptlbd->refcount <= 0 ) {
177 ptlbd_end_request_havelock(req);
181 spin_unlock_irq(&io_request_lock);
183 /* XXX dunno if we're supposed to get this or not.. */
184 LASSERT(req->cmd != READA);
186 if ( req->cmd == READ )
191 ptlbd_send_req(ptlbd, cmd, req->bh);
193 spin_lock_irq(&io_request_lock);
195 ptlbd_end_request_havelock(req);
199 static struct block_device_operations ptlbd_ops = {
200 .owner = THIS_MODULE,
202 .release = ptlbd_release,
203 .ioctl = ptlbd_ioctl,
206 int ptlbd_blk_init(void)
212 ret = register_blkdev(PTLBD_MAJOR, "ptlbd", &ptlbd_ops);
216 blk_size[PTLBD_MAJOR] = ptlbd_size;
217 blksize_size[PTLBD_MAJOR] = ptlbd_size_size;
218 hardsect_size[PTLBD_MAJOR] = ptlbd_hardsect_size;
219 max_sectors[PTLBD_MAJOR] = ptlbd_max_sectors;
220 //RHism blkdev_varyio[PTLBD_MAJOR] = ptlbd_dev_varyio;
222 blk_init_queue(BLK_DEFAULT_QUEUE(PTLBD_MAJOR), ptlbd_request);
223 blk_queue_headactive(BLK_DEFAULT_QUEUE(MAJOR_NR), 0);
225 for ( i = 0 ; i < PTLBD_MAX_MINOR ; i++) {
226 ptlbd_size_size[i] = 4096;
227 ptlbd_size[i] = (4096*2048) >> BLOCK_SIZE_BITS;
228 ptlbd_hardsect_size[i] = 4096;
229 ptlbd_max_sectors[i] = 2;
230 //RHism ptlbd_dev_varyio[i] = 0;
231 /* XXX register_disk? */
237 void ptlbd_blk_exit(void)
241 blk_cleanup_queue(BLK_DEFAULT_QUEUE(PTLBD_MAJOR));
242 ret = unregister_blkdev(PTLBD_MAJOR, "ptlbd");
244 printk("unregister_blkdev() failed: %d\n", ret);