cee31a4ee6d0a31403096ed0dd280f0d44f3bdf3
[linux-2.6.git] / drivers / dump / dump_blockdev.c
1 /*
2  * Implements the dump driver interface for saving a dump to 
3  * a block device through the kernel's generic low level block i/o
4  * routines.
5  *
6  * Started: June 2002 - Mohamed Abbas <mohamed.abbas@intel.com>
7  *      Moved original lkcd kiobuf dump i/o code from dump_base.c
8  *      to use generic dump device interfaces
9  *
10  * Sept 2002 - Bharata B. Rao <bharata@in.ibm.com>
11  *      Convert dump i/o to directly use bio instead of kiobuf for 2.5
12  *
13  * Oct 2002  - Suparna Bhattacharya <suparna@in.ibm.com>
14  *      Rework to new dumpdev.h structures, implement open/close/
15  *      silence, misc fixes (blocknr removal, bio_add_page usage)  
16  *
17  * Copyright (C) 1999 - 2002 Silicon Graphics, Inc. All rights reserved.
18  * Copyright (C) 2001 - 2002 Matt D. Robinson.  All rights reserved.
19  * Copyright (C) 2002 International Business Machines Corp. 
20  *
21  * This code is released under version 2 of the GNU GPL.
22  */
23
24 #include <linux/types.h>
25 #include <linux/proc_fs.h>
26 #include <linux/module.h>
27 #include <linux/init.h>
28 #include <linux/blkdev.h>
29 #include <linux/bio.h>
30 #include <asm/hardirq.h>
31 #include <linux/dump.h>
32 #include "dump_methods.h"
33
34 extern void *dump_page_buf;
35
36 /* The end_io callback for dump i/o completion */
37 static int
38 dump_bio_end_io(struct bio *bio, unsigned int bytes_done, int error)
39 {
40         struct dump_blockdev *dump_bdev;
41
42         if (bio->bi_size) {
43                 /* some bytes still left to transfer */
44                 return 1; /* not complete */
45         }
46
47         dump_bdev = (struct dump_blockdev *)bio->bi_private;
48         if (error) {
49                 printk("IO error while writing the dump, aborting\n");
50         }
51
52         dump_bdev->err = error;
53
54         /* no wakeup needed, since caller polls for completion */
55         return 0;
56 }
57
58 /* Check if the dump bio is already mapped to the specified buffer */
59 static int
60 dump_block_map_valid(struct dump_blockdev *dev, struct page *page, 
61         int len) 
62 {
63         struct bio *bio = dev->bio;
64         unsigned long bsize = 0;
65
66         if (!bio->bi_vcnt)
67                 return 0; /* first time, not mapped */
68
69
70         if ((bio_page(bio) != page) || (len > bio->bi_vcnt << PAGE_SHIFT))
71                 return 0; /* buffer not mapped */
72
73         bsize = bdev_hardsect_size(bio->bi_bdev);
74         if ((len & (PAGE_SIZE - 1)) || (len & bsize))
75                 return 0; /* alignment checks needed */
76
77         /* quick check to decide if we need to redo bio_add_page */
78         if (bdev_get_queue(bio->bi_bdev)->merge_bvec_fn)
79                 return 0; /* device may have other restrictions */
80
81         return 1; /* already mapped */
82 }
83
84 /* 
85  * Set up the dump bio for i/o from the specified buffer 
86  * Return value indicates whether the full buffer could be mapped or not
87  */
88 static int
89 dump_block_map(struct dump_blockdev *dev, void *buf, int len)
90 {
91         struct page *page = virt_to_page(buf);
92         struct bio *bio = dev->bio;
93         unsigned long bsize = 0;
94
95         bio->bi_bdev = dev->bdev;
96         bio->bi_sector = (dev->start_offset + dev->ddev.curr_offset) >> 9;
97         bio->bi_idx = 0; /* reset index to the beginning */
98
99         if (dump_block_map_valid(dev, page, len)) {
100                 /* already mapped and usable rightaway */
101                 bio->bi_size = len; /* reset size to the whole bio */
102         } else {
103                 /* need to map the bio */
104                 bio->bi_size = 0;
105                 bio->bi_vcnt = 0;
106                 bsize = bdev_hardsect_size(bio->bi_bdev);
107
108                 /* first a few sanity checks */
109                 if (len < bsize) {
110                         printk("map: len less than hardsect size \n");
111                         return -EINVAL;
112                 }
113
114                 if ((unsigned long)buf & bsize) {
115                         printk("map: not aligned \n");
116                         return -EINVAL;
117                 }
118
119                 /* assume contig. page aligned low mem buffer( no vmalloc) */
120                 if ((page_address(page) != buf) || (len & (PAGE_SIZE - 1))) {
121                         printk("map: invalid buffer alignment!\n");
122                         return -EINVAL; 
123                 }
124                 /* finally we can go ahead and map it */
125                 while (bio->bi_size < len)
126                         if (bio_add_page(bio, page++, PAGE_SIZE, 0) == 0) {
127                                 break;
128                         }
129
130                 bio->bi_end_io = dump_bio_end_io;
131                 bio->bi_private = dev;
132         }
133
134         if (bio->bi_size != len) {
135                 printk("map: bio size = %d not enough for len = %d!\n",
136                         bio->bi_size, len);
137                 return -E2BIG;
138         }
139         return 0;
140 }
141
142 static void
143 dump_free_bio(struct bio *bio)
144 {
145         if (bio)
146                 kfree(bio->bi_io_vec);
147         kfree(bio);
148 }
149
150 /*
151  * Prepares the dump device so we can take a dump later. 
152  * The caller is expected to have filled up the dev_id field in the 
153  * block dump dev structure.
154  *
155  * At dump time when dump_block_write() is invoked it will be too 
156  * late to recover, so as far as possible make sure obvious errors 
157  * get caught right here and reported back to the caller.
158  */
159 static int
160 dump_block_open(struct dump_dev *dev, unsigned long arg)
161 {
162         struct dump_blockdev *dump_bdev = DUMP_BDEV(dev);
163         struct block_device *bdev;
164         int retval = 0;
165         struct bio_vec *bvec;
166
167         /* make sure this is a valid block device */
168         if (!arg) {
169                 retval = -EINVAL;
170                 goto err;
171         }
172
173         /* Convert it to the new dev_t format */
174         arg = MKDEV((arg >> OLDMINORBITS), (arg & OLDMINORMASK));
175         
176         /* get a corresponding block_dev struct for this */
177         bdev = bdget((dev_t)arg);
178         if (!bdev) {
179                 retval = -ENODEV;
180                 goto err;
181         }
182
183         /* get the block device opened */
184         if ((retval = blkdev_get(bdev, O_RDWR | O_LARGEFILE, 0))) {
185                 goto err1;
186         }
187
188         if ((dump_bdev->bio = kmalloc(sizeof(struct bio), GFP_KERNEL)) 
189                 == NULL) {
190                 printk("Cannot allocate bio\n");
191                 retval = -ENOMEM;
192                 goto err2;
193         }
194
195         bio_init(dump_bdev->bio);
196
197         if ((bvec = kmalloc(sizeof(struct bio_vec) * 
198                 (DUMP_BUFFER_SIZE >> PAGE_SHIFT), GFP_KERNEL)) == NULL) {
199                 retval = -ENOMEM;
200                 goto err3;
201         }
202
203         /* assign the new dump dev structure */
204         dump_bdev->dev_id = (dev_t)arg;
205         dump_bdev->bdev = bdev;
206
207         /* make a note of the limit */
208         dump_bdev->limit = bdev->bd_inode->i_size;
209         
210         /* now make sure we can map the dump buffer */
211         dump_bdev->bio->bi_io_vec = bvec;
212         dump_bdev->bio->bi_max_vecs = DUMP_BUFFER_SIZE >> PAGE_SHIFT;
213
214         retval = dump_block_map(dump_bdev, dump_config.dumper->dump_buf, 
215                 DUMP_BUFFER_SIZE);
216                 
217         if (retval) {
218                 printk("open: dump_block_map failed, ret %d\n", retval);
219                 goto err3;
220         }
221
222         printk("Block device (%d,%d) successfully configured for dumping\n",
223                MAJOR(dump_bdev->dev_id),
224                MINOR(dump_bdev->dev_id));
225
226
227         /* after opening the block device, return */
228         return retval;
229
230 err3:   dump_free_bio(dump_bdev->bio);
231         dump_bdev->bio = NULL;
232 err2:   if (bdev) blkdev_put(bdev);
233                 goto err;
234 err1:   if (bdev) bdput(bdev);
235         dump_bdev->bdev = NULL;
236 err:    return retval;
237 }
238
239 /*
240  * Close the dump device and release associated resources
241  * Invoked when unconfiguring the dump device.
242  */
243 static int
244 dump_block_release(struct dump_dev *dev)
245 {
246         struct dump_blockdev *dump_bdev = DUMP_BDEV(dev);
247
248         /* release earlier bdev if present */
249         if (dump_bdev->bdev) {
250                 blkdev_put(dump_bdev->bdev);
251                 dump_bdev->bdev = NULL;
252         }
253
254         dump_free_bio(dump_bdev->bio);
255         dump_bdev->bio = NULL;
256
257         return 0;
258 }
259
260
261 /*
262  * Prepare the dump device for use (silence any ongoing activity
263  * and quiesce state) when the system crashes.
264  */
265 static int
266 dump_block_silence(struct dump_dev *dev)
267 {
268         struct dump_blockdev *dump_bdev = DUMP_BDEV(dev);
269         struct request_queue *q = bdev_get_queue(dump_bdev->bdev);
270         int ret;
271
272         /* If we can't get request queue lock, refuse to take the dump */
273         if (!spin_trylock(q->queue_lock))
274                 return -EBUSY;
275
276         ret = elv_queue_empty(q);
277         spin_unlock(q->queue_lock);
278
279         /* For now we assume we have the device to ourselves */
280         /* Just a quick sanity check */
281         if (!ret) {
282                 /* Warn the user and move on */
283                 printk(KERN_ALERT "Warning: Non-empty request queue\n");
284                 printk(KERN_ALERT "I/O requests in flight at dump time\n");
285         }
286
287         /* 
288          * Move to a softer level of silencing where no spin_lock_irqs 
289          * are held on other cpus
290          */
291         dump_silence_level = DUMP_SOFT_SPIN_CPUS;       
292
293         ret = __dump_irq_enable();
294         if (ret) {
295                 return ret;
296         }
297
298         printk("Dumping to block device (%d,%d) on CPU %d ...\n",
299                MAJOR(dump_bdev->dev_id), MINOR(dump_bdev->dev_id),
300                smp_processor_id());
301         
302         return 0;
303 }
304
305 /*
306  * Invoked when dumping is done. This is the time to put things back 
307  * (i.e. undo the effects of dump_block_silence) so the device is 
308  * available for normal use.
309  */
310 static int
311 dump_block_resume(struct dump_dev *dev)
312 {
313         __dump_irq_restore();
314         return 0;
315 }
316
317
318 /*
319  * Seek to the specified offset in the dump device.
320  * Makes sure this is a valid offset, otherwise returns an error.
321  */
322 static int
323 dump_block_seek(struct dump_dev *dev, loff_t off)
324 {
325         struct dump_blockdev *dump_bdev = DUMP_BDEV(dev);
326         loff_t offset = off + dump_bdev->start_offset;
327         
328         if (offset & ( PAGE_SIZE - 1)) {
329                 printk("seek: non-page aligned\n");
330                 return -EINVAL;
331         }
332
333         if (offset & (bdev_hardsect_size(dump_bdev->bdev) - 1)) {
334                 printk("seek: not sector aligned \n");
335                 return -EINVAL;
336         }
337
338         if (offset > dump_bdev->limit) {
339                 printk("seek: not enough space left on device!\n");
340                 return -ENOSPC; 
341         }
342         dev->curr_offset = off;
343         return 0;
344 }
345
346 /*
347  * Write out a buffer after checking the device limitations, 
348  * sector sizes, etc. Assumes the buffer is in directly mapped 
349  * kernel address space (not vmalloc'ed).
350  *
351  * Returns: number of bytes written or -ERRNO. 
352  */
353 static int
354 dump_block_write(struct dump_dev *dev, void *buf, 
355         unsigned long len)
356 {
357         struct dump_blockdev *dump_bdev = DUMP_BDEV(dev);
358         loff_t offset = dev->curr_offset + dump_bdev->start_offset;
359         int retval = -ENOSPC;
360
361         if (offset >= dump_bdev->limit) {
362                 printk("write: not enough space left on device!\n");
363                 goto out;
364         }
365
366         /* don't write more blocks than our max limit */
367         if (offset + len > dump_bdev->limit) 
368                 len = dump_bdev->limit - offset;
369
370
371         retval = dump_block_map(dump_bdev, buf, len);
372         if (retval){
373                 printk("write: dump_block_map failed! err %d\n", retval);
374                 goto out;
375         }
376
377         /*
378          * Write out the data to disk.
379          * Assumes the entire buffer mapped to a single bio, which we can
380          * submit and wait for io completion. In the future, may consider
381          * increasing the dump buffer size and submitting multiple bio s 
382          * for better throughput.
383          */
384         dump_bdev->err = -EAGAIN;
385         submit_bio(WRITE, dump_bdev->bio);
386
387         dump_bdev->ddev.curr_offset += len;
388         retval = len;
389  out:
390         return retval;
391 }
392
393 /*
394  * Name: dump_block_ready()
395  * Func: check if the last dump i/o is over and ready for next request
396  */
397 static int
398 dump_block_ready(struct dump_dev *dev, void *buf)
399 {
400         struct dump_blockdev *dump_bdev = DUMP_BDEV(dev);
401         request_queue_t *q = bdev_get_queue(dump_bdev->bio->bi_bdev);
402
403         /* check for io completion */
404         if (dump_bdev->err == -EAGAIN) {
405                 q->unplug_fn(q);
406                 return -EAGAIN;
407         }
408
409         if (dump_bdev->err) {
410                 printk("dump i/o err\n");
411                 return dump_bdev->err;
412         }
413
414         return 0;
415 }
416
417
418 struct dump_dev_ops dump_blockdev_ops = {
419         .open           = dump_block_open,
420         .release        = dump_block_release,
421         .silence        = dump_block_silence,
422         .resume         = dump_block_resume,
423         .seek           = dump_block_seek,
424         .write          = dump_block_write,
425         /* .read not implemented */
426         .ready          = dump_block_ready
427 };
428
429 static struct dump_blockdev default_dump_blockdev = {
430         .ddev = {.type_name = "blockdev", .ops = &dump_blockdev_ops, 
431                         .curr_offset = 0},
432         /* 
433          * leave enough room for the longest swap header possibly written 
434          * written by mkswap (likely the largest page size supported by
435          * the arch
436          */
437         .start_offset   = DUMP_HEADER_OFFSET,
438         .err            = 0
439         /* assume the rest of the fields are zeroed by default */
440 };      
441         
442 struct dump_blockdev *dump_blockdev = &default_dump_blockdev;
443
444 static int __init
445 dump_blockdev_init(void)
446 {
447         if (dump_register_device(&dump_blockdev->ddev) < 0) {
448                 printk("block device driver registration failed\n");
449                 return -1;
450         }
451                 
452         printk("block device driver for LKCD registered\n");
453         return 0;
454 }
455
456 static void __exit
457 dump_blockdev_cleanup(void)
458 {
459         dump_unregister_device(&dump_blockdev->ddev);
460         printk("block device driver for LKCD unregistered\n");
461 }
462
463 MODULE_AUTHOR("LKCD Development Team <lkcd-devel@lists.sourceforge.net>");
464 MODULE_DESCRIPTION("Block Dump Driver for Linux Kernel Crash Dump (LKCD)");
465 MODULE_LICENSE("GPL");
466
467 module_init(dump_blockdev_init);
468 module_exit(dump_blockdev_cleanup);