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