Whamcloud - gitweb
Branch b1_8
[fs/lustre-release.git] / lustre / kernel_patches / patches / dev_read_only-2.6-lnxi.patch
1 Index: linux-2.6.5-lnxi/drivers/block/ll_rw_blk.c
2 ===================================================================
3 --- linux-2.6.5-lnxi.orig/drivers/block/ll_rw_blk.c
4 +++ linux-2.6.5-lnxi/drivers/block/ll_rw_blk.c
5 @@ -2718,7 +2718,7 @@ static inline void blk_partition_remap(s
6         }
7  }
8  
9 -int dev_check_rdonly(dev_t dev);
10 +int dev_check_rdonly(struct block_device *bdev);
11  
12  /**
13   * generic_make_request: hand a buffer to its device driver for I/O
14 @@ -2810,7 +2810,7 @@ end_io:
15  
16                 /* this is cfs's dev_rdonly check */
17                 if (bio->bi_rw == WRITE &&
18 -                               dev_check_rdonly(bio->bi_bdev->bd_dev)) {
19 +                               dev_check_rdonly(bio->bi_bdev)) {
20                         bio_endio(bio, bio->bi_size, 0);
21                         break;
22                 }
23 @@ -3395,53 +3395,86 @@ void swap_io_context(struct io_context *
24         *ioc2 = temp;
25  }
26  
27 -#define MAX_RDONLY_DEVS                16
28 -
29 -static dev_t rdonly_devs[MAX_RDONLY_DEVS] = {0, };
30 -
31  /*
32   * Debug code for turning block devices "read-only" (will discard writes
33   * silently).  This is for filesystem crash/recovery testing.
34   */
35 -void dev_set_rdonly(struct block_device *bdev, int no_write)
36 +struct deventry {
37 +       dev_t dev;
38 +       struct deventry *next;
39 +};
40 +
41 +static struct deventry *devlist = NULL;
42 +static spinlock_t devlock = SPIN_LOCK_UNLOCKED; 
43 +
44 +int dev_check_rdonly(struct block_device *bdev) 
45  {
46 -       if (no_write >= MAX_RDONLY_DEVS) {
47 -               printk(KERN_ALERT "%s:%d illegal arg %d (max %d)\n",
48 -                               __FILE__, __LINE__, no_write, MAX_RDONLY_DEVS);
49 -               return;
50 +       struct deventry *cur;
51 +       if (!bdev) return 0;
52 +       spin_lock(&devlock);
53 +       cur = devlist;
54 +       while(cur) {
55 +               if (bdev->bd_dev == cur->dev) {
56 +                       spin_unlock(&devlock);
57 +                       return 1;
58         }
59 -
60 -       if (bdev) {
61 -               printk(KERN_WARNING "Turning device %s read-only at %d\n",
62 -                               bdev->bd_disk ? bdev->bd_disk->disk_name : "?",
63 -                               no_write);
64 -               rdonly_devs[no_write] = bdev->bd_dev;
65 +               cur = cur->next;
66         }
67 +       spin_unlock(&devlock);
68 +       return 0;
69  }
70  
71 -void dev_clear_rdonly(int no_write)
72 +void dev_set_rdonly(struct block_device *bdev)
73  {
74 -       if (no_write >= MAX_RDONLY_DEVS) {
75 -               printk(KERN_ALERT "%s:%d illegal arg %d (max %d)\n",
76 -                               __FILE__, __LINE__, no_write, MAX_RDONLY_DEVS);
77 -               return;
78 -       }
79 +       struct deventry *newdev, *cur;
80  
81 -       if (rdonly_devs[no_write] == 0)
82 +       if (!bdev) 
83 +               return;
84 +       newdev = kmalloc(sizeof(struct deventry), GFP_KERNEL);
85 +       if (!newdev) 
86                 return;
87         
88 -       printk(KERN_WARNING "Clearing read-only at %d\n", no_write);
89 -       rdonly_devs[no_write] = 0;
90 -}
91 -
92 -int dev_check_rdonly(dev_t dev)
93 -{
94 -       int i;
95 -
96 -       for (i = 0; i < MAX_RDONLY_DEVS; i++)
97 -               if (rdonly_devs[i] == dev)
98 -                       return 1;
99 -       return 0;
100 +       spin_lock(&devlock);
101 +       cur = devlist;
102 +       while(cur) {
103 +               if (bdev->bd_dev == cur->dev) {
104 +                       spin_unlock(&devlock);
105 +                       kfree(newdev);
106 +                       return;
107 +               }
108 +               cur = cur->next;
109 +       }
110 +       newdev->dev = bdev->bd_dev;
111 +       newdev->next = devlist;
112 +       devlist = newdev;
113 +       spin_unlock(&devlock);
114 +       printk(KERN_WARNING "Turning device %s (%#x) read-only\n",
115 +              bdev->bd_disk ? bdev->bd_disk->disk_name : "", bdev->bd_dev);
116 +}
117 +
118 +void dev_clear_rdonly(struct block_device *bdev) 
119 +{
120 +       struct deventry *cur, *last = NULL;
121 +       if (!bdev) return;
122 +       spin_lock(&devlock);
123 +       cur = devlist;
124 +       while(cur) {
125 +               if (bdev->bd_dev == cur->dev) {
126 +                       if (last) 
127 +                               last->next = cur->next;
128 +                       else
129 +                               devlist = cur->next;
130 +                       spin_unlock(&devlock);
131 +                       kfree(cur);
132 +                       printk(KERN_WARNING "Removing read-only on %s (%#x)\n",
133 +                              bdev->bd_disk ? bdev->bd_disk->disk_name :
134 +                                              "unknown block", bdev->bd_dev);
135 +                       return;
136 +               }
137 +               last = cur;
138 +               cur = cur->next;
139 +       }
140 +       spin_unlock(&devlock);
141  }
142  
143  EXPORT_SYMBOL(dev_set_rdonly);
144 Index: linux-2.6.5-lnxi/fs/block_dev.c
145 ===================================================================
146 --- linux-2.6.5-lnxi.orig/fs/block_dev.c
147 +++ linux-2.6.5-lnxi/fs/block_dev.c
148 @@ -767,6 +767,7 @@ int blkdev_put(struct block_device *bdev
149                         blkdev_put(bdev->bd_contains);
150                 }
151                 bdev->bd_contains = NULL;
152 +               dev_clear_rdonly(bdev);
153         }
154         unlock_kernel();
155         up(&bdev->bd_sem);
156 Index: linux-2.6.5-lnxi/include/linux/fs.h
157 ===================================================================
158 --- linux-2.6.5-lnxi.orig/include/linux/fs.h
159 +++ linux-2.6.5-lnxi/include/linux/fs.h
160 @@ -1424,6 +1424,10 @@ extern void file_kill(struct file *f);
161  struct bio;
162  extern int submit_bio(int, struct bio *);
163  extern int bdev_read_only(struct block_device *);
164 +#define HAVE_CLEAR_RDONLY_ON_PUT
165 +void dev_set_rdonly(struct block_device *bdev);
166 +int dev_check_rdonly(struct block_device *bdev);
167 +void dev_clear_rdonly(struct block_device *bdev);
168  extern int set_blocksize(struct block_device *, int);
169  extern int sb_set_blocksize(struct super_block *, int);
170  extern int sb_min_blocksize(struct super_block *, int);