1 diff -ur linux-2.6.5-lnxi.orig/drivers/block/ll_rw_blk.c linux-2.6.5-lnxi/drivers/block/ll_rw_blk.c
2 --- linux-2.6.5-lnxi.orig/drivers/block/ll_rw_blk.c 2004-11-11 07:28:51.000000000 -0800
3 +++ linux-2.6.5-lnxi/drivers/block/ll_rw_blk.c 2005-04-11 09:42:22.750936924 -0700
4 @@ -2458,7 +2458,7 @@ static inline void blk_partition_remap(s
8 -int dev_check_rdonly(dev_t dev);
9 +int dev_check_rdonly(struct block_device *bdev);
12 * generic_make_request: hand a buffer to its device driver for I/O
13 @@ -2550,7 +2550,7 @@ end_io:
15 /* this is cfs's dev_rdonly check */
16 if (bio->bi_rw == WRITE &&
17 - dev_check_rdonly(bio->bi_bdev->bd_dev)) {
18 + dev_check_rdonly(bio->bi_bdev)) {
19 bio_endio(bio, bio->bi_size, 0);
22 @@ -3086,53 +3086,86 @@ void swap_io_context(struct io_context *
26 -#define MAX_RDONLY_DEVS 16
28 -static dev_t rdonly_devs[MAX_RDONLY_DEVS] = {0, };
31 * Debug code for turning block devices "read-only" (will discard writes
32 * silently). This is for filesystem crash/recovery testing.
34 -void dev_set_rdonly(struct block_device *bdev, int no_write)
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 - if (no_write >= MAX_RDONLY_DEVS) {
46 - printk(KERN_ALERT "%s:%d illegal arg %d (max %d)\n",
47 - __FILE__, __LINE__, no_write, MAX_RDONLY_DEVS);
49 + struct deventry *cur;
50 + if (!bdev) return 0;
51 + spin_lock(&devlock);
54 + if (bdev->bd_dev == cur->dev) {
55 + spin_unlock(&devlock);
60 - printk(KERN_WARNING "Turning device %s read-only at %d\n",
61 - bdev->bd_disk ? bdev->bd_disk->disk_name : "?",
63 - rdonly_devs[no_write] = bdev->bd_dev;
66 + spin_unlock(&devlock);
70 -void dev_clear_rdonly(int no_write)
71 +void dev_set_rdonly(struct block_device *bdev)
73 - if (no_write >= MAX_RDONLY_DEVS) {
74 - printk(KERN_ALERT "%s:%d illegal arg %d (max %d)\n",
75 - __FILE__, __LINE__, no_write, MAX_RDONLY_DEVS);
78 + struct deventry *newdev, *cur;
80 - if (rdonly_devs[no_write] == 0)
83 + newdev = kmalloc(sizeof(struct deventry), GFP_KERNEL);
87 - printk(KERN_WARNING "Clearing read-only at %d\n", no_write);
88 - rdonly_devs[no_write] = 0;
91 -int dev_check_rdonly(dev_t dev)
95 - for (i = 0; i < MAX_RDONLY_DEVS; i++)
96 - if (rdonly_devs[i] == dev)
99 + spin_lock(&devlock);
102 + if (bdev->bd_dev == cur->dev) {
103 + spin_unlock(&devlock);
109 + newdev->dev = bdev->bd_dev;
110 + newdev->next = devlist;
112 + spin_unlock(&devlock);
113 + printk(KERN_WARNING "Turning device %s (%#x) read-only\n",
114 + bdev->bd_disk ? bdev->bd_disk->disk_name : "", bdev->bd_dev);
117 +void dev_clear_rdonly(struct block_device *bdev)
119 + struct deventry *cur, *last = NULL;
121 + spin_lock(&devlock);
124 + if (bdev->bd_dev == cur->dev) {
126 + last->next = cur->next;
128 + devlist = cur->next;
129 + spin_unlock(&devlock);
131 + printk(KERN_WARNING "Removing read-only on %s (%#x)\n",
132 + bdev->bd_disk ? bdev->bd_disk->disk_name :
133 + "unknown block", bdev->bd_dev);
139 + spin_unlock(&devlock);
142 EXPORT_SYMBOL(dev_set_rdonly);
143 diff -ur linux-2.6.5-lnxi.orig/fs/block_dev.c linux-2.6.5-lnxi/fs/block_dev.c
144 --- linux-2.6.5-lnxi.orig/fs/block_dev.c 2004-11-11 07:28:30.000000000 -0800
145 +++ linux-2.6.5-lnxi/fs/block_dev.c 2005-04-11 09:49:01.891407856 -0700
146 @@ -739,6 +739,7 @@ int blkdev_put(struct block_device *bdev
150 + dev_clear_rdonly(bdev);
154 diff -ur linux-2.6.5-lnxi.orig/include/linux/fs.h linux-2.6.5-lnxi/include/linux/fs.h
155 --- linux-2.6.5-lnxi.orig/include/linux/fs.h 2004-11-11 07:28:45.000000000 -0800
156 +++ linux-2.6.5-lnxi/include/linux/fs.h 2005-04-11 09:43:27.423116140 -0700
157 @@ -1385,6 +1385,10 @@ extern void file_kill(struct file *f);
159 extern int submit_bio(int, struct bio *);
160 extern int bdev_read_only(struct block_device *);
161 +#define HAVE_CLEAR_RDONLY_ON_PUT
162 +void dev_set_rdonly(struct block_device *bdev);
163 +int dev_check_rdonly(struct block_device *bdev);
164 +void dev_clear_rdonly(struct block_device *bdev);
165 extern int set_blocksize(struct block_device *, int);
166 extern int sb_set_blocksize(struct super_block *, int);
167 extern int sb_min_blocksize(struct super_block *, int);