---- linux-2.6.5.orig/drivers/block/ll_rw_blk.c 2005-03-16 11:08:47.404935605 -0800
-+++ linux-2.6.5/drivers/block/ll_rw_blk.c 2005-03-16 10:57:38.197357003 -0800
-@@ -2458,6 +2458,8 @@ static inline void blk_partition_remap(s
- }
+Index: linux-2.6.9/drivers/block/ll_rw_blk.c
+===================================================================
+--- linux-2.6.9.orig/drivers/block/ll_rw_blk.c
++++ linux-2.6.9/drivers/block/ll_rw_blk.c
+@@ -2326,6 +2326,8 @@ static inline int attempt_front_merge(re
+ return 0;
}
+int dev_check_rdonly(struct block_device *bdev);
+
/**
- * generic_make_request: hand a buffer to its device driver for I/O
- * @bio: The bio describing the location in memory and on the device.
-@@ -2546,6 +2548,13 @@ end_io:
+ * blk_attempt_remerge - attempt to remerge active head with next request
+ * @q: The &request_queue_t belonging to the device
+@@ -2631,6 +2633,13 @@ end_io:
if (test_bit(QUEUE_FLAG_DEAD, &q->queue_flags))
goto end_io;
+ /* this is cfs's dev_rdonly check */
+ if (bio->bi_rw == WRITE &&
-+ dev_check_rdonly(bio->bi_bdev)) {
-+ bio_endio(bio, bio->bi_size, 0);
-+ break;
++ dev_check_rdonly(bio->bi_bdev)) {
++ bio_endio(bio, bio->bi_size, 0);
++ break;
+ }
+
/*
* If this device has partitions, remap block n
* of partition p to block n+start(p) of the disk.
-@@ -3078,6 +3087,91 @@ void swap_io_context(struct io_context *
- }
+@@ -3180,6 +3189,92 @@ void swap_io_context(struct io_context *
+
/*
+ * Debug code for turning block devices "read-only" (will discard writes
+ * silently). This is for filesystem crash/recovery testing.
+ */
+struct deventry {
-+ dev_t dev;
-+ struct deventry *next;
++ dev_t dev;
++ struct deventry *next;
+};
+
+static struct deventry *devlist = NULL;
+
+int dev_check_rdonly(struct block_device *bdev)
+{
-+ struct deventry *cur;
-+ if (!bdev) return 0;
-+ spin_lock(&devlock);
-+ cur = devlist;
-+ while(cur) {
-+ if (bdev->bd_dev == cur->dev) {
-+ spin_unlock(&devlock);
-+ return 1;
-+ }
-+ cur = cur->next;
-+ }
-+ spin_unlock(&devlock);
-+ return 0;
++ struct deventry *cur;
++ if (!bdev) return 0;
++ spin_lock(&devlock);
++ cur = devlist;
++ while(cur) {
++ if (bdev->bd_dev == cur->dev) {
++ spin_unlock(&devlock);
++ return 1;
++ }
++ cur = cur->next;
++ }
++ spin_unlock(&devlock);
++ return 0;
+}
+
+void dev_set_rdonly(struct block_device *bdev)
+{
-+ struct deventry *newdev, *cur;
++ struct deventry *newdev, *cur;
+
-+ if (!bdev)
-+ return;
-+ newdev = kmalloc(sizeof(struct deventry), GFP_KERNEL);
-+ if (!newdev)
-+ return;
-+
-+ spin_lock(&devlock);
-+ cur = devlist;
-+ while(cur) {
-+ if (bdev->bd_dev == cur->dev) {
-+ spin_unlock(&devlock);
-+ kfree(newdev);
-+ return;
-+ }
-+ cur = cur->next;
-+ }
-+ newdev->dev = bdev->bd_dev;
-+ newdev->next = devlist;
-+ devlist = newdev;
-+ spin_unlock(&devlock);
-+ printk(KERN_WARNING "Turning device %s read-only\n",
-+ bdev->bd_disk ? bdev->bd_disk->disk_name : "?");
++ if (!bdev)
++ return;
++ newdev = kmalloc(sizeof(struct deventry), GFP_KERNEL);
++ if (!newdev)
++ return;
++
++ spin_lock(&devlock);
++ cur = devlist;
++ while(cur) {
++ if (bdev->bd_dev == cur->dev) {
++ spin_unlock(&devlock);
++ kfree(newdev);
++ return;
++ }
++ cur = cur->next;
++ }
++ newdev->dev = bdev->bd_dev;
++ newdev->next = devlist;
++ devlist = newdev;
++ spin_unlock(&devlock);
++ printk(KERN_WARNING "Turning device %s (%#x) read-only\n",
++ bdev->bd_disk ? bdev->bd_disk->disk_name : "", bdev->bd_dev);
+}
+
+void dev_clear_rdonly(struct block_device *bdev)
+{
-+ struct deventry *cur, *last = NULL;
-+ if (!bdev) return;
-+ spin_lock(&devlock);
-+ cur = devlist;
-+ while(cur) {
-+ if (bdev->bd_dev == cur->dev) {
-+ if (last)
-+ last->next = cur->next;
-+ else
-+ devlist = cur->next;
-+ spin_unlock(&devlock);
-+ kfree(cur);
-+ printk(KERN_WARNING "Removing read-only on %s\n",
-+ bdev->bd_disk ? bdev->bd_disk->disk_name : "?");
++ struct deventry *cur, *last = NULL;
++ if (!bdev) return;
++ spin_lock(&devlock);
++ cur = devlist;
++ while(cur) {
++ if (bdev->bd_dev == cur->dev) {
++ if (last)
++ last->next = cur->next;
++ else
++ devlist = cur->next;
++ spin_unlock(&devlock);
++ kfree(cur);
++ printk(KERN_WARNING "Removing read-only on %s (%#x)\n",
++ bdev->bd_disk ? bdev->bd_disk->disk_name :
++ "unknown block", bdev->bd_dev);
+ return;
-+ }
-+ last = cur;
-+ cur = cur->next;
-+ }
-+ spin_unlock(&devlock);
++ }
++ last = cur;
++ cur = cur->next;
++ }
++ spin_unlock(&devlock);
+}
+
+EXPORT_SYMBOL(dev_set_rdonly);
* sysfs parts below
*/
struct queue_sysfs_entry {
+Index: linux-2.6.9/fs/block_dev.c
+===================================================================
+--- linux-2.6.9.orig/fs/block_dev.c
++++ linux-2.6.9/fs/block_dev.c
+@@ -60,6 +60,7 @@ static void kill_bdev(struct block_devic
+ {
+ invalidate_bdev(bdev, 1);
+ truncate_inode_pages(bdev->bd_inode->i_mapping, 0);
++ dev_clear_rdonly(bdev);
+ }
+
+ int set_blocksize(struct block_device *bdev, int size)
+Index: linux-2.6.9/include/linux/fs.h
+===================================================================
+--- linux-2.6.9.orig/include/linux/fs.h
++++ linux-2.6.9/include/linux/fs.h
+@@ -1492,6 +1492,10 @@ extern void file_kill(struct file *f);
+ struct bio;
+ extern void submit_bio(int, struct bio *);
+ extern int bdev_read_only(struct block_device *);
++#define HAVE_CLEAR_RDONLY_ON_PUT
++void dev_set_rdonly(struct block_device *bdev);
++int dev_check_rdonly(struct block_device *bdev);
++void dev_clear_rdonly(struct block_device *bdev);
+ extern int set_blocksize(struct block_device *, int);
+ extern int sb_set_blocksize(struct super_block *, int);
+ extern int sb_min_blocksize(struct super_block *, int);