1 Index: linux-2.6.18.1/block/ll_rw_blk.c
2 ===================================================================
3 --- linux-2.6.18.1.orig/block/ll_rw_blk.c
4 +++ linux-2.6.18.1/block/ll_rw_blk.c
5 @@ -3067,6 +3067,8 @@ static void handle_bad_sector(struct bio
6 set_bit(BIO_EOF, &bio->bi_flags);
9 +int dev_check_rdonly(struct block_device *bdev);
12 * generic_make_request: hand a buffer to its device driver for I/O
13 * @bio: The bio describing the location in memory and on the device.
14 @@ -3151,6 +3153,12 @@ end_io:
16 if (unlikely(test_bit(QUEUE_FLAG_DEAD, &q->queue_flags)))
18 + /* this is cfs's dev_rdonly check */
19 + if (bio->bi_rw == WRITE &&
20 + dev_check_rdonly(bio->bi_bdev)) {
21 + bio_endio(bio, bio->bi_size, 0);
26 * If this device has partitions, remap block n
27 @@ -3765,6 +3773,91 @@ void swap_io_context(struct io_context *
30 EXPORT_SYMBOL(swap_io_context);
32 + * Debug code for turning block devices "read-only" (will discard writes
33 + * silently). This is for filesystem crash/recovery testing.
37 + struct deventry *next;
40 +static struct deventry *devlist = NULL;
41 +static spinlock_t devlock = SPIN_LOCK_UNLOCKED;
43 +int dev_check_rdonly(struct block_device *bdev)
45 + struct deventry *cur;
46 + if (!bdev) return 0;
47 + spin_lock(&devlock);
50 + if (bdev->bd_dev == cur->dev) {
51 + spin_unlock(&devlock);
56 + spin_unlock(&devlock);
60 +void dev_set_rdonly(struct block_device *bdev)
62 + struct deventry *newdev, *cur;
66 + newdev = kmalloc(sizeof(struct deventry), GFP_KERNEL);
70 + spin_lock(&devlock);
73 + if (bdev->bd_dev == cur->dev) {
74 + spin_unlock(&devlock);
80 + newdev->dev = bdev->bd_dev;
81 + newdev->next = devlist;
83 + spin_unlock(&devlock);
84 + printk(KERN_WARNING "Turning device %s (%#x) read-only\n",
85 + bdev->bd_disk ? bdev->bd_disk->disk_name : "", bdev->bd_dev);
88 +void dev_clear_rdonly(struct block_device *bdev)
90 + struct deventry *cur, *last = NULL;
92 + spin_lock(&devlock);
95 + if (bdev->bd_dev == cur->dev) {
97 + last->next = cur->next;
99 + devlist = cur->next;
100 + spin_unlock(&devlock);
102 + printk(KERN_WARNING "Removing read-only on %s (%#x)\n",
103 + bdev->bd_disk ? bdev->bd_disk->disk_name :
104 + "unknown block", bdev->bd_dev);
110 + spin_unlock(&devlock);
113 +EXPORT_SYMBOL(dev_set_rdonly);
114 +EXPORT_SYMBOL(dev_clear_rdonly);
115 +EXPORT_SYMBOL(dev_check_rdonly);
119 Index: linux-2.6.18.1/fs/block_dev.c
120 ===================================================================
121 --- linux-2.6.18.1.orig/fs/block_dev.c
122 +++ linux-2.6.18.1/fs/block_dev.c
123 @@ -1059,6 +1059,7 @@ static int __blkdev_put(struct block_dev
124 if (bdev != bdev->bd_contains)
125 victim = bdev->bd_contains;
126 bdev->bd_contains = NULL;
127 + dev_clear_rdonly(bdev);
130 mutex_unlock(&bdev->bd_mutex);
131 Index: linux-2.6.18.1/include/linux/fs.h
132 ===================================================================
133 --- linux-2.6.18.1.orig/include/linux/fs.h
134 +++ linux-2.6.18.1/include/linux/fs.h
135 @@ -1685,6 +1685,10 @@ extern void file_kill(struct file *f);
137 extern void submit_bio(int, struct bio *);
138 extern int bdev_read_only(struct block_device *);
139 +#define HAVE_CLEAR_RDONLY_ON_PUT
140 +void dev_set_rdonly(struct block_device *bdev);
141 +int dev_check_rdonly(struct block_device *bdev);
142 +void dev_clear_rdonly(struct block_device *bdev);
143 extern int set_blocksize(struct block_device *, int);
144 extern int sb_set_blocksize(struct super_block *, int);
145 extern int sb_min_blocksize(struct super_block *, int);