Whamcloud - gitweb
38aecf32aea225340dd2a9d2c58f44fdc762f35e
[fs/lustre-release.git] / lustre / kernel_patches / patches / dev_read_only-2.6.32-rhel6.patch
1 This functionality is mainly used during testing, in order to
2 simulate a server crash for ldiskfs by discarding all of the
3 writes to the filesystem.  For recovery testing we could simulate
4 this by using a special loopback or DM device that also discards
5 writes to the device.
6
7 This functionality is also used by target "failback" in order
8 to speed up service shutdown and takeover by the other node
9 during controlled operation.  However, it would also be possible
10 to do this by simply allowing all of the in-flight requests to
11 complete and then waiting for the service to stop.  This will
12 also be needed by the DMU-OSD, because discarding of writes on
13 a DMU-based target is not safe as it could trigger a storage
14 failure if the data is ever read from disk again and the
15 checksum does not match that expected by the block pointer.
16
17 Initial efforts to remove this patch are under way in bug 20776.
18 Once this work comes to fruition this patch can be dropped.
19
20 Index: linux-2.6.32-131.0.15.el6.x86_64/block/blk-core.c
21 ===================================================================
22 --- linux-2.6.32-131.0.15.el6.x86_64.orig/block/blk-core.c      2011-05-10 21:38:33.000000000 +0300
23 +++ linux-2.6.32-131.0.15.el6.x86_64/block/blk-core.c   2011-05-19 21:01:04.000000000 +0300
24 @@ -1416,6 +1416,8 @@ static inline int should_fail_request(st
25  
26  #endif /* CONFIG_FAIL_MAKE_REQUEST */
27  
28 +int dev_check_rdonly(struct block_device *bdev);
29 +
30  /*
31   * Check whether this bio extends beyond the end of the device.
32   */
33 @@ -1517,6 +1519,12 @@ static inline void __generic_make_reques
34                 if (unlikely(test_bit(QUEUE_FLAG_DEAD, &q->queue_flags)))
35                         goto end_io;
36  
37 +               /* this is cfs's dev_rdonly check */
38 +               if (bio_rw(bio) == WRITE && dev_check_rdonly(bio->bi_bdev)) {
39 +                       err = 0;
40 +                       goto end_io;
41 +               }
42 +
43                 if (should_fail_request(bio))
44                         goto end_io;
45  
46 @@ -2619,6 +2638,99 @@ int kblockd_schedule_work(struct request
47  }
48  EXPORT_SYMBOL(kblockd_schedule_work);
49  
50 + /*
51 + * Debug code for turning block devices "read-only" (will discard writes
52 + * silently).  This is for filesystem crash/recovery testing.
53 + */
54 +struct deventry {
55 +       dev_t dev;
56 +       struct deventry *next;
57 +};
58 +
59 +static struct deventry *devlist = NULL;
60 +static spinlock_t devlock = SPIN_LOCK_UNLOCKED;
61 +
62 +int dev_check_rdonly(struct block_device *bdev)
63 +{
64 +       struct deventry *cur;
65 +
66 +       if (!bdev)
67 +               return 0;
68 +
69 +       spin_lock(&devlock);
70 +       cur = devlist;
71 +       while(cur) {
72 +               if (bdev->bd_dev == cur->dev) {
73 +                       spin_unlock(&devlock);
74 +                       return 1;
75 +               }
76 +               cur = cur->next;
77 +       }
78 +       spin_unlock(&devlock);
79 +       return 0;
80 +}
81 +
82 +void dev_set_rdonly(struct block_device *bdev)
83 +{
84 +       struct deventry *newdev, *cur;
85 +
86 +       if (!bdev)
87 +               return;
88 +
89 +       newdev = kmalloc(sizeof(struct deventry), GFP_KERNEL);
90 +       if (!newdev)
91 +               return;
92 +
93 +       spin_lock(&devlock);
94 +       cur = devlist;
95 +       while(cur) {
96 +               if (bdev->bd_dev == cur->dev) {
97 +                       spin_unlock(&devlock);
98 +                       kfree(newdev);
99 +                       return;
100 +               }
101 +               cur = cur->next;
102 +       }
103 +       newdev->dev = bdev->bd_dev;
104 +       newdev->next = devlist;
105 +       devlist = newdev;
106 +       spin_unlock(&devlock);
107 +       printk(KERN_WARNING "Turning device %s (%#x) read-only\n",
108 +               bdev->bd_disk ? bdev->bd_disk->disk_name : "", bdev->bd_dev);
109 +}
110 +
111 +void dev_clear_rdonly(struct block_device *bdev)
112 +{
113 +       struct deventry *cur, *last = NULL;
114 +
115 +       if (!bdev)
116 +               return;
117 +
118 +       spin_lock(&devlock);
119 +       cur = devlist;
120 +       while(cur) {
121 +               if (bdev->bd_dev == cur->dev) {
122 +                       if (last)
123 +                               last->next = cur->next;
124 +                       else
125 +                               devlist = cur->next;
126 +                       spin_unlock(&devlock);
127 +                       kfree(cur);
128 +                       printk(KERN_WARNING "Removing read-only on %s (%#x)\n",
129 +                               bdev->bd_disk ? bdev->bd_disk->disk_name :
130 +                                               "unknown block",
131 +                               bdev->bd_dev);
132 +                       return;
133 +               }
134 +               last = cur;
135 +               cur = cur->next;
136 +       }
137 +       spin_unlock(&devlock);
138 +}
139 +
140 +EXPORT_SYMBOL(dev_set_rdonly);
141 +EXPORT_SYMBOL(dev_clear_rdonly);
142 +EXPORT_SYMBOL(dev_check_rdonly);
143  int __init blk_dev_init(void)
144  {
145         BUILD_BUG_ON(__REQ_NR_BITS > 8 *
146 Index: linux-2.6.32-131.0.15.el6.x86_64/fs/block_dev.c
147 ===================================================================
148 --- linux-2.6.32-131.0.15.el6.x86_64.orig/fs/block_dev.c        2011-05-10 21:38:29.000000000 +0300
149 +++ linux-2.6.32-131.0.15.el6.x86_64/fs/block_dev.c     2011-05-19 21:01:04.000000000 +0300
150 @@ -1389,6 +1389,7 @@ static int __blkdev_put(struct block_dev
151                 if (bdev != bdev->bd_contains)
152                         victim = bdev->bd_contains;
153                 bdev->bd_contains = NULL;
154 +               dev_clear_rdonly(bdev);
155         }
156         unlock_kernel();
157         mutex_unlock(&bdev->bd_mutex);
158 Index: linux-2.6.32-131.0.15.el6.x86_64/include/linux/fs.h
159 ===================================================================
160 --- linux-2.6.32-131.0.15.el6.x86_64.orig/include/linux/fs.h    2011-05-10 21:38:29.000000000 +0300
161 +++ linux-2.6.32-131.0.15.el6.x86_64/include/linux/fs.h 2011-05-19 21:01:04.000000000 +0300
162 @@ -2244,6 +2244,10 @@ struct bio;
163  extern void submit_bio(int, struct bio *);
164  extern int bdev_read_only(struct block_device *);
165  #endif
166 +#define HAVE_CLEAR_RDONLY_ON_PUT
167 +extern void dev_set_rdonly(struct block_device *bdev);
168 +extern int dev_check_rdonly(struct block_device *bdev);
169 +extern void dev_clear_rdonly(struct block_device *bdev);
170  extern int set_blocksize(struct block_device *, int);
171  extern int sb_set_blocksize(struct super_block *, int);
172  extern int sb_min_blocksize(struct super_block *, int);