Whamcloud - gitweb
399f04d9ff8b82ec90bf9f90b4054d40fe2789ad
[fs/lustre-release.git] / lustre / kernel_patches / patches / dev_read_only-2.6.27-vanilla.patch
1 Index: linux-2.6.27.21-0.1/block/blk-core.c
2 ===================================================================
3 --- linux-2.6.27.21-0.1.orig/block/blk-core.c   2009-04-23 02:12:51.000000000 -0600
4 +++ linux-2.6.27.21-0.1/block/blk-core.c        2009-05-22 08:38:02.000000000 -0600
5 @@ -1335,6 +1335,8 @@
6  
7  #endif /* CONFIG_FAIL_MAKE_REQUEST */
8  
9 +int dev_check_rdonly(struct block_device *bdev);
10 +
11  /*
12   * Check whether this bio extends beyond the end of the device.
13   */
14 @@ -1436,6 +1438,23 @@
15  
16                 if (unlikely(test_bit(QUEUE_FLAG_DEAD, &q->queue_flags)))
17                         goto end_io;
18
19 +               /* this is cfs's dev_rdonly check */
20 +               if (bio->bi_rw == WRITE && dev_check_rdonly(bio->bi_bdev)) {
21 +                       struct block_device *bdev = bio->bi_bdev;
22 +
23 +                       printk(KERN_WARNING "Write to readonly device %s (%#x) "
24 +                              "bi_flags: %lx, bi_vcnt: %d, bi_idx: %d, "
25 +                              "bi->size: %d, bi_cnt: %d, bi_private: %p\n",
26 +                              bdev->bd_disk ? bdev->bd_disk->disk_name : "",
27 +                              bdev->bd_dev, bio->bi_flags, bio->bi_vcnt,
28 +                              bio->bi_idx, bio->bi_size,
29 +                              atomic_read(&bio->bi_cnt), bio->bi_private);
30 +                       set_bit(BIO_RDONLY, &bio->bi_flags);
31 +                       bio_endio(bio, bio->bi_size, 0);
32 +                       clear_bit(BIO_RDONLY, &bio->bi_flags);
33 +                       break;
34 +               }
35 +
36                 if (should_fail_request(bio))
37                         goto end_io;
38 @@ -2189,6 +2208,91 @@
39  }
40  EXPORT_SYMBOL(kblockd_flush_work);
41  
42 + /*
43 + * Debug code for turning block devices "read-only" (will discard writes
44 + * silently).  This is for filesystem crash/recovery testing.
45 + */
46 +struct deventry {
47 +       dev_t dev;
48 +       struct deventry *next;
49 +};
50 +
51 +static struct deventry *devlist = NULL;
52 +static spinlock_t devlock = SPIN_LOCK_UNLOCKED; 
53 +
54 +int dev_check_rdonly(struct block_device *bdev) 
55 +{
56 +       struct deventry *cur;
57 +       if (!bdev) return 0;
58 +       spin_lock(&devlock);
59 +       cur = devlist;
60 +       while(cur) {
61 +               if (bdev->bd_dev == cur->dev) {
62 +                       spin_unlock(&devlock);
63 +                       return 1;
64 +       }
65 +               cur = cur->next;
66 +       }
67 +       spin_unlock(&devlock);
68 +       return 0;
69 +}
70 +
71 +void dev_set_rdonly(struct block_device *bdev)
72 +{
73 +       struct deventry *newdev, *cur;
74 +
75 +       if (!bdev) 
76 +               return;
77 +       newdev = kmalloc(sizeof(struct deventry), GFP_KERNEL);
78 +       if (!newdev) 
79 +               return;
80 +       
81 +       spin_lock(&devlock);
82 +       cur = devlist;
83 +       while(cur) {
84 +               if (bdev->bd_dev == cur->dev) {
85 +                       spin_unlock(&devlock);
86 +                       kfree(newdev);
87 +                       return;
88 +               }
89 +               cur = cur->next;
90 +       }
91 +       newdev->dev = bdev->bd_dev;
92 +       newdev->next = devlist;
93 +       devlist = newdev;
94 +       spin_unlock(&devlock);
95 +       printk(KERN_WARNING "Turning device %s (%#x) read-only\n",
96 +              bdev->bd_disk ? bdev->bd_disk->disk_name : "", bdev->bd_dev);
97 +}
98 +
99 +void dev_clear_rdonly(struct block_device *bdev) 
100 +{
101 +       struct deventry *cur, *last = NULL;
102 +       if (!bdev) return;
103 +       spin_lock(&devlock);
104 +       cur = devlist;
105 +       while(cur) {
106 +               if (bdev->bd_dev == cur->dev) {
107 +                       if (last) 
108 +                               last->next = cur->next;
109 +                       else
110 +                               devlist = cur->next;
111 +                       spin_unlock(&devlock);
112 +                       kfree(cur);
113 +                       printk(KERN_WARNING "Removing read-only on %s (%#x)\n",
114 +                              bdev->bd_disk ? bdev->bd_disk->disk_name :
115 +                                              "unknown block", bdev->bd_dev);
116 +                       return;
117 +               }
118 +               last = cur;
119 +               cur = cur->next;
120 +       }
121 +       spin_unlock(&devlock);
122 +}
123 +
124 +EXPORT_SYMBOL(dev_set_rdonly);
125 +EXPORT_SYMBOL(dev_clear_rdonly);
126 +EXPORT_SYMBOL(dev_check_rdonly);
127  int __init blk_dev_init(void)
128  {
129         kblockd_workqueue = create_workqueue("kblockd");
130 Index: linux-2.6.27.21-0.1/fs/block_dev.c
131 ===================================================================
132 --- linux-2.6.27.21-0.1.orig/fs/block_dev.c     2009-04-23 02:12:56.000000000 -0600
133 +++ linux-2.6.27.21-0.1/fs/block_dev.c  2009-05-22 08:38:02.000000000 -0600
134 @@ -1208,6 +1208,7 @@
135                 if (bdev != bdev->bd_contains)
136                         victim = bdev->bd_contains;
137                 bdev->bd_contains = NULL;
138 +               dev_clear_rdonly(bdev);
139         }
140         unlock_kernel();
141         mutex_unlock(&bdev->bd_mutex);
142 Index: linux-2.6.27.21-0.1/include/linux/fs.h
143 ===================================================================
144 --- linux-2.6.27.21-0.1.orig/include/linux/fs.h 2009-05-22 08:38:00.000000000 -0600
145 +++ linux-2.6.27.21-0.1/include/linux/fs.h      2009-05-22 08:38:02.000000000 -0600
146 @@ -1898,6 +1898,10 @@
147  extern void submit_bio(int, struct bio *);
148  extern int bdev_read_only(struct block_device *);
149  #endif
150 +#define HAVE_CLEAR_RDONLY_ON_PUT
151 +extern void dev_set_rdonly(struct block_device *bdev);
152 +extern int dev_check_rdonly(struct block_device *bdev);
153 +extern void dev_clear_rdonly(struct block_device *bdev);
154  extern int set_blocksize(struct block_device *, int);
155  extern int sb_set_blocksize(struct super_block *, int);
156  extern int sb_min_blocksize(struct super_block *, int);
157 Index: linux-2.6.27.21-0.1/include/linux/bio.h
158 ===================================================================
159 --- linux-2.6.27.21-0.1.orig/include/linux/bio.h 2009-05-22 08:38:00.000000000 -0600
160 +++ linux-2.6.27.21-0.1/include/linux/bio.h      2009-05-22 08:38:02.000000000 -0600
161 @@ -117,6 +117,7 @@
162  #define BIO_CPU_AFFINE 8       /* complete bio on same CPU as submitted */
163  #define BIO_FS_INTEGRITY 10    /* fs owns integrity data, not block layer */
164  #define BIO_QUIET      11      /* Make BIO Quiet */
165 +#define BIO_RDONLY     31      /* device is readonly */
166  #define bio_flagged(bio, flag) ((bio)->bi_flags & (1 << (flag)))
167  
168  /*