diff options
47 files changed, 2741 insertions, 564 deletions
diff --git a/Documentation/ABI/testing/sysfs-block b/Documentation/ABI/testing/sysfs-block index 4bd9ea539129..44f52a4f5903 100644 --- a/Documentation/ABI/testing/sysfs-block +++ b/Documentation/ABI/testing/sysfs-block | |||
@@ -26,3 +26,37 @@ Description: | |||
26 | I/O statistics of partition <part>. The format is the | 26 | I/O statistics of partition <part>. The format is the |
27 | same as the above-written /sys/block/<disk>/stat | 27 | same as the above-written /sys/block/<disk>/stat |
28 | format. | 28 | format. |
29 | |||
30 | |||
31 | What: /sys/block/<disk>/integrity/format | ||
32 | Date: June 2008 | ||
33 | Contact: Martin K. Petersen <martin.petersen@oracle.com> | ||
34 | Description: | ||
35 | Metadata format for integrity capable block device. | ||
36 | E.g. T10-DIF-TYPE1-CRC. | ||
37 | |||
38 | |||
39 | What: /sys/block/<disk>/integrity/read_verify | ||
40 | Date: June 2008 | ||
41 | Contact: Martin K. Petersen <martin.petersen@oracle.com> | ||
42 | Description: | ||
43 | Indicates whether the block layer should verify the | ||
44 | integrity of read requests serviced by devices that | ||
45 | support sending integrity metadata. | ||
46 | |||
47 | |||
48 | What: /sys/block/<disk>/integrity/tag_size | ||
49 | Date: June 2008 | ||
50 | Contact: Martin K. Petersen <martin.petersen@oracle.com> | ||
51 | Description: | ||
52 | Number of bytes of integrity tag space available per | ||
53 | 512 bytes of data. | ||
54 | |||
55 | |||
56 | What: /sys/block/<disk>/integrity/write_generate | ||
57 | Date: June 2008 | ||
58 | Contact: Martin K. Petersen <martin.petersen@oracle.com> | ||
59 | Description: | ||
60 | Indicates whether the block layer should automatically | ||
61 | generate checksums for write requests bound for | ||
62 | devices that support receiving integrity metadata. | ||
diff --git a/Documentation/block/data-integrity.txt b/Documentation/block/data-integrity.txt new file mode 100644 index 000000000000..e9dc8d86adc7 --- /dev/null +++ b/Documentation/block/data-integrity.txt | |||
@@ -0,0 +1,327 @@ | |||
1 | ---------------------------------------------------------------------- | ||
2 | 1. INTRODUCTION | ||
3 | |||
4 | Modern filesystems feature checksumming of data and metadata to | ||
5 | protect against data corruption. However, the detection of the | ||
6 | corruption is done at read time which could potentially be months | ||
7 | after the data was written. At that point the original data that the | ||
8 | application tried to write is most likely lost. | ||
9 | |||
10 | The solution is to ensure that the disk is actually storing what the | ||
11 | application meant it to. Recent additions to both the SCSI family | ||
12 | protocols (SBC Data Integrity Field, SCC protection proposal) as well | ||
13 | as SATA/T13 (External Path Protection) try to remedy this by adding | ||
14 | support for appending integrity metadata to an I/O. The integrity | ||
15 | metadata (or protection information in SCSI terminology) includes a | ||
16 | checksum for each sector as well as an incrementing counter that | ||
17 | ensures the individual sectors are written in the right order. And | ||
18 | for some protection schemes also that the I/O is written to the right | ||
19 | place on disk. | ||
20 | |||
21 | Current storage controllers and devices implement various protective | ||
22 | measures, for instance checksumming and scrubbing. But these | ||
23 | technologies are working in their own isolated domains or at best | ||
24 | between adjacent nodes in the I/O path. The interesting thing about | ||
25 | DIF and the other integrity extensions is that the protection format | ||
26 | is well defined and every node in the I/O path can verify the | ||
27 | integrity of the I/O and reject it if corruption is detected. This | ||
28 | allows not only corruption prevention but also isolation of the point | ||
29 | of failure. | ||
30 | |||
31 | ---------------------------------------------------------------------- | ||
32 | 2. THE DATA INTEGRITY EXTENSIONS | ||
33 | |||
34 | As written, the protocol extensions only protect the path between | ||
35 | controller and storage device. However, many controllers actually | ||
36 | allow the operating system to interact with the integrity metadata | ||
37 | (IMD). We have been working with several FC/SAS HBA vendors to enable | ||
38 | the protection information to be transferred to and from their | ||
39 | controllers. | ||
40 | |||
41 | The SCSI Data Integrity Field works by appending 8 bytes of protection | ||
42 | information to each sector. The data + integrity metadata is stored | ||
43 | in 520 byte sectors on disk. Data + IMD are interleaved when | ||
44 | transferred between the controller and target. The T13 proposal is | ||
45 | similar. | ||
46 | |||
47 | Because it is highly inconvenient for operating systems to deal with | ||
48 | 520 (and 4104) byte sectors, we approached several HBA vendors and | ||
49 | encouraged them to allow separation of the data and integrity metadata | ||
50 | scatter-gather lists. | ||
51 | |||
52 | The controller will interleave the buffers on write and split them on | ||
53 | read. This means that the Linux can DMA the data buffers to and from | ||
54 | host memory without changes to the page cache. | ||
55 | |||
56 | Also, the 16-bit CRC checksum mandated by both the SCSI and SATA specs | ||
57 | is somewhat heavy to compute in software. Benchmarks found that | ||
58 | calculating this checksum had a significant impact on system | ||
59 | performance for a number of workloads. Some controllers allow a | ||
60 | lighter-weight checksum to be used when interfacing with the operating | ||
61 | system. Emulex, for instance, supports the TCP/IP checksum instead. | ||
62 | The IP checksum received from the OS is converted to the 16-bit CRC | ||
63 | when writing and vice versa. This allows the integrity metadata to be | ||
64 | generated by Linux or the application at very low cost (comparable to | ||
65 | software RAID5). | ||
66 | |||
67 | The IP checksum is weaker than the CRC in terms of detecting bit | ||
68 | errors. However, the strength is really in the separation of the data | ||
69 | buffers and the integrity metadata. These two distinct buffers much | ||
70 | match up for an I/O to complete. | ||
71 | |||
72 | The separation of the data and integrity metadata buffers as well as | ||
73 | the choice in checksums is referred to as the Data Integrity | ||
74 | Extensions. As these extensions are outside the scope of the protocol | ||
75 | bodies (T10, T13), Oracle and its partners are trying to standardize | ||
76 | them within the Storage Networking Industry Association. | ||
77 | |||
78 | ---------------------------------------------------------------------- | ||
79 | 3. KERNEL CHANGES | ||
80 | |||
81 | The data integrity framework in Linux enables protection information | ||
82 | to be pinned to I/Os and sent to/received from controllers that | ||
83 | support it. | ||
84 | |||
85 | The advantage to the integrity extensions in SCSI and SATA is that | ||
86 | they enable us to protect the entire path from application to storage | ||
87 | device. However, at the same time this is also the biggest | ||
88 | disadvantage. It means that the protection information must be in a | ||
89 | format that can be understood by the disk. | ||
90 | |||
91 | Generally Linux/POSIX applications are agnostic to the intricacies of | ||
92 | the storage devices they are accessing. The virtual filesystem switch | ||
93 | and the block layer make things like hardware sector size and | ||
94 | transport protocols completely transparent to the application. | ||
95 | |||
96 | However, this level of detail is required when preparing the | ||
97 | protection information to send to a disk. Consequently, the very | ||
98 | concept of an end-to-end protection scheme is a layering violation. | ||
99 | It is completely unreasonable for an application to be aware whether | ||
100 | it is accessing a SCSI or SATA disk. | ||
101 | |||
102 | The data integrity support implemented in Linux attempts to hide this | ||
103 | from the application. As far as the application (and to some extent | ||
104 | the kernel) is concerned, the integrity metadata is opaque information | ||
105 | that's attached to the I/O. | ||
106 | |||
107 | The current implementation allows the block layer to automatically | ||
108 | generate the protection information for any I/O. Eventually the | ||
109 | intent is to move the integrity metadata calculation to userspace for | ||
110 | user data. Metadata and other I/O that originates within the kernel | ||
111 | will still use the automatic generation interface. | ||
112 | |||
113 | Some storage devices allow each hardware sector to be tagged with a | ||
114 | 16-bit value. The owner of this tag space is the owner of the block | ||
115 | device. I.e. the filesystem in most cases. The filesystem can use | ||
116 | this extra space to tag sectors as they see fit. Because the tag | ||
117 | space is limited, the block interface allows tagging bigger chunks by | ||
118 | way of interleaving. This way, 8*16 bits of information can be | ||
119 | attached to a typical 4KB filesystem block. | ||
120 | |||
121 | This also means that applications such as fsck and mkfs will need | ||
122 | access to manipulate the tags from user space. A passthrough | ||
123 | interface for this is being worked on. | ||
124 | |||
125 | |||
126 | ---------------------------------------------------------------------- | ||
127 | 4. BLOCK LAYER IMPLEMENTATION DETAILS | ||
128 | |||
129 | 4.1 BIO | ||
130 | |||
131 | The data integrity patches add a new field to struct bio when | ||
132 | CONFIG_BLK_DEV_INTEGRITY is enabled. bio->bi_integrity is a pointer | ||
133 | to a struct bip which contains the bio integrity payload. Essentially | ||
134 | a bip is a trimmed down struct bio which holds a bio_vec containing | ||
135 | the integrity metadata and the required housekeeping information (bvec | ||
136 | pool, vector count, etc.) | ||
137 | |||
138 | A kernel subsystem can enable data integrity protection on a bio by | ||
139 | calling bio_integrity_alloc(bio). This will allocate and attach the | ||
140 | bip to the bio. | ||
141 | |||
142 | Individual pages containing integrity metadata can subsequently be | ||
143 | attached using bio_integrity_add_page(). | ||
144 | |||
145 | bio_free() will automatically free the bip. | ||
146 | |||
147 | |||
148 | 4.2 BLOCK DEVICE | ||
149 | |||
150 | Because the format of the protection data is tied to the physical | ||
151 | disk, each block device has been extended with a block integrity | ||
152 | profile (struct blk_integrity). This optional profile is registered | ||
153 | with the block layer using blk_integrity_register(). | ||
154 | |||
155 | The profile contains callback functions for generating and verifying | ||
156 | the protection data, as well as getting and setting application tags. | ||
157 | The profile also contains a few constants to aid in completing, | ||
158 | merging and splitting the integrity metadata. | ||
159 | |||
160 | Layered block devices will need to pick a profile that's appropriate | ||
161 | for all subdevices. blk_integrity_compare() can help with that. DM | ||
162 | and MD linear, RAID0 and RAID1 are currently supported. RAID4/5/6 | ||
163 | will require extra work due to the application tag. | ||
164 | |||
165 | |||
166 | ---------------------------------------------------------------------- | ||
167 | 5.0 BLOCK LAYER INTEGRITY API | ||
168 | |||
169 | 5.1 NORMAL FILESYSTEM | ||
170 | |||
171 | The normal filesystem is unaware that the underlying block device | ||
172 | is capable of sending/receiving integrity metadata. The IMD will | ||
173 | be automatically generated by the block layer at submit_bio() time | ||
174 | in case of a WRITE. A READ request will cause the I/O integrity | ||
175 | to be verified upon completion. | ||
176 | |||
177 | IMD generation and verification can be toggled using the | ||
178 | |||
179 | /sys/block/<bdev>/integrity/write_generate | ||
180 | |||
181 | and | ||
182 | |||
183 | /sys/block/<bdev>/integrity/read_verify | ||
184 | |||
185 | flags. | ||
186 | |||
187 | |||
188 | 5.2 INTEGRITY-AWARE FILESYSTEM | ||
189 | |||
190 | A filesystem that is integrity-aware can prepare I/Os with IMD | ||
191 | attached. It can also use the application tag space if this is | ||
192 | supported by the block device. | ||
193 | |||
194 | |||
195 | int bdev_integrity_enabled(block_device, int rw); | ||
196 | |||
197 | bdev_integrity_enabled() will return 1 if the block device | ||
198 | supports integrity metadata transfer for the data direction | ||
199 | specified in 'rw'. | ||
200 | |||
201 | bdev_integrity_enabled() honors the write_generate and | ||
202 | read_verify flags in sysfs and will respond accordingly. | ||
203 | |||
204 | |||
205 | int bio_integrity_prep(bio); | ||
206 | |||
207 | To generate IMD for WRITE and to set up buffers for READ, the | ||
208 | filesystem must call bio_integrity_prep(bio). | ||
209 | |||
210 | Prior to calling this function, the bio data direction and start | ||
211 | sector must be set, and the bio should have all data pages | ||
212 | added. It is up to the caller to ensure that the bio does not | ||
213 | change while I/O is in progress. | ||
214 | |||
215 | bio_integrity_prep() should only be called if | ||
216 | bio_integrity_enabled() returned 1. | ||
217 | |||
218 | |||
219 | int bio_integrity_tag_size(bio); | ||
220 | |||
221 | If the filesystem wants to use the application tag space it will | ||
222 | first have to find out how much storage space is available. | ||
223 | Because tag space is generally limited (usually 2 bytes per | ||
224 | sector regardless of sector size), the integrity framework | ||
225 | supports interleaving the information between the sectors in an | ||
226 | I/O. | ||
227 | |||
228 | Filesystems can call bio_integrity_tag_size(bio) to find out how | ||
229 | many bytes of storage are available for that particular bio. | ||
230 | |||
231 | Another option is bdev_get_tag_size(block_device) which will | ||
232 | return the number of available bytes per hardware sector. | ||
233 | |||
234 | |||
235 | int bio_integrity_set_tag(bio, void *tag_buf, len); | ||
236 | |||
237 | After a successful return from bio_integrity_prep(), | ||
238 | bio_integrity_set_tag() can be used to attach an opaque tag | ||
239 | buffer to a bio. Obviously this only makes sense if the I/O is | ||
240 | a WRITE. | ||
241 | |||
242 | |||
243 | int bio_integrity_get_tag(bio, void *tag_buf, len); | ||
244 | |||
245 | Similarly, at READ I/O completion time the filesystem can | ||
246 | retrieve the tag buffer using bio_integrity_get_tag(). | ||
247 | |||
248 | |||
249 | 6.3 PASSING EXISTING INTEGRITY METADATA | ||
250 | |||
251 | Filesystems that either generate their own integrity metadata or | ||
252 | are capable of transferring IMD from user space can use the | ||
253 | following calls: | ||
254 | |||
255 | |||
256 | struct bip * bio_integrity_alloc(bio, gfp_mask, nr_pages); | ||
257 | |||
258 | Allocates the bio integrity payload and hangs it off of the bio. | ||
259 | nr_pages indicate how many pages of protection data need to be | ||
260 | stored in the integrity bio_vec list (similar to bio_alloc()). | ||
261 | |||
262 | The integrity payload will be freed at bio_free() time. | ||
263 | |||
264 | |||
265 | int bio_integrity_add_page(bio, page, len, offset); | ||
266 | |||
267 | Attaches a page containing integrity metadata to an existing | ||
268 | bio. The bio must have an existing bip, | ||
269 | i.e. bio_integrity_alloc() must have been called. For a WRITE, | ||
270 | the integrity metadata in the pages must be in a format | ||
271 | understood by the target device with the notable exception that | ||
272 | the sector numbers will be remapped as the request traverses the | ||
273 | I/O stack. This implies that the pages added using this call | ||
274 | will be modified during I/O! The first reference tag in the | ||
275 | integrity metadata must have a value of bip->bip_sector. | ||
276 | |||
277 | Pages can be added using bio_integrity_add_page() as long as | ||
278 | there is room in the bip bio_vec array (nr_pages). | ||
279 | |||
280 | Upon completion of a READ operation, the attached pages will | ||
281 | contain the integrity metadata received from the storage device. | ||
282 | It is up to the receiver to process them and verify data | ||
283 | integrity upon completion. | ||
284 | |||
285 | |||
286 | 6.4 REGISTERING A BLOCK DEVICE AS CAPABLE OF EXCHANGING INTEGRITY | ||
287 | METADATA | ||
288 | |||
289 | To enable integrity exchange on a block device the gendisk must be | ||
290 | registered as capable: | ||
291 | |||
292 | int blk_integrity_register(gendisk, blk_integrity); | ||
293 | |||
294 | The blk_integrity struct is a template and should contain the | ||
295 | following: | ||
296 | |||
297 | static struct blk_integrity my_profile = { | ||
298 | .name = "STANDARDSBODY-TYPE-VARIANT-CSUM", | ||
299 | .generate_fn = my_generate_fn, | ||
300 | .verify_fn = my_verify_fn, | ||
301 | .get_tag_fn = my_get_tag_fn, | ||
302 | .set_tag_fn = my_set_tag_fn, | ||
303 | .tuple_size = sizeof(struct my_tuple_size), | ||
304 | .tag_size = <tag bytes per hw sector>, | ||
305 | }; | ||
306 | |||
307 | 'name' is a text string which will be visible in sysfs. This is | ||
308 | part of the userland API so chose it carefully and never change | ||
309 | it. The format is standards body-type-variant. | ||
310 | E.g. T10-DIF-TYPE1-IP or T13-EPP-0-CRC. | ||
311 | |||
312 | 'generate_fn' generates appropriate integrity metadata (for WRITE). | ||
313 | |||
314 | 'verify_fn' verifies that the data buffer matches the integrity | ||
315 | metadata. | ||
316 | |||
317 | 'tuple_size' must be set to match the size of the integrity | ||
318 | metadata per sector. I.e. 8 for DIF and EPP. | ||
319 | |||
320 | 'tag_size' must be set to identify how many bytes of tag space | ||
321 | are available per hardware sector. For DIF this is either 2 or | ||
322 | 0 depending on the value of the Control Mode Page ATO bit. | ||
323 | |||
324 | See 6.2 for a description of get_tag_fn and set_tag_fn. | ||
325 | |||
326 | ---------------------------------------------------------------------- | ||
327 | 2007-12-24 Martin K. Petersen <martin.petersen@oracle.com> | ||
diff --git a/block/Kconfig b/block/Kconfig index 3e97f2bc446f..1ab7c15c8d7a 100644 --- a/block/Kconfig +++ b/block/Kconfig | |||
@@ -81,6 +81,18 @@ config BLK_DEV_BSG | |||
81 | 81 | ||
82 | If unsure, say N. | 82 | If unsure, say N. |
83 | 83 | ||
84 | config BLK_DEV_INTEGRITY | ||
85 | bool "Block layer data integrity support" | ||
86 | ---help--- | ||
87 | Some storage devices allow extra information to be | ||
88 | stored/retrieved to help protect the data. The block layer | ||
89 | data integrity option provides hooks which can be used by | ||
90 | filesystems to ensure better data integrity. | ||
91 | |||
92 | Say yes here if you have a storage device that provides the | ||
93 | T10/SCSI Data Integrity Field or the T13/ATA External Path | ||
94 | Protection. If in doubt, say N. | ||
95 | |||
84 | endif # BLOCK | 96 | endif # BLOCK |
85 | 97 | ||
86 | config BLOCK_COMPAT | 98 | config BLOCK_COMPAT |
diff --git a/block/Makefile b/block/Makefile index 5a43c7d79594..208000b0750d 100644 --- a/block/Makefile +++ b/block/Makefile | |||
@@ -4,7 +4,8 @@ | |||
4 | 4 | ||
5 | obj-$(CONFIG_BLOCK) := elevator.o blk-core.o blk-tag.o blk-sysfs.o \ | 5 | obj-$(CONFIG_BLOCK) := elevator.o blk-core.o blk-tag.o blk-sysfs.o \ |
6 | blk-barrier.o blk-settings.o blk-ioc.o blk-map.o \ | 6 | blk-barrier.o blk-settings.o blk-ioc.o blk-map.o \ |
7 | blk-exec.o blk-merge.o ioctl.o genhd.o scsi_ioctl.o | 7 | blk-exec.o blk-merge.o ioctl.o genhd.o scsi_ioctl.o \ |
8 | cmd-filter.o | ||
8 | 9 | ||
9 | obj-$(CONFIG_BLK_DEV_BSG) += bsg.o | 10 | obj-$(CONFIG_BLK_DEV_BSG) += bsg.o |
10 | obj-$(CONFIG_IOSCHED_NOOP) += noop-iosched.o | 11 | obj-$(CONFIG_IOSCHED_NOOP) += noop-iosched.o |
@@ -14,3 +15,4 @@ obj-$(CONFIG_IOSCHED_CFQ) += cfq-iosched.o | |||
14 | 15 | ||
15 | obj-$(CONFIG_BLK_DEV_IO_TRACE) += blktrace.o | 16 | obj-$(CONFIG_BLK_DEV_IO_TRACE) += blktrace.o |
16 | obj-$(CONFIG_BLOCK_COMPAT) += compat_ioctl.o | 17 | obj-$(CONFIG_BLOCK_COMPAT) += compat_ioctl.o |
18 | obj-$(CONFIG_BLK_DEV_INTEGRITY) += blk-integrity.o | ||
diff --git a/block/as-iosched.c b/block/as-iosched.c index 743f33a01a07..9735acb5b4f5 100644 --- a/block/as-iosched.c +++ b/block/as-iosched.c | |||
@@ -151,6 +151,7 @@ enum arq_state { | |||
151 | 151 | ||
152 | static DEFINE_PER_CPU(unsigned long, ioc_count); | 152 | static DEFINE_PER_CPU(unsigned long, ioc_count); |
153 | static struct completion *ioc_gone; | 153 | static struct completion *ioc_gone; |
154 | static DEFINE_SPINLOCK(ioc_gone_lock); | ||
154 | 155 | ||
155 | static void as_move_to_dispatch(struct as_data *ad, struct request *rq); | 156 | static void as_move_to_dispatch(struct as_data *ad, struct request *rq); |
156 | static void as_antic_stop(struct as_data *ad); | 157 | static void as_antic_stop(struct as_data *ad); |
@@ -164,8 +165,19 @@ static void free_as_io_context(struct as_io_context *aic) | |||
164 | { | 165 | { |
165 | kfree(aic); | 166 | kfree(aic); |
166 | elv_ioc_count_dec(ioc_count); | 167 | elv_ioc_count_dec(ioc_count); |
167 | if (ioc_gone && !elv_ioc_count_read(ioc_count)) | 168 | if (ioc_gone) { |
168 | complete(ioc_gone); | 169 | /* |
170 | * AS scheduler is exiting, grab exit lock and check | ||
171 | * the pending io context count. If it hits zero, | ||
172 | * complete ioc_gone and set it back to NULL. | ||
173 | */ | ||
174 | spin_lock(&ioc_gone_lock); | ||
175 | if (ioc_gone && !elv_ioc_count_read(ioc_count)) { | ||
176 | complete(ioc_gone); | ||
177 | ioc_gone = NULL; | ||
178 | } | ||
179 | spin_unlock(&ioc_gone_lock); | ||
180 | } | ||
169 | } | 181 | } |
170 | 182 | ||
171 | static void as_trim(struct io_context *ioc) | 183 | static void as_trim(struct io_context *ioc) |
@@ -1493,7 +1505,7 @@ static void __exit as_exit(void) | |||
1493 | /* ioc_gone's update must be visible before reading ioc_count */ | 1505 | /* ioc_gone's update must be visible before reading ioc_count */ |
1494 | smp_wmb(); | 1506 | smp_wmb(); |
1495 | if (elv_ioc_count_read(ioc_count)) | 1507 | if (elv_ioc_count_read(ioc_count)) |
1496 | wait_for_completion(ioc_gone); | 1508 | wait_for_completion(&all_gone); |
1497 | synchronize_rcu(); | 1509 | synchronize_rcu(); |
1498 | } | 1510 | } |
1499 | 1511 | ||
diff --git a/block/blk-core.c b/block/blk-core.c index 1905aaba49fb..dbc7f42b5d2b 100644 --- a/block/blk-core.c +++ b/block/blk-core.c | |||
@@ -143,6 +143,10 @@ static void req_bio_endio(struct request *rq, struct bio *bio, | |||
143 | 143 | ||
144 | bio->bi_size -= nbytes; | 144 | bio->bi_size -= nbytes; |
145 | bio->bi_sector += (nbytes >> 9); | 145 | bio->bi_sector += (nbytes >> 9); |
146 | |||
147 | if (bio_integrity(bio)) | ||
148 | bio_integrity_advance(bio, nbytes); | ||
149 | |||
146 | if (bio->bi_size == 0) | 150 | if (bio->bi_size == 0) |
147 | bio_endio(bio, error); | 151 | bio_endio(bio, error); |
148 | } else { | 152 | } else { |
@@ -201,8 +205,7 @@ void blk_plug_device(struct request_queue *q) | |||
201 | if (blk_queue_stopped(q)) | 205 | if (blk_queue_stopped(q)) |
202 | return; | 206 | return; |
203 | 207 | ||
204 | if (!test_bit(QUEUE_FLAG_PLUGGED, &q->queue_flags)) { | 208 | if (!queue_flag_test_and_set(QUEUE_FLAG_PLUGGED, q)) { |
205 | __set_bit(QUEUE_FLAG_PLUGGED, &q->queue_flags); | ||
206 | mod_timer(&q->unplug_timer, jiffies + q->unplug_delay); | 209 | mod_timer(&q->unplug_timer, jiffies + q->unplug_delay); |
207 | blk_add_trace_generic(q, NULL, 0, BLK_TA_PLUG); | 210 | blk_add_trace_generic(q, NULL, 0, BLK_TA_PLUG); |
208 | } | 211 | } |
@@ -217,10 +220,9 @@ int blk_remove_plug(struct request_queue *q) | |||
217 | { | 220 | { |
218 | WARN_ON(!irqs_disabled()); | 221 | WARN_ON(!irqs_disabled()); |
219 | 222 | ||
220 | if (!test_bit(QUEUE_FLAG_PLUGGED, &q->queue_flags)) | 223 | if (!queue_flag_test_and_clear(QUEUE_FLAG_PLUGGED, q)) |
221 | return 0; | 224 | return 0; |
222 | 225 | ||
223 | queue_flag_clear(QUEUE_FLAG_PLUGGED, q); | ||
224 | del_timer(&q->unplug_timer); | 226 | del_timer(&q->unplug_timer); |
225 | return 1; | 227 | return 1; |
226 | } | 228 | } |
@@ -324,8 +326,7 @@ void blk_start_queue(struct request_queue *q) | |||
324 | * one level of recursion is ok and is much faster than kicking | 326 | * one level of recursion is ok and is much faster than kicking |
325 | * the unplug handling | 327 | * the unplug handling |
326 | */ | 328 | */ |
327 | if (!test_bit(QUEUE_FLAG_REENTER, &q->queue_flags)) { | 329 | if (!queue_flag_test_and_set(QUEUE_FLAG_REENTER, q)) { |
328 | queue_flag_set(QUEUE_FLAG_REENTER, q); | ||
329 | q->request_fn(q); | 330 | q->request_fn(q); |
330 | queue_flag_clear(QUEUE_FLAG_REENTER, q); | 331 | queue_flag_clear(QUEUE_FLAG_REENTER, q); |
331 | } else { | 332 | } else { |
@@ -390,8 +391,7 @@ void __blk_run_queue(struct request_queue *q) | |||
390 | * handling reinvoke the handler shortly if we already got there. | 391 | * handling reinvoke the handler shortly if we already got there. |
391 | */ | 392 | */ |
392 | if (!elv_queue_empty(q)) { | 393 | if (!elv_queue_empty(q)) { |
393 | if (!test_bit(QUEUE_FLAG_REENTER, &q->queue_flags)) { | 394 | if (!queue_flag_test_and_set(QUEUE_FLAG_REENTER, q)) { |
394 | queue_flag_set(QUEUE_FLAG_REENTER, q); | ||
395 | q->request_fn(q); | 395 | q->request_fn(q); |
396 | queue_flag_clear(QUEUE_FLAG_REENTER, q); | 396 | queue_flag_clear(QUEUE_FLAG_REENTER, q); |
397 | } else { | 397 | } else { |
@@ -1381,6 +1381,9 @@ end_io: | |||
1381 | */ | 1381 | */ |
1382 | blk_partition_remap(bio); | 1382 | blk_partition_remap(bio); |
1383 | 1383 | ||
1384 | if (bio_integrity_enabled(bio) && bio_integrity_prep(bio)) | ||
1385 | goto end_io; | ||
1386 | |||
1384 | if (old_sector != -1) | 1387 | if (old_sector != -1) |
1385 | blk_add_trace_remap(q, bio, old_dev, bio->bi_sector, | 1388 | blk_add_trace_remap(q, bio, old_dev, bio->bi_sector, |
1386 | old_sector); | 1389 | old_sector); |
diff --git a/block/blk-integrity.c b/block/blk-integrity.c new file mode 100644 index 000000000000..3f1a8478cc38 --- /dev/null +++ b/block/blk-integrity.c | |||
@@ -0,0 +1,381 @@ | |||
1 | /* | ||
2 | * blk-integrity.c - Block layer data integrity extensions | ||
3 | * | ||
4 | * Copyright (C) 2007, 2008 Oracle Corporation | ||
5 | * Written by: Martin K. Petersen <martin.petersen@oracle.com> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or | ||
8 | * modify it under the terms of the GNU General Public License version | ||
9 | * 2 as published by the Free Software Foundation. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, but | ||
12 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
14 | * General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; see the file COPYING. If not, write to | ||
18 | * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, | ||
19 | * USA. | ||
20 | * | ||
21 | */ | ||
22 | |||
23 | #include <linux/blkdev.h> | ||
24 | #include <linux/mempool.h> | ||
25 | #include <linux/bio.h> | ||
26 | #include <linux/scatterlist.h> | ||
27 | |||
28 | #include "blk.h" | ||
29 | |||
30 | static struct kmem_cache *integrity_cachep; | ||
31 | |||
32 | /** | ||
33 | * blk_rq_count_integrity_sg - Count number of integrity scatterlist elements | ||
34 | * @rq: request with integrity metadata attached | ||
35 | * | ||
36 | * Description: Returns the number of elements required in a | ||
37 | * scatterlist corresponding to the integrity metadata in a request. | ||
38 | */ | ||
39 | int blk_rq_count_integrity_sg(struct request *rq) | ||
40 | { | ||
41 | struct bio_vec *iv, *ivprv; | ||
42 | struct req_iterator iter; | ||
43 | unsigned int segments; | ||
44 | |||
45 | ivprv = NULL; | ||
46 | segments = 0; | ||
47 | |||
48 | rq_for_each_integrity_segment(iv, rq, iter) { | ||
49 | |||
50 | if (!ivprv || !BIOVEC_PHYS_MERGEABLE(ivprv, iv)) | ||
51 | segments++; | ||
52 | |||
53 | ivprv = iv; | ||
54 | } | ||
55 | |||
56 | return segments; | ||
57 | } | ||
58 | EXPORT_SYMBOL(blk_rq_count_integrity_sg); | ||
59 | |||
60 | /** | ||
61 | * blk_rq_map_integrity_sg - Map integrity metadata into a scatterlist | ||
62 | * @rq: request with integrity metadata attached | ||
63 | * @sglist: target scatterlist | ||
64 | * | ||
65 | * Description: Map the integrity vectors in request into a | ||
66 | * scatterlist. The scatterlist must be big enough to hold all | ||
67 | * elements. I.e. sized using blk_rq_count_integrity_sg(). | ||
68 | */ | ||
69 | int blk_rq_map_integrity_sg(struct request *rq, struct scatterlist *sglist) | ||
70 | { | ||
71 | struct bio_vec *iv, *ivprv; | ||
72 | struct req_iterator iter; | ||
73 | struct scatterlist *sg; | ||
74 | unsigned int segments; | ||
75 | |||
76 | ivprv = NULL; | ||
77 | sg = NULL; | ||
78 | segments = 0; | ||
79 | |||
80 | rq_for_each_integrity_segment(iv, rq, iter) { | ||
81 | |||
82 | if (ivprv) { | ||
83 | if (!BIOVEC_PHYS_MERGEABLE(ivprv, iv)) | ||
84 | goto new_segment; | ||
85 | |||
86 | sg->length += iv->bv_len; | ||
87 | } else { | ||
88 | new_segment: | ||
89 | if (!sg) | ||
90 | sg = sglist; | ||
91 | else { | ||
92 | sg->page_link &= ~0x02; | ||
93 | sg = sg_next(sg); | ||
94 | } | ||
95 | |||
96 | sg_set_page(sg, iv->bv_page, iv->bv_len, iv->bv_offset); | ||
97 | segments++; | ||
98 | } | ||
99 | |||
100 | ivprv = iv; | ||
101 | } | ||
102 | |||
103 | if (sg) | ||
104 | sg_mark_end(sg); | ||
105 | |||
106 | return segments; | ||
107 | } | ||
108 | EXPORT_SYMBOL(blk_rq_map_integrity_sg); | ||
109 | |||
110 | /** | ||
111 | * blk_integrity_compare - Compare integrity profile of two block devices | ||
112 | * @b1: Device to compare | ||
113 | * @b2: Device to compare | ||
114 | * | ||
115 | * Description: Meta-devices like DM and MD need to verify that all | ||
116 | * sub-devices use the same integrity format before advertising to | ||
117 | * upper layers that they can send/receive integrity metadata. This | ||
118 | * function can be used to check whether two block devices have | ||
119 | * compatible integrity formats. | ||
120 | */ | ||
121 | int blk_integrity_compare(struct block_device *bd1, struct block_device *bd2) | ||
122 | { | ||
123 | struct blk_integrity *b1 = bd1->bd_disk->integrity; | ||
124 | struct blk_integrity *b2 = bd2->bd_disk->integrity; | ||
125 | |||
126 | BUG_ON(bd1->bd_disk == NULL); | ||
127 | BUG_ON(bd2->bd_disk == NULL); | ||
128 | |||
129 | if (!b1 || !b2) | ||
130 | return 0; | ||
131 | |||
132 | if (b1->sector_size != b2->sector_size) { | ||
133 | printk(KERN_ERR "%s: %s/%s sector sz %u != %u\n", __func__, | ||
134 | bd1->bd_disk->disk_name, bd2->bd_disk->disk_name, | ||
135 | b1->sector_size, b2->sector_size); | ||
136 | return -1; | ||
137 | } | ||
138 | |||
139 | if (b1->tuple_size != b2->tuple_size) { | ||
140 | printk(KERN_ERR "%s: %s/%s tuple sz %u != %u\n", __func__, | ||
141 | bd1->bd_disk->disk_name, bd2->bd_disk->disk_name, | ||
142 | b1->tuple_size, b2->tuple_size); | ||
143 | return -1; | ||
144 | } | ||
145 | |||
146 | if (b1->tag_size && b2->tag_size && (b1->tag_size != b2->tag_size)) { | ||
147 | printk(KERN_ERR "%s: %s/%s tag sz %u != %u\n", __func__, | ||
148 | bd1->bd_disk->disk_name, bd2->bd_disk->disk_name, | ||
149 | b1->tag_size, b2->tag_size); | ||
150 | return -1; | ||
151 | } | ||
152 | |||
153 | if (strcmp(b1->name, b2->name)) { | ||
154 | printk(KERN_ERR "%s: %s/%s type %s != %s\n", __func__, | ||
155 | bd1->bd_disk->disk_name, bd2->bd_disk->disk_name, | ||
156 | b1->name, b2->name); | ||
157 | return -1; | ||
158 | } | ||
159 | |||
160 | return 0; | ||
161 | } | ||
162 | EXPORT_SYMBOL(blk_integrity_compare); | ||
163 | |||
164 | struct integrity_sysfs_entry { | ||
165 | struct attribute attr; | ||
166 | ssize_t (*show)(struct blk_integrity *, char *); | ||
167 | ssize_t (*store)(struct blk_integrity *, const char *, size_t); | ||
168 | }; | ||
169 | |||
170 | static ssize_t integrity_attr_show(struct kobject *kobj, struct attribute *attr, | ||
171 | char *page) | ||
172 | { | ||
173 | struct blk_integrity *bi = | ||
174 | container_of(kobj, struct blk_integrity, kobj); | ||
175 | struct integrity_sysfs_entry *entry = | ||
176 | container_of(attr, struct integrity_sysfs_entry, attr); | ||
177 | |||
178 | return entry->show(bi, page); | ||
179 | } | ||
180 | |||
181 | static ssize_t integrity_attr_store(struct kobject *kobj, | ||
182 | struct attribute *attr, const char *page, | ||
183 | size_t count) | ||
184 | { | ||
185 | struct blk_integrity *bi = | ||
186 | container_of(kobj, struct blk_integrity, kobj); | ||
187 | struct integrity_sysfs_entry *entry = | ||
188 | container_of(attr, struct integrity_sysfs_entry, attr); | ||
189 | ssize_t ret = 0; | ||
190 | |||
191 | if (entry->store) | ||
192 | ret = entry->store(bi, page, count); | ||
193 | |||
194 | return ret; | ||
195 | } | ||
196 | |||
197 | static ssize_t integrity_format_show(struct blk_integrity *bi, char *page) | ||
198 | { | ||
199 | if (bi != NULL && bi->name != NULL) | ||
200 | return sprintf(page, "%s\n", bi->name); | ||
201 | else | ||
202 | return sprintf(page, "none\n"); | ||
203 | } | ||
204 | |||
205 | static ssize_t integrity_tag_size_show(struct blk_integrity *bi, char *page) | ||
206 | { | ||
207 | if (bi != NULL) | ||
208 | return sprintf(page, "%u\n", bi->tag_size); | ||
209 | else | ||
210 | return sprintf(page, "0\n"); | ||
211 | } | ||
212 | |||
213 | static ssize_t integrity_read_store(struct blk_integrity *bi, | ||
214 | const char *page, size_t count) | ||
215 | { | ||
216 | char *p = (char *) page; | ||
217 | unsigned long val = simple_strtoul(p, &p, 10); | ||
218 | |||
219 | if (val) | ||
220 | bi->flags |= INTEGRITY_FLAG_READ; | ||
221 | else | ||
222 | bi->flags &= ~INTEGRITY_FLAG_READ; | ||
223 | |||
224 | return count; | ||
225 | } | ||
226 | |||
227 | static ssize_t integrity_read_show(struct blk_integrity *bi, char *page) | ||
228 | { | ||
229 | return sprintf(page, "%d\n", (bi->flags & INTEGRITY_FLAG_READ) != 0); | ||
230 | } | ||
231 | |||
232 | static ssize_t integrity_write_store(struct blk_integrity *bi, | ||
233 | const char *page, size_t count) | ||
234 | { | ||
235 | char *p = (char *) page; | ||
236 | unsigned long val = simple_strtoul(p, &p, 10); | ||
237 | |||
238 | if (val) | ||
239 | bi->flags |= INTEGRITY_FLAG_WRITE; | ||
240 | else | ||
241 | bi->flags &= ~INTEGRITY_FLAG_WRITE; | ||
242 | |||
243 | return count; | ||
244 | } | ||
245 | |||
246 | static ssize_t integrity_write_show(struct blk_integrity *bi, char *page) | ||
247 | { | ||
248 | return sprintf(page, "%d\n", (bi->flags & INTEGRITY_FLAG_WRITE) != 0); | ||
249 | } | ||
250 | |||
251 | static struct integrity_sysfs_entry integrity_format_entry = { | ||
252 | .attr = { .name = "format", .mode = S_IRUGO }, | ||
253 | .show = integrity_format_show, | ||
254 | }; | ||
255 | |||
256 | static struct integrity_sysfs_entry integrity_tag_size_entry = { | ||
257 | .attr = { .name = "tag_size", .mode = S_IRUGO }, | ||
258 | .show = integrity_tag_size_show, | ||
259 | }; | ||
260 | |||
261 | static struct integrity_sysfs_entry integrity_read_entry = { | ||
262 | .attr = { .name = "read_verify", .mode = S_IRUGO | S_IWUSR }, | ||
263 | .show = integrity_read_show, | ||
264 | .store = integrity_read_store, | ||
265 | }; | ||
266 | |||
267 | static struct integrity_sysfs_entry integrity_write_entry = { | ||
268 | .attr = { .name = "write_generate", .mode = S_IRUGO | S_IWUSR }, | ||
269 | .show = integrity_write_show, | ||
270 | .store = integrity_write_store, | ||
271 | }; | ||
272 | |||
273 | static struct attribute *integrity_attrs[] = { | ||
274 | &integrity_format_entry.attr, | ||
275 | &integrity_tag_size_entry.attr, | ||
276 | &integrity_read_entry.attr, | ||
277 | &integrity_write_entry.attr, | ||
278 | NULL, | ||
279 | }; | ||
280 | |||
281 | static struct sysfs_ops integrity_ops = { | ||
282 | .show = &integrity_attr_show, | ||
283 | .store = &integrity_attr_store, | ||
284 | }; | ||
285 | |||
286 | static int __init blk_dev_integrity_init(void) | ||
287 | { | ||
288 | integrity_cachep = kmem_cache_create("blkdev_integrity", | ||
289 | sizeof(struct blk_integrity), | ||
290 | 0, SLAB_PANIC, NULL); | ||
291 | return 0; | ||
292 | } | ||
293 | subsys_initcall(blk_dev_integrity_init); | ||
294 | |||
295 | static void blk_integrity_release(struct kobject *kobj) | ||
296 | { | ||
297 | struct blk_integrity *bi = | ||
298 | container_of(kobj, struct blk_integrity, kobj); | ||
299 | |||
300 | kmem_cache_free(integrity_cachep, bi); | ||
301 | } | ||
302 | |||
303 | static struct kobj_type integrity_ktype = { | ||
304 | .default_attrs = integrity_attrs, | ||
305 | .sysfs_ops = &integrity_ops, | ||
306 | .release = blk_integrity_release, | ||
307 | }; | ||
308 | |||
309 | /** | ||
310 | * blk_integrity_register - Register a gendisk as being integrity-capable | ||
311 | * @disk: struct gendisk pointer to make integrity-aware | ||
312 | * @template: integrity profile | ||
313 | * | ||
314 | * Description: When a device needs to advertise itself as being able | ||
315 | * to send/receive integrity metadata it must use this function to | ||
316 | * register the capability with the block layer. The template is a | ||
317 | * blk_integrity struct with values appropriate for the underlying | ||
318 | * hardware. See Documentation/block/data-integrity.txt. | ||
319 | */ | ||
320 | int blk_integrity_register(struct gendisk *disk, struct blk_integrity *template) | ||
321 | { | ||
322 | struct blk_integrity *bi; | ||
323 | |||
324 | BUG_ON(disk == NULL); | ||
325 | BUG_ON(template == NULL); | ||
326 | |||
327 | if (disk->integrity == NULL) { | ||
328 | bi = kmem_cache_alloc(integrity_cachep, | ||
329 | GFP_KERNEL | __GFP_ZERO); | ||
330 | if (!bi) | ||
331 | return -1; | ||
332 | |||
333 | if (kobject_init_and_add(&bi->kobj, &integrity_ktype, | ||
334 | &disk->dev.kobj, "%s", "integrity")) { | ||
335 | kmem_cache_free(integrity_cachep, bi); | ||
336 | return -1; | ||
337 | } | ||
338 | |||
339 | kobject_uevent(&bi->kobj, KOBJ_ADD); | ||
340 | |||
341 | bi->flags |= INTEGRITY_FLAG_READ | INTEGRITY_FLAG_WRITE; | ||
342 | bi->sector_size = disk->queue->hardsect_size; | ||
343 | disk->integrity = bi; | ||
344 | } else | ||
345 | bi = disk->integrity; | ||
346 | |||
347 | /* Use the provided profile as template */ | ||
348 | bi->name = template->name; | ||
349 | bi->generate_fn = template->generate_fn; | ||
350 | bi->verify_fn = template->verify_fn; | ||
351 | bi->tuple_size = template->tuple_size; | ||
352 | bi->set_tag_fn = template->set_tag_fn; | ||
353 | bi->get_tag_fn = template->get_tag_fn; | ||
354 | bi->tag_size = template->tag_size; | ||
355 | |||
356 | return 0; | ||
357 | } | ||
358 | EXPORT_SYMBOL(blk_integrity_register); | ||
359 | |||
360 | /** | ||
361 | * blk_integrity_unregister - Remove block integrity profile | ||
362 | * @disk: disk whose integrity profile to deallocate | ||
363 | * | ||
364 | * Description: This function frees all memory used by the block | ||
365 | * integrity profile. To be called at device teardown. | ||
366 | */ | ||
367 | void blk_integrity_unregister(struct gendisk *disk) | ||
368 | { | ||
369 | struct blk_integrity *bi; | ||
370 | |||
371 | if (!disk || !disk->integrity) | ||
372 | return; | ||
373 | |||
374 | bi = disk->integrity; | ||
375 | |||
376 | kobject_uevent(&bi->kobj, KOBJ_REMOVE); | ||
377 | kobject_del(&bi->kobj); | ||
378 | kobject_put(&disk->dev.kobj); | ||
379 | kmem_cache_free(integrity_cachep, bi); | ||
380 | } | ||
381 | EXPORT_SYMBOL(blk_integrity_unregister); | ||
diff --git a/block/blk-map.c b/block/blk-map.c index 0b1af5a3537c..ddd96fb11a7d 100644 --- a/block/blk-map.c +++ b/block/blk-map.c | |||
@@ -210,6 +210,7 @@ int blk_rq_map_user_iov(struct request_queue *q, struct request *rq, | |||
210 | if (!bio_flagged(bio, BIO_USER_MAPPED)) | 210 | if (!bio_flagged(bio, BIO_USER_MAPPED)) |
211 | rq->cmd_flags |= REQ_COPY_USER; | 211 | rq->cmd_flags |= REQ_COPY_USER; |
212 | 212 | ||
213 | blk_queue_bounce(q, &bio); | ||
213 | bio_get(bio); | 214 | bio_get(bio); |
214 | blk_rq_bio_prep(q, rq, bio); | 215 | blk_rq_bio_prep(q, rq, bio); |
215 | rq->buffer = rq->data = NULL; | 216 | rq->buffer = rq->data = NULL; |
@@ -268,6 +269,7 @@ int blk_rq_map_kern(struct request_queue *q, struct request *rq, void *kbuf, | |||
268 | int reading = rq_data_dir(rq) == READ; | 269 | int reading = rq_data_dir(rq) == READ; |
269 | int do_copy = 0; | 270 | int do_copy = 0; |
270 | struct bio *bio; | 271 | struct bio *bio; |
272 | unsigned long stack_mask = ~(THREAD_SIZE - 1); | ||
271 | 273 | ||
272 | if (len > (q->max_hw_sectors << 9)) | 274 | if (len > (q->max_hw_sectors << 9)) |
273 | return -EINVAL; | 275 | return -EINVAL; |
@@ -278,6 +280,10 @@ int blk_rq_map_kern(struct request_queue *q, struct request *rq, void *kbuf, | |||
278 | alignment = queue_dma_alignment(q) | q->dma_pad_mask; | 280 | alignment = queue_dma_alignment(q) | q->dma_pad_mask; |
279 | do_copy = ((kaddr & alignment) || (len & alignment)); | 281 | do_copy = ((kaddr & alignment) || (len & alignment)); |
280 | 282 | ||
283 | if (!((kaddr & stack_mask) ^ | ||
284 | ((unsigned long)current->stack & stack_mask))) | ||
285 | do_copy = 1; | ||
286 | |||
281 | if (do_copy) | 287 | if (do_copy) |
282 | bio = bio_copy_kern(q, kbuf, len, gfp_mask, reading); | 288 | bio = bio_copy_kern(q, kbuf, len, gfp_mask, reading); |
283 | else | 289 | else |
diff --git a/block/blk-merge.c b/block/blk-merge.c index 651136aae76e..5efc9e7a68b7 100644 --- a/block/blk-merge.c +++ b/block/blk-merge.c | |||
@@ -441,6 +441,9 @@ static int attempt_merge(struct request_queue *q, struct request *req, | |||
441 | || next->special) | 441 | || next->special) |
442 | return 0; | 442 | return 0; |
443 | 443 | ||
444 | if (blk_integrity_rq(req) != blk_integrity_rq(next)) | ||
445 | return 0; | ||
446 | |||
444 | /* | 447 | /* |
445 | * If we are allowed to merge, then append bio list | 448 | * If we are allowed to merge, then append bio list |
446 | * from next to rq and release next. merge_requests_fn | 449 | * from next to rq and release next. merge_requests_fn |
diff --git a/block/blk-settings.c b/block/blk-settings.c index 8dd86418f35d..dfc77012843f 100644 --- a/block/blk-settings.c +++ b/block/blk-settings.c | |||
@@ -302,11 +302,10 @@ EXPORT_SYMBOL(blk_queue_stack_limits); | |||
302 | * @q: the request queue for the device | 302 | * @q: the request queue for the device |
303 | * @mask: pad mask | 303 | * @mask: pad mask |
304 | * | 304 | * |
305 | * Set pad mask. Direct IO requests are padded to the mask specified. | 305 | * Set dma pad mask. |
306 | * | 306 | * |
307 | * Appending pad buffer to a request modifies ->data_len such that it | 307 | * Appending pad buffer to a request modifies the last entry of a |
308 | * includes the pad buffer. The original requested data length can be | 308 | * scatter list such that it includes the pad buffer. |
309 | * obtained using blk_rq_raw_data_len(). | ||
310 | **/ | 309 | **/ |
311 | void blk_queue_dma_pad(struct request_queue *q, unsigned int mask) | 310 | void blk_queue_dma_pad(struct request_queue *q, unsigned int mask) |
312 | { | 311 | { |
@@ -315,6 +314,23 @@ void blk_queue_dma_pad(struct request_queue *q, unsigned int mask) | |||
315 | EXPORT_SYMBOL(blk_queue_dma_pad); | 314 | EXPORT_SYMBOL(blk_queue_dma_pad); |
316 | 315 | ||
317 | /** | 316 | /** |
317 | * blk_queue_update_dma_pad - update pad mask | ||
318 | * @q: the request queue for the device | ||
319 | * @mask: pad mask | ||
320 | * | ||
321 | * Update dma pad mask. | ||
322 | * | ||
323 | * Appending pad buffer to a request modifies the last entry of a | ||
324 | * scatter list such that it includes the pad buffer. | ||
325 | **/ | ||
326 | void blk_queue_update_dma_pad(struct request_queue *q, unsigned int mask) | ||
327 | { | ||
328 | if (mask > q->dma_pad_mask) | ||
329 | q->dma_pad_mask = mask; | ||
330 | } | ||
331 | EXPORT_SYMBOL(blk_queue_update_dma_pad); | ||
332 | |||
333 | /** | ||
318 | * blk_queue_dma_drain - Set up a drain buffer for excess dma. | 334 | * blk_queue_dma_drain - Set up a drain buffer for excess dma. |
319 | * @q: the request queue for the device | 335 | * @q: the request queue for the device |
320 | * @dma_drain_needed: fn which returns non-zero if drain is necessary | 336 | * @dma_drain_needed: fn which returns non-zero if drain is necessary |
diff --git a/block/blk.h b/block/blk.h index 59776ab4742a..c79f30e1df52 100644 --- a/block/blk.h +++ b/block/blk.h | |||
@@ -51,4 +51,12 @@ static inline int queue_congestion_off_threshold(struct request_queue *q) | |||
51 | return q->nr_congestion_off; | 51 | return q->nr_congestion_off; |
52 | } | 52 | } |
53 | 53 | ||
54 | #if defined(CONFIG_BLK_DEV_INTEGRITY) | ||
55 | |||
56 | #define rq_for_each_integrity_segment(bvl, _rq, _iter) \ | ||
57 | __rq_for_each_bio(_iter.bio, _rq) \ | ||
58 | bip_for_each_vec(bvl, _iter.bio->bi_integrity, _iter.i) | ||
59 | |||
60 | #endif /* BLK_DEV_INTEGRITY */ | ||
61 | |||
54 | #endif | 62 | #endif |
diff --git a/block/blktrace.c b/block/blktrace.c index 8d3a27780260..eb9651ccb241 100644 --- a/block/blktrace.c +++ b/block/blktrace.c | |||
@@ -244,6 +244,7 @@ err: | |||
244 | static void blk_trace_cleanup(struct blk_trace *bt) | 244 | static void blk_trace_cleanup(struct blk_trace *bt) |
245 | { | 245 | { |
246 | relay_close(bt->rchan); | 246 | relay_close(bt->rchan); |
247 | debugfs_remove(bt->msg_file); | ||
247 | debugfs_remove(bt->dropped_file); | 248 | debugfs_remove(bt->dropped_file); |
248 | blk_remove_tree(bt->dir); | 249 | blk_remove_tree(bt->dir); |
249 | free_percpu(bt->sequence); | 250 | free_percpu(bt->sequence); |
@@ -291,6 +292,44 @@ static const struct file_operations blk_dropped_fops = { | |||
291 | .read = blk_dropped_read, | 292 | .read = blk_dropped_read, |
292 | }; | 293 | }; |
293 | 294 | ||
295 | static int blk_msg_open(struct inode *inode, struct file *filp) | ||
296 | { | ||
297 | filp->private_data = inode->i_private; | ||
298 | |||
299 | return 0; | ||
300 | } | ||
301 | |||
302 | static ssize_t blk_msg_write(struct file *filp, const char __user *buffer, | ||
303 | size_t count, loff_t *ppos) | ||
304 | { | ||
305 | char *msg; | ||
306 | struct blk_trace *bt; | ||
307 | |||
308 | if (count > BLK_TN_MAX_MSG) | ||
309 | return -EINVAL; | ||
310 | |||
311 | msg = kmalloc(count, GFP_KERNEL); | ||
312 | if (msg == NULL) | ||
313 | return -ENOMEM; | ||
314 | |||
315 | if (copy_from_user(msg, buffer, count)) { | ||
316 | kfree(msg); | ||
317 | return -EFAULT; | ||
318 | } | ||
319 | |||
320 | bt = filp->private_data; | ||
321 | __trace_note_message(bt, "%s", msg); | ||
322 | kfree(msg); | ||
323 | |||
324 | return count; | ||
325 | } | ||
326 | |||
327 | static const struct file_operations blk_msg_fops = { | ||
328 | .owner = THIS_MODULE, | ||
329 | .open = blk_msg_open, | ||
330 | .write = blk_msg_write, | ||
331 | }; | ||
332 | |||
294 | /* | 333 | /* |
295 | * Keep track of how many times we encountered a full subbuffer, to aid | 334 | * Keep track of how many times we encountered a full subbuffer, to aid |
296 | * the user space app in telling how many lost events there were. | 335 | * the user space app in telling how many lost events there were. |
@@ -380,6 +419,10 @@ int do_blk_trace_setup(struct request_queue *q, char *name, dev_t dev, | |||
380 | if (!bt->dropped_file) | 419 | if (!bt->dropped_file) |
381 | goto err; | 420 | goto err; |
382 | 421 | ||
422 | bt->msg_file = debugfs_create_file("msg", 0222, dir, bt, &blk_msg_fops); | ||
423 | if (!bt->msg_file) | ||
424 | goto err; | ||
425 | |||
383 | bt->rchan = relay_open("trace", dir, buts->buf_size, | 426 | bt->rchan = relay_open("trace", dir, buts->buf_size, |
384 | buts->buf_nr, &blk_relay_callbacks, bt); | 427 | buts->buf_nr, &blk_relay_callbacks, bt); |
385 | if (!bt->rchan) | 428 | if (!bt->rchan) |
@@ -409,6 +452,8 @@ err: | |||
409 | if (dir) | 452 | if (dir) |
410 | blk_remove_tree(dir); | 453 | blk_remove_tree(dir); |
411 | if (bt) { | 454 | if (bt) { |
455 | if (bt->msg_file) | ||
456 | debugfs_remove(bt->msg_file); | ||
412 | if (bt->dropped_file) | 457 | if (bt->dropped_file) |
413 | debugfs_remove(bt->dropped_file); | 458 | debugfs_remove(bt->dropped_file); |
414 | free_percpu(bt->sequence); | 459 | free_percpu(bt->sequence); |
diff --git a/block/bsg.c b/block/bsg.c index 54d617f7df3e..93e757d7174b 100644 --- a/block/bsg.c +++ b/block/bsg.c | |||
@@ -44,11 +44,12 @@ struct bsg_device { | |||
44 | char name[BUS_ID_SIZE]; | 44 | char name[BUS_ID_SIZE]; |
45 | int max_queue; | 45 | int max_queue; |
46 | unsigned long flags; | 46 | unsigned long flags; |
47 | struct blk_scsi_cmd_filter *cmd_filter; | ||
48 | mode_t *f_mode; | ||
47 | }; | 49 | }; |
48 | 50 | ||
49 | enum { | 51 | enum { |
50 | BSG_F_BLOCK = 1, | 52 | BSG_F_BLOCK = 1, |
51 | BSG_F_WRITE_PERM = 2, | ||
52 | }; | 53 | }; |
53 | 54 | ||
54 | #define BSG_DEFAULT_CMDS 64 | 55 | #define BSG_DEFAULT_CMDS 64 |
@@ -172,7 +173,7 @@ unlock: | |||
172 | } | 173 | } |
173 | 174 | ||
174 | static int blk_fill_sgv4_hdr_rq(struct request_queue *q, struct request *rq, | 175 | static int blk_fill_sgv4_hdr_rq(struct request_queue *q, struct request *rq, |
175 | struct sg_io_v4 *hdr, int has_write_perm) | 176 | struct sg_io_v4 *hdr, struct bsg_device *bd) |
176 | { | 177 | { |
177 | if (hdr->request_len > BLK_MAX_CDB) { | 178 | if (hdr->request_len > BLK_MAX_CDB) { |
178 | rq->cmd = kzalloc(hdr->request_len, GFP_KERNEL); | 179 | rq->cmd = kzalloc(hdr->request_len, GFP_KERNEL); |
@@ -185,7 +186,8 @@ static int blk_fill_sgv4_hdr_rq(struct request_queue *q, struct request *rq, | |||
185 | return -EFAULT; | 186 | return -EFAULT; |
186 | 187 | ||
187 | if (hdr->subprotocol == BSG_SUB_PROTOCOL_SCSI_CMD) { | 188 | if (hdr->subprotocol == BSG_SUB_PROTOCOL_SCSI_CMD) { |
188 | if (blk_verify_command(rq->cmd, has_write_perm)) | 189 | if (blk_cmd_filter_verify_command(bd->cmd_filter, rq->cmd, |
190 | bd->f_mode)) | ||
189 | return -EPERM; | 191 | return -EPERM; |
190 | } else if (!capable(CAP_SYS_RAWIO)) | 192 | } else if (!capable(CAP_SYS_RAWIO)) |
191 | return -EPERM; | 193 | return -EPERM; |
@@ -263,8 +265,7 @@ bsg_map_hdr(struct bsg_device *bd, struct sg_io_v4 *hdr) | |||
263 | rq = blk_get_request(q, rw, GFP_KERNEL); | 265 | rq = blk_get_request(q, rw, GFP_KERNEL); |
264 | if (!rq) | 266 | if (!rq) |
265 | return ERR_PTR(-ENOMEM); | 267 | return ERR_PTR(-ENOMEM); |
266 | ret = blk_fill_sgv4_hdr_rq(q, rq, hdr, test_bit(BSG_F_WRITE_PERM, | 268 | ret = blk_fill_sgv4_hdr_rq(q, rq, hdr, bd); |
267 | &bd->flags)); | ||
268 | if (ret) | 269 | if (ret) |
269 | goto out; | 270 | goto out; |
270 | 271 | ||
@@ -566,12 +567,23 @@ static inline void bsg_set_block(struct bsg_device *bd, struct file *file) | |||
566 | set_bit(BSG_F_BLOCK, &bd->flags); | 567 | set_bit(BSG_F_BLOCK, &bd->flags); |
567 | } | 568 | } |
568 | 569 | ||
569 | static inline void bsg_set_write_perm(struct bsg_device *bd, struct file *file) | 570 | static void bsg_set_cmd_filter(struct bsg_device *bd, |
571 | struct file *file) | ||
570 | { | 572 | { |
571 | if (file->f_mode & FMODE_WRITE) | 573 | struct inode *inode; |
572 | set_bit(BSG_F_WRITE_PERM, &bd->flags); | 574 | struct gendisk *disk; |
573 | else | 575 | |
574 | clear_bit(BSG_F_WRITE_PERM, &bd->flags); | 576 | if (!file) |
577 | return; | ||
578 | |||
579 | inode = file->f_dentry->d_inode; | ||
580 | if (!inode) | ||
581 | return; | ||
582 | |||
583 | disk = inode->i_bdev->bd_disk; | ||
584 | |||
585 | bd->cmd_filter = &disk->cmd_filter; | ||
586 | bd->f_mode = &file->f_mode; | ||
575 | } | 587 | } |
576 | 588 | ||
577 | /* | 589 | /* |
@@ -595,6 +607,8 @@ bsg_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) | |||
595 | dprintk("%s: read %Zd bytes\n", bd->name, count); | 607 | dprintk("%s: read %Zd bytes\n", bd->name, count); |
596 | 608 | ||
597 | bsg_set_block(bd, file); | 609 | bsg_set_block(bd, file); |
610 | bsg_set_cmd_filter(bd, file); | ||
611 | |||
598 | bytes_read = 0; | 612 | bytes_read = 0; |
599 | ret = __bsg_read(buf, count, bd, NULL, &bytes_read); | 613 | ret = __bsg_read(buf, count, bd, NULL, &bytes_read); |
600 | *ppos = bytes_read; | 614 | *ppos = bytes_read; |
@@ -668,7 +682,7 @@ bsg_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) | |||
668 | dprintk("%s: write %Zd bytes\n", bd->name, count); | 682 | dprintk("%s: write %Zd bytes\n", bd->name, count); |
669 | 683 | ||
670 | bsg_set_block(bd, file); | 684 | bsg_set_block(bd, file); |
671 | bsg_set_write_perm(bd, file); | 685 | bsg_set_cmd_filter(bd, file); |
672 | 686 | ||
673 | bytes_written = 0; | 687 | bytes_written = 0; |
674 | ret = __bsg_write(bd, buf, count, &bytes_written); | 688 | ret = __bsg_write(bd, buf, count, &bytes_written); |
@@ -772,7 +786,9 @@ static struct bsg_device *bsg_add_device(struct inode *inode, | |||
772 | } | 786 | } |
773 | 787 | ||
774 | bd->queue = rq; | 788 | bd->queue = rq; |
789 | |||
775 | bsg_set_block(bd, file); | 790 | bsg_set_block(bd, file); |
791 | bsg_set_cmd_filter(bd, file); | ||
776 | 792 | ||
777 | atomic_set(&bd->ref_count, 1); | 793 | atomic_set(&bd->ref_count, 1); |
778 | mutex_lock(&bsg_mutex); | 794 | mutex_lock(&bsg_mutex); |
diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c index d01b411c72f0..1e2aff812ee2 100644 --- a/block/cfq-iosched.c +++ b/block/cfq-iosched.c | |||
@@ -11,6 +11,7 @@ | |||
11 | #include <linux/elevator.h> | 11 | #include <linux/elevator.h> |
12 | #include <linux/rbtree.h> | 12 | #include <linux/rbtree.h> |
13 | #include <linux/ioprio.h> | 13 | #include <linux/ioprio.h> |
14 | #include <linux/blktrace_api.h> | ||
14 | 15 | ||
15 | /* | 16 | /* |
16 | * tunables | 17 | * tunables |
@@ -41,13 +42,14 @@ static int cfq_slice_idle = HZ / 125; | |||
41 | 42 | ||
42 | #define RQ_CIC(rq) \ | 43 | #define RQ_CIC(rq) \ |
43 | ((struct cfq_io_context *) (rq)->elevator_private) | 44 | ((struct cfq_io_context *) (rq)->elevator_private) |
44 | #define RQ_CFQQ(rq) ((rq)->elevator_private2) | 45 | #define RQ_CFQQ(rq) (struct cfq_queue *) ((rq)->elevator_private2) |
45 | 46 | ||
46 | static struct kmem_cache *cfq_pool; | 47 | static struct kmem_cache *cfq_pool; |
47 | static struct kmem_cache *cfq_ioc_pool; | 48 | static struct kmem_cache *cfq_ioc_pool; |
48 | 49 | ||
49 | static DEFINE_PER_CPU(unsigned long, ioc_count); | 50 | static DEFINE_PER_CPU(unsigned long, ioc_count); |
50 | static struct completion *ioc_gone; | 51 | static struct completion *ioc_gone; |
52 | static DEFINE_SPINLOCK(ioc_gone_lock); | ||
51 | 53 | ||
52 | #define CFQ_PRIO_LISTS IOPRIO_BE_NR | 54 | #define CFQ_PRIO_LISTS IOPRIO_BE_NR |
53 | #define cfq_class_idle(cfqq) ((cfqq)->ioprio_class == IOPRIO_CLASS_IDLE) | 55 | #define cfq_class_idle(cfqq) ((cfqq)->ioprio_class == IOPRIO_CLASS_IDLE) |
@@ -155,6 +157,7 @@ struct cfq_queue { | |||
155 | unsigned short ioprio, org_ioprio; | 157 | unsigned short ioprio, org_ioprio; |
156 | unsigned short ioprio_class, org_ioprio_class; | 158 | unsigned short ioprio_class, org_ioprio_class; |
157 | 159 | ||
160 | pid_t pid; | ||
158 | }; | 161 | }; |
159 | 162 | ||
160 | enum cfqq_state_flags { | 163 | enum cfqq_state_flags { |
@@ -198,6 +201,11 @@ CFQ_CFQQ_FNS(slice_new); | |||
198 | CFQ_CFQQ_FNS(sync); | 201 | CFQ_CFQQ_FNS(sync); |
199 | #undef CFQ_CFQQ_FNS | 202 | #undef CFQ_CFQQ_FNS |
200 | 203 | ||
204 | #define cfq_log_cfqq(cfqd, cfqq, fmt, args...) \ | ||
205 | blk_add_trace_msg((cfqd)->queue, "cfq%d " fmt, (cfqq)->pid, ##args) | ||
206 | #define cfq_log(cfqd, fmt, args...) \ | ||
207 | blk_add_trace_msg((cfqd)->queue, "cfq " fmt, ##args) | ||
208 | |||
201 | static void cfq_dispatch_insert(struct request_queue *, struct request *); | 209 | static void cfq_dispatch_insert(struct request_queue *, struct request *); |
202 | static struct cfq_queue *cfq_get_queue(struct cfq_data *, int, | 210 | static struct cfq_queue *cfq_get_queue(struct cfq_data *, int, |
203 | struct io_context *, gfp_t); | 211 | struct io_context *, gfp_t); |
@@ -234,8 +242,10 @@ static inline int cfq_bio_sync(struct bio *bio) | |||
234 | */ | 242 | */ |
235 | static inline void cfq_schedule_dispatch(struct cfq_data *cfqd) | 243 | static inline void cfq_schedule_dispatch(struct cfq_data *cfqd) |
236 | { | 244 | { |
237 | if (cfqd->busy_queues) | 245 | if (cfqd->busy_queues) { |
246 | cfq_log(cfqd, "schedule dispatch"); | ||
238 | kblockd_schedule_work(&cfqd->unplug_work); | 247 | kblockd_schedule_work(&cfqd->unplug_work); |
248 | } | ||
239 | } | 249 | } |
240 | 250 | ||
241 | static int cfq_queue_empty(struct request_queue *q) | 251 | static int cfq_queue_empty(struct request_queue *q) |
@@ -270,6 +280,7 @@ static inline void | |||
270 | cfq_set_prio_slice(struct cfq_data *cfqd, struct cfq_queue *cfqq) | 280 | cfq_set_prio_slice(struct cfq_data *cfqd, struct cfq_queue *cfqq) |
271 | { | 281 | { |
272 | cfqq->slice_end = cfq_prio_to_slice(cfqd, cfqq) + jiffies; | 282 | cfqq->slice_end = cfq_prio_to_slice(cfqd, cfqq) + jiffies; |
283 | cfq_log_cfqq(cfqd, cfqq, "set_slice=%lu", cfqq->slice_end - jiffies); | ||
273 | } | 284 | } |
274 | 285 | ||
275 | /* | 286 | /* |
@@ -539,6 +550,7 @@ static void cfq_resort_rr_list(struct cfq_data *cfqd, struct cfq_queue *cfqq) | |||
539 | */ | 550 | */ |
540 | static void cfq_add_cfqq_rr(struct cfq_data *cfqd, struct cfq_queue *cfqq) | 551 | static void cfq_add_cfqq_rr(struct cfq_data *cfqd, struct cfq_queue *cfqq) |
541 | { | 552 | { |
553 | cfq_log_cfqq(cfqd, cfqq, "add_to_rr"); | ||
542 | BUG_ON(cfq_cfqq_on_rr(cfqq)); | 554 | BUG_ON(cfq_cfqq_on_rr(cfqq)); |
543 | cfq_mark_cfqq_on_rr(cfqq); | 555 | cfq_mark_cfqq_on_rr(cfqq); |
544 | cfqd->busy_queues++; | 556 | cfqd->busy_queues++; |
@@ -552,6 +564,7 @@ static void cfq_add_cfqq_rr(struct cfq_data *cfqd, struct cfq_queue *cfqq) | |||
552 | */ | 564 | */ |
553 | static void cfq_del_cfqq_rr(struct cfq_data *cfqd, struct cfq_queue *cfqq) | 565 | static void cfq_del_cfqq_rr(struct cfq_data *cfqd, struct cfq_queue *cfqq) |
554 | { | 566 | { |
567 | cfq_log_cfqq(cfqd, cfqq, "del_from_rr"); | ||
555 | BUG_ON(!cfq_cfqq_on_rr(cfqq)); | 568 | BUG_ON(!cfq_cfqq_on_rr(cfqq)); |
556 | cfq_clear_cfqq_on_rr(cfqq); | 569 | cfq_clear_cfqq_on_rr(cfqq); |
557 | 570 | ||
@@ -638,6 +651,8 @@ static void cfq_activate_request(struct request_queue *q, struct request *rq) | |||
638 | struct cfq_data *cfqd = q->elevator->elevator_data; | 651 | struct cfq_data *cfqd = q->elevator->elevator_data; |
639 | 652 | ||
640 | cfqd->rq_in_driver++; | 653 | cfqd->rq_in_driver++; |
654 | cfq_log_cfqq(cfqd, RQ_CFQQ(rq), "activate rq, drv=%d", | ||
655 | cfqd->rq_in_driver); | ||
641 | 656 | ||
642 | /* | 657 | /* |
643 | * If the depth is larger 1, it really could be queueing. But lets | 658 | * If the depth is larger 1, it really could be queueing. But lets |
@@ -657,6 +672,8 @@ static void cfq_deactivate_request(struct request_queue *q, struct request *rq) | |||
657 | 672 | ||
658 | WARN_ON(!cfqd->rq_in_driver); | 673 | WARN_ON(!cfqd->rq_in_driver); |
659 | cfqd->rq_in_driver--; | 674 | cfqd->rq_in_driver--; |
675 | cfq_log_cfqq(cfqd, RQ_CFQQ(rq), "deactivate rq, drv=%d", | ||
676 | cfqd->rq_in_driver); | ||
660 | } | 677 | } |
661 | 678 | ||
662 | static void cfq_remove_request(struct request *rq) | 679 | static void cfq_remove_request(struct request *rq) |
@@ -746,6 +763,7 @@ static void __cfq_set_active_queue(struct cfq_data *cfqd, | |||
746 | struct cfq_queue *cfqq) | 763 | struct cfq_queue *cfqq) |
747 | { | 764 | { |
748 | if (cfqq) { | 765 | if (cfqq) { |
766 | cfq_log_cfqq(cfqd, cfqq, "set_active"); | ||
749 | cfqq->slice_end = 0; | 767 | cfqq->slice_end = 0; |
750 | cfq_clear_cfqq_must_alloc_slice(cfqq); | 768 | cfq_clear_cfqq_must_alloc_slice(cfqq); |
751 | cfq_clear_cfqq_fifo_expire(cfqq); | 769 | cfq_clear_cfqq_fifo_expire(cfqq); |
@@ -763,6 +781,8 @@ static void | |||
763 | __cfq_slice_expired(struct cfq_data *cfqd, struct cfq_queue *cfqq, | 781 | __cfq_slice_expired(struct cfq_data *cfqd, struct cfq_queue *cfqq, |
764 | int timed_out) | 782 | int timed_out) |
765 | { | 783 | { |
784 | cfq_log_cfqq(cfqd, cfqq, "slice expired t=%d", timed_out); | ||
785 | |||
766 | if (cfq_cfqq_wait_request(cfqq)) | 786 | if (cfq_cfqq_wait_request(cfqq)) |
767 | del_timer(&cfqd->idle_slice_timer); | 787 | del_timer(&cfqd->idle_slice_timer); |
768 | 788 | ||
@@ -772,8 +792,10 @@ __cfq_slice_expired(struct cfq_data *cfqd, struct cfq_queue *cfqq, | |||
772 | /* | 792 | /* |
773 | * store what was left of this slice, if the queue idled/timed out | 793 | * store what was left of this slice, if the queue idled/timed out |
774 | */ | 794 | */ |
775 | if (timed_out && !cfq_cfqq_slice_new(cfqq)) | 795 | if (timed_out && !cfq_cfqq_slice_new(cfqq)) { |
776 | cfqq->slice_resid = cfqq->slice_end - jiffies; | 796 | cfqq->slice_resid = cfqq->slice_end - jiffies; |
797 | cfq_log_cfqq(cfqd, cfqq, "resid=%ld", cfqq->slice_resid); | ||
798 | } | ||
777 | 799 | ||
778 | cfq_resort_rr_list(cfqd, cfqq); | 800 | cfq_resort_rr_list(cfqd, cfqq); |
779 | 801 | ||
@@ -866,6 +888,12 @@ static void cfq_arm_slice_timer(struct cfq_data *cfqd) | |||
866 | return; | 888 | return; |
867 | 889 | ||
868 | /* | 890 | /* |
891 | * still requests with the driver, don't idle | ||
892 | */ | ||
893 | if (cfqd->rq_in_driver) | ||
894 | return; | ||
895 | |||
896 | /* | ||
869 | * task has exited, don't wait | 897 | * task has exited, don't wait |
870 | */ | 898 | */ |
871 | cic = cfqd->active_cic; | 899 | cic = cfqd->active_cic; |
@@ -892,6 +920,7 @@ static void cfq_arm_slice_timer(struct cfq_data *cfqd) | |||
892 | sl = min(sl, msecs_to_jiffies(CFQ_MIN_TT)); | 920 | sl = min(sl, msecs_to_jiffies(CFQ_MIN_TT)); |
893 | 921 | ||
894 | mod_timer(&cfqd->idle_slice_timer, jiffies + sl); | 922 | mod_timer(&cfqd->idle_slice_timer, jiffies + sl); |
923 | cfq_log(cfqd, "arm_idle: %lu", sl); | ||
895 | } | 924 | } |
896 | 925 | ||
897 | /* | 926 | /* |
@@ -902,6 +931,8 @@ static void cfq_dispatch_insert(struct request_queue *q, struct request *rq) | |||
902 | struct cfq_data *cfqd = q->elevator->elevator_data; | 931 | struct cfq_data *cfqd = q->elevator->elevator_data; |
903 | struct cfq_queue *cfqq = RQ_CFQQ(rq); | 932 | struct cfq_queue *cfqq = RQ_CFQQ(rq); |
904 | 933 | ||
934 | cfq_log_cfqq(cfqd, cfqq, "dispatch_insert"); | ||
935 | |||
905 | cfq_remove_request(rq); | 936 | cfq_remove_request(rq); |
906 | cfqq->dispatched++; | 937 | cfqq->dispatched++; |
907 | elv_dispatch_sort(q, rq); | 938 | elv_dispatch_sort(q, rq); |
@@ -931,8 +962,9 @@ static struct request *cfq_check_fifo(struct cfq_queue *cfqq) | |||
931 | rq = rq_entry_fifo(cfqq->fifo.next); | 962 | rq = rq_entry_fifo(cfqq->fifo.next); |
932 | 963 | ||
933 | if (time_before(jiffies, rq->start_time + cfqd->cfq_fifo_expire[fifo])) | 964 | if (time_before(jiffies, rq->start_time + cfqd->cfq_fifo_expire[fifo])) |
934 | return NULL; | 965 | rq = NULL; |
935 | 966 | ||
967 | cfq_log_cfqq(cfqd, cfqq, "fifo=%p", rq); | ||
936 | return rq; | 968 | return rq; |
937 | } | 969 | } |
938 | 970 | ||
@@ -1072,6 +1104,7 @@ static int cfq_forced_dispatch(struct cfq_data *cfqd) | |||
1072 | 1104 | ||
1073 | BUG_ON(cfqd->busy_queues); | 1105 | BUG_ON(cfqd->busy_queues); |
1074 | 1106 | ||
1107 | cfq_log(cfqd, "forced_dispatch=%d\n", dispatched); | ||
1075 | return dispatched; | 1108 | return dispatched; |
1076 | } | 1109 | } |
1077 | 1110 | ||
@@ -1112,6 +1145,7 @@ static int cfq_dispatch_requests(struct request_queue *q, int force) | |||
1112 | dispatched += __cfq_dispatch_requests(cfqd, cfqq, max_dispatch); | 1145 | dispatched += __cfq_dispatch_requests(cfqd, cfqq, max_dispatch); |
1113 | } | 1146 | } |
1114 | 1147 | ||
1148 | cfq_log(cfqd, "dispatched=%d", dispatched); | ||
1115 | return dispatched; | 1149 | return dispatched; |
1116 | } | 1150 | } |
1117 | 1151 | ||
@@ -1130,6 +1164,7 @@ static void cfq_put_queue(struct cfq_queue *cfqq) | |||
1130 | if (!atomic_dec_and_test(&cfqq->ref)) | 1164 | if (!atomic_dec_and_test(&cfqq->ref)) |
1131 | return; | 1165 | return; |
1132 | 1166 | ||
1167 | cfq_log_cfqq(cfqd, cfqq, "put_queue"); | ||
1133 | BUG_ON(rb_first(&cfqq->sort_list)); | 1168 | BUG_ON(rb_first(&cfqq->sort_list)); |
1134 | BUG_ON(cfqq->allocated[READ] + cfqq->allocated[WRITE]); | 1169 | BUG_ON(cfqq->allocated[READ] + cfqq->allocated[WRITE]); |
1135 | BUG_ON(cfq_cfqq_on_rr(cfqq)); | 1170 | BUG_ON(cfq_cfqq_on_rr(cfqq)); |
@@ -1177,8 +1212,19 @@ static void cfq_cic_free_rcu(struct rcu_head *head) | |||
1177 | kmem_cache_free(cfq_ioc_pool, cic); | 1212 | kmem_cache_free(cfq_ioc_pool, cic); |
1178 | elv_ioc_count_dec(ioc_count); | 1213 | elv_ioc_count_dec(ioc_count); |
1179 | 1214 | ||
1180 | if (ioc_gone && !elv_ioc_count_read(ioc_count)) | 1215 | if (ioc_gone) { |
1181 | complete(ioc_gone); | 1216 | /* |
1217 | * CFQ scheduler is exiting, grab exit lock and check | ||
1218 | * the pending io context count. If it hits zero, | ||
1219 | * complete ioc_gone and set it back to NULL | ||
1220 | */ | ||
1221 | spin_lock(&ioc_gone_lock); | ||
1222 | if (ioc_gone && !elv_ioc_count_read(ioc_count)) { | ||
1223 | complete(ioc_gone); | ||
1224 | ioc_gone = NULL; | ||
1225 | } | ||
1226 | spin_unlock(&ioc_gone_lock); | ||
1227 | } | ||
1182 | } | 1228 | } |
1183 | 1229 | ||
1184 | static void cfq_cic_free(struct cfq_io_context *cic) | 1230 | static void cfq_cic_free(struct cfq_io_context *cic) |
@@ -1427,6 +1473,8 @@ retry: | |||
1427 | cfq_mark_cfqq_idle_window(cfqq); | 1473 | cfq_mark_cfqq_idle_window(cfqq); |
1428 | cfq_mark_cfqq_sync(cfqq); | 1474 | cfq_mark_cfqq_sync(cfqq); |
1429 | } | 1475 | } |
1476 | cfqq->pid = current->pid; | ||
1477 | cfq_log_cfqq(cfqd, cfqq, "alloced"); | ||
1430 | } | 1478 | } |
1431 | 1479 | ||
1432 | if (new_cfqq) | 1480 | if (new_cfqq) |
@@ -1675,7 +1723,7 @@ static void | |||
1675 | cfq_update_idle_window(struct cfq_data *cfqd, struct cfq_queue *cfqq, | 1723 | cfq_update_idle_window(struct cfq_data *cfqd, struct cfq_queue *cfqq, |
1676 | struct cfq_io_context *cic) | 1724 | struct cfq_io_context *cic) |
1677 | { | 1725 | { |
1678 | int enable_idle; | 1726 | int old_idle, enable_idle; |
1679 | 1727 | ||
1680 | /* | 1728 | /* |
1681 | * Don't idle for async or idle io prio class | 1729 | * Don't idle for async or idle io prio class |
@@ -1683,7 +1731,7 @@ cfq_update_idle_window(struct cfq_data *cfqd, struct cfq_queue *cfqq, | |||
1683 | if (!cfq_cfqq_sync(cfqq) || cfq_class_idle(cfqq)) | 1731 | if (!cfq_cfqq_sync(cfqq) || cfq_class_idle(cfqq)) |
1684 | return; | 1732 | return; |
1685 | 1733 | ||
1686 | enable_idle = cfq_cfqq_idle_window(cfqq); | 1734 | enable_idle = old_idle = cfq_cfqq_idle_window(cfqq); |
1687 | 1735 | ||
1688 | if (!atomic_read(&cic->ioc->nr_tasks) || !cfqd->cfq_slice_idle || | 1736 | if (!atomic_read(&cic->ioc->nr_tasks) || !cfqd->cfq_slice_idle || |
1689 | (cfqd->hw_tag && CIC_SEEKY(cic))) | 1737 | (cfqd->hw_tag && CIC_SEEKY(cic))) |
@@ -1695,10 +1743,13 @@ cfq_update_idle_window(struct cfq_data *cfqd, struct cfq_queue *cfqq, | |||
1695 | enable_idle = 1; | 1743 | enable_idle = 1; |
1696 | } | 1744 | } |
1697 | 1745 | ||
1698 | if (enable_idle) | 1746 | if (old_idle != enable_idle) { |
1699 | cfq_mark_cfqq_idle_window(cfqq); | 1747 | cfq_log_cfqq(cfqd, cfqq, "idle=%d", enable_idle); |
1700 | else | 1748 | if (enable_idle) |
1701 | cfq_clear_cfqq_idle_window(cfqq); | 1749 | cfq_mark_cfqq_idle_window(cfqq); |
1750 | else | ||
1751 | cfq_clear_cfqq_idle_window(cfqq); | ||
1752 | } | ||
1702 | } | 1753 | } |
1703 | 1754 | ||
1704 | /* | 1755 | /* |
@@ -1757,6 +1808,7 @@ cfq_should_preempt(struct cfq_data *cfqd, struct cfq_queue *new_cfqq, | |||
1757 | */ | 1808 | */ |
1758 | static void cfq_preempt_queue(struct cfq_data *cfqd, struct cfq_queue *cfqq) | 1809 | static void cfq_preempt_queue(struct cfq_data *cfqd, struct cfq_queue *cfqq) |
1759 | { | 1810 | { |
1811 | cfq_log_cfqq(cfqd, cfqq, "preempt"); | ||
1760 | cfq_slice_expired(cfqd, 1); | 1812 | cfq_slice_expired(cfqd, 1); |
1761 | 1813 | ||
1762 | /* | 1814 | /* |
@@ -1818,6 +1870,7 @@ static void cfq_insert_request(struct request_queue *q, struct request *rq) | |||
1818 | struct cfq_data *cfqd = q->elevator->elevator_data; | 1870 | struct cfq_data *cfqd = q->elevator->elevator_data; |
1819 | struct cfq_queue *cfqq = RQ_CFQQ(rq); | 1871 | struct cfq_queue *cfqq = RQ_CFQQ(rq); |
1820 | 1872 | ||
1873 | cfq_log_cfqq(cfqd, cfqq, "insert_request"); | ||
1821 | cfq_init_prio_data(cfqq, RQ_CIC(rq)->ioc); | 1874 | cfq_init_prio_data(cfqq, RQ_CIC(rq)->ioc); |
1822 | 1875 | ||
1823 | cfq_add_rq_rb(rq); | 1876 | cfq_add_rq_rb(rq); |
@@ -1835,6 +1888,7 @@ static void cfq_completed_request(struct request_queue *q, struct request *rq) | |||
1835 | unsigned long now; | 1888 | unsigned long now; |
1836 | 1889 | ||
1837 | now = jiffies; | 1890 | now = jiffies; |
1891 | cfq_log_cfqq(cfqd, cfqq, "complete"); | ||
1838 | 1892 | ||
1839 | WARN_ON(!cfqd->rq_in_driver); | 1893 | WARN_ON(!cfqd->rq_in_driver); |
1840 | WARN_ON(!cfqq->dispatched); | 1894 | WARN_ON(!cfqq->dispatched); |
@@ -2004,6 +2058,7 @@ queue_fail: | |||
2004 | 2058 | ||
2005 | cfq_schedule_dispatch(cfqd); | 2059 | cfq_schedule_dispatch(cfqd); |
2006 | spin_unlock_irqrestore(q->queue_lock, flags); | 2060 | spin_unlock_irqrestore(q->queue_lock, flags); |
2061 | cfq_log(cfqd, "set_request fail"); | ||
2007 | return 1; | 2062 | return 1; |
2008 | } | 2063 | } |
2009 | 2064 | ||
@@ -2029,6 +2084,8 @@ static void cfq_idle_slice_timer(unsigned long data) | |||
2029 | unsigned long flags; | 2084 | unsigned long flags; |
2030 | int timed_out = 1; | 2085 | int timed_out = 1; |
2031 | 2086 | ||
2087 | cfq_log(cfqd, "idle timer fired"); | ||
2088 | |||
2032 | spin_lock_irqsave(cfqd->queue->queue_lock, flags); | 2089 | spin_lock_irqsave(cfqd->queue->queue_lock, flags); |
2033 | 2090 | ||
2034 | cfqq = cfqd->active_queue; | 2091 | cfqq = cfqd->active_queue; |
@@ -2317,7 +2374,7 @@ static void __exit cfq_exit(void) | |||
2317 | * pending RCU callbacks | 2374 | * pending RCU callbacks |
2318 | */ | 2375 | */ |
2319 | if (elv_ioc_count_read(ioc_count)) | 2376 | if (elv_ioc_count_read(ioc_count)) |
2320 | wait_for_completion(ioc_gone); | 2377 | wait_for_completion(&all_gone); |
2321 | cfq_slab_kill(); | 2378 | cfq_slab_kill(); |
2322 | } | 2379 | } |
2323 | 2380 | ||
diff --git a/block/cmd-filter.c b/block/cmd-filter.c new file mode 100644 index 000000000000..eec4404fd357 --- /dev/null +++ b/block/cmd-filter.c | |||
@@ -0,0 +1,334 @@ | |||
1 | /* | ||
2 | * Copyright 2004 Peter M. Jones <pjones@redhat.com> | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License version 2 as | ||
6 | * published by the Free Software Foundation. | ||
7 | * | ||
8 | * This program is distributed in the hope that it will be useful, | ||
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
10 | * | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public Licens | ||
15 | * along with this program; if not, write to the Free Software | ||
16 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111- | ||
17 | * | ||
18 | */ | ||
19 | |||
20 | #include <linux/list.h> | ||
21 | #include <linux/genhd.h> | ||
22 | #include <linux/spinlock.h> | ||
23 | #include <linux/parser.h> | ||
24 | #include <linux/capability.h> | ||
25 | #include <linux/bitops.h> | ||
26 | |||
27 | #include <scsi/scsi.h> | ||
28 | #include <linux/cdrom.h> | ||
29 | |||
30 | int blk_cmd_filter_verify_command(struct blk_scsi_cmd_filter *filter, | ||
31 | unsigned char *cmd, mode_t *f_mode) | ||
32 | { | ||
33 | /* root can do any command. */ | ||
34 | if (capable(CAP_SYS_RAWIO)) | ||
35 | return 0; | ||
36 | |||
37 | /* if there's no filter set, assume we're filtering everything out */ | ||
38 | if (!filter) | ||
39 | return -EPERM; | ||
40 | |||
41 | /* Anybody who can open the device can do a read-safe command */ | ||
42 | if (test_bit(cmd[0], filter->read_ok)) | ||
43 | return 0; | ||
44 | |||
45 | /* Write-safe commands require a writable open */ | ||
46 | if (test_bit(cmd[0], filter->write_ok) && (*f_mode & FMODE_WRITE)) | ||
47 | return 0; | ||
48 | |||
49 | return -EPERM; | ||
50 | } | ||
51 | EXPORT_SYMBOL(blk_cmd_filter_verify_command); | ||
52 | |||
53 | int blk_verify_command(struct file *file, unsigned char *cmd) | ||
54 | { | ||
55 | struct gendisk *disk; | ||
56 | struct inode *inode; | ||
57 | |||
58 | if (!file) | ||
59 | return -EINVAL; | ||
60 | |||
61 | inode = file->f_dentry->d_inode; | ||
62 | if (!inode) | ||
63 | return -EINVAL; | ||
64 | |||
65 | disk = inode->i_bdev->bd_disk; | ||
66 | |||
67 | return blk_cmd_filter_verify_command(&disk->cmd_filter, | ||
68 | cmd, &file->f_mode); | ||
69 | } | ||
70 | EXPORT_SYMBOL(blk_verify_command); | ||
71 | |||
72 | /* and now, the sysfs stuff */ | ||
73 | static ssize_t rcf_cmds_show(struct blk_scsi_cmd_filter *filter, char *page, | ||
74 | int rw) | ||
75 | { | ||
76 | char *npage = page; | ||
77 | unsigned long *okbits; | ||
78 | int i; | ||
79 | |||
80 | if (rw == READ) | ||
81 | okbits = filter->read_ok; | ||
82 | else | ||
83 | okbits = filter->write_ok; | ||
84 | |||
85 | for (i = 0; i < BLK_SCSI_MAX_CMDS; i++) { | ||
86 | if (test_bit(i, okbits)) { | ||
87 | sprintf(npage, "%02x", i); | ||
88 | npage += 2; | ||
89 | if (i < BLK_SCSI_MAX_CMDS - 1) | ||
90 | sprintf(npage++, " "); | ||
91 | } | ||
92 | } | ||
93 | |||
94 | if (npage != page) | ||
95 | npage += sprintf(npage, "\n"); | ||
96 | |||
97 | return npage - page; | ||
98 | } | ||
99 | |||
100 | static ssize_t rcf_readcmds_show(struct blk_scsi_cmd_filter *filter, char *page) | ||
101 | { | ||
102 | return rcf_cmds_show(filter, page, READ); | ||
103 | } | ||
104 | |||
105 | static ssize_t rcf_writecmds_show(struct blk_scsi_cmd_filter *filter, | ||
106 | char *page) | ||
107 | { | ||
108 | return rcf_cmds_show(filter, page, WRITE); | ||
109 | } | ||
110 | |||
111 | static ssize_t rcf_cmds_store(struct blk_scsi_cmd_filter *filter, | ||
112 | const char *page, size_t count, int rw) | ||
113 | { | ||
114 | ssize_t ret = 0; | ||
115 | unsigned long okbits[BLK_SCSI_CMD_PER_LONG], *target_okbits; | ||
116 | int cmd, status, len; | ||
117 | substring_t ss; | ||
118 | |||
119 | memset(&okbits, 0, sizeof(okbits)); | ||
120 | |||
121 | for (len = strlen(page); len > 0; len -= 3) { | ||
122 | if (len < 2) | ||
123 | break; | ||
124 | ss.from = (char *) page + ret; | ||
125 | ss.to = (char *) page + ret + 2; | ||
126 | ret += 3; | ||
127 | status = match_hex(&ss, &cmd); | ||
128 | /* either of these cases means invalid input, so do nothing. */ | ||
129 | if (status || cmd >= BLK_SCSI_MAX_CMDS) | ||
130 | return -EINVAL; | ||
131 | |||
132 | __set_bit(cmd, okbits); | ||
133 | } | ||
134 | |||
135 | if (rw == READ) | ||
136 | target_okbits = filter->read_ok; | ||
137 | else | ||
138 | target_okbits = filter->write_ok; | ||
139 | |||
140 | memmove(target_okbits, okbits, sizeof(okbits)); | ||
141 | return count; | ||
142 | } | ||
143 | |||
144 | static ssize_t rcf_readcmds_store(struct blk_scsi_cmd_filter *filter, | ||
145 | const char *page, size_t count) | ||
146 | { | ||
147 | return rcf_cmds_store(filter, page, count, READ); | ||
148 | } | ||
149 | |||
150 | static ssize_t rcf_writecmds_store(struct blk_scsi_cmd_filter *filter, | ||
151 | const char *page, size_t count) | ||
152 | { | ||
153 | return rcf_cmds_store(filter, page, count, WRITE); | ||
154 | } | ||
155 | |||
156 | struct rcf_sysfs_entry { | ||
157 | struct attribute attr; | ||
158 | ssize_t (*show)(struct blk_scsi_cmd_filter *, char *); | ||
159 | ssize_t (*store)(struct blk_scsi_cmd_filter *, const char *, size_t); | ||
160 | }; | ||
161 | |||
162 | static struct rcf_sysfs_entry rcf_readcmds_entry = { | ||
163 | .attr = { .name = "read_table", .mode = S_IRUGO | S_IWUSR }, | ||
164 | .show = rcf_readcmds_show, | ||
165 | .store = rcf_readcmds_store, | ||
166 | }; | ||
167 | |||
168 | static struct rcf_sysfs_entry rcf_writecmds_entry = { | ||
169 | .attr = {.name = "write_table", .mode = S_IRUGO | S_IWUSR }, | ||
170 | .show = rcf_writecmds_show, | ||
171 | .store = rcf_writecmds_store, | ||
172 | }; | ||
173 | |||
174 | static struct attribute *default_attrs[] = { | ||
175 | &rcf_readcmds_entry.attr, | ||
176 | &rcf_writecmds_entry.attr, | ||
177 | NULL, | ||
178 | }; | ||
179 | |||
180 | #define to_rcf(atr) container_of((atr), struct rcf_sysfs_entry, attr) | ||
181 | |||
182 | static ssize_t | ||
183 | rcf_attr_show(struct kobject *kobj, struct attribute *attr, char *page) | ||
184 | { | ||
185 | struct rcf_sysfs_entry *entry = to_rcf(attr); | ||
186 | struct blk_scsi_cmd_filter *filter; | ||
187 | |||
188 | filter = container_of(kobj, struct blk_scsi_cmd_filter, kobj); | ||
189 | if (entry->show) | ||
190 | return entry->show(filter, page); | ||
191 | |||
192 | return 0; | ||
193 | } | ||
194 | |||
195 | static ssize_t | ||
196 | rcf_attr_store(struct kobject *kobj, struct attribute *attr, | ||
197 | const char *page, size_t length) | ||
198 | { | ||
199 | struct rcf_sysfs_entry *entry = to_rcf(attr); | ||
200 | struct blk_scsi_cmd_filter *filter; | ||
201 | |||
202 | if (!capable(CAP_SYS_RAWIO)) | ||
203 | return -EPERM; | ||
204 | |||
205 | if (!entry->store) | ||
206 | return -EINVAL; | ||
207 | |||
208 | filter = container_of(kobj, struct blk_scsi_cmd_filter, kobj); | ||
209 | return entry->store(filter, page, length); | ||
210 | } | ||
211 | |||
212 | static struct sysfs_ops rcf_sysfs_ops = { | ||
213 | .show = rcf_attr_show, | ||
214 | .store = rcf_attr_store, | ||
215 | }; | ||
216 | |||
217 | static struct kobj_type rcf_ktype = { | ||
218 | .sysfs_ops = &rcf_sysfs_ops, | ||
219 | .default_attrs = default_attrs, | ||
220 | }; | ||
221 | |||
222 | #ifndef MAINTENANCE_IN_CMD | ||
223 | #define MAINTENANCE_IN_CMD 0xa3 | ||
224 | #endif | ||
225 | |||
226 | static void rcf_set_defaults(struct blk_scsi_cmd_filter *filter) | ||
227 | { | ||
228 | /* Basic read-only commands */ | ||
229 | __set_bit(TEST_UNIT_READY, filter->read_ok); | ||
230 | __set_bit(REQUEST_SENSE, filter->read_ok); | ||
231 | __set_bit(READ_6, filter->read_ok); | ||
232 | __set_bit(READ_10, filter->read_ok); | ||
233 | __set_bit(READ_12, filter->read_ok); | ||
234 | __set_bit(READ_16, filter->read_ok); | ||
235 | __set_bit(READ_BUFFER, filter->read_ok); | ||
236 | __set_bit(READ_DEFECT_DATA, filter->read_ok); | ||
237 | __set_bit(READ_CAPACITY, filter->read_ok); | ||
238 | __set_bit(READ_LONG, filter->read_ok); | ||
239 | __set_bit(INQUIRY, filter->read_ok); | ||
240 | __set_bit(MODE_SENSE, filter->read_ok); | ||
241 | __set_bit(MODE_SENSE_10, filter->read_ok); | ||
242 | __set_bit(LOG_SENSE, filter->read_ok); | ||
243 | __set_bit(START_STOP, filter->read_ok); | ||
244 | __set_bit(GPCMD_VERIFY_10, filter->read_ok); | ||
245 | __set_bit(VERIFY_16, filter->read_ok); | ||
246 | __set_bit(REPORT_LUNS, filter->read_ok); | ||
247 | __set_bit(SERVICE_ACTION_IN, filter->read_ok); | ||
248 | __set_bit(RECEIVE_DIAGNOSTIC, filter->read_ok); | ||
249 | __set_bit(MAINTENANCE_IN_CMD, filter->read_ok); | ||
250 | __set_bit(GPCMD_READ_BUFFER_CAPACITY, filter->read_ok); | ||
251 | |||
252 | /* Audio CD commands */ | ||
253 | __set_bit(GPCMD_PLAY_CD, filter->read_ok); | ||
254 | __set_bit(GPCMD_PLAY_AUDIO_10, filter->read_ok); | ||
255 | __set_bit(GPCMD_PLAY_AUDIO_MSF, filter->read_ok); | ||
256 | __set_bit(GPCMD_PLAY_AUDIO_TI, filter->read_ok); | ||
257 | __set_bit(GPCMD_PAUSE_RESUME, filter->read_ok); | ||
258 | |||
259 | /* CD/DVD data reading */ | ||
260 | __set_bit(GPCMD_READ_CD, filter->read_ok); | ||
261 | __set_bit(GPCMD_READ_CD_MSF, filter->read_ok); | ||
262 | __set_bit(GPCMD_READ_DISC_INFO, filter->read_ok); | ||
263 | __set_bit(GPCMD_READ_CDVD_CAPACITY, filter->read_ok); | ||
264 | __set_bit(GPCMD_READ_DVD_STRUCTURE, filter->read_ok); | ||
265 | __set_bit(GPCMD_READ_HEADER, filter->read_ok); | ||
266 | __set_bit(GPCMD_READ_TRACK_RZONE_INFO, filter->read_ok); | ||
267 | __set_bit(GPCMD_READ_SUBCHANNEL, filter->read_ok); | ||
268 | __set_bit(GPCMD_READ_TOC_PMA_ATIP, filter->read_ok); | ||
269 | __set_bit(GPCMD_REPORT_KEY, filter->read_ok); | ||
270 | __set_bit(GPCMD_SCAN, filter->read_ok); | ||
271 | __set_bit(GPCMD_GET_CONFIGURATION, filter->read_ok); | ||
272 | __set_bit(GPCMD_READ_FORMAT_CAPACITIES, filter->read_ok); | ||
273 | __set_bit(GPCMD_GET_EVENT_STATUS_NOTIFICATION, filter->read_ok); | ||
274 | __set_bit(GPCMD_GET_PERFORMANCE, filter->read_ok); | ||
275 | __set_bit(GPCMD_SEEK, filter->read_ok); | ||
276 | __set_bit(GPCMD_STOP_PLAY_SCAN, filter->read_ok); | ||
277 | |||
278 | /* Basic writing commands */ | ||
279 | __set_bit(WRITE_6, filter->write_ok); | ||
280 | __set_bit(WRITE_10, filter->write_ok); | ||
281 | __set_bit(WRITE_VERIFY, filter->write_ok); | ||
282 | __set_bit(WRITE_12, filter->write_ok); | ||
283 | __set_bit(WRITE_VERIFY_12, filter->write_ok); | ||
284 | __set_bit(WRITE_16, filter->write_ok); | ||
285 | __set_bit(WRITE_LONG, filter->write_ok); | ||
286 | __set_bit(WRITE_LONG_2, filter->write_ok); | ||
287 | __set_bit(ERASE, filter->write_ok); | ||
288 | __set_bit(GPCMD_MODE_SELECT_10, filter->write_ok); | ||
289 | __set_bit(MODE_SELECT, filter->write_ok); | ||
290 | __set_bit(LOG_SELECT, filter->write_ok); | ||
291 | __set_bit(GPCMD_BLANK, filter->write_ok); | ||
292 | __set_bit(GPCMD_CLOSE_TRACK, filter->write_ok); | ||
293 | __set_bit(GPCMD_FLUSH_CACHE, filter->write_ok); | ||
294 | __set_bit(GPCMD_FORMAT_UNIT, filter->write_ok); | ||
295 | __set_bit(GPCMD_REPAIR_RZONE_TRACK, filter->write_ok); | ||
296 | __set_bit(GPCMD_RESERVE_RZONE_TRACK, filter->write_ok); | ||
297 | __set_bit(GPCMD_SEND_DVD_STRUCTURE, filter->write_ok); | ||
298 | __set_bit(GPCMD_SEND_EVENT, filter->write_ok); | ||
299 | __set_bit(GPCMD_SEND_KEY, filter->write_ok); | ||
300 | __set_bit(GPCMD_SEND_OPC, filter->write_ok); | ||
301 | __set_bit(GPCMD_SEND_CUE_SHEET, filter->write_ok); | ||
302 | __set_bit(GPCMD_SET_SPEED, filter->write_ok); | ||
303 | __set_bit(GPCMD_PREVENT_ALLOW_MEDIUM_REMOVAL, filter->write_ok); | ||
304 | __set_bit(GPCMD_LOAD_UNLOAD, filter->write_ok); | ||
305 | __set_bit(GPCMD_SET_STREAMING, filter->write_ok); | ||
306 | } | ||
307 | |||
308 | int blk_register_filter(struct gendisk *disk) | ||
309 | { | ||
310 | int ret; | ||
311 | struct blk_scsi_cmd_filter *filter = &disk->cmd_filter; | ||
312 | struct kobject *parent = kobject_get(disk->holder_dir->parent); | ||
313 | |||
314 | if (!parent) | ||
315 | return -ENODEV; | ||
316 | |||
317 | ret = kobject_init_and_add(&filter->kobj, &rcf_ktype, parent, | ||
318 | "%s", "cmd_filter"); | ||
319 | |||
320 | if (ret < 0) | ||
321 | return ret; | ||
322 | |||
323 | rcf_set_defaults(filter); | ||
324 | return 0; | ||
325 | } | ||
326 | |||
327 | void blk_unregister_filter(struct gendisk *disk) | ||
328 | { | ||
329 | struct blk_scsi_cmd_filter *filter = &disk->cmd_filter; | ||
330 | |||
331 | kobject_put(&filter->kobj); | ||
332 | kobject_put(disk->holder_dir->parent); | ||
333 | } | ||
334 | |||
diff --git a/block/elevator.c b/block/elevator.c index 902dd1344d56..ed6f8f32d27e 100644 --- a/block/elevator.c +++ b/block/elevator.c | |||
@@ -86,6 +86,12 @@ int elv_rq_merge_ok(struct request *rq, struct bio *bio) | |||
86 | if (rq->rq_disk != bio->bi_bdev->bd_disk || rq->special) | 86 | if (rq->rq_disk != bio->bi_bdev->bd_disk || rq->special) |
87 | return 0; | 87 | return 0; |
88 | 88 | ||
89 | /* | ||
90 | * only merge integrity protected bio into ditto rq | ||
91 | */ | ||
92 | if (bio_integrity(bio) != blk_integrity_rq(rq)) | ||
93 | return 0; | ||
94 | |||
89 | if (!elv_iosched_allow_merge(rq, bio)) | 95 | if (!elv_iosched_allow_merge(rq, bio)) |
90 | return 0; | 96 | return 0; |
91 | 97 | ||
@@ -144,7 +150,7 @@ static struct elevator_type *elevator_get(const char *name) | |||
144 | else | 150 | else |
145 | sprintf(elv, "%s-iosched", name); | 151 | sprintf(elv, "%s-iosched", name); |
146 | 152 | ||
147 | request_module(elv); | 153 | request_module("%s", elv); |
148 | spin_lock(&elv_list_lock); | 154 | spin_lock(&elv_list_lock); |
149 | e = elevator_find(name); | 155 | e = elevator_find(name); |
150 | } | 156 | } |
diff --git a/block/genhd.c b/block/genhd.c index b922d4801c87..9074f384b097 100644 --- a/block/genhd.c +++ b/block/genhd.c | |||
@@ -189,6 +189,7 @@ void add_disk(struct gendisk *disk) | |||
189 | disk->minors, NULL, exact_match, exact_lock, disk); | 189 | disk->minors, NULL, exact_match, exact_lock, disk); |
190 | register_disk(disk); | 190 | register_disk(disk); |
191 | blk_register_queue(disk); | 191 | blk_register_queue(disk); |
192 | blk_register_filter(disk); | ||
192 | 193 | ||
193 | bdi = &disk->queue->backing_dev_info; | 194 | bdi = &disk->queue->backing_dev_info; |
194 | bdi_register_dev(bdi, MKDEV(disk->major, disk->first_minor)); | 195 | bdi_register_dev(bdi, MKDEV(disk->major, disk->first_minor)); |
@@ -200,6 +201,7 @@ EXPORT_SYMBOL(del_gendisk); /* in partitions/check.c */ | |||
200 | 201 | ||
201 | void unlink_gendisk(struct gendisk *disk) | 202 | void unlink_gendisk(struct gendisk *disk) |
202 | { | 203 | { |
204 | blk_unregister_filter(disk); | ||
203 | sysfs_remove_link(&disk->dev.kobj, "bdi"); | 205 | sysfs_remove_link(&disk->dev.kobj, "bdi"); |
204 | bdi_unregister(&disk->queue->backing_dev_info); | 206 | bdi_unregister(&disk->queue->backing_dev_info); |
205 | blk_unregister_queue(disk); | 207 | blk_unregister_queue(disk); |
@@ -400,6 +402,14 @@ static ssize_t disk_removable_show(struct device *dev, | |||
400 | (disk->flags & GENHD_FL_REMOVABLE ? 1 : 0)); | 402 | (disk->flags & GENHD_FL_REMOVABLE ? 1 : 0)); |
401 | } | 403 | } |
402 | 404 | ||
405 | static ssize_t disk_ro_show(struct device *dev, | ||
406 | struct device_attribute *attr, char *buf) | ||
407 | { | ||
408 | struct gendisk *disk = dev_to_disk(dev); | ||
409 | |||
410 | return sprintf(buf, "%d\n", disk->policy ? 1 : 0); | ||
411 | } | ||
412 | |||
403 | static ssize_t disk_size_show(struct device *dev, | 413 | static ssize_t disk_size_show(struct device *dev, |
404 | struct device_attribute *attr, char *buf) | 414 | struct device_attribute *attr, char *buf) |
405 | { | 415 | { |
@@ -472,6 +482,7 @@ static ssize_t disk_fail_store(struct device *dev, | |||
472 | 482 | ||
473 | static DEVICE_ATTR(range, S_IRUGO, disk_range_show, NULL); | 483 | static DEVICE_ATTR(range, S_IRUGO, disk_range_show, NULL); |
474 | static DEVICE_ATTR(removable, S_IRUGO, disk_removable_show, NULL); | 484 | static DEVICE_ATTR(removable, S_IRUGO, disk_removable_show, NULL); |
485 | static DEVICE_ATTR(ro, S_IRUGO, disk_ro_show, NULL); | ||
475 | static DEVICE_ATTR(size, S_IRUGO, disk_size_show, NULL); | 486 | static DEVICE_ATTR(size, S_IRUGO, disk_size_show, NULL); |
476 | static DEVICE_ATTR(capability, S_IRUGO, disk_capability_show, NULL); | 487 | static DEVICE_ATTR(capability, S_IRUGO, disk_capability_show, NULL); |
477 | static DEVICE_ATTR(stat, S_IRUGO, disk_stat_show, NULL); | 488 | static DEVICE_ATTR(stat, S_IRUGO, disk_stat_show, NULL); |
@@ -483,6 +494,7 @@ static struct device_attribute dev_attr_fail = | |||
483 | static struct attribute *disk_attrs[] = { | 494 | static struct attribute *disk_attrs[] = { |
484 | &dev_attr_range.attr, | 495 | &dev_attr_range.attr, |
485 | &dev_attr_removable.attr, | 496 | &dev_attr_removable.attr, |
497 | &dev_attr_ro.attr, | ||
486 | &dev_attr_size.attr, | 498 | &dev_attr_size.attr, |
487 | &dev_attr_capability.attr, | 499 | &dev_attr_capability.attr, |
488 | &dev_attr_stat.attr, | 500 | &dev_attr_stat.attr, |
diff --git a/block/scsi_ioctl.c b/block/scsi_ioctl.c index 78199c08ec92..c5b9bcfc0a6d 100644 --- a/block/scsi_ioctl.c +++ b/block/scsi_ioctl.c | |||
@@ -105,120 +105,12 @@ static int sg_emulated_host(struct request_queue *q, int __user *p) | |||
105 | return put_user(1, p); | 105 | return put_user(1, p); |
106 | } | 106 | } |
107 | 107 | ||
108 | #define CMD_READ_SAFE 0x01 | ||
109 | #define CMD_WRITE_SAFE 0x02 | ||
110 | #define CMD_WARNED 0x04 | ||
111 | #define safe_for_read(cmd) [cmd] = CMD_READ_SAFE | ||
112 | #define safe_for_write(cmd) [cmd] = CMD_WRITE_SAFE | ||
113 | |||
114 | int blk_verify_command(unsigned char *cmd, int has_write_perm) | ||
115 | { | ||
116 | static unsigned char cmd_type[256] = { | ||
117 | |||
118 | /* Basic read-only commands */ | ||
119 | safe_for_read(TEST_UNIT_READY), | ||
120 | safe_for_read(REQUEST_SENSE), | ||
121 | safe_for_read(READ_6), | ||
122 | safe_for_read(READ_10), | ||
123 | safe_for_read(READ_12), | ||
124 | safe_for_read(READ_16), | ||
125 | safe_for_read(READ_BUFFER), | ||
126 | safe_for_read(READ_DEFECT_DATA), | ||
127 | safe_for_read(READ_LONG), | ||
128 | safe_for_read(INQUIRY), | ||
129 | safe_for_read(MODE_SENSE), | ||
130 | safe_for_read(MODE_SENSE_10), | ||
131 | safe_for_read(LOG_SENSE), | ||
132 | safe_for_read(START_STOP), | ||
133 | safe_for_read(GPCMD_VERIFY_10), | ||
134 | safe_for_read(VERIFY_16), | ||
135 | |||
136 | /* Audio CD commands */ | ||
137 | safe_for_read(GPCMD_PLAY_CD), | ||
138 | safe_for_read(GPCMD_PLAY_AUDIO_10), | ||
139 | safe_for_read(GPCMD_PLAY_AUDIO_MSF), | ||
140 | safe_for_read(GPCMD_PLAY_AUDIO_TI), | ||
141 | safe_for_read(GPCMD_PAUSE_RESUME), | ||
142 | |||
143 | /* CD/DVD data reading */ | ||
144 | safe_for_read(GPCMD_READ_BUFFER_CAPACITY), | ||
145 | safe_for_read(GPCMD_READ_CD), | ||
146 | safe_for_read(GPCMD_READ_CD_MSF), | ||
147 | safe_for_read(GPCMD_READ_DISC_INFO), | ||
148 | safe_for_read(GPCMD_READ_CDVD_CAPACITY), | ||
149 | safe_for_read(GPCMD_READ_DVD_STRUCTURE), | ||
150 | safe_for_read(GPCMD_READ_HEADER), | ||
151 | safe_for_read(GPCMD_READ_TRACK_RZONE_INFO), | ||
152 | safe_for_read(GPCMD_READ_SUBCHANNEL), | ||
153 | safe_for_read(GPCMD_READ_TOC_PMA_ATIP), | ||
154 | safe_for_read(GPCMD_REPORT_KEY), | ||
155 | safe_for_read(GPCMD_SCAN), | ||
156 | safe_for_read(GPCMD_GET_CONFIGURATION), | ||
157 | safe_for_read(GPCMD_READ_FORMAT_CAPACITIES), | ||
158 | safe_for_read(GPCMD_GET_EVENT_STATUS_NOTIFICATION), | ||
159 | safe_for_read(GPCMD_GET_PERFORMANCE), | ||
160 | safe_for_read(GPCMD_SEEK), | ||
161 | safe_for_read(GPCMD_STOP_PLAY_SCAN), | ||
162 | |||
163 | /* Basic writing commands */ | ||
164 | safe_for_write(WRITE_6), | ||
165 | safe_for_write(WRITE_10), | ||
166 | safe_for_write(WRITE_VERIFY), | ||
167 | safe_for_write(WRITE_12), | ||
168 | safe_for_write(WRITE_VERIFY_12), | ||
169 | safe_for_write(WRITE_16), | ||
170 | safe_for_write(WRITE_LONG), | ||
171 | safe_for_write(WRITE_LONG_2), | ||
172 | safe_for_write(ERASE), | ||
173 | safe_for_write(GPCMD_MODE_SELECT_10), | ||
174 | safe_for_write(MODE_SELECT), | ||
175 | safe_for_write(LOG_SELECT), | ||
176 | safe_for_write(GPCMD_BLANK), | ||
177 | safe_for_write(GPCMD_CLOSE_TRACK), | ||
178 | safe_for_write(GPCMD_FLUSH_CACHE), | ||
179 | safe_for_write(GPCMD_FORMAT_UNIT), | ||
180 | safe_for_write(GPCMD_REPAIR_RZONE_TRACK), | ||
181 | safe_for_write(GPCMD_RESERVE_RZONE_TRACK), | ||
182 | safe_for_write(GPCMD_SEND_DVD_STRUCTURE), | ||
183 | safe_for_write(GPCMD_SEND_EVENT), | ||
184 | safe_for_write(GPCMD_SEND_KEY), | ||
185 | safe_for_write(GPCMD_SEND_OPC), | ||
186 | safe_for_write(GPCMD_SEND_CUE_SHEET), | ||
187 | safe_for_write(GPCMD_SET_SPEED), | ||
188 | safe_for_write(GPCMD_PREVENT_ALLOW_MEDIUM_REMOVAL), | ||
189 | safe_for_write(GPCMD_LOAD_UNLOAD), | ||
190 | safe_for_write(GPCMD_SET_STREAMING), | ||
191 | }; | ||
192 | unsigned char type = cmd_type[cmd[0]]; | ||
193 | |||
194 | /* Anybody who can open the device can do a read-safe command */ | ||
195 | if (type & CMD_READ_SAFE) | ||
196 | return 0; | ||
197 | |||
198 | /* Write-safe commands just require a writable open.. */ | ||
199 | if ((type & CMD_WRITE_SAFE) && has_write_perm) | ||
200 | return 0; | ||
201 | |||
202 | /* And root can do any command.. */ | ||
203 | if (capable(CAP_SYS_RAWIO)) | ||
204 | return 0; | ||
205 | |||
206 | if (!type) { | ||
207 | cmd_type[cmd[0]] = CMD_WARNED; | ||
208 | printk(KERN_WARNING "scsi: unknown opcode 0x%02x\n", cmd[0]); | ||
209 | } | ||
210 | |||
211 | /* Otherwise fail it with an "Operation not permitted" */ | ||
212 | return -EPERM; | ||
213 | } | ||
214 | EXPORT_SYMBOL_GPL(blk_verify_command); | ||
215 | |||
216 | static int blk_fill_sghdr_rq(struct request_queue *q, struct request *rq, | 108 | static int blk_fill_sghdr_rq(struct request_queue *q, struct request *rq, |
217 | struct sg_io_hdr *hdr, int has_write_perm) | 109 | struct sg_io_hdr *hdr, struct file *file) |
218 | { | 110 | { |
219 | if (copy_from_user(rq->cmd, hdr->cmdp, hdr->cmd_len)) | 111 | if (copy_from_user(rq->cmd, hdr->cmdp, hdr->cmd_len)) |
220 | return -EFAULT; | 112 | return -EFAULT; |
221 | if (blk_verify_command(rq->cmd, has_write_perm)) | 113 | if (blk_verify_command(file, rq->cmd)) |
222 | return -EPERM; | 114 | return -EPERM; |
223 | 115 | ||
224 | /* | 116 | /* |
@@ -287,7 +179,7 @@ static int sg_io(struct file *file, struct request_queue *q, | |||
287 | struct gendisk *bd_disk, struct sg_io_hdr *hdr) | 179 | struct gendisk *bd_disk, struct sg_io_hdr *hdr) |
288 | { | 180 | { |
289 | unsigned long start_time; | 181 | unsigned long start_time; |
290 | int writing = 0, ret = 0, has_write_perm = 0; | 182 | int writing = 0, ret = 0; |
291 | struct request *rq; | 183 | struct request *rq; |
292 | char sense[SCSI_SENSE_BUFFERSIZE]; | 184 | char sense[SCSI_SENSE_BUFFERSIZE]; |
293 | struct bio *bio; | 185 | struct bio *bio; |
@@ -316,10 +208,7 @@ static int sg_io(struct file *file, struct request_queue *q, | |||
316 | if (!rq) | 208 | if (!rq) |
317 | return -ENOMEM; | 209 | return -ENOMEM; |
318 | 210 | ||
319 | if (file) | 211 | if (blk_fill_sghdr_rq(q, rq, hdr, file)) { |
320 | has_write_perm = file->f_mode & FMODE_WRITE; | ||
321 | |||
322 | if (blk_fill_sghdr_rq(q, rq, hdr, has_write_perm)) { | ||
323 | blk_put_request(rq); | 212 | blk_put_request(rq); |
324 | return -EFAULT; | 213 | return -EFAULT; |
325 | } | 214 | } |
@@ -451,7 +340,7 @@ int sg_scsi_ioctl(struct file *file, struct request_queue *q, | |||
451 | if (in_len && copy_from_user(buffer, sic->data + cmdlen, in_len)) | 340 | if (in_len && copy_from_user(buffer, sic->data + cmdlen, in_len)) |
452 | goto error; | 341 | goto error; |
453 | 342 | ||
454 | err = blk_verify_command(rq->cmd, file->f_mode & FMODE_WRITE); | 343 | err = blk_verify_command(file, rq->cmd); |
455 | if (err) | 344 | if (err) |
456 | goto error; | 345 | goto error; |
457 | 346 | ||
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index 57a43649a461..499ccc628d81 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c | |||
@@ -885,7 +885,8 @@ static int ata_scsi_dev_config(struct scsi_device *sdev, | |||
885 | /* set the min alignment and padding */ | 885 | /* set the min alignment and padding */ |
886 | blk_queue_update_dma_alignment(sdev->request_queue, | 886 | blk_queue_update_dma_alignment(sdev->request_queue, |
887 | ATA_DMA_PAD_SZ - 1); | 887 | ATA_DMA_PAD_SZ - 1); |
888 | blk_queue_dma_pad(sdev->request_queue, ATA_DMA_PAD_SZ - 1); | 888 | blk_queue_update_dma_pad(sdev->request_queue, |
889 | ATA_DMA_PAD_SZ - 1); | ||
889 | 890 | ||
890 | /* configure draining */ | 891 | /* configure draining */ |
891 | buf = kmalloc(ATAPI_MAX_DRAIN, q->bounce_gfp | GFP_KERNEL); | 892 | buf = kmalloc(ATAPI_MAX_DRAIN, q->bounce_gfp | GFP_KERNEL); |
diff --git a/drivers/block/DAC960.c b/drivers/block/DAC960.c index cd03473f3547..a002a381df92 100644 --- a/drivers/block/DAC960.c +++ b/drivers/block/DAC960.c | |||
@@ -6628,15 +6628,18 @@ static void DAC960_DestroyProcEntries(DAC960_Controller_T *Controller) | |||
6628 | * DAC960_gam_ioctl is the ioctl function for performing RAID operations. | 6628 | * DAC960_gam_ioctl is the ioctl function for performing RAID operations. |
6629 | */ | 6629 | */ |
6630 | 6630 | ||
6631 | static int DAC960_gam_ioctl(struct inode *inode, struct file *file, | 6631 | static long DAC960_gam_ioctl(struct file *file, unsigned int Request, |
6632 | unsigned int Request, unsigned long Argument) | 6632 | unsigned long Argument) |
6633 | { | 6633 | { |
6634 | int ErrorCode = 0; | 6634 | long ErrorCode = 0; |
6635 | if (!capable(CAP_SYS_ADMIN)) return -EACCES; | 6635 | if (!capable(CAP_SYS_ADMIN)) return -EACCES; |
6636 | |||
6637 | lock_kernel(); | ||
6636 | switch (Request) | 6638 | switch (Request) |
6637 | { | 6639 | { |
6638 | case DAC960_IOCTL_GET_CONTROLLER_COUNT: | 6640 | case DAC960_IOCTL_GET_CONTROLLER_COUNT: |
6639 | return DAC960_ControllerCount; | 6641 | ErrorCode = DAC960_ControllerCount; |
6642 | break; | ||
6640 | case DAC960_IOCTL_GET_CONTROLLER_INFO: | 6643 | case DAC960_IOCTL_GET_CONTROLLER_INFO: |
6641 | { | 6644 | { |
6642 | DAC960_ControllerInfo_T __user *UserSpaceControllerInfo = | 6645 | DAC960_ControllerInfo_T __user *UserSpaceControllerInfo = |
@@ -6644,15 +6647,20 @@ static int DAC960_gam_ioctl(struct inode *inode, struct file *file, | |||
6644 | DAC960_ControllerInfo_T ControllerInfo; | 6647 | DAC960_ControllerInfo_T ControllerInfo; |
6645 | DAC960_Controller_T *Controller; | 6648 | DAC960_Controller_T *Controller; |
6646 | int ControllerNumber; | 6649 | int ControllerNumber; |
6647 | if (UserSpaceControllerInfo == NULL) return -EINVAL; | 6650 | if (UserSpaceControllerInfo == NULL) |
6648 | ErrorCode = get_user(ControllerNumber, | 6651 | ErrorCode = -EINVAL; |
6652 | else ErrorCode = get_user(ControllerNumber, | ||
6649 | &UserSpaceControllerInfo->ControllerNumber); | 6653 | &UserSpaceControllerInfo->ControllerNumber); |
6650 | if (ErrorCode != 0) return ErrorCode; | 6654 | if (ErrorCode != 0) |
6655 | break;; | ||
6656 | ErrorCode = -ENXIO; | ||
6651 | if (ControllerNumber < 0 || | 6657 | if (ControllerNumber < 0 || |
6652 | ControllerNumber > DAC960_ControllerCount - 1) | 6658 | ControllerNumber > DAC960_ControllerCount - 1) { |
6653 | return -ENXIO; | 6659 | break; |
6660 | } | ||
6654 | Controller = DAC960_Controllers[ControllerNumber]; | 6661 | Controller = DAC960_Controllers[ControllerNumber]; |
6655 | if (Controller == NULL) return -ENXIO; | 6662 | if (Controller == NULL) |
6663 | break;; | ||
6656 | memset(&ControllerInfo, 0, sizeof(DAC960_ControllerInfo_T)); | 6664 | memset(&ControllerInfo, 0, sizeof(DAC960_ControllerInfo_T)); |
6657 | ControllerInfo.ControllerNumber = ControllerNumber; | 6665 | ControllerInfo.ControllerNumber = ControllerNumber; |
6658 | ControllerInfo.FirmwareType = Controller->FirmwareType; | 6666 | ControllerInfo.FirmwareType = Controller->FirmwareType; |
@@ -6665,8 +6673,9 @@ static int DAC960_gam_ioctl(struct inode *inode, struct file *file, | |||
6665 | ControllerInfo.PCI_Address = Controller->PCI_Address; | 6673 | ControllerInfo.PCI_Address = Controller->PCI_Address; |
6666 | strcpy(ControllerInfo.ModelName, Controller->ModelName); | 6674 | strcpy(ControllerInfo.ModelName, Controller->ModelName); |
6667 | strcpy(ControllerInfo.FirmwareVersion, Controller->FirmwareVersion); | 6675 | strcpy(ControllerInfo.FirmwareVersion, Controller->FirmwareVersion); |
6668 | return (copy_to_user(UserSpaceControllerInfo, &ControllerInfo, | 6676 | ErrorCode = (copy_to_user(UserSpaceControllerInfo, &ControllerInfo, |
6669 | sizeof(DAC960_ControllerInfo_T)) ? -EFAULT : 0); | 6677 | sizeof(DAC960_ControllerInfo_T)) ? -EFAULT : 0); |
6678 | break; | ||
6670 | } | 6679 | } |
6671 | case DAC960_IOCTL_V1_EXECUTE_COMMAND: | 6680 | case DAC960_IOCTL_V1_EXECUTE_COMMAND: |
6672 | { | 6681 | { |
@@ -6684,30 +6693,39 @@ static int DAC960_gam_ioctl(struct inode *inode, struct file *file, | |||
6684 | int ControllerNumber, DataTransferLength; | 6693 | int ControllerNumber, DataTransferLength; |
6685 | unsigned char *DataTransferBuffer = NULL; | 6694 | unsigned char *DataTransferBuffer = NULL; |
6686 | dma_addr_t DataTransferBufferDMA; | 6695 | dma_addr_t DataTransferBufferDMA; |
6687 | if (UserSpaceUserCommand == NULL) return -EINVAL; | 6696 | if (UserSpaceUserCommand == NULL) { |
6697 | ErrorCode = -EINVAL; | ||
6698 | break; | ||
6699 | } | ||
6688 | if (copy_from_user(&UserCommand, UserSpaceUserCommand, | 6700 | if (copy_from_user(&UserCommand, UserSpaceUserCommand, |
6689 | sizeof(DAC960_V1_UserCommand_T))) { | 6701 | sizeof(DAC960_V1_UserCommand_T))) { |
6690 | ErrorCode = -EFAULT; | 6702 | ErrorCode = -EFAULT; |
6691 | goto Failure1a; | 6703 | break; |
6692 | } | 6704 | } |
6693 | ControllerNumber = UserCommand.ControllerNumber; | 6705 | ControllerNumber = UserCommand.ControllerNumber; |
6706 | ErrorCode = -ENXIO; | ||
6694 | if (ControllerNumber < 0 || | 6707 | if (ControllerNumber < 0 || |
6695 | ControllerNumber > DAC960_ControllerCount - 1) | 6708 | ControllerNumber > DAC960_ControllerCount - 1) |
6696 | return -ENXIO; | 6709 | break; |
6697 | Controller = DAC960_Controllers[ControllerNumber]; | 6710 | Controller = DAC960_Controllers[ControllerNumber]; |
6698 | if (Controller == NULL) return -ENXIO; | 6711 | if (Controller == NULL) |
6699 | if (Controller->FirmwareType != DAC960_V1_Controller) return -EINVAL; | 6712 | break; |
6713 | ErrorCode = -EINVAL; | ||
6714 | if (Controller->FirmwareType != DAC960_V1_Controller) | ||
6715 | break; | ||
6700 | CommandOpcode = UserCommand.CommandMailbox.Common.CommandOpcode; | 6716 | CommandOpcode = UserCommand.CommandMailbox.Common.CommandOpcode; |
6701 | DataTransferLength = UserCommand.DataTransferLength; | 6717 | DataTransferLength = UserCommand.DataTransferLength; |
6702 | if (CommandOpcode & 0x80) return -EINVAL; | 6718 | if (CommandOpcode & 0x80) |
6719 | break; | ||
6703 | if (CommandOpcode == DAC960_V1_DCDB) | 6720 | if (CommandOpcode == DAC960_V1_DCDB) |
6704 | { | 6721 | { |
6705 | if (copy_from_user(&DCDB, UserCommand.DCDB, | 6722 | if (copy_from_user(&DCDB, UserCommand.DCDB, |
6706 | sizeof(DAC960_V1_DCDB_T))) { | 6723 | sizeof(DAC960_V1_DCDB_T))) { |
6707 | ErrorCode = -EFAULT; | 6724 | ErrorCode = -EFAULT; |
6708 | goto Failure1a; | 6725 | break; |
6709 | } | 6726 | } |
6710 | if (DCDB.Channel >= DAC960_V1_MaxChannels) return -EINVAL; | 6727 | if (DCDB.Channel >= DAC960_V1_MaxChannels) |
6728 | break; | ||
6711 | if (!((DataTransferLength == 0 && | 6729 | if (!((DataTransferLength == 0 && |
6712 | DCDB.Direction | 6730 | DCDB.Direction |
6713 | == DAC960_V1_DCDB_NoDataTransfer) || | 6731 | == DAC960_V1_DCDB_NoDataTransfer) || |
@@ -6717,38 +6735,37 @@ static int DAC960_gam_ioctl(struct inode *inode, struct file *file, | |||
6717 | (DataTransferLength < 0 && | 6735 | (DataTransferLength < 0 && |
6718 | DCDB.Direction | 6736 | DCDB.Direction |
6719 | == DAC960_V1_DCDB_DataTransferSystemToDevice))) | 6737 | == DAC960_V1_DCDB_DataTransferSystemToDevice))) |
6720 | return -EINVAL; | 6738 | break; |
6721 | if (((DCDB.TransferLengthHigh4 << 16) | DCDB.TransferLength) | 6739 | if (((DCDB.TransferLengthHigh4 << 16) | DCDB.TransferLength) |
6722 | != abs(DataTransferLength)) | 6740 | != abs(DataTransferLength)) |
6723 | return -EINVAL; | 6741 | break; |
6724 | DCDB_IOBUF = pci_alloc_consistent(Controller->PCIDevice, | 6742 | DCDB_IOBUF = pci_alloc_consistent(Controller->PCIDevice, |
6725 | sizeof(DAC960_V1_DCDB_T), &DCDB_IOBUFDMA); | 6743 | sizeof(DAC960_V1_DCDB_T), &DCDB_IOBUFDMA); |
6726 | if (DCDB_IOBUF == NULL) | 6744 | if (DCDB_IOBUF == NULL) { |
6727 | return -ENOMEM; | 6745 | ErrorCode = -ENOMEM; |
6746 | break; | ||
6747 | } | ||
6728 | } | 6748 | } |
6749 | ErrorCode = -ENOMEM; | ||
6729 | if (DataTransferLength > 0) | 6750 | if (DataTransferLength > 0) |
6730 | { | 6751 | { |
6731 | DataTransferBuffer = pci_alloc_consistent(Controller->PCIDevice, | 6752 | DataTransferBuffer = pci_alloc_consistent(Controller->PCIDevice, |
6732 | DataTransferLength, &DataTransferBufferDMA); | 6753 | DataTransferLength, &DataTransferBufferDMA); |
6733 | if (DataTransferBuffer == NULL) { | 6754 | if (DataTransferBuffer == NULL) |
6734 | ErrorCode = -ENOMEM; | 6755 | break; |
6735 | goto Failure1; | ||
6736 | } | ||
6737 | memset(DataTransferBuffer, 0, DataTransferLength); | 6756 | memset(DataTransferBuffer, 0, DataTransferLength); |
6738 | } | 6757 | } |
6739 | else if (DataTransferLength < 0) | 6758 | else if (DataTransferLength < 0) |
6740 | { | 6759 | { |
6741 | DataTransferBuffer = pci_alloc_consistent(Controller->PCIDevice, | 6760 | DataTransferBuffer = pci_alloc_consistent(Controller->PCIDevice, |
6742 | -DataTransferLength, &DataTransferBufferDMA); | 6761 | -DataTransferLength, &DataTransferBufferDMA); |
6743 | if (DataTransferBuffer == NULL) { | 6762 | if (DataTransferBuffer == NULL) |
6744 | ErrorCode = -ENOMEM; | 6763 | break; |
6745 | goto Failure1; | ||
6746 | } | ||
6747 | if (copy_from_user(DataTransferBuffer, | 6764 | if (copy_from_user(DataTransferBuffer, |
6748 | UserCommand.DataTransferBuffer, | 6765 | UserCommand.DataTransferBuffer, |
6749 | -DataTransferLength)) { | 6766 | -DataTransferLength)) { |
6750 | ErrorCode = -EFAULT; | 6767 | ErrorCode = -EFAULT; |
6751 | goto Failure1; | 6768 | break; |
6752 | } | 6769 | } |
6753 | } | 6770 | } |
6754 | if (CommandOpcode == DAC960_V1_DCDB) | 6771 | if (CommandOpcode == DAC960_V1_DCDB) |
@@ -6825,8 +6842,7 @@ static int DAC960_gam_ioctl(struct inode *inode, struct file *file, | |||
6825 | if (DCDB_IOBUF != NULL) | 6842 | if (DCDB_IOBUF != NULL) |
6826 | pci_free_consistent(Controller->PCIDevice, sizeof(DAC960_V1_DCDB_T), | 6843 | pci_free_consistent(Controller->PCIDevice, sizeof(DAC960_V1_DCDB_T), |
6827 | DCDB_IOBUF, DCDB_IOBUFDMA); | 6844 | DCDB_IOBUF, DCDB_IOBUFDMA); |
6828 | Failure1a: | 6845 | break; |
6829 | return ErrorCode; | ||
6830 | } | 6846 | } |
6831 | case DAC960_IOCTL_V2_EXECUTE_COMMAND: | 6847 | case DAC960_IOCTL_V2_EXECUTE_COMMAND: |
6832 | { | 6848 | { |
@@ -6844,32 +6860,43 @@ static int DAC960_gam_ioctl(struct inode *inode, struct file *file, | |||
6844 | dma_addr_t DataTransferBufferDMA; | 6860 | dma_addr_t DataTransferBufferDMA; |
6845 | unsigned char *RequestSenseBuffer = NULL; | 6861 | unsigned char *RequestSenseBuffer = NULL; |
6846 | dma_addr_t RequestSenseBufferDMA; | 6862 | dma_addr_t RequestSenseBufferDMA; |
6847 | if (UserSpaceUserCommand == NULL) return -EINVAL; | 6863 | |
6864 | ErrorCode = -EINVAL; | ||
6865 | if (UserSpaceUserCommand == NULL) | ||
6866 | break; | ||
6848 | if (copy_from_user(&UserCommand, UserSpaceUserCommand, | 6867 | if (copy_from_user(&UserCommand, UserSpaceUserCommand, |
6849 | sizeof(DAC960_V2_UserCommand_T))) { | 6868 | sizeof(DAC960_V2_UserCommand_T))) { |
6850 | ErrorCode = -EFAULT; | 6869 | ErrorCode = -EFAULT; |
6851 | goto Failure2a; | 6870 | break; |
6852 | } | 6871 | } |
6872 | ErrorCode = -ENXIO; | ||
6853 | ControllerNumber = UserCommand.ControllerNumber; | 6873 | ControllerNumber = UserCommand.ControllerNumber; |
6854 | if (ControllerNumber < 0 || | 6874 | if (ControllerNumber < 0 || |
6855 | ControllerNumber > DAC960_ControllerCount - 1) | 6875 | ControllerNumber > DAC960_ControllerCount - 1) |
6856 | return -ENXIO; | 6876 | break; |
6857 | Controller = DAC960_Controllers[ControllerNumber]; | 6877 | Controller = DAC960_Controllers[ControllerNumber]; |
6858 | if (Controller == NULL) return -ENXIO; | 6878 | if (Controller == NULL) |
6859 | if (Controller->FirmwareType != DAC960_V2_Controller) return -EINVAL; | 6879 | break; |
6880 | if (Controller->FirmwareType != DAC960_V2_Controller){ | ||
6881 | ErrorCode = -EINVAL; | ||
6882 | break; | ||
6883 | } | ||
6860 | DataTransferLength = UserCommand.DataTransferLength; | 6884 | DataTransferLength = UserCommand.DataTransferLength; |
6885 | ErrorCode = -ENOMEM; | ||
6861 | if (DataTransferLength > 0) | 6886 | if (DataTransferLength > 0) |
6862 | { | 6887 | { |
6863 | DataTransferBuffer = pci_alloc_consistent(Controller->PCIDevice, | 6888 | DataTransferBuffer = pci_alloc_consistent(Controller->PCIDevice, |
6864 | DataTransferLength, &DataTransferBufferDMA); | 6889 | DataTransferLength, &DataTransferBufferDMA); |
6865 | if (DataTransferBuffer == NULL) return -ENOMEM; | 6890 | if (DataTransferBuffer == NULL) |
6891 | break; | ||
6866 | memset(DataTransferBuffer, 0, DataTransferLength); | 6892 | memset(DataTransferBuffer, 0, DataTransferLength); |
6867 | } | 6893 | } |
6868 | else if (DataTransferLength < 0) | 6894 | else if (DataTransferLength < 0) |
6869 | { | 6895 | { |
6870 | DataTransferBuffer = pci_alloc_consistent(Controller->PCIDevice, | 6896 | DataTransferBuffer = pci_alloc_consistent(Controller->PCIDevice, |
6871 | -DataTransferLength, &DataTransferBufferDMA); | 6897 | -DataTransferLength, &DataTransferBufferDMA); |
6872 | if (DataTransferBuffer == NULL) return -ENOMEM; | 6898 | if (DataTransferBuffer == NULL) |
6899 | break; | ||
6873 | if (copy_from_user(DataTransferBuffer, | 6900 | if (copy_from_user(DataTransferBuffer, |
6874 | UserCommand.DataTransferBuffer, | 6901 | UserCommand.DataTransferBuffer, |
6875 | -DataTransferLength)) { | 6902 | -DataTransferLength)) { |
@@ -6979,8 +7006,7 @@ static int DAC960_gam_ioctl(struct inode *inode, struct file *file, | |||
6979 | if (RequestSenseBuffer != NULL) | 7006 | if (RequestSenseBuffer != NULL) |
6980 | pci_free_consistent(Controller->PCIDevice, RequestSenseLength, | 7007 | pci_free_consistent(Controller->PCIDevice, RequestSenseLength, |
6981 | RequestSenseBuffer, RequestSenseBufferDMA); | 7008 | RequestSenseBuffer, RequestSenseBufferDMA); |
6982 | Failure2a: | 7009 | break; |
6983 | return ErrorCode; | ||
6984 | } | 7010 | } |
6985 | case DAC960_IOCTL_V2_GET_HEALTH_STATUS: | 7011 | case DAC960_IOCTL_V2_GET_HEALTH_STATUS: |
6986 | { | 7012 | { |
@@ -6990,21 +7016,33 @@ static int DAC960_gam_ioctl(struct inode *inode, struct file *file, | |||
6990 | DAC960_V2_HealthStatusBuffer_T HealthStatusBuffer; | 7016 | DAC960_V2_HealthStatusBuffer_T HealthStatusBuffer; |
6991 | DAC960_Controller_T *Controller; | 7017 | DAC960_Controller_T *Controller; |
6992 | int ControllerNumber; | 7018 | int ControllerNumber; |
6993 | if (UserSpaceGetHealthStatus == NULL) return -EINVAL; | 7019 | if (UserSpaceGetHealthStatus == NULL) { |
7020 | ErrorCode = -EINVAL; | ||
7021 | break; | ||
7022 | } | ||
6994 | if (copy_from_user(&GetHealthStatus, UserSpaceGetHealthStatus, | 7023 | if (copy_from_user(&GetHealthStatus, UserSpaceGetHealthStatus, |
6995 | sizeof(DAC960_V2_GetHealthStatus_T))) | 7024 | sizeof(DAC960_V2_GetHealthStatus_T))) { |
6996 | return -EFAULT; | 7025 | ErrorCode = -EFAULT; |
7026 | break; | ||
7027 | } | ||
7028 | ErrorCode = -ENXIO; | ||
6997 | ControllerNumber = GetHealthStatus.ControllerNumber; | 7029 | ControllerNumber = GetHealthStatus.ControllerNumber; |
6998 | if (ControllerNumber < 0 || | 7030 | if (ControllerNumber < 0 || |
6999 | ControllerNumber > DAC960_ControllerCount - 1) | 7031 | ControllerNumber > DAC960_ControllerCount - 1) |
7000 | return -ENXIO; | 7032 | break; |
7001 | Controller = DAC960_Controllers[ControllerNumber]; | 7033 | Controller = DAC960_Controllers[ControllerNumber]; |
7002 | if (Controller == NULL) return -ENXIO; | 7034 | if (Controller == NULL) |
7003 | if (Controller->FirmwareType != DAC960_V2_Controller) return -EINVAL; | 7035 | break; |
7036 | if (Controller->FirmwareType != DAC960_V2_Controller) { | ||
7037 | ErrorCode = -EINVAL; | ||
7038 | break; | ||
7039 | } | ||
7004 | if (copy_from_user(&HealthStatusBuffer, | 7040 | if (copy_from_user(&HealthStatusBuffer, |
7005 | GetHealthStatus.HealthStatusBuffer, | 7041 | GetHealthStatus.HealthStatusBuffer, |
7006 | sizeof(DAC960_V2_HealthStatusBuffer_T))) | 7042 | sizeof(DAC960_V2_HealthStatusBuffer_T))) { |
7007 | return -EFAULT; | 7043 | ErrorCode = -EFAULT; |
7044 | break; | ||
7045 | } | ||
7008 | while (Controller->V2.HealthStatusBuffer->StatusChangeCounter | 7046 | while (Controller->V2.HealthStatusBuffer->StatusChangeCounter |
7009 | == HealthStatusBuffer.StatusChangeCounter && | 7047 | == HealthStatusBuffer.StatusChangeCounter && |
7010 | Controller->V2.HealthStatusBuffer->NextEventSequenceNumber | 7048 | Controller->V2.HealthStatusBuffer->NextEventSequenceNumber |
@@ -7012,21 +7050,28 @@ static int DAC960_gam_ioctl(struct inode *inode, struct file *file, | |||
7012 | { | 7050 | { |
7013 | interruptible_sleep_on_timeout(&Controller->HealthStatusWaitQueue, | 7051 | interruptible_sleep_on_timeout(&Controller->HealthStatusWaitQueue, |
7014 | DAC960_MonitoringTimerInterval); | 7052 | DAC960_MonitoringTimerInterval); |
7015 | if (signal_pending(current)) return -EINTR; | 7053 | if (signal_pending(current)) { |
7054 | ErrorCode = -EINTR; | ||
7055 | break; | ||
7056 | } | ||
7016 | } | 7057 | } |
7017 | if (copy_to_user(GetHealthStatus.HealthStatusBuffer, | 7058 | if (copy_to_user(GetHealthStatus.HealthStatusBuffer, |
7018 | Controller->V2.HealthStatusBuffer, | 7059 | Controller->V2.HealthStatusBuffer, |
7019 | sizeof(DAC960_V2_HealthStatusBuffer_T))) | 7060 | sizeof(DAC960_V2_HealthStatusBuffer_T))) |
7020 | return -EFAULT; | 7061 | ErrorCode = -EFAULT; |
7021 | return 0; | 7062 | else |
7063 | ErrorCode = 0; | ||
7022 | } | 7064 | } |
7065 | default: | ||
7066 | ErrorCode = -ENOTTY; | ||
7023 | } | 7067 | } |
7024 | return -EINVAL; | 7068 | unlock_kernel(); |
7069 | return ErrorCode; | ||
7025 | } | 7070 | } |
7026 | 7071 | ||
7027 | static const struct file_operations DAC960_gam_fops = { | 7072 | static const struct file_operations DAC960_gam_fops = { |
7028 | .owner = THIS_MODULE, | 7073 | .owner = THIS_MODULE, |
7029 | .ioctl = DAC960_gam_ioctl | 7074 | .unlocked_ioctl = DAC960_gam_ioctl |
7030 | }; | 7075 | }; |
7031 | 7076 | ||
7032 | static struct miscdevice DAC960_gam_dev = { | 7077 | static struct miscdevice DAC960_gam_dev = { |
diff --git a/drivers/block/aoe/aoecmd.c b/drivers/block/aoe/aoecmd.c index 41f818be2f7e..2f1746295d06 100644 --- a/drivers/block/aoe/aoecmd.c +++ b/drivers/block/aoe/aoecmd.c | |||
@@ -1003,7 +1003,7 @@ aoecmd_cfg_rsp(struct sk_buff *skb) | |||
1003 | * Enough people have their dip switches set backwards to | 1003 | * Enough people have their dip switches set backwards to |
1004 | * warrant a loud message for this special case. | 1004 | * warrant a loud message for this special case. |
1005 | */ | 1005 | */ |
1006 | aoemajor = be16_to_cpu(get_unaligned(&h->major)); | 1006 | aoemajor = get_unaligned_be16(&h->major); |
1007 | if (aoemajor == 0xfff) { | 1007 | if (aoemajor == 0xfff) { |
1008 | printk(KERN_ERR "aoe: Warning: shelf address is all ones. " | 1008 | printk(KERN_ERR "aoe: Warning: shelf address is all ones. " |
1009 | "Check shelf dip switches.\n"); | 1009 | "Check shelf dip switches.\n"); |
diff --git a/drivers/block/paride/pt.c b/drivers/block/paride/pt.c index 8b9549ab4a4e..27455ee1e9da 100644 --- a/drivers/block/paride/pt.c +++ b/drivers/block/paride/pt.c | |||
@@ -146,6 +146,7 @@ static int (*drives[4])[6] = {&drive0, &drive1, &drive2, &drive3}; | |||
146 | #include <linux/mtio.h> | 146 | #include <linux/mtio.h> |
147 | #include <linux/device.h> | 147 | #include <linux/device.h> |
148 | #include <linux/sched.h> /* current, TASK_*, schedule_timeout() */ | 148 | #include <linux/sched.h> /* current, TASK_*, schedule_timeout() */ |
149 | #include <linux/smp_lock.h> | ||
149 | 150 | ||
150 | #include <asm/uaccess.h> | 151 | #include <asm/uaccess.h> |
151 | 152 | ||
@@ -189,8 +190,7 @@ module_param_array(drive3, int, NULL, 0); | |||
189 | #define ATAPI_LOG_SENSE 0x4d | 190 | #define ATAPI_LOG_SENSE 0x4d |
190 | 191 | ||
191 | static int pt_open(struct inode *inode, struct file *file); | 192 | static int pt_open(struct inode *inode, struct file *file); |
192 | static int pt_ioctl(struct inode *inode, struct file *file, | 193 | static long pt_ioctl(struct file *file, unsigned int cmd, unsigned long arg); |
193 | unsigned int cmd, unsigned long arg); | ||
194 | static int pt_release(struct inode *inode, struct file *file); | 194 | static int pt_release(struct inode *inode, struct file *file); |
195 | static ssize_t pt_read(struct file *filp, char __user *buf, | 195 | static ssize_t pt_read(struct file *filp, char __user *buf, |
196 | size_t count, loff_t * ppos); | 196 | size_t count, loff_t * ppos); |
@@ -236,7 +236,7 @@ static const struct file_operations pt_fops = { | |||
236 | .owner = THIS_MODULE, | 236 | .owner = THIS_MODULE, |
237 | .read = pt_read, | 237 | .read = pt_read, |
238 | .write = pt_write, | 238 | .write = pt_write, |
239 | .ioctl = pt_ioctl, | 239 | .unlocked_ioctl = pt_ioctl, |
240 | .open = pt_open, | 240 | .open = pt_open, |
241 | .release = pt_release, | 241 | .release = pt_release, |
242 | }; | 242 | }; |
@@ -685,8 +685,7 @@ out: | |||
685 | return err; | 685 | return err; |
686 | } | 686 | } |
687 | 687 | ||
688 | static int pt_ioctl(struct inode *inode, struct file *file, | 688 | static long pt_ioctl(struct file *file, unsigned int cmd, unsigned long arg) |
689 | unsigned int cmd, unsigned long arg) | ||
690 | { | 689 | { |
691 | struct pt_unit *tape = file->private_data; | 690 | struct pt_unit *tape = file->private_data; |
692 | struct mtop __user *p = (void __user *)arg; | 691 | struct mtop __user *p = (void __user *)arg; |
@@ -700,23 +699,26 @@ static int pt_ioctl(struct inode *inode, struct file *file, | |||
700 | switch (mtop.mt_op) { | 699 | switch (mtop.mt_op) { |
701 | 700 | ||
702 | case MTREW: | 701 | case MTREW: |
702 | lock_kernel(); | ||
703 | pt_rewind(tape); | 703 | pt_rewind(tape); |
704 | unlock_kernel(); | ||
704 | return 0; | 705 | return 0; |
705 | 706 | ||
706 | case MTWEOF: | 707 | case MTWEOF: |
708 | lock_kernel(); | ||
707 | pt_write_fm(tape); | 709 | pt_write_fm(tape); |
710 | unlock_kernel(); | ||
708 | return 0; | 711 | return 0; |
709 | 712 | ||
710 | default: | 713 | default: |
711 | printk("%s: Unimplemented mt_op %d\n", tape->name, | 714 | /* FIXME: rate limit ?? */ |
715 | printk(KERN_DEBUG "%s: Unimplemented mt_op %d\n", tape->name, | ||
712 | mtop.mt_op); | 716 | mtop.mt_op); |
713 | return -EINVAL; | 717 | return -EINVAL; |
714 | } | 718 | } |
715 | 719 | ||
716 | default: | 720 | default: |
717 | printk("%s: Unimplemented ioctl 0x%x\n", tape->name, cmd); | 721 | return -ENOTTY; |
718 | return -EINVAL; | ||
719 | |||
720 | } | 722 | } |
721 | } | 723 | } |
722 | 724 | ||
diff --git a/drivers/block/pktcdvd.c b/drivers/block/pktcdvd.c index 3ba1df93e9e3..45bee918c46a 100644 --- a/drivers/block/pktcdvd.c +++ b/drivers/block/pktcdvd.c | |||
@@ -49,6 +49,7 @@ | |||
49 | #include <linux/types.h> | 49 | #include <linux/types.h> |
50 | #include <linux/kernel.h> | 50 | #include <linux/kernel.h> |
51 | #include <linux/kthread.h> | 51 | #include <linux/kthread.h> |
52 | #include <linux/smp_lock.h> | ||
52 | #include <linux/errno.h> | 53 | #include <linux/errno.h> |
53 | #include <linux/spinlock.h> | 54 | #include <linux/spinlock.h> |
54 | #include <linux/file.h> | 55 | #include <linux/file.h> |
@@ -2079,7 +2080,6 @@ static noinline_for_stack int pkt_write_caching(struct pktcdvd_device *pd, | |||
2079 | unsigned char buf[64]; | 2080 | unsigned char buf[64]; |
2080 | int ret; | 2081 | int ret; |
2081 | 2082 | ||
2082 | memset(buf, 0, sizeof(buf)); | ||
2083 | init_cdrom_command(&cgc, buf, sizeof(buf), CGC_DATA_READ); | 2083 | init_cdrom_command(&cgc, buf, sizeof(buf), CGC_DATA_READ); |
2084 | cgc.sense = &sense; | 2084 | cgc.sense = &sense; |
2085 | cgc.buflen = pd->mode_offset + 12; | 2085 | cgc.buflen = pd->mode_offset + 12; |
@@ -2126,7 +2126,6 @@ static noinline_for_stack int pkt_get_max_speed(struct pktcdvd_device *pd, | |||
2126 | unsigned char *cap_buf; | 2126 | unsigned char *cap_buf; |
2127 | int ret, offset; | 2127 | int ret, offset; |
2128 | 2128 | ||
2129 | memset(buf, 0, sizeof(buf)); | ||
2130 | cap_buf = &buf[sizeof(struct mode_page_header) + pd->mode_offset]; | 2129 | cap_buf = &buf[sizeof(struct mode_page_header) + pd->mode_offset]; |
2131 | init_cdrom_command(&cgc, buf, sizeof(buf), CGC_DATA_UNKNOWN); | 2130 | init_cdrom_command(&cgc, buf, sizeof(buf), CGC_DATA_UNKNOWN); |
2132 | cgc.sense = &sense; | 2131 | cgc.sense = &sense; |
@@ -2633,11 +2632,12 @@ end_io: | |||
2633 | 2632 | ||
2634 | 2633 | ||
2635 | 2634 | ||
2636 | static int pkt_merge_bvec(struct request_queue *q, struct bio *bio, struct bio_vec *bvec) | 2635 | static int pkt_merge_bvec(struct request_queue *q, struct bvec_merge_data *bmd, |
2636 | struct bio_vec *bvec) | ||
2637 | { | 2637 | { |
2638 | struct pktcdvd_device *pd = q->queuedata; | 2638 | struct pktcdvd_device *pd = q->queuedata; |
2639 | sector_t zone = ZONE(bio->bi_sector, pd); | 2639 | sector_t zone = ZONE(bmd->bi_sector, pd); |
2640 | int used = ((bio->bi_sector - zone) << 9) + bio->bi_size; | 2640 | int used = ((bmd->bi_sector - zone) << 9) + bmd->bi_size; |
2641 | int remaining = (pd->settings.size << 9) - used; | 2641 | int remaining = (pd->settings.size << 9) - used; |
2642 | int remaining2; | 2642 | int remaining2; |
2643 | 2643 | ||
@@ -2645,7 +2645,7 @@ static int pkt_merge_bvec(struct request_queue *q, struct bio *bio, struct bio_v | |||
2645 | * A bio <= PAGE_SIZE must be allowed. If it crosses a packet | 2645 | * A bio <= PAGE_SIZE must be allowed. If it crosses a packet |
2646 | * boundary, pkt_make_request() will split the bio. | 2646 | * boundary, pkt_make_request() will split the bio. |
2647 | */ | 2647 | */ |
2648 | remaining2 = PAGE_SIZE - bio->bi_size; | 2648 | remaining2 = PAGE_SIZE - bmd->bi_size; |
2649 | remaining = max(remaining, remaining2); | 2649 | remaining = max(remaining, remaining2); |
2650 | 2650 | ||
2651 | BUG_ON(remaining < 0); | 2651 | BUG_ON(remaining < 0); |
@@ -2796,9 +2796,14 @@ out_mem: | |||
2796 | return ret; | 2796 | return ret; |
2797 | } | 2797 | } |
2798 | 2798 | ||
2799 | static int pkt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) | 2799 | static long pkt_ioctl(struct file *file, unsigned int cmd, unsigned long arg) |
2800 | { | 2800 | { |
2801 | struct pktcdvd_device *pd = inode->i_bdev->bd_disk->private_data; | 2801 | struct inode *inode = file->f_path.dentry->d_inode; |
2802 | struct pktcdvd_device *pd; | ||
2803 | long ret; | ||
2804 | |||
2805 | lock_kernel(); | ||
2806 | pd = inode->i_bdev->bd_disk->private_data; | ||
2802 | 2807 | ||
2803 | VPRINTK("pkt_ioctl: cmd %x, dev %d:%d\n", cmd, imajor(inode), iminor(inode)); | 2808 | VPRINTK("pkt_ioctl: cmd %x, dev %d:%d\n", cmd, imajor(inode), iminor(inode)); |
2804 | 2809 | ||
@@ -2811,7 +2816,8 @@ static int pkt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, u | |||
2811 | case CDROM_LAST_WRITTEN: | 2816 | case CDROM_LAST_WRITTEN: |
2812 | case CDROM_SEND_PACKET: | 2817 | case CDROM_SEND_PACKET: |
2813 | case SCSI_IOCTL_SEND_COMMAND: | 2818 | case SCSI_IOCTL_SEND_COMMAND: |
2814 | return blkdev_ioctl(pd->bdev->bd_inode, file, cmd, arg); | 2819 | ret = blkdev_ioctl(pd->bdev->bd_inode, file, cmd, arg); |
2820 | break; | ||
2815 | 2821 | ||
2816 | case CDROMEJECT: | 2822 | case CDROMEJECT: |
2817 | /* | 2823 | /* |
@@ -2820,14 +2826,15 @@ static int pkt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, u | |||
2820 | */ | 2826 | */ |
2821 | if (pd->refcnt == 1) | 2827 | if (pd->refcnt == 1) |
2822 | pkt_lock_door(pd, 0); | 2828 | pkt_lock_door(pd, 0); |
2823 | return blkdev_ioctl(pd->bdev->bd_inode, file, cmd, arg); | 2829 | ret = blkdev_ioctl(pd->bdev->bd_inode, file, cmd, arg); |
2830 | break; | ||
2824 | 2831 | ||
2825 | default: | 2832 | default: |
2826 | VPRINTK(DRIVER_NAME": Unknown ioctl for %s (%x)\n", pd->name, cmd); | 2833 | VPRINTK(DRIVER_NAME": Unknown ioctl for %s (%x)\n", pd->name, cmd); |
2827 | return -ENOTTY; | 2834 | ret = -ENOTTY; |
2828 | } | 2835 | } |
2829 | 2836 | unlock_kernel(); | |
2830 | return 0; | 2837 | return ret; |
2831 | } | 2838 | } |
2832 | 2839 | ||
2833 | static int pkt_media_changed(struct gendisk *disk) | 2840 | static int pkt_media_changed(struct gendisk *disk) |
@@ -2849,7 +2856,7 @@ static struct block_device_operations pktcdvd_ops = { | |||
2849 | .owner = THIS_MODULE, | 2856 | .owner = THIS_MODULE, |
2850 | .open = pkt_open, | 2857 | .open = pkt_open, |
2851 | .release = pkt_close, | 2858 | .release = pkt_close, |
2852 | .ioctl = pkt_ioctl, | 2859 | .unlocked_ioctl = pkt_ioctl, |
2853 | .media_changed = pkt_media_changed, | 2860 | .media_changed = pkt_media_changed, |
2854 | }; | 2861 | }; |
2855 | 2862 | ||
@@ -3014,7 +3021,8 @@ static void pkt_get_status(struct pkt_ctrl_command *ctrl_cmd) | |||
3014 | mutex_unlock(&ctl_mutex); | 3021 | mutex_unlock(&ctl_mutex); |
3015 | } | 3022 | } |
3016 | 3023 | ||
3017 | static int pkt_ctl_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) | 3024 | static long pkt_ctl_ioctl(struct file *file, unsigned int cmd, |
3025 | unsigned long arg) | ||
3018 | { | 3026 | { |
3019 | void __user *argp = (void __user *)arg; | 3027 | void __user *argp = (void __user *)arg; |
3020 | struct pkt_ctrl_command ctrl_cmd; | 3028 | struct pkt_ctrl_command ctrl_cmd; |
@@ -3031,16 +3039,22 @@ static int pkt_ctl_ioctl(struct inode *inode, struct file *file, unsigned int cm | |||
3031 | case PKT_CTRL_CMD_SETUP: | 3039 | case PKT_CTRL_CMD_SETUP: |
3032 | if (!capable(CAP_SYS_ADMIN)) | 3040 | if (!capable(CAP_SYS_ADMIN)) |
3033 | return -EPERM; | 3041 | return -EPERM; |
3042 | lock_kernel(); | ||
3034 | ret = pkt_setup_dev(new_decode_dev(ctrl_cmd.dev), &pkt_dev); | 3043 | ret = pkt_setup_dev(new_decode_dev(ctrl_cmd.dev), &pkt_dev); |
3035 | ctrl_cmd.pkt_dev = new_encode_dev(pkt_dev); | 3044 | ctrl_cmd.pkt_dev = new_encode_dev(pkt_dev); |
3045 | unlock_kernel(); | ||
3036 | break; | 3046 | break; |
3037 | case PKT_CTRL_CMD_TEARDOWN: | 3047 | case PKT_CTRL_CMD_TEARDOWN: |
3038 | if (!capable(CAP_SYS_ADMIN)) | 3048 | if (!capable(CAP_SYS_ADMIN)) |
3039 | return -EPERM; | 3049 | return -EPERM; |
3050 | lock_kernel(); | ||
3040 | ret = pkt_remove_dev(new_decode_dev(ctrl_cmd.pkt_dev)); | 3051 | ret = pkt_remove_dev(new_decode_dev(ctrl_cmd.pkt_dev)); |
3052 | unlock_kernel(); | ||
3041 | break; | 3053 | break; |
3042 | case PKT_CTRL_CMD_STATUS: | 3054 | case PKT_CTRL_CMD_STATUS: |
3055 | lock_kernel(); | ||
3043 | pkt_get_status(&ctrl_cmd); | 3056 | pkt_get_status(&ctrl_cmd); |
3057 | unlock_kernel(); | ||
3044 | break; | 3058 | break; |
3045 | default: | 3059 | default: |
3046 | return -ENOTTY; | 3060 | return -ENOTTY; |
@@ -3053,7 +3067,7 @@ static int pkt_ctl_ioctl(struct inode *inode, struct file *file, unsigned int cm | |||
3053 | 3067 | ||
3054 | 3068 | ||
3055 | static const struct file_operations pkt_ctl_fops = { | 3069 | static const struct file_operations pkt_ctl_fops = { |
3056 | .ioctl = pkt_ctl_ioctl, | 3070 | .unlocked_ioctl = pkt_ctl_ioctl, |
3057 | .owner = THIS_MODULE, | 3071 | .owner = THIS_MODULE, |
3058 | }; | 3072 | }; |
3059 | 3073 | ||
diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c index f2fff5799ddf..9ae05c584234 100644 --- a/drivers/block/xen-blkfront.c +++ b/drivers/block/xen-blkfront.c | |||
@@ -38,6 +38,7 @@ | |||
38 | #include <linux/interrupt.h> | 38 | #include <linux/interrupt.h> |
39 | #include <linux/blkdev.h> | 39 | #include <linux/blkdev.h> |
40 | #include <linux/hdreg.h> | 40 | #include <linux/hdreg.h> |
41 | #include <linux/cdrom.h> | ||
41 | #include <linux/module.h> | 42 | #include <linux/module.h> |
42 | 43 | ||
43 | #include <xen/xenbus.h> | 44 | #include <xen/xenbus.h> |
@@ -153,6 +154,40 @@ static int blkif_getgeo(struct block_device *bd, struct hd_geometry *hg) | |||
153 | return 0; | 154 | return 0; |
154 | } | 155 | } |
155 | 156 | ||
157 | int blkif_ioctl(struct inode *inode, struct file *filep, | ||
158 | unsigned command, unsigned long argument) | ||
159 | { | ||
160 | struct blkfront_info *info = | ||
161 | inode->i_bdev->bd_disk->private_data; | ||
162 | int i; | ||
163 | |||
164 | dev_dbg(&info->xbdev->dev, "command: 0x%x, argument: 0x%lx\n", | ||
165 | command, (long)argument); | ||
166 | |||
167 | switch (command) { | ||
168 | case CDROMMULTISESSION: | ||
169 | dev_dbg(&info->xbdev->dev, "FIXME: support multisession CDs later\n"); | ||
170 | for (i = 0; i < sizeof(struct cdrom_multisession); i++) | ||
171 | if (put_user(0, (char __user *)(argument + i))) | ||
172 | return -EFAULT; | ||
173 | return 0; | ||
174 | |||
175 | case CDROM_GET_CAPABILITY: { | ||
176 | struct gendisk *gd = info->gd; | ||
177 | if (gd->flags & GENHD_FL_CD) | ||
178 | return 0; | ||
179 | return -EINVAL; | ||
180 | } | ||
181 | |||
182 | default: | ||
183 | /*printk(KERN_ALERT "ioctl %08x not supported by Xen blkdev\n", | ||
184 | command);*/ | ||
185 | return -EINVAL; /* same return as native Linux */ | ||
186 | } | ||
187 | |||
188 | return 0; | ||
189 | } | ||
190 | |||
156 | /* | 191 | /* |
157 | * blkif_queue_request | 192 | * blkif_queue_request |
158 | * | 193 | * |
@@ -324,6 +359,9 @@ static int xlvbd_init_blk_queue(struct gendisk *gd, u16 sector_size) | |||
324 | /* Make sure buffer addresses are sector-aligned. */ | 359 | /* Make sure buffer addresses are sector-aligned. */ |
325 | blk_queue_dma_alignment(rq, 511); | 360 | blk_queue_dma_alignment(rq, 511); |
326 | 361 | ||
362 | /* Make sure we don't use bounce buffers. */ | ||
363 | blk_queue_bounce_limit(rq, BLK_BOUNCE_ANY); | ||
364 | |||
327 | gd->queue = rq; | 365 | gd->queue = rq; |
328 | 366 | ||
329 | return 0; | 367 | return 0; |
@@ -546,7 +584,7 @@ static int setup_blkring(struct xenbus_device *dev, | |||
546 | 584 | ||
547 | info->ring_ref = GRANT_INVALID_REF; | 585 | info->ring_ref = GRANT_INVALID_REF; |
548 | 586 | ||
549 | sring = (struct blkif_sring *)__get_free_page(GFP_KERNEL); | 587 | sring = (struct blkif_sring *)__get_free_page(GFP_NOIO | __GFP_HIGH); |
550 | if (!sring) { | 588 | if (!sring) { |
551 | xenbus_dev_fatal(dev, -ENOMEM, "allocating shared ring"); | 589 | xenbus_dev_fatal(dev, -ENOMEM, "allocating shared ring"); |
552 | return -ENOMEM; | 590 | return -ENOMEM; |
@@ -703,7 +741,8 @@ static int blkif_recover(struct blkfront_info *info) | |||
703 | int j; | 741 | int j; |
704 | 742 | ||
705 | /* Stage 1: Make a safe copy of the shadow state. */ | 743 | /* Stage 1: Make a safe copy of the shadow state. */ |
706 | copy = kmalloc(sizeof(info->shadow), GFP_KERNEL); | 744 | copy = kmalloc(sizeof(info->shadow), |
745 | GFP_NOIO | __GFP_REPEAT | __GFP_HIGH); | ||
707 | if (!copy) | 746 | if (!copy) |
708 | return -ENOMEM; | 747 | return -ENOMEM; |
709 | memcpy(copy, info->shadow, sizeof(info->shadow)); | 748 | memcpy(copy, info->shadow, sizeof(info->shadow)); |
@@ -959,7 +998,7 @@ static int blkif_release(struct inode *inode, struct file *filep) | |||
959 | struct xenbus_device *dev = info->xbdev; | 998 | struct xenbus_device *dev = info->xbdev; |
960 | enum xenbus_state state = xenbus_read_driver_state(dev->otherend); | 999 | enum xenbus_state state = xenbus_read_driver_state(dev->otherend); |
961 | 1000 | ||
962 | if (state == XenbusStateClosing) | 1001 | if (state == XenbusStateClosing && info->is_ready) |
963 | blkfront_closing(dev); | 1002 | blkfront_closing(dev); |
964 | } | 1003 | } |
965 | return 0; | 1004 | return 0; |
@@ -971,6 +1010,7 @@ static struct block_device_operations xlvbd_block_fops = | |||
971 | .open = blkif_open, | 1010 | .open = blkif_open, |
972 | .release = blkif_release, | 1011 | .release = blkif_release, |
973 | .getgeo = blkif_getgeo, | 1012 | .getgeo = blkif_getgeo, |
1013 | .ioctl = blkif_ioctl, | ||
974 | }; | 1014 | }; |
975 | 1015 | ||
976 | 1016 | ||
@@ -1006,7 +1046,7 @@ static int __init xlblk_init(void) | |||
1006 | module_init(xlblk_init); | 1046 | module_init(xlblk_init); |
1007 | 1047 | ||
1008 | 1048 | ||
1009 | static void xlblk_exit(void) | 1049 | static void __exit xlblk_exit(void) |
1010 | { | 1050 | { |
1011 | return xenbus_unregister_driver(&blkfront); | 1051 | return xenbus_unregister_driver(&blkfront); |
1012 | } | 1052 | } |
diff --git a/drivers/cdrom/cdrom.c b/drivers/cdrom/cdrom.c index 69f26eb6415b..a5da35632651 100644 --- a/drivers/cdrom/cdrom.c +++ b/drivers/cdrom/cdrom.c | |||
@@ -461,37 +461,27 @@ int cdrom_get_media_event(struct cdrom_device_info *cdi, | |||
461 | struct media_event_desc *med) | 461 | struct media_event_desc *med) |
462 | { | 462 | { |
463 | struct packet_command cgc; | 463 | struct packet_command cgc; |
464 | unsigned char *buffer; | 464 | unsigned char buffer[8]; |
465 | struct event_header *eh; | 465 | struct event_header *eh = (struct event_header *) buffer; |
466 | int ret = 1; | ||
467 | |||
468 | buffer = kmalloc(8, GFP_KERNEL); | ||
469 | if (!buffer) | ||
470 | return -ENOMEM; | ||
471 | 466 | ||
472 | eh = (struct event_header *)buffer; | 467 | init_cdrom_command(&cgc, buffer, sizeof(buffer), CGC_DATA_READ); |
473 | |||
474 | init_cdrom_command(&cgc, buffer, 8, CGC_DATA_READ); | ||
475 | cgc.cmd[0] = GPCMD_GET_EVENT_STATUS_NOTIFICATION; | 468 | cgc.cmd[0] = GPCMD_GET_EVENT_STATUS_NOTIFICATION; |
476 | cgc.cmd[1] = 1; /* IMMED */ | 469 | cgc.cmd[1] = 1; /* IMMED */ |
477 | cgc.cmd[4] = 1 << 4; /* media event */ | 470 | cgc.cmd[4] = 1 << 4; /* media event */ |
478 | cgc.cmd[8] = 8; | 471 | cgc.cmd[8] = sizeof(buffer); |
479 | cgc.quiet = 1; | 472 | cgc.quiet = 1; |
480 | 473 | ||
481 | if (cdi->ops->generic_packet(cdi, &cgc)) | 474 | if (cdi->ops->generic_packet(cdi, &cgc)) |
482 | goto err; | 475 | return 1; |
483 | 476 | ||
484 | if (be16_to_cpu(eh->data_len) < sizeof(*med)) | 477 | if (be16_to_cpu(eh->data_len) < sizeof(*med)) |
485 | goto err; | 478 | return 1; |
486 | 479 | ||
487 | if (eh->nea || eh->notification_class != 0x4) | 480 | if (eh->nea || eh->notification_class != 0x4) |
488 | goto err; | 481 | return 1; |
489 | 482 | ||
490 | memcpy(med, buffer + sizeof(*eh), sizeof(*med)); | 483 | memcpy(med, &buffer[sizeof(*eh)], sizeof(*med)); |
491 | ret = 0; | 484 | return 0; |
492 | err: | ||
493 | kfree(buffer); | ||
494 | return ret; | ||
495 | } | 485 | } |
496 | 486 | ||
497 | /* | 487 | /* |
@@ -501,82 +491,68 @@ err: | |||
501 | static int cdrom_mrw_probe_pc(struct cdrom_device_info *cdi) | 491 | static int cdrom_mrw_probe_pc(struct cdrom_device_info *cdi) |
502 | { | 492 | { |
503 | struct packet_command cgc; | 493 | struct packet_command cgc; |
504 | char *buffer; | 494 | char buffer[16]; |
505 | int ret = 1; | ||
506 | |||
507 | buffer = kmalloc(16, GFP_KERNEL); | ||
508 | if (!buffer) | ||
509 | return -ENOMEM; | ||
510 | 495 | ||
511 | init_cdrom_command(&cgc, buffer, 16, CGC_DATA_READ); | 496 | init_cdrom_command(&cgc, buffer, sizeof(buffer), CGC_DATA_READ); |
512 | 497 | ||
513 | cgc.timeout = HZ; | 498 | cgc.timeout = HZ; |
514 | cgc.quiet = 1; | 499 | cgc.quiet = 1; |
515 | 500 | ||
516 | if (!cdrom_mode_sense(cdi, &cgc, MRW_MODE_PC, 0)) { | 501 | if (!cdrom_mode_sense(cdi, &cgc, MRW_MODE_PC, 0)) { |
517 | cdi->mrw_mode_page = MRW_MODE_PC; | 502 | cdi->mrw_mode_page = MRW_MODE_PC; |
518 | ret = 0; | 503 | return 0; |
519 | } else if (!cdrom_mode_sense(cdi, &cgc, MRW_MODE_PC_PRE1, 0)) { | 504 | } else if (!cdrom_mode_sense(cdi, &cgc, MRW_MODE_PC_PRE1, 0)) { |
520 | cdi->mrw_mode_page = MRW_MODE_PC_PRE1; | 505 | cdi->mrw_mode_page = MRW_MODE_PC_PRE1; |
521 | ret = 0; | 506 | return 0; |
522 | } | 507 | } |
523 | kfree(buffer); | 508 | |
524 | return ret; | 509 | return 1; |
525 | } | 510 | } |
526 | 511 | ||
527 | static int cdrom_is_mrw(struct cdrom_device_info *cdi, int *write) | 512 | static int cdrom_is_mrw(struct cdrom_device_info *cdi, int *write) |
528 | { | 513 | { |
529 | struct packet_command cgc; | 514 | struct packet_command cgc; |
530 | struct mrw_feature_desc *mfd; | 515 | struct mrw_feature_desc *mfd; |
531 | unsigned char *buffer; | 516 | unsigned char buffer[16]; |
532 | int ret; | 517 | int ret; |
533 | 518 | ||
534 | *write = 0; | 519 | *write = 0; |
535 | buffer = kmalloc(16, GFP_KERNEL); | ||
536 | if (!buffer) | ||
537 | return -ENOMEM; | ||
538 | 520 | ||
539 | init_cdrom_command(&cgc, buffer, 16, CGC_DATA_READ); | 521 | init_cdrom_command(&cgc, buffer, sizeof(buffer), CGC_DATA_READ); |
540 | 522 | ||
541 | cgc.cmd[0] = GPCMD_GET_CONFIGURATION; | 523 | cgc.cmd[0] = GPCMD_GET_CONFIGURATION; |
542 | cgc.cmd[3] = CDF_MRW; | 524 | cgc.cmd[3] = CDF_MRW; |
543 | cgc.cmd[8] = 16; | 525 | cgc.cmd[8] = sizeof(buffer); |
544 | cgc.quiet = 1; | 526 | cgc.quiet = 1; |
545 | 527 | ||
546 | if ((ret = cdi->ops->generic_packet(cdi, &cgc))) | 528 | if ((ret = cdi->ops->generic_packet(cdi, &cgc))) |
547 | goto err; | 529 | return ret; |
548 | 530 | ||
549 | mfd = (struct mrw_feature_desc *)&buffer[sizeof(struct feature_header)]; | 531 | mfd = (struct mrw_feature_desc *)&buffer[sizeof(struct feature_header)]; |
550 | if (be16_to_cpu(mfd->feature_code) != CDF_MRW) { | 532 | if (be16_to_cpu(mfd->feature_code) != CDF_MRW) |
551 | ret = 1; | 533 | return 1; |
552 | goto err; | ||
553 | } | ||
554 | *write = mfd->write; | 534 | *write = mfd->write; |
555 | 535 | ||
556 | if ((ret = cdrom_mrw_probe_pc(cdi))) { | 536 | if ((ret = cdrom_mrw_probe_pc(cdi))) { |
557 | *write = 0; | 537 | *write = 0; |
538 | return ret; | ||
558 | } | 539 | } |
559 | err: | 540 | |
560 | kfree(buffer); | 541 | return 0; |
561 | return ret; | ||
562 | } | 542 | } |
563 | 543 | ||
564 | static int cdrom_mrw_bgformat(struct cdrom_device_info *cdi, int cont) | 544 | static int cdrom_mrw_bgformat(struct cdrom_device_info *cdi, int cont) |
565 | { | 545 | { |
566 | struct packet_command cgc; | 546 | struct packet_command cgc; |
567 | unsigned char *buffer; | 547 | unsigned char buffer[12]; |
568 | int ret; | 548 | int ret; |
569 | 549 | ||
570 | printk(KERN_INFO "cdrom: %sstarting format\n", cont ? "Re" : ""); | 550 | printk(KERN_INFO "cdrom: %sstarting format\n", cont ? "Re" : ""); |
571 | 551 | ||
572 | buffer = kmalloc(12, GFP_KERNEL); | ||
573 | if (!buffer) | ||
574 | return -ENOMEM; | ||
575 | |||
576 | /* | 552 | /* |
577 | * FmtData bit set (bit 4), format type is 1 | 553 | * FmtData bit set (bit 4), format type is 1 |
578 | */ | 554 | */ |
579 | init_cdrom_command(&cgc, buffer, 12, CGC_DATA_WRITE); | 555 | init_cdrom_command(&cgc, buffer, sizeof(buffer), CGC_DATA_WRITE); |
580 | cgc.cmd[0] = GPCMD_FORMAT_UNIT; | 556 | cgc.cmd[0] = GPCMD_FORMAT_UNIT; |
581 | cgc.cmd[1] = (1 << 4) | 1; | 557 | cgc.cmd[1] = (1 << 4) | 1; |
582 | 558 | ||
@@ -603,7 +579,6 @@ static int cdrom_mrw_bgformat(struct cdrom_device_info *cdi, int cont) | |||
603 | if (ret) | 579 | if (ret) |
604 | printk(KERN_INFO "cdrom: bgformat failed\n"); | 580 | printk(KERN_INFO "cdrom: bgformat failed\n"); |
605 | 581 | ||
606 | kfree(buffer); | ||
607 | return ret; | 582 | return ret; |
608 | } | 583 | } |
609 | 584 | ||
@@ -663,17 +638,16 @@ static int cdrom_mrw_set_lba_space(struct cdrom_device_info *cdi, int space) | |||
663 | { | 638 | { |
664 | struct packet_command cgc; | 639 | struct packet_command cgc; |
665 | struct mode_page_header *mph; | 640 | struct mode_page_header *mph; |
666 | char *buffer; | 641 | char buffer[16]; |
667 | int ret, offset, size; | 642 | int ret, offset, size; |
668 | 643 | ||
669 | buffer = kmalloc(16, GFP_KERNEL); | 644 | init_cdrom_command(&cgc, buffer, sizeof(buffer), CGC_DATA_READ); |
670 | if (!buffer) | ||
671 | return -ENOMEM; | ||
672 | 645 | ||
673 | init_cdrom_command(&cgc, buffer, 16, CGC_DATA_READ); | 646 | cgc.buffer = buffer; |
647 | cgc.buflen = sizeof(buffer); | ||
674 | 648 | ||
675 | if ((ret = cdrom_mode_sense(cdi, &cgc, cdi->mrw_mode_page, 0))) | 649 | if ((ret = cdrom_mode_sense(cdi, &cgc, cdi->mrw_mode_page, 0))) |
676 | goto err; | 650 | return ret; |
677 | 651 | ||
678 | mph = (struct mode_page_header *) buffer; | 652 | mph = (struct mode_page_header *) buffer; |
679 | offset = be16_to_cpu(mph->desc_length); | 653 | offset = be16_to_cpu(mph->desc_length); |
@@ -683,70 +657,55 @@ static int cdrom_mrw_set_lba_space(struct cdrom_device_info *cdi, int space) | |||
683 | cgc.buflen = size; | 657 | cgc.buflen = size; |
684 | 658 | ||
685 | if ((ret = cdrom_mode_select(cdi, &cgc))) | 659 | if ((ret = cdrom_mode_select(cdi, &cgc))) |
686 | goto err; | 660 | return ret; |
687 | 661 | ||
688 | printk(KERN_INFO "cdrom: %s: mrw address space %s selected\n", cdi->name, mrw_address_space[space]); | 662 | printk(KERN_INFO "cdrom: %s: mrw address space %s selected\n", cdi->name, mrw_address_space[space]); |
689 | ret = 0; | 663 | return 0; |
690 | err: | ||
691 | kfree(buffer); | ||
692 | return ret; | ||
693 | } | 664 | } |
694 | 665 | ||
695 | static int cdrom_get_random_writable(struct cdrom_device_info *cdi, | 666 | static int cdrom_get_random_writable(struct cdrom_device_info *cdi, |
696 | struct rwrt_feature_desc *rfd) | 667 | struct rwrt_feature_desc *rfd) |
697 | { | 668 | { |
698 | struct packet_command cgc; | 669 | struct packet_command cgc; |
699 | char *buffer; | 670 | char buffer[24]; |
700 | int ret; | 671 | int ret; |
701 | 672 | ||
702 | buffer = kmalloc(24, GFP_KERNEL); | 673 | init_cdrom_command(&cgc, buffer, sizeof(buffer), CGC_DATA_READ); |
703 | if (!buffer) | ||
704 | return -ENOMEM; | ||
705 | |||
706 | init_cdrom_command(&cgc, buffer, 24, CGC_DATA_READ); | ||
707 | 674 | ||
708 | cgc.cmd[0] = GPCMD_GET_CONFIGURATION; /* often 0x46 */ | 675 | cgc.cmd[0] = GPCMD_GET_CONFIGURATION; /* often 0x46 */ |
709 | cgc.cmd[3] = CDF_RWRT; /* often 0x0020 */ | 676 | cgc.cmd[3] = CDF_RWRT; /* often 0x0020 */ |
710 | cgc.cmd[8] = 24; /* often 0x18 */ | 677 | cgc.cmd[8] = sizeof(buffer); /* often 0x18 */ |
711 | cgc.quiet = 1; | 678 | cgc.quiet = 1; |
712 | 679 | ||
713 | if ((ret = cdi->ops->generic_packet(cdi, &cgc))) | 680 | if ((ret = cdi->ops->generic_packet(cdi, &cgc))) |
714 | goto err; | 681 | return ret; |
715 | 682 | ||
716 | memcpy(rfd, &buffer[sizeof(struct feature_header)], sizeof (*rfd)); | 683 | memcpy(rfd, &buffer[sizeof(struct feature_header)], sizeof (*rfd)); |
717 | ret = 0; | 684 | return 0; |
718 | err: | ||
719 | kfree(buffer); | ||
720 | return ret; | ||
721 | } | 685 | } |
722 | 686 | ||
723 | static int cdrom_has_defect_mgt(struct cdrom_device_info *cdi) | 687 | static int cdrom_has_defect_mgt(struct cdrom_device_info *cdi) |
724 | { | 688 | { |
725 | struct packet_command cgc; | 689 | struct packet_command cgc; |
726 | char *buffer; | 690 | char buffer[16]; |
727 | __be16 *feature_code; | 691 | __be16 *feature_code; |
728 | int ret; | 692 | int ret; |
729 | 693 | ||
730 | buffer = kmalloc(16, GFP_KERNEL); | 694 | init_cdrom_command(&cgc, buffer, sizeof(buffer), CGC_DATA_READ); |
731 | if (!buffer) | ||
732 | return -ENOMEM; | ||
733 | |||
734 | init_cdrom_command(&cgc, buffer, 16, CGC_DATA_READ); | ||
735 | 695 | ||
736 | cgc.cmd[0] = GPCMD_GET_CONFIGURATION; | 696 | cgc.cmd[0] = GPCMD_GET_CONFIGURATION; |
737 | cgc.cmd[3] = CDF_HWDM; | 697 | cgc.cmd[3] = CDF_HWDM; |
738 | cgc.cmd[8] = 16; | 698 | cgc.cmd[8] = sizeof(buffer); |
739 | cgc.quiet = 1; | 699 | cgc.quiet = 1; |
740 | 700 | ||
741 | if ((ret = cdi->ops->generic_packet(cdi, &cgc))) | 701 | if ((ret = cdi->ops->generic_packet(cdi, &cgc))) |
742 | goto err; | 702 | return ret; |
743 | 703 | ||
744 | feature_code = (__be16 *) &buffer[sizeof(struct feature_header)]; | 704 | feature_code = (__be16 *) &buffer[sizeof(struct feature_header)]; |
745 | if (be16_to_cpu(*feature_code) == CDF_HWDM) | 705 | if (be16_to_cpu(*feature_code) == CDF_HWDM) |
746 | ret = 0; | 706 | return 0; |
747 | err: | 707 | |
748 | kfree(buffer); | 708 | return 1; |
749 | return ret; | ||
750 | } | 709 | } |
751 | 710 | ||
752 | 711 | ||
@@ -837,14 +796,10 @@ static int cdrom_mrw_open_write(struct cdrom_device_info *cdi) | |||
837 | static int mo_open_write(struct cdrom_device_info *cdi) | 796 | static int mo_open_write(struct cdrom_device_info *cdi) |
838 | { | 797 | { |
839 | struct packet_command cgc; | 798 | struct packet_command cgc; |
840 | char *buffer; | 799 | char buffer[255]; |
841 | int ret; | 800 | int ret; |
842 | 801 | ||
843 | buffer = kmalloc(255, GFP_KERNEL); | 802 | init_cdrom_command(&cgc, &buffer, 4, CGC_DATA_READ); |
844 | if (!buffer) | ||
845 | return -ENOMEM; | ||
846 | |||
847 | init_cdrom_command(&cgc, buffer, 4, CGC_DATA_READ); | ||
848 | cgc.quiet = 1; | 803 | cgc.quiet = 1; |
849 | 804 | ||
850 | /* | 805 | /* |
@@ -861,15 +816,10 @@ static int mo_open_write(struct cdrom_device_info *cdi) | |||
861 | } | 816 | } |
862 | 817 | ||
863 | /* drive gave us no info, let the user go ahead */ | 818 | /* drive gave us no info, let the user go ahead */ |
864 | if (ret) { | 819 | if (ret) |
865 | ret = 0; | 820 | return 0; |
866 | goto err; | ||
867 | } | ||
868 | 821 | ||
869 | ret = buffer[3] & 0x80; | 822 | return buffer[3] & 0x80; |
870 | err: | ||
871 | kfree(buffer); | ||
872 | return ret; | ||
873 | } | 823 | } |
874 | 824 | ||
875 | static int cdrom_ram_open_write(struct cdrom_device_info *cdi) | 825 | static int cdrom_ram_open_write(struct cdrom_device_info *cdi) |
@@ -892,19 +842,15 @@ static int cdrom_ram_open_write(struct cdrom_device_info *cdi) | |||
892 | static void cdrom_mmc3_profile(struct cdrom_device_info *cdi) | 842 | static void cdrom_mmc3_profile(struct cdrom_device_info *cdi) |
893 | { | 843 | { |
894 | struct packet_command cgc; | 844 | struct packet_command cgc; |
895 | char *buffer; | 845 | char buffer[32]; |
896 | int ret, mmc3_profile; | 846 | int ret, mmc3_profile; |
897 | 847 | ||
898 | buffer = kmalloc(32, GFP_KERNEL); | 848 | init_cdrom_command(&cgc, buffer, sizeof(buffer), CGC_DATA_READ); |
899 | if (!buffer) | ||
900 | return; | ||
901 | |||
902 | init_cdrom_command(&cgc, buffer, 32, CGC_DATA_READ); | ||
903 | 849 | ||
904 | cgc.cmd[0] = GPCMD_GET_CONFIGURATION; | 850 | cgc.cmd[0] = GPCMD_GET_CONFIGURATION; |
905 | cgc.cmd[1] = 0; | 851 | cgc.cmd[1] = 0; |
906 | cgc.cmd[2] = cgc.cmd[3] = 0; /* Starting Feature Number */ | 852 | cgc.cmd[2] = cgc.cmd[3] = 0; /* Starting Feature Number */ |
907 | cgc.cmd[8] = 32; /* Allocation Length */ | 853 | cgc.cmd[8] = sizeof(buffer); /* Allocation Length */ |
908 | cgc.quiet = 1; | 854 | cgc.quiet = 1; |
909 | 855 | ||
910 | if ((ret = cdi->ops->generic_packet(cdi, &cgc))) | 856 | if ((ret = cdi->ops->generic_packet(cdi, &cgc))) |
@@ -913,7 +859,6 @@ static void cdrom_mmc3_profile(struct cdrom_device_info *cdi) | |||
913 | mmc3_profile = (buffer[6] << 8) | buffer[7]; | 859 | mmc3_profile = (buffer[6] << 8) | buffer[7]; |
914 | 860 | ||
915 | cdi->mmc3_profile = mmc3_profile; | 861 | cdi->mmc3_profile = mmc3_profile; |
916 | kfree(buffer); | ||
917 | } | 862 | } |
918 | 863 | ||
919 | static int cdrom_is_dvd_rw(struct cdrom_device_info *cdi) | 864 | static int cdrom_is_dvd_rw(struct cdrom_device_info *cdi) |
@@ -1628,15 +1573,12 @@ static void setup_send_key(struct packet_command *cgc, unsigned agid, unsigned t | |||
1628 | static int dvd_do_auth(struct cdrom_device_info *cdi, dvd_authinfo *ai) | 1573 | static int dvd_do_auth(struct cdrom_device_info *cdi, dvd_authinfo *ai) |
1629 | { | 1574 | { |
1630 | int ret; | 1575 | int ret; |
1631 | u_char *buf; | 1576 | u_char buf[20]; |
1632 | struct packet_command cgc; | 1577 | struct packet_command cgc; |
1633 | struct cdrom_device_ops *cdo = cdi->ops; | 1578 | struct cdrom_device_ops *cdo = cdi->ops; |
1634 | rpc_state_t *rpc_state; | 1579 | rpc_state_t rpc_state; |
1635 | |||
1636 | buf = kzalloc(20, GFP_KERNEL); | ||
1637 | if (!buf) | ||
1638 | return -ENOMEM; | ||
1639 | 1580 | ||
1581 | memset(buf, 0, sizeof(buf)); | ||
1640 | init_cdrom_command(&cgc, buf, 0, CGC_DATA_READ); | 1582 | init_cdrom_command(&cgc, buf, 0, CGC_DATA_READ); |
1641 | 1583 | ||
1642 | switch (ai->type) { | 1584 | switch (ai->type) { |
@@ -1647,7 +1589,7 @@ static int dvd_do_auth(struct cdrom_device_info *cdi, dvd_authinfo *ai) | |||
1647 | setup_report_key(&cgc, ai->lsa.agid, 0); | 1589 | setup_report_key(&cgc, ai->lsa.agid, 0); |
1648 | 1590 | ||
1649 | if ((ret = cdo->generic_packet(cdi, &cgc))) | 1591 | if ((ret = cdo->generic_packet(cdi, &cgc))) |
1650 | goto err; | 1592 | return ret; |
1651 | 1593 | ||
1652 | ai->lsa.agid = buf[7] >> 6; | 1594 | ai->lsa.agid = buf[7] >> 6; |
1653 | /* Returning data, let host change state */ | 1595 | /* Returning data, let host change state */ |
@@ -1658,7 +1600,7 @@ static int dvd_do_auth(struct cdrom_device_info *cdi, dvd_authinfo *ai) | |||
1658 | setup_report_key(&cgc, ai->lsk.agid, 2); | 1600 | setup_report_key(&cgc, ai->lsk.agid, 2); |
1659 | 1601 | ||
1660 | if ((ret = cdo->generic_packet(cdi, &cgc))) | 1602 | if ((ret = cdo->generic_packet(cdi, &cgc))) |
1661 | goto err; | 1603 | return ret; |
1662 | 1604 | ||
1663 | copy_key(ai->lsk.key, &buf[4]); | 1605 | copy_key(ai->lsk.key, &buf[4]); |
1664 | /* Returning data, let host change state */ | 1606 | /* Returning data, let host change state */ |
@@ -1669,7 +1611,7 @@ static int dvd_do_auth(struct cdrom_device_info *cdi, dvd_authinfo *ai) | |||
1669 | setup_report_key(&cgc, ai->lsc.agid, 1); | 1611 | setup_report_key(&cgc, ai->lsc.agid, 1); |
1670 | 1612 | ||
1671 | if ((ret = cdo->generic_packet(cdi, &cgc))) | 1613 | if ((ret = cdo->generic_packet(cdi, &cgc))) |
1672 | goto err; | 1614 | return ret; |
1673 | 1615 | ||
1674 | copy_chal(ai->lsc.chal, &buf[4]); | 1616 | copy_chal(ai->lsc.chal, &buf[4]); |
1675 | /* Returning data, let host change state */ | 1617 | /* Returning data, let host change state */ |
@@ -1686,7 +1628,7 @@ static int dvd_do_auth(struct cdrom_device_info *cdi, dvd_authinfo *ai) | |||
1686 | cgc.cmd[2] = ai->lstk.lba >> 24; | 1628 | cgc.cmd[2] = ai->lstk.lba >> 24; |
1687 | 1629 | ||
1688 | if ((ret = cdo->generic_packet(cdi, &cgc))) | 1630 | if ((ret = cdo->generic_packet(cdi, &cgc))) |
1689 | goto err; | 1631 | return ret; |
1690 | 1632 | ||
1691 | ai->lstk.cpm = (buf[4] >> 7) & 1; | 1633 | ai->lstk.cpm = (buf[4] >> 7) & 1; |
1692 | ai->lstk.cp_sec = (buf[4] >> 6) & 1; | 1634 | ai->lstk.cp_sec = (buf[4] >> 6) & 1; |
@@ -1700,7 +1642,7 @@ static int dvd_do_auth(struct cdrom_device_info *cdi, dvd_authinfo *ai) | |||
1700 | setup_report_key(&cgc, ai->lsasf.agid, 5); | 1642 | setup_report_key(&cgc, ai->lsasf.agid, 5); |
1701 | 1643 | ||
1702 | if ((ret = cdo->generic_packet(cdi, &cgc))) | 1644 | if ((ret = cdo->generic_packet(cdi, &cgc))) |
1703 | goto err; | 1645 | return ret; |
1704 | 1646 | ||
1705 | ai->lsasf.asf = buf[7] & 1; | 1647 | ai->lsasf.asf = buf[7] & 1; |
1706 | break; | 1648 | break; |
@@ -1713,7 +1655,7 @@ static int dvd_do_auth(struct cdrom_device_info *cdi, dvd_authinfo *ai) | |||
1713 | copy_chal(&buf[4], ai->hsc.chal); | 1655 | copy_chal(&buf[4], ai->hsc.chal); |
1714 | 1656 | ||
1715 | if ((ret = cdo->generic_packet(cdi, &cgc))) | 1657 | if ((ret = cdo->generic_packet(cdi, &cgc))) |
1716 | goto err; | 1658 | return ret; |
1717 | 1659 | ||
1718 | ai->type = DVD_LU_SEND_KEY1; | 1660 | ai->type = DVD_LU_SEND_KEY1; |
1719 | break; | 1661 | break; |
@@ -1726,7 +1668,7 @@ static int dvd_do_auth(struct cdrom_device_info *cdi, dvd_authinfo *ai) | |||
1726 | 1668 | ||
1727 | if ((ret = cdo->generic_packet(cdi, &cgc))) { | 1669 | if ((ret = cdo->generic_packet(cdi, &cgc))) { |
1728 | ai->type = DVD_AUTH_FAILURE; | 1670 | ai->type = DVD_AUTH_FAILURE; |
1729 | goto err; | 1671 | return ret; |
1730 | } | 1672 | } |
1731 | ai->type = DVD_AUTH_ESTABLISHED; | 1673 | ai->type = DVD_AUTH_ESTABLISHED; |
1732 | break; | 1674 | break; |
@@ -1737,23 +1679,24 @@ static int dvd_do_auth(struct cdrom_device_info *cdi, dvd_authinfo *ai) | |||
1737 | cdinfo(CD_DVD, "entering DVD_INVALIDATE_AGID\n"); | 1679 | cdinfo(CD_DVD, "entering DVD_INVALIDATE_AGID\n"); |
1738 | setup_report_key(&cgc, ai->lsa.agid, 0x3f); | 1680 | setup_report_key(&cgc, ai->lsa.agid, 0x3f); |
1739 | if ((ret = cdo->generic_packet(cdi, &cgc))) | 1681 | if ((ret = cdo->generic_packet(cdi, &cgc))) |
1740 | goto err; | 1682 | return ret; |
1741 | break; | 1683 | break; |
1742 | 1684 | ||
1743 | /* Get region settings */ | 1685 | /* Get region settings */ |
1744 | case DVD_LU_SEND_RPC_STATE: | 1686 | case DVD_LU_SEND_RPC_STATE: |
1745 | cdinfo(CD_DVD, "entering DVD_LU_SEND_RPC_STATE\n"); | 1687 | cdinfo(CD_DVD, "entering DVD_LU_SEND_RPC_STATE\n"); |
1746 | setup_report_key(&cgc, 0, 8); | 1688 | setup_report_key(&cgc, 0, 8); |
1689 | memset(&rpc_state, 0, sizeof(rpc_state_t)); | ||
1690 | cgc.buffer = (char *) &rpc_state; | ||
1747 | 1691 | ||
1748 | if ((ret = cdo->generic_packet(cdi, &cgc))) | 1692 | if ((ret = cdo->generic_packet(cdi, &cgc))) |
1749 | goto err; | 1693 | return ret; |
1750 | 1694 | ||
1751 | rpc_state = (rpc_state_t *)buf; | 1695 | ai->lrpcs.type = rpc_state.type_code; |
1752 | ai->lrpcs.type = rpc_state->type_code; | 1696 | ai->lrpcs.vra = rpc_state.vra; |
1753 | ai->lrpcs.vra = rpc_state->vra; | 1697 | ai->lrpcs.ucca = rpc_state.ucca; |
1754 | ai->lrpcs.ucca = rpc_state->ucca; | 1698 | ai->lrpcs.region_mask = rpc_state.region_mask; |
1755 | ai->lrpcs.region_mask = rpc_state->region_mask; | 1699 | ai->lrpcs.rpc_scheme = rpc_state.rpc_scheme; |
1756 | ai->lrpcs.rpc_scheme = rpc_state->rpc_scheme; | ||
1757 | break; | 1700 | break; |
1758 | 1701 | ||
1759 | /* Set region settings */ | 1702 | /* Set region settings */ |
@@ -1764,23 +1707,20 @@ static int dvd_do_auth(struct cdrom_device_info *cdi, dvd_authinfo *ai) | |||
1764 | buf[4] = ai->hrpcs.pdrc; | 1707 | buf[4] = ai->hrpcs.pdrc; |
1765 | 1708 | ||
1766 | if ((ret = cdo->generic_packet(cdi, &cgc))) | 1709 | if ((ret = cdo->generic_packet(cdi, &cgc))) |
1767 | goto err; | 1710 | return ret; |
1768 | break; | 1711 | break; |
1769 | 1712 | ||
1770 | default: | 1713 | default: |
1771 | cdinfo(CD_WARNING, "Invalid DVD key ioctl (%d)\n", ai->type); | 1714 | cdinfo(CD_WARNING, "Invalid DVD key ioctl (%d)\n", ai->type); |
1772 | ret = -ENOTTY; | 1715 | return -ENOTTY; |
1773 | goto err; | ||
1774 | } | 1716 | } |
1775 | ret = 0; | 1717 | |
1776 | err: | 1718 | return 0; |
1777 | kfree(buf); | ||
1778 | return ret; | ||
1779 | } | 1719 | } |
1780 | 1720 | ||
1781 | static int dvd_read_physical(struct cdrom_device_info *cdi, dvd_struct *s) | 1721 | static int dvd_read_physical(struct cdrom_device_info *cdi, dvd_struct *s) |
1782 | { | 1722 | { |
1783 | unsigned char *buf, *base; | 1723 | unsigned char buf[21], *base; |
1784 | struct dvd_layer *layer; | 1724 | struct dvd_layer *layer; |
1785 | struct packet_command cgc; | 1725 | struct packet_command cgc; |
1786 | struct cdrom_device_ops *cdo = cdi->ops; | 1726 | struct cdrom_device_ops *cdo = cdi->ops; |
@@ -1789,11 +1729,7 @@ static int dvd_read_physical(struct cdrom_device_info *cdi, dvd_struct *s) | |||
1789 | if (layer_num >= DVD_LAYERS) | 1729 | if (layer_num >= DVD_LAYERS) |
1790 | return -EINVAL; | 1730 | return -EINVAL; |
1791 | 1731 | ||
1792 | buf = kmalloc(21, GFP_KERNEL); | 1732 | init_cdrom_command(&cgc, buf, sizeof(buf), CGC_DATA_READ); |
1793 | if (!buf) | ||
1794 | return -ENOMEM; | ||
1795 | |||
1796 | init_cdrom_command(&cgc, buf, 21, CGC_DATA_READ); | ||
1797 | cgc.cmd[0] = GPCMD_READ_DVD_STRUCTURE; | 1733 | cgc.cmd[0] = GPCMD_READ_DVD_STRUCTURE; |
1798 | cgc.cmd[6] = layer_num; | 1734 | cgc.cmd[6] = layer_num; |
1799 | cgc.cmd[7] = s->type; | 1735 | cgc.cmd[7] = s->type; |
@@ -1805,7 +1741,7 @@ static int dvd_read_physical(struct cdrom_device_info *cdi, dvd_struct *s) | |||
1805 | cgc.quiet = 1; | 1741 | cgc.quiet = 1; |
1806 | 1742 | ||
1807 | if ((ret = cdo->generic_packet(cdi, &cgc))) | 1743 | if ((ret = cdo->generic_packet(cdi, &cgc))) |
1808 | goto err; | 1744 | return ret; |
1809 | 1745 | ||
1810 | base = &buf[4]; | 1746 | base = &buf[4]; |
1811 | layer = &s->physical.layer[layer_num]; | 1747 | layer = &s->physical.layer[layer_num]; |
@@ -1829,24 +1765,17 @@ static int dvd_read_physical(struct cdrom_device_info *cdi, dvd_struct *s) | |||
1829 | layer->end_sector_l0 = base[13] << 16 | base[14] << 8 | base[15]; | 1765 | layer->end_sector_l0 = base[13] << 16 | base[14] << 8 | base[15]; |
1830 | layer->bca = base[16] >> 7; | 1766 | layer->bca = base[16] >> 7; |
1831 | 1767 | ||
1832 | ret = 0; | 1768 | return 0; |
1833 | err: | ||
1834 | kfree(buf); | ||
1835 | return ret; | ||
1836 | } | 1769 | } |
1837 | 1770 | ||
1838 | static int dvd_read_copyright(struct cdrom_device_info *cdi, dvd_struct *s) | 1771 | static int dvd_read_copyright(struct cdrom_device_info *cdi, dvd_struct *s) |
1839 | { | 1772 | { |
1840 | int ret; | 1773 | int ret; |
1841 | u_char *buf; | 1774 | u_char buf[8]; |
1842 | struct packet_command cgc; | 1775 | struct packet_command cgc; |
1843 | struct cdrom_device_ops *cdo = cdi->ops; | 1776 | struct cdrom_device_ops *cdo = cdi->ops; |
1844 | 1777 | ||
1845 | buf = kmalloc(8, GFP_KERNEL); | 1778 | init_cdrom_command(&cgc, buf, sizeof(buf), CGC_DATA_READ); |
1846 | if (!buf) | ||
1847 | return -ENOMEM; | ||
1848 | |||
1849 | init_cdrom_command(&cgc, buf, 8, CGC_DATA_READ); | ||
1850 | cgc.cmd[0] = GPCMD_READ_DVD_STRUCTURE; | 1779 | cgc.cmd[0] = GPCMD_READ_DVD_STRUCTURE; |
1851 | cgc.cmd[6] = s->copyright.layer_num; | 1780 | cgc.cmd[6] = s->copyright.layer_num; |
1852 | cgc.cmd[7] = s->type; | 1781 | cgc.cmd[7] = s->type; |
@@ -1854,15 +1783,12 @@ static int dvd_read_copyright(struct cdrom_device_info *cdi, dvd_struct *s) | |||
1854 | cgc.cmd[9] = cgc.buflen & 0xff; | 1783 | cgc.cmd[9] = cgc.buflen & 0xff; |
1855 | 1784 | ||
1856 | if ((ret = cdo->generic_packet(cdi, &cgc))) | 1785 | if ((ret = cdo->generic_packet(cdi, &cgc))) |
1857 | goto err; | 1786 | return ret; |
1858 | 1787 | ||
1859 | s->copyright.cpst = buf[4]; | 1788 | s->copyright.cpst = buf[4]; |
1860 | s->copyright.rmi = buf[5]; | 1789 | s->copyright.rmi = buf[5]; |
1861 | 1790 | ||
1862 | ret = 0; | 1791 | return 0; |
1863 | err: | ||
1864 | kfree(buf); | ||
1865 | return ret; | ||
1866 | } | 1792 | } |
1867 | 1793 | ||
1868 | static int dvd_read_disckey(struct cdrom_device_info *cdi, dvd_struct *s) | 1794 | static int dvd_read_disckey(struct cdrom_device_info *cdi, dvd_struct *s) |
@@ -1894,33 +1820,26 @@ static int dvd_read_disckey(struct cdrom_device_info *cdi, dvd_struct *s) | |||
1894 | static int dvd_read_bca(struct cdrom_device_info *cdi, dvd_struct *s) | 1820 | static int dvd_read_bca(struct cdrom_device_info *cdi, dvd_struct *s) |
1895 | { | 1821 | { |
1896 | int ret; | 1822 | int ret; |
1897 | u_char *buf; | 1823 | u_char buf[4 + 188]; |
1898 | struct packet_command cgc; | 1824 | struct packet_command cgc; |
1899 | struct cdrom_device_ops *cdo = cdi->ops; | 1825 | struct cdrom_device_ops *cdo = cdi->ops; |
1900 | 1826 | ||
1901 | buf = kmalloc(4 + 188, GFP_KERNEL); | 1827 | init_cdrom_command(&cgc, buf, sizeof(buf), CGC_DATA_READ); |
1902 | if (!buf) | ||
1903 | return -ENOMEM; | ||
1904 | |||
1905 | init_cdrom_command(&cgc, buf, 4 + 188, CGC_DATA_READ); | ||
1906 | cgc.cmd[0] = GPCMD_READ_DVD_STRUCTURE; | 1828 | cgc.cmd[0] = GPCMD_READ_DVD_STRUCTURE; |
1907 | cgc.cmd[7] = s->type; | 1829 | cgc.cmd[7] = s->type; |
1908 | cgc.cmd[9] = cgc.buflen & 0xff; | 1830 | cgc.cmd[9] = cgc.buflen & 0xff; |
1909 | 1831 | ||
1910 | if ((ret = cdo->generic_packet(cdi, &cgc))) | 1832 | if ((ret = cdo->generic_packet(cdi, &cgc))) |
1911 | goto err; | 1833 | return ret; |
1912 | 1834 | ||
1913 | s->bca.len = buf[0] << 8 | buf[1]; | 1835 | s->bca.len = buf[0] << 8 | buf[1]; |
1914 | if (s->bca.len < 12 || s->bca.len > 188) { | 1836 | if (s->bca.len < 12 || s->bca.len > 188) { |
1915 | cdinfo(CD_WARNING, "Received invalid BCA length (%d)\n", s->bca.len); | 1837 | cdinfo(CD_WARNING, "Received invalid BCA length (%d)\n", s->bca.len); |
1916 | ret = -EIO; | 1838 | return -EIO; |
1917 | goto err; | ||
1918 | } | 1839 | } |
1919 | memcpy(s->bca.value, &buf[4], s->bca.len); | 1840 | memcpy(s->bca.value, &buf[4], s->bca.len); |
1920 | ret = 0; | 1841 | |
1921 | err: | 1842 | return 0; |
1922 | kfree(buf); | ||
1923 | return ret; | ||
1924 | } | 1843 | } |
1925 | 1844 | ||
1926 | static int dvd_read_manufact(struct cdrom_device_info *cdi, dvd_struct *s) | 1845 | static int dvd_read_manufact(struct cdrom_device_info *cdi, dvd_struct *s) |
@@ -2020,13 +1939,9 @@ static int cdrom_read_subchannel(struct cdrom_device_info *cdi, | |||
2020 | { | 1939 | { |
2021 | struct cdrom_device_ops *cdo = cdi->ops; | 1940 | struct cdrom_device_ops *cdo = cdi->ops; |
2022 | struct packet_command cgc; | 1941 | struct packet_command cgc; |
2023 | char *buffer; | 1942 | char buffer[32]; |
2024 | int ret; | 1943 | int ret; |
2025 | 1944 | ||
2026 | buffer = kmalloc(32, GFP_KERNEL); | ||
2027 | if (!buffer) | ||
2028 | return -ENOMEM; | ||
2029 | |||
2030 | init_cdrom_command(&cgc, buffer, 16, CGC_DATA_READ); | 1945 | init_cdrom_command(&cgc, buffer, 16, CGC_DATA_READ); |
2031 | cgc.cmd[0] = GPCMD_READ_SUBCHANNEL; | 1946 | cgc.cmd[0] = GPCMD_READ_SUBCHANNEL; |
2032 | cgc.cmd[1] = 2; /* MSF addressing */ | 1947 | cgc.cmd[1] = 2; /* MSF addressing */ |
@@ -2035,7 +1950,7 @@ static int cdrom_read_subchannel(struct cdrom_device_info *cdi, | |||
2035 | cgc.cmd[8] = 16; | 1950 | cgc.cmd[8] = 16; |
2036 | 1951 | ||
2037 | if ((ret = cdo->generic_packet(cdi, &cgc))) | 1952 | if ((ret = cdo->generic_packet(cdi, &cgc))) |
2038 | goto err; | 1953 | return ret; |
2039 | 1954 | ||
2040 | subchnl->cdsc_audiostatus = cgc.buffer[1]; | 1955 | subchnl->cdsc_audiostatus = cgc.buffer[1]; |
2041 | subchnl->cdsc_format = CDROM_MSF; | 1956 | subchnl->cdsc_format = CDROM_MSF; |
@@ -2050,10 +1965,7 @@ static int cdrom_read_subchannel(struct cdrom_device_info *cdi, | |||
2050 | subchnl->cdsc_absaddr.msf.second = cgc.buffer[10]; | 1965 | subchnl->cdsc_absaddr.msf.second = cgc.buffer[10]; |
2051 | subchnl->cdsc_absaddr.msf.frame = cgc.buffer[11]; | 1966 | subchnl->cdsc_absaddr.msf.frame = cgc.buffer[11]; |
2052 | 1967 | ||
2053 | ret = 0; | 1968 | return 0; |
2054 | err: | ||
2055 | kfree(buffer); | ||
2056 | return ret; | ||
2057 | } | 1969 | } |
2058 | 1970 | ||
2059 | /* | 1971 | /* |
diff --git a/drivers/md/linear.c b/drivers/md/linear.c index 10748240cb2f..6a866d7c8ae5 100644 --- a/drivers/md/linear.c +++ b/drivers/md/linear.c | |||
@@ -50,17 +50,19 @@ static inline dev_info_t *which_dev(mddev_t *mddev, sector_t sector) | |||
50 | /** | 50 | /** |
51 | * linear_mergeable_bvec -- tell bio layer if two requests can be merged | 51 | * linear_mergeable_bvec -- tell bio layer if two requests can be merged |
52 | * @q: request queue | 52 | * @q: request queue |
53 | * @bio: the buffer head that's been built up so far | 53 | * @bvm: properties of new bio |
54 | * @biovec: the request that could be merged to it. | 54 | * @biovec: the request that could be merged to it. |
55 | * | 55 | * |
56 | * Return amount of bytes we can take at this offset | 56 | * Return amount of bytes we can take at this offset |
57 | */ | 57 | */ |
58 | static int linear_mergeable_bvec(struct request_queue *q, struct bio *bio, struct bio_vec *biovec) | 58 | static int linear_mergeable_bvec(struct request_queue *q, |
59 | struct bvec_merge_data *bvm, | ||
60 | struct bio_vec *biovec) | ||
59 | { | 61 | { |
60 | mddev_t *mddev = q->queuedata; | 62 | mddev_t *mddev = q->queuedata; |
61 | dev_info_t *dev0; | 63 | dev_info_t *dev0; |
62 | unsigned long maxsectors, bio_sectors = bio->bi_size >> 9; | 64 | unsigned long maxsectors, bio_sectors = bvm->bi_size >> 9; |
63 | sector_t sector = bio->bi_sector + get_start_sect(bio->bi_bdev); | 65 | sector_t sector = bvm->bi_sector + get_start_sect(bvm->bi_bdev); |
64 | 66 | ||
65 | dev0 = which_dev(mddev, sector); | 67 | dev0 = which_dev(mddev, sector); |
66 | maxsectors = (dev0->size << 1) - (sector - (dev0->offset<<1)); | 68 | maxsectors = (dev0->size << 1) - (sector - (dev0->offset<<1)); |
diff --git a/drivers/md/raid0.c b/drivers/md/raid0.c index 914c04ddec7c..bcbb82594a19 100644 --- a/drivers/md/raid0.c +++ b/drivers/md/raid0.c | |||
@@ -241,18 +241,20 @@ static int create_strip_zones (mddev_t *mddev) | |||
241 | /** | 241 | /** |
242 | * raid0_mergeable_bvec -- tell bio layer if a two requests can be merged | 242 | * raid0_mergeable_bvec -- tell bio layer if a two requests can be merged |
243 | * @q: request queue | 243 | * @q: request queue |
244 | * @bio: the buffer head that's been built up so far | 244 | * @bvm: properties of new bio |
245 | * @biovec: the request that could be merged to it. | 245 | * @biovec: the request that could be merged to it. |
246 | * | 246 | * |
247 | * Return amount of bytes we can accept at this offset | 247 | * Return amount of bytes we can accept at this offset |
248 | */ | 248 | */ |
249 | static int raid0_mergeable_bvec(struct request_queue *q, struct bio *bio, struct bio_vec *biovec) | 249 | static int raid0_mergeable_bvec(struct request_queue *q, |
250 | struct bvec_merge_data *bvm, | ||
251 | struct bio_vec *biovec) | ||
250 | { | 252 | { |
251 | mddev_t *mddev = q->queuedata; | 253 | mddev_t *mddev = q->queuedata; |
252 | sector_t sector = bio->bi_sector + get_start_sect(bio->bi_bdev); | 254 | sector_t sector = bvm->bi_sector + get_start_sect(bvm->bi_bdev); |
253 | int max; | 255 | int max; |
254 | unsigned int chunk_sectors = mddev->chunk_size >> 9; | 256 | unsigned int chunk_sectors = mddev->chunk_size >> 9; |
255 | unsigned int bio_sectors = bio->bi_size >> 9; | 257 | unsigned int bio_sectors = bvm->bi_size >> 9; |
256 | 258 | ||
257 | max = (chunk_sectors - ((sector & (chunk_sectors - 1)) + bio_sectors)) << 9; | 259 | max = (chunk_sectors - ((sector & (chunk_sectors - 1)) + bio_sectors)) << 9; |
258 | if (max < 0) max = 0; /* bio_add cannot handle a negative return */ | 260 | if (max < 0) max = 0; /* bio_add cannot handle a negative return */ |
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c index a71277b640ab..22bb2b1b886d 100644 --- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c | |||
@@ -439,26 +439,27 @@ static sector_t raid10_find_virt(conf_t *conf, sector_t sector, int dev) | |||
439 | /** | 439 | /** |
440 | * raid10_mergeable_bvec -- tell bio layer if a two requests can be merged | 440 | * raid10_mergeable_bvec -- tell bio layer if a two requests can be merged |
441 | * @q: request queue | 441 | * @q: request queue |
442 | * @bio: the buffer head that's been built up so far | 442 | * @bvm: properties of new bio |
443 | * @biovec: the request that could be merged to it. | 443 | * @biovec: the request that could be merged to it. |
444 | * | 444 | * |
445 | * Return amount of bytes we can accept at this offset | 445 | * Return amount of bytes we can accept at this offset |
446 | * If near_copies == raid_disk, there are no striping issues, | 446 | * If near_copies == raid_disk, there are no striping issues, |
447 | * but in that case, the function isn't called at all. | 447 | * but in that case, the function isn't called at all. |
448 | */ | 448 | */ |
449 | static int raid10_mergeable_bvec(struct request_queue *q, struct bio *bio, | 449 | static int raid10_mergeable_bvec(struct request_queue *q, |
450 | struct bio_vec *bio_vec) | 450 | struct bvec_merge_data *bvm, |
451 | struct bio_vec *biovec) | ||
451 | { | 452 | { |
452 | mddev_t *mddev = q->queuedata; | 453 | mddev_t *mddev = q->queuedata; |
453 | sector_t sector = bio->bi_sector + get_start_sect(bio->bi_bdev); | 454 | sector_t sector = bvm->bi_sector + get_start_sect(bvm->bi_bdev); |
454 | int max; | 455 | int max; |
455 | unsigned int chunk_sectors = mddev->chunk_size >> 9; | 456 | unsigned int chunk_sectors = mddev->chunk_size >> 9; |
456 | unsigned int bio_sectors = bio->bi_size >> 9; | 457 | unsigned int bio_sectors = bvm->bi_size >> 9; |
457 | 458 | ||
458 | max = (chunk_sectors - ((sector & (chunk_sectors - 1)) + bio_sectors)) << 9; | 459 | max = (chunk_sectors - ((sector & (chunk_sectors - 1)) + bio_sectors)) << 9; |
459 | if (max < 0) max = 0; /* bio_add cannot handle a negative return */ | 460 | if (max < 0) max = 0; /* bio_add cannot handle a negative return */ |
460 | if (max <= bio_vec->bv_len && bio_sectors == 0) | 461 | if (max <= biovec->bv_len && bio_sectors == 0) |
461 | return bio_vec->bv_len; | 462 | return biovec->bv_len; |
462 | else | 463 | else |
463 | return max; | 464 | return max; |
464 | } | 465 | } |
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index 3b27df52456b..9ce7154845c6 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c | |||
@@ -3314,15 +3314,17 @@ static int raid5_congested(void *data, int bits) | |||
3314 | /* We want read requests to align with chunks where possible, | 3314 | /* We want read requests to align with chunks where possible, |
3315 | * but write requests don't need to. | 3315 | * but write requests don't need to. |
3316 | */ | 3316 | */ |
3317 | static int raid5_mergeable_bvec(struct request_queue *q, struct bio *bio, struct bio_vec *biovec) | 3317 | static int raid5_mergeable_bvec(struct request_queue *q, |
3318 | struct bvec_merge_data *bvm, | ||
3319 | struct bio_vec *biovec) | ||
3318 | { | 3320 | { |
3319 | mddev_t *mddev = q->queuedata; | 3321 | mddev_t *mddev = q->queuedata; |
3320 | sector_t sector = bio->bi_sector + get_start_sect(bio->bi_bdev); | 3322 | sector_t sector = bvm->bi_sector + get_start_sect(bvm->bi_bdev); |
3321 | int max; | 3323 | int max; |
3322 | unsigned int chunk_sectors = mddev->chunk_size >> 9; | 3324 | unsigned int chunk_sectors = mddev->chunk_size >> 9; |
3323 | unsigned int bio_sectors = bio->bi_size >> 9; | 3325 | unsigned int bio_sectors = bvm->bi_size >> 9; |
3324 | 3326 | ||
3325 | if (bio_data_dir(bio) == WRITE) | 3327 | if ((bvm->bi_rw & 1) == WRITE) |
3326 | return biovec->bv_len; /* always allow writes to be mergeable */ | 3328 | return biovec->bv_len; /* always allow writes to be mergeable */ |
3327 | 3329 | ||
3328 | max = (chunk_sectors - ((sector & (chunk_sectors - 1)) + bio_sectors)) << 9; | 3330 | max = (chunk_sectors - ((sector & (chunk_sectors - 1)) + bio_sectors)) << 9; |
diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c index d26f69b0184f..ef671d1a3bf0 100644 --- a/drivers/net/xen-netfront.c +++ b/drivers/net/xen-netfront.c | |||
@@ -1324,7 +1324,7 @@ static int setup_netfront(struct xenbus_device *dev, struct netfront_info *info) | |||
1324 | goto fail; | 1324 | goto fail; |
1325 | } | 1325 | } |
1326 | 1326 | ||
1327 | txs = (struct xen_netif_tx_sring *)get_zeroed_page(GFP_KERNEL); | 1327 | txs = (struct xen_netif_tx_sring *)get_zeroed_page(GFP_NOIO | __GFP_HIGH); |
1328 | if (!txs) { | 1328 | if (!txs) { |
1329 | err = -ENOMEM; | 1329 | err = -ENOMEM; |
1330 | xenbus_dev_fatal(dev, err, "allocating tx ring page"); | 1330 | xenbus_dev_fatal(dev, err, "allocating tx ring page"); |
@@ -1340,7 +1340,7 @@ static int setup_netfront(struct xenbus_device *dev, struct netfront_info *info) | |||
1340 | } | 1340 | } |
1341 | 1341 | ||
1342 | info->tx_ring_ref = err; | 1342 | info->tx_ring_ref = err; |
1343 | rxs = (struct xen_netif_rx_sring *)get_zeroed_page(GFP_KERNEL); | 1343 | rxs = (struct xen_netif_rx_sring *)get_zeroed_page(GFP_NOIO | __GFP_HIGH); |
1344 | if (!rxs) { | 1344 | if (!rxs) { |
1345 | err = -ENOMEM; | 1345 | err = -ENOMEM; |
1346 | xenbus_dev_fatal(dev, err, "allocating rx ring page"); | 1346 | xenbus_dev_fatal(dev, err, "allocating rx ring page"); |
diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c index ea0edd1b2e76..fe694f0ee19a 100644 --- a/drivers/scsi/sg.c +++ b/drivers/scsi/sg.c | |||
@@ -182,8 +182,9 @@ static int sg_build_sgat(Sg_scatter_hold * schp, const Sg_fd * sfp, | |||
182 | int tablesize); | 182 | int tablesize); |
183 | static ssize_t sg_new_read(Sg_fd * sfp, char __user *buf, size_t count, | 183 | static ssize_t sg_new_read(Sg_fd * sfp, char __user *buf, size_t count, |
184 | Sg_request * srp); | 184 | Sg_request * srp); |
185 | static ssize_t sg_new_write(Sg_fd * sfp, const char __user *buf, size_t count, | 185 | static ssize_t sg_new_write(Sg_fd *sfp, struct file *file, |
186 | int blocking, int read_only, Sg_request ** o_srp); | 186 | const char __user *buf, size_t count, int blocking, |
187 | int read_only, Sg_request **o_srp); | ||
187 | static int sg_common_write(Sg_fd * sfp, Sg_request * srp, | 188 | static int sg_common_write(Sg_fd * sfp, Sg_request * srp, |
188 | unsigned char *cmnd, int timeout, int blocking); | 189 | unsigned char *cmnd, int timeout, int blocking); |
189 | static int sg_u_iovec(sg_io_hdr_t * hp, int sg_num, int ind, | 190 | static int sg_u_iovec(sg_io_hdr_t * hp, int sg_num, int ind, |
@@ -204,7 +205,6 @@ static Sg_request *sg_get_rq_mark(Sg_fd * sfp, int pack_id); | |||
204 | static Sg_request *sg_add_request(Sg_fd * sfp); | 205 | static Sg_request *sg_add_request(Sg_fd * sfp); |
205 | static int sg_remove_request(Sg_fd * sfp, Sg_request * srp); | 206 | static int sg_remove_request(Sg_fd * sfp, Sg_request * srp); |
206 | static int sg_res_in_use(Sg_fd * sfp); | 207 | static int sg_res_in_use(Sg_fd * sfp); |
207 | static int sg_allow_access(unsigned char opcode, char dev_type); | ||
208 | static int sg_build_direct(Sg_request * srp, Sg_fd * sfp, int dxfer_len); | 208 | static int sg_build_direct(Sg_request * srp, Sg_fd * sfp, int dxfer_len); |
209 | static Sg_device *sg_get_dev(int dev); | 209 | static Sg_device *sg_get_dev(int dev); |
210 | #ifdef CONFIG_SCSI_PROC_FS | 210 | #ifdef CONFIG_SCSI_PROC_FS |
@@ -544,7 +544,7 @@ sg_write(struct file *filp, const char __user *buf, size_t count, loff_t * ppos) | |||
544 | return -EFAULT; | 544 | return -EFAULT; |
545 | blocking = !(filp->f_flags & O_NONBLOCK); | 545 | blocking = !(filp->f_flags & O_NONBLOCK); |
546 | if (old_hdr.reply_len < 0) | 546 | if (old_hdr.reply_len < 0) |
547 | return sg_new_write(sfp, buf, count, blocking, 0, NULL); | 547 | return sg_new_write(sfp, filp, buf, count, blocking, 0, NULL); |
548 | if (count < (SZ_SG_HEADER + 6)) | 548 | if (count < (SZ_SG_HEADER + 6)) |
549 | return -EIO; /* The minimum scsi command length is 6 bytes. */ | 549 | return -EIO; /* The minimum scsi command length is 6 bytes. */ |
550 | 550 | ||
@@ -621,8 +621,9 @@ sg_write(struct file *filp, const char __user *buf, size_t count, loff_t * ppos) | |||
621 | } | 621 | } |
622 | 622 | ||
623 | static ssize_t | 623 | static ssize_t |
624 | sg_new_write(Sg_fd * sfp, const char __user *buf, size_t count, | 624 | sg_new_write(Sg_fd *sfp, struct file *file, const char __user *buf, |
625 | int blocking, int read_only, Sg_request ** o_srp) | 625 | size_t count, int blocking, int read_only, |
626 | Sg_request **o_srp) | ||
626 | { | 627 | { |
627 | int k; | 628 | int k; |
628 | Sg_request *srp; | 629 | Sg_request *srp; |
@@ -678,8 +679,7 @@ sg_new_write(Sg_fd * sfp, const char __user *buf, size_t count, | |||
678 | sg_remove_request(sfp, srp); | 679 | sg_remove_request(sfp, srp); |
679 | return -EFAULT; | 680 | return -EFAULT; |
680 | } | 681 | } |
681 | if (read_only && | 682 | if (read_only && !blk_verify_command(file, cmnd)) { |
682 | (!sg_allow_access(cmnd[0], sfp->parentdp->device->type))) { | ||
683 | sg_remove_request(sfp, srp); | 683 | sg_remove_request(sfp, srp); |
684 | return -EPERM; | 684 | return -EPERM; |
685 | } | 685 | } |
@@ -799,7 +799,7 @@ sg_ioctl(struct inode *inode, struct file *filp, | |||
799 | if (!access_ok(VERIFY_WRITE, p, SZ_SG_IO_HDR)) | 799 | if (!access_ok(VERIFY_WRITE, p, SZ_SG_IO_HDR)) |
800 | return -EFAULT; | 800 | return -EFAULT; |
801 | result = | 801 | result = |
802 | sg_new_write(sfp, p, SZ_SG_IO_HDR, | 802 | sg_new_write(sfp, filp, p, SZ_SG_IO_HDR, |
803 | blocking, read_only, &srp); | 803 | blocking, read_only, &srp); |
804 | if (result < 0) | 804 | if (result < 0) |
805 | return result; | 805 | return result; |
@@ -1048,7 +1048,7 @@ sg_ioctl(struct inode *inode, struct file *filp, | |||
1048 | 1048 | ||
1049 | if (copy_from_user(&opcode, siocp->data, 1)) | 1049 | if (copy_from_user(&opcode, siocp->data, 1)) |
1050 | return -EFAULT; | 1050 | return -EFAULT; |
1051 | if (!sg_allow_access(opcode, sdp->device->type)) | 1051 | if (!blk_verify_command(filp, &opcode)) |
1052 | return -EPERM; | 1052 | return -EPERM; |
1053 | } | 1053 | } |
1054 | return sg_scsi_ioctl(filp, sdp->device->request_queue, NULL, p); | 1054 | return sg_scsi_ioctl(filp, sdp->device->request_queue, NULL, p); |
@@ -2502,30 +2502,6 @@ sg_page_free(struct page *page, int size) | |||
2502 | __free_pages(page, order); | 2502 | __free_pages(page, order); |
2503 | } | 2503 | } |
2504 | 2504 | ||
2505 | #ifndef MAINTENANCE_IN_CMD | ||
2506 | #define MAINTENANCE_IN_CMD 0xa3 | ||
2507 | #endif | ||
2508 | |||
2509 | static unsigned char allow_ops[] = { TEST_UNIT_READY, REQUEST_SENSE, | ||
2510 | INQUIRY, READ_CAPACITY, READ_BUFFER, READ_6, READ_10, READ_12, | ||
2511 | READ_16, MODE_SENSE, MODE_SENSE_10, LOG_SENSE, REPORT_LUNS, | ||
2512 | SERVICE_ACTION_IN, RECEIVE_DIAGNOSTIC, READ_LONG, MAINTENANCE_IN_CMD | ||
2513 | }; | ||
2514 | |||
2515 | static int | ||
2516 | sg_allow_access(unsigned char opcode, char dev_type) | ||
2517 | { | ||
2518 | int k; | ||
2519 | |||
2520 | if (TYPE_SCANNER == dev_type) /* TYPE_ROM maybe burner */ | ||
2521 | return 1; | ||
2522 | for (k = 0; k < sizeof (allow_ops); ++k) { | ||
2523 | if (opcode == allow_ops[k]) | ||
2524 | return 1; | ||
2525 | } | ||
2526 | return 0; | ||
2527 | } | ||
2528 | |||
2529 | #ifdef CONFIG_SCSI_PROC_FS | 2505 | #ifdef CONFIG_SCSI_PROC_FS |
2530 | static int | 2506 | static int |
2531 | sg_idr_max_id(int id, void *p, void *data) | 2507 | sg_idr_max_id(int id, void *p, void *data) |
diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c index c82df8bd4d89..27f5bfd1def3 100644 --- a/drivers/scsi/sr.c +++ b/drivers/scsi/sr.c | |||
@@ -673,24 +673,20 @@ fail: | |||
673 | static void get_sectorsize(struct scsi_cd *cd) | 673 | static void get_sectorsize(struct scsi_cd *cd) |
674 | { | 674 | { |
675 | unsigned char cmd[10]; | 675 | unsigned char cmd[10]; |
676 | unsigned char *buffer; | 676 | unsigned char buffer[8]; |
677 | int the_result, retries = 3; | 677 | int the_result, retries = 3; |
678 | int sector_size; | 678 | int sector_size; |
679 | struct request_queue *queue; | 679 | struct request_queue *queue; |
680 | 680 | ||
681 | buffer = kmalloc(512, GFP_KERNEL | GFP_DMA); | ||
682 | if (!buffer) | ||
683 | goto Enomem; | ||
684 | |||
685 | do { | 681 | do { |
686 | cmd[0] = READ_CAPACITY; | 682 | cmd[0] = READ_CAPACITY; |
687 | memset((void *) &cmd[1], 0, 9); | 683 | memset((void *) &cmd[1], 0, 9); |
688 | memset(buffer, 0, 8); | 684 | memset(buffer, 0, sizeof(buffer)); |
689 | 685 | ||
690 | /* Do the command and wait.. */ | 686 | /* Do the command and wait.. */ |
691 | the_result = scsi_execute_req(cd->device, cmd, DMA_FROM_DEVICE, | 687 | the_result = scsi_execute_req(cd->device, cmd, DMA_FROM_DEVICE, |
692 | buffer, 8, NULL, SR_TIMEOUT, | 688 | buffer, sizeof(buffer), NULL, |
693 | MAX_RETRIES); | 689 | SR_TIMEOUT, MAX_RETRIES); |
694 | 690 | ||
695 | retries--; | 691 | retries--; |
696 | 692 | ||
@@ -745,14 +741,8 @@ static void get_sectorsize(struct scsi_cd *cd) | |||
745 | 741 | ||
746 | queue = cd->device->request_queue; | 742 | queue = cd->device->request_queue; |
747 | blk_queue_hardsect_size(queue, sector_size); | 743 | blk_queue_hardsect_size(queue, sector_size); |
748 | out: | ||
749 | kfree(buffer); | ||
750 | return; | ||
751 | 744 | ||
752 | Enomem: | 745 | return; |
753 | cd->capacity = 0x1fffff; | ||
754 | cd->device->sector_size = 2048; /* A guess, just in case */ | ||
755 | goto out; | ||
756 | } | 746 | } |
757 | 747 | ||
758 | static void get_capabilities(struct scsi_cd *cd) | 748 | static void get_capabilities(struct scsi_cd *cd) |
diff --git a/drivers/xen/xenbus/xenbus_client.c b/drivers/xen/xenbus/xenbus_client.c index 0f86b0ff7879..9678b3e98c63 100644 --- a/drivers/xen/xenbus/xenbus_client.c +++ b/drivers/xen/xenbus/xenbus_client.c | |||
@@ -117,7 +117,7 @@ int xenbus_watch_pathfmt(struct xenbus_device *dev, | |||
117 | char *path; | 117 | char *path; |
118 | 118 | ||
119 | va_start(ap, pathfmt); | 119 | va_start(ap, pathfmt); |
120 | path = kvasprintf(GFP_KERNEL, pathfmt, ap); | 120 | path = kvasprintf(GFP_NOIO | __GFP_HIGH, pathfmt, ap); |
121 | va_end(ap); | 121 | va_end(ap); |
122 | 122 | ||
123 | if (!path) { | 123 | if (!path) { |
diff --git a/drivers/xen/xenbus/xenbus_xs.c b/drivers/xen/xenbus/xenbus_xs.c index 227d53b12a5c..7f2f91c0e11d 100644 --- a/drivers/xen/xenbus/xenbus_xs.c +++ b/drivers/xen/xenbus/xenbus_xs.c | |||
@@ -283,9 +283,9 @@ static char *join(const char *dir, const char *name) | |||
283 | char *buffer; | 283 | char *buffer; |
284 | 284 | ||
285 | if (strlen(name) == 0) | 285 | if (strlen(name) == 0) |
286 | buffer = kasprintf(GFP_KERNEL, "%s", dir); | 286 | buffer = kasprintf(GFP_NOIO | __GFP_HIGH, "%s", dir); |
287 | else | 287 | else |
288 | buffer = kasprintf(GFP_KERNEL, "%s/%s", dir, name); | 288 | buffer = kasprintf(GFP_NOIO | __GFP_HIGH, "%s/%s", dir, name); |
289 | return (!buffer) ? ERR_PTR(-ENOMEM) : buffer; | 289 | return (!buffer) ? ERR_PTR(-ENOMEM) : buffer; |
290 | } | 290 | } |
291 | 291 | ||
@@ -297,7 +297,7 @@ static char **split(char *strings, unsigned int len, unsigned int *num) | |||
297 | *num = count_strings(strings, len); | 297 | *num = count_strings(strings, len); |
298 | 298 | ||
299 | /* Transfer to one big alloc for easy freeing. */ | 299 | /* Transfer to one big alloc for easy freeing. */ |
300 | ret = kmalloc(*num * sizeof(char *) + len, GFP_KERNEL); | 300 | ret = kmalloc(*num * sizeof(char *) + len, GFP_NOIO | __GFP_HIGH); |
301 | if (!ret) { | 301 | if (!ret) { |
302 | kfree(strings); | 302 | kfree(strings); |
303 | return ERR_PTR(-ENOMEM); | 303 | return ERR_PTR(-ENOMEM); |
@@ -751,7 +751,7 @@ static int process_msg(void) | |||
751 | } | 751 | } |
752 | 752 | ||
753 | 753 | ||
754 | msg = kmalloc(sizeof(*msg), GFP_KERNEL); | 754 | msg = kmalloc(sizeof(*msg), GFP_NOIO | __GFP_HIGH); |
755 | if (msg == NULL) { | 755 | if (msg == NULL) { |
756 | err = -ENOMEM; | 756 | err = -ENOMEM; |
757 | goto out; | 757 | goto out; |
@@ -763,7 +763,7 @@ static int process_msg(void) | |||
763 | goto out; | 763 | goto out; |
764 | } | 764 | } |
765 | 765 | ||
766 | body = kmalloc(msg->hdr.len + 1, GFP_KERNEL); | 766 | body = kmalloc(msg->hdr.len + 1, GFP_NOIO | __GFP_HIGH); |
767 | if (body == NULL) { | 767 | if (body == NULL) { |
768 | kfree(msg); | 768 | kfree(msg); |
769 | err = -ENOMEM; | 769 | err = -ENOMEM; |
diff --git a/fs/Makefile b/fs/Makefile index 1e7a11bd4da1..277b079dec9e 100644 --- a/fs/Makefile +++ b/fs/Makefile | |||
@@ -19,6 +19,7 @@ else | |||
19 | obj-y += no-block.o | 19 | obj-y += no-block.o |
20 | endif | 20 | endif |
21 | 21 | ||
22 | obj-$(CONFIG_BLK_DEV_INTEGRITY) += bio-integrity.o | ||
22 | obj-$(CONFIG_INOTIFY) += inotify.o | 23 | obj-$(CONFIG_INOTIFY) += inotify.o |
23 | obj-$(CONFIG_INOTIFY_USER) += inotify_user.o | 24 | obj-$(CONFIG_INOTIFY_USER) += inotify_user.o |
24 | obj-$(CONFIG_EPOLL) += eventpoll.o | 25 | obj-$(CONFIG_EPOLL) += eventpoll.o |
diff --git a/fs/bio-integrity.c b/fs/bio-integrity.c new file mode 100644 index 000000000000..63e2ee63058d --- /dev/null +++ b/fs/bio-integrity.c | |||
@@ -0,0 +1,719 @@ | |||
1 | /* | ||
2 | * bio-integrity.c - bio data integrity extensions | ||
3 | * | ||
4 | * Copyright (C) 2007, 2008 Oracle Corporation | ||
5 | * Written by: Martin K. Petersen <martin.petersen@oracle.com> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or | ||
8 | * modify it under the terms of the GNU General Public License version | ||
9 | * 2 as published by the Free Software Foundation. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, but | ||
12 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
14 | * General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; see the file COPYING. If not, write to | ||
18 | * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, | ||
19 | * USA. | ||
20 | * | ||
21 | */ | ||
22 | |||
23 | #include <linux/blkdev.h> | ||
24 | #include <linux/mempool.h> | ||
25 | #include <linux/bio.h> | ||
26 | #include <linux/workqueue.h> | ||
27 | |||
28 | static struct kmem_cache *bio_integrity_slab __read_mostly; | ||
29 | static struct workqueue_struct *kintegrityd_wq; | ||
30 | |||
31 | /** | ||
32 | * bio_integrity_alloc_bioset - Allocate integrity payload and attach it to bio | ||
33 | * @bio: bio to attach integrity metadata to | ||
34 | * @gfp_mask: Memory allocation mask | ||
35 | * @nr_vecs: Number of integrity metadata scatter-gather elements | ||
36 | * @bs: bio_set to allocate from | ||
37 | * | ||
38 | * Description: This function prepares a bio for attaching integrity | ||
39 | * metadata. nr_vecs specifies the maximum number of pages containing | ||
40 | * integrity metadata that can be attached. | ||
41 | */ | ||
42 | struct bio_integrity_payload *bio_integrity_alloc_bioset(struct bio *bio, | ||
43 | gfp_t gfp_mask, | ||
44 | unsigned int nr_vecs, | ||
45 | struct bio_set *bs) | ||
46 | { | ||
47 | struct bio_integrity_payload *bip; | ||
48 | struct bio_vec *iv; | ||
49 | unsigned long idx; | ||
50 | |||
51 | BUG_ON(bio == NULL); | ||
52 | |||
53 | bip = mempool_alloc(bs->bio_integrity_pool, gfp_mask); | ||
54 | if (unlikely(bip == NULL)) { | ||
55 | printk(KERN_ERR "%s: could not alloc bip\n", __func__); | ||
56 | return NULL; | ||
57 | } | ||
58 | |||
59 | memset(bip, 0, sizeof(*bip)); | ||
60 | |||
61 | iv = bvec_alloc_bs(gfp_mask, nr_vecs, &idx, bs); | ||
62 | if (unlikely(iv == NULL)) { | ||
63 | printk(KERN_ERR "%s: could not alloc bip_vec\n", __func__); | ||
64 | mempool_free(bip, bs->bio_integrity_pool); | ||
65 | return NULL; | ||
66 | } | ||
67 | |||
68 | bip->bip_pool = idx; | ||
69 | bip->bip_vec = iv; | ||
70 | bip->bip_bio = bio; | ||
71 | bio->bi_integrity = bip; | ||
72 | |||
73 | return bip; | ||
74 | } | ||
75 | EXPORT_SYMBOL(bio_integrity_alloc_bioset); | ||
76 | |||
77 | /** | ||
78 | * bio_integrity_alloc - Allocate integrity payload and attach it to bio | ||
79 | * @bio: bio to attach integrity metadata to | ||
80 | * @gfp_mask: Memory allocation mask | ||
81 | * @nr_vecs: Number of integrity metadata scatter-gather elements | ||
82 | * | ||
83 | * Description: This function prepares a bio for attaching integrity | ||
84 | * metadata. nr_vecs specifies the maximum number of pages containing | ||
85 | * integrity metadata that can be attached. | ||
86 | */ | ||
87 | struct bio_integrity_payload *bio_integrity_alloc(struct bio *bio, | ||
88 | gfp_t gfp_mask, | ||
89 | unsigned int nr_vecs) | ||
90 | { | ||
91 | return bio_integrity_alloc_bioset(bio, gfp_mask, nr_vecs, fs_bio_set); | ||
92 | } | ||
93 | EXPORT_SYMBOL(bio_integrity_alloc); | ||
94 | |||
95 | /** | ||
96 | * bio_integrity_free - Free bio integrity payload | ||
97 | * @bio: bio containing bip to be freed | ||
98 | * @bs: bio_set this bio was allocated from | ||
99 | * | ||
100 | * Description: Used to free the integrity portion of a bio. Usually | ||
101 | * called from bio_free(). | ||
102 | */ | ||
103 | void bio_integrity_free(struct bio *bio, struct bio_set *bs) | ||
104 | { | ||
105 | struct bio_integrity_payload *bip = bio->bi_integrity; | ||
106 | |||
107 | BUG_ON(bip == NULL); | ||
108 | |||
109 | /* A cloned bio doesn't own the integrity metadata */ | ||
110 | if (!bio_flagged(bio, BIO_CLONED) && bip->bip_buf != NULL) | ||
111 | kfree(bip->bip_buf); | ||
112 | |||
113 | mempool_free(bip->bip_vec, bs->bvec_pools[bip->bip_pool]); | ||
114 | mempool_free(bip, bs->bio_integrity_pool); | ||
115 | |||
116 | bio->bi_integrity = NULL; | ||
117 | } | ||
118 | EXPORT_SYMBOL(bio_integrity_free); | ||
119 | |||
120 | /** | ||
121 | * bio_integrity_add_page - Attach integrity metadata | ||
122 | * @bio: bio to update | ||
123 | * @page: page containing integrity metadata | ||
124 | * @len: number of bytes of integrity metadata in page | ||
125 | * @offset: start offset within page | ||
126 | * | ||
127 | * Description: Attach a page containing integrity metadata to bio. | ||
128 | */ | ||
129 | int bio_integrity_add_page(struct bio *bio, struct page *page, | ||
130 | unsigned int len, unsigned int offset) | ||
131 | { | ||
132 | struct bio_integrity_payload *bip = bio->bi_integrity; | ||
133 | struct bio_vec *iv; | ||
134 | |||
135 | if (bip->bip_vcnt >= bvec_nr_vecs(bip->bip_pool)) { | ||
136 | printk(KERN_ERR "%s: bip_vec full\n", __func__); | ||
137 | return 0; | ||
138 | } | ||
139 | |||
140 | iv = bip_vec_idx(bip, bip->bip_vcnt); | ||
141 | BUG_ON(iv == NULL); | ||
142 | BUG_ON(iv->bv_page != NULL); | ||
143 | |||
144 | iv->bv_page = page; | ||
145 | iv->bv_len = len; | ||
146 | iv->bv_offset = offset; | ||
147 | bip->bip_vcnt++; | ||
148 | |||
149 | return len; | ||
150 | } | ||
151 | EXPORT_SYMBOL(bio_integrity_add_page); | ||
152 | |||
153 | /** | ||
154 | * bio_integrity_enabled - Check whether integrity can be passed | ||
155 | * @bio: bio to check | ||
156 | * | ||
157 | * Description: Determines whether bio_integrity_prep() can be called | ||
158 | * on this bio or not. bio data direction and target device must be | ||
159 | * set prior to calling. The functions honors the write_generate and | ||
160 | * read_verify flags in sysfs. | ||
161 | */ | ||
162 | int bio_integrity_enabled(struct bio *bio) | ||
163 | { | ||
164 | /* Already protected? */ | ||
165 | if (bio_integrity(bio)) | ||
166 | return 0; | ||
167 | |||
168 | return bdev_integrity_enabled(bio->bi_bdev, bio_data_dir(bio)); | ||
169 | } | ||
170 | EXPORT_SYMBOL(bio_integrity_enabled); | ||
171 | |||
172 | /** | ||
173 | * bio_integrity_hw_sectors - Convert 512b sectors to hardware ditto | ||
174 | * @bi: blk_integrity profile for device | ||
175 | * @sectors: Number of 512 sectors to convert | ||
176 | * | ||
177 | * Description: The block layer calculates everything in 512 byte | ||
178 | * sectors but integrity metadata is done in terms of the hardware | ||
179 | * sector size of the storage device. Convert the block layer sectors | ||
180 | * to physical sectors. | ||
181 | */ | ||
182 | static inline unsigned int bio_integrity_hw_sectors(struct blk_integrity *bi, | ||
183 | unsigned int sectors) | ||
184 | { | ||
185 | /* At this point there are only 512b or 4096b DIF/EPP devices */ | ||
186 | if (bi->sector_size == 4096) | ||
187 | return sectors >>= 3; | ||
188 | |||
189 | return sectors; | ||
190 | } | ||
191 | |||
192 | /** | ||
193 | * bio_integrity_tag_size - Retrieve integrity tag space | ||
194 | * @bio: bio to inspect | ||
195 | * | ||
196 | * Description: Returns the maximum number of tag bytes that can be | ||
197 | * attached to this bio. Filesystems can use this to determine how | ||
198 | * much metadata to attach to an I/O. | ||
199 | */ | ||
200 | unsigned int bio_integrity_tag_size(struct bio *bio) | ||
201 | { | ||
202 | struct blk_integrity *bi = bdev_get_integrity(bio->bi_bdev); | ||
203 | |||
204 | BUG_ON(bio->bi_size == 0); | ||
205 | |||
206 | return bi->tag_size * (bio->bi_size / bi->sector_size); | ||
207 | } | ||
208 | EXPORT_SYMBOL(bio_integrity_tag_size); | ||
209 | |||
210 | int bio_integrity_tag(struct bio *bio, void *tag_buf, unsigned int len, int set) | ||
211 | { | ||
212 | struct bio_integrity_payload *bip = bio->bi_integrity; | ||
213 | struct blk_integrity *bi = bdev_get_integrity(bio->bi_bdev); | ||
214 | unsigned int nr_sectors; | ||
215 | |||
216 | BUG_ON(bip->bip_buf == NULL); | ||
217 | |||
218 | if (bi->tag_size == 0) | ||
219 | return -1; | ||
220 | |||
221 | nr_sectors = bio_integrity_hw_sectors(bi, | ||
222 | DIV_ROUND_UP(len, bi->tag_size)); | ||
223 | |||
224 | if (nr_sectors * bi->tuple_size > bip->bip_size) { | ||
225 | printk(KERN_ERR "%s: tag too big for bio: %u > %u\n", | ||
226 | __func__, nr_sectors * bi->tuple_size, bip->bip_size); | ||
227 | return -1; | ||
228 | } | ||
229 | |||
230 | if (set) | ||
231 | bi->set_tag_fn(bip->bip_buf, tag_buf, nr_sectors); | ||
232 | else | ||
233 | bi->get_tag_fn(bip->bip_buf, tag_buf, nr_sectors); | ||
234 | |||
235 | return 0; | ||
236 | } | ||
237 | |||
238 | /** | ||
239 | * bio_integrity_set_tag - Attach a tag buffer to a bio | ||
240 | * @bio: bio to attach buffer to | ||
241 | * @tag_buf: Pointer to a buffer containing tag data | ||
242 | * @len: Length of the included buffer | ||
243 | * | ||
244 | * Description: Use this function to tag a bio by leveraging the extra | ||
245 | * space provided by devices formatted with integrity protection. The | ||
246 | * size of the integrity buffer must be <= to the size reported by | ||
247 | * bio_integrity_tag_size(). | ||
248 | */ | ||
249 | int bio_integrity_set_tag(struct bio *bio, void *tag_buf, unsigned int len) | ||
250 | { | ||
251 | BUG_ON(bio_data_dir(bio) != WRITE); | ||
252 | |||
253 | return bio_integrity_tag(bio, tag_buf, len, 1); | ||
254 | } | ||
255 | EXPORT_SYMBOL(bio_integrity_set_tag); | ||
256 | |||
257 | /** | ||
258 | * bio_integrity_get_tag - Retrieve a tag buffer from a bio | ||
259 | * @bio: bio to retrieve buffer from | ||
260 | * @tag_buf: Pointer to a buffer for the tag data | ||
261 | * @len: Length of the target buffer | ||
262 | * | ||
263 | * Description: Use this function to retrieve the tag buffer from a | ||
264 | * completed I/O. The size of the integrity buffer must be <= to the | ||
265 | * size reported by bio_integrity_tag_size(). | ||
266 | */ | ||
267 | int bio_integrity_get_tag(struct bio *bio, void *tag_buf, unsigned int len) | ||
268 | { | ||
269 | BUG_ON(bio_data_dir(bio) != READ); | ||
270 | |||
271 | return bio_integrity_tag(bio, tag_buf, len, 0); | ||
272 | } | ||
273 | EXPORT_SYMBOL(bio_integrity_get_tag); | ||
274 | |||
275 | /** | ||
276 | * bio_integrity_generate - Generate integrity metadata for a bio | ||
277 | * @bio: bio to generate integrity metadata for | ||
278 | * | ||
279 | * Description: Generates integrity metadata for a bio by calling the | ||
280 | * block device's generation callback function. The bio must have a | ||
281 | * bip attached with enough room to accommodate the generated | ||
282 | * integrity metadata. | ||
283 | */ | ||
284 | static void bio_integrity_generate(struct bio *bio) | ||
285 | { | ||
286 | struct blk_integrity *bi = bdev_get_integrity(bio->bi_bdev); | ||
287 | struct blk_integrity_exchg bix; | ||
288 | struct bio_vec *bv; | ||
289 | sector_t sector = bio->bi_sector; | ||
290 | unsigned int i, sectors, total; | ||
291 | void *prot_buf = bio->bi_integrity->bip_buf; | ||
292 | |||
293 | total = 0; | ||
294 | bix.disk_name = bio->bi_bdev->bd_disk->disk_name; | ||
295 | bix.sector_size = bi->sector_size; | ||
296 | |||
297 | bio_for_each_segment(bv, bio, i) { | ||
298 | void *kaddr = kmap_atomic(bv->bv_page, KM_USER0); | ||
299 | bix.data_buf = kaddr + bv->bv_offset; | ||
300 | bix.data_size = bv->bv_len; | ||
301 | bix.prot_buf = prot_buf; | ||
302 | bix.sector = sector; | ||
303 | |||
304 | bi->generate_fn(&bix); | ||
305 | |||
306 | sectors = bv->bv_len / bi->sector_size; | ||
307 | sector += sectors; | ||
308 | prot_buf += sectors * bi->tuple_size; | ||
309 | total += sectors * bi->tuple_size; | ||
310 | BUG_ON(total > bio->bi_integrity->bip_size); | ||
311 | |||
312 | kunmap_atomic(kaddr, KM_USER0); | ||
313 | } | ||
314 | } | ||
315 | |||
316 | /** | ||
317 | * bio_integrity_prep - Prepare bio for integrity I/O | ||
318 | * @bio: bio to prepare | ||
319 | * | ||
320 | * Description: Allocates a buffer for integrity metadata, maps the | ||
321 | * pages and attaches them to a bio. The bio must have data | ||
322 | * direction, target device and start sector set priot to calling. In | ||
323 | * the WRITE case, integrity metadata will be generated using the | ||
324 | * block device's integrity function. In the READ case, the buffer | ||
325 | * will be prepared for DMA and a suitable end_io handler set up. | ||
326 | */ | ||
327 | int bio_integrity_prep(struct bio *bio) | ||
328 | { | ||
329 | struct bio_integrity_payload *bip; | ||
330 | struct blk_integrity *bi; | ||
331 | struct request_queue *q; | ||
332 | void *buf; | ||
333 | unsigned long start, end; | ||
334 | unsigned int len, nr_pages; | ||
335 | unsigned int bytes, offset, i; | ||
336 | unsigned int sectors; | ||
337 | |||
338 | bi = bdev_get_integrity(bio->bi_bdev); | ||
339 | q = bdev_get_queue(bio->bi_bdev); | ||
340 | BUG_ON(bi == NULL); | ||
341 | BUG_ON(bio_integrity(bio)); | ||
342 | |||
343 | sectors = bio_integrity_hw_sectors(bi, bio_sectors(bio)); | ||
344 | |||
345 | /* Allocate kernel buffer for protection data */ | ||
346 | len = sectors * blk_integrity_tuple_size(bi); | ||
347 | buf = kmalloc(len, GFP_NOIO | __GFP_NOFAIL | q->bounce_gfp); | ||
348 | if (unlikely(buf == NULL)) { | ||
349 | printk(KERN_ERR "could not allocate integrity buffer\n"); | ||
350 | return -EIO; | ||
351 | } | ||
352 | |||
353 | end = (((unsigned long) buf) + len + PAGE_SIZE - 1) >> PAGE_SHIFT; | ||
354 | start = ((unsigned long) buf) >> PAGE_SHIFT; | ||
355 | nr_pages = end - start; | ||
356 | |||
357 | /* Allocate bio integrity payload and integrity vectors */ | ||
358 | bip = bio_integrity_alloc(bio, GFP_NOIO, nr_pages); | ||
359 | if (unlikely(bip == NULL)) { | ||
360 | printk(KERN_ERR "could not allocate data integrity bioset\n"); | ||
361 | kfree(buf); | ||
362 | return -EIO; | ||
363 | } | ||
364 | |||
365 | bip->bip_buf = buf; | ||
366 | bip->bip_size = len; | ||
367 | bip->bip_sector = bio->bi_sector; | ||
368 | |||
369 | /* Map it */ | ||
370 | offset = offset_in_page(buf); | ||
371 | for (i = 0 ; i < nr_pages ; i++) { | ||
372 | int ret; | ||
373 | bytes = PAGE_SIZE - offset; | ||
374 | |||
375 | if (len <= 0) | ||
376 | break; | ||
377 | |||
378 | if (bytes > len) | ||
379 | bytes = len; | ||
380 | |||
381 | ret = bio_integrity_add_page(bio, virt_to_page(buf), | ||
382 | bytes, offset); | ||
383 | |||
384 | if (ret == 0) | ||
385 | return 0; | ||
386 | |||
387 | if (ret < bytes) | ||
388 | break; | ||
389 | |||
390 | buf += bytes; | ||
391 | len -= bytes; | ||
392 | offset = 0; | ||
393 | } | ||
394 | |||
395 | /* Install custom I/O completion handler if read verify is enabled */ | ||
396 | if (bio_data_dir(bio) == READ) { | ||
397 | bip->bip_end_io = bio->bi_end_io; | ||
398 | bio->bi_end_io = bio_integrity_endio; | ||
399 | } | ||
400 | |||
401 | /* Auto-generate integrity metadata if this is a write */ | ||
402 | if (bio_data_dir(bio) == WRITE) | ||
403 | bio_integrity_generate(bio); | ||
404 | |||
405 | return 0; | ||
406 | } | ||
407 | EXPORT_SYMBOL(bio_integrity_prep); | ||
408 | |||
409 | /** | ||
410 | * bio_integrity_verify - Verify integrity metadata for a bio | ||
411 | * @bio: bio to verify | ||
412 | * | ||
413 | * Description: This function is called to verify the integrity of a | ||
414 | * bio. The data in the bio io_vec is compared to the integrity | ||
415 | * metadata returned by the HBA. | ||
416 | */ | ||
417 | static int bio_integrity_verify(struct bio *bio) | ||
418 | { | ||
419 | struct blk_integrity *bi = bdev_get_integrity(bio->bi_bdev); | ||
420 | struct blk_integrity_exchg bix; | ||
421 | struct bio_vec *bv; | ||
422 | sector_t sector = bio->bi_integrity->bip_sector; | ||
423 | unsigned int i, sectors, total, ret; | ||
424 | void *prot_buf = bio->bi_integrity->bip_buf; | ||
425 | |||
426 | ret = total = 0; | ||
427 | bix.disk_name = bio->bi_bdev->bd_disk->disk_name; | ||
428 | bix.sector_size = bi->sector_size; | ||
429 | |||
430 | bio_for_each_segment(bv, bio, i) { | ||
431 | void *kaddr = kmap_atomic(bv->bv_page, KM_USER0); | ||
432 | bix.data_buf = kaddr + bv->bv_offset; | ||
433 | bix.data_size = bv->bv_len; | ||
434 | bix.prot_buf = prot_buf; | ||
435 | bix.sector = sector; | ||
436 | |||
437 | ret = bi->verify_fn(&bix); | ||
438 | |||
439 | if (ret) { | ||
440 | kunmap_atomic(kaddr, KM_USER0); | ||
441 | break; | ||
442 | } | ||
443 | |||
444 | sectors = bv->bv_len / bi->sector_size; | ||
445 | sector += sectors; | ||
446 | prot_buf += sectors * bi->tuple_size; | ||
447 | total += sectors * bi->tuple_size; | ||
448 | BUG_ON(total > bio->bi_integrity->bip_size); | ||
449 | |||
450 | kunmap_atomic(kaddr, KM_USER0); | ||
451 | } | ||
452 | |||
453 | return ret; | ||
454 | } | ||
455 | |||
456 | /** | ||
457 | * bio_integrity_verify_fn - Integrity I/O completion worker | ||
458 | * @work: Work struct stored in bio to be verified | ||
459 | * | ||
460 | * Description: This workqueue function is called to complete a READ | ||
461 | * request. The function verifies the transferred integrity metadata | ||
462 | * and then calls the original bio end_io function. | ||
463 | */ | ||
464 | static void bio_integrity_verify_fn(struct work_struct *work) | ||
465 | { | ||
466 | struct bio_integrity_payload *bip = | ||
467 | container_of(work, struct bio_integrity_payload, bip_work); | ||
468 | struct bio *bio = bip->bip_bio; | ||
469 | int error = bip->bip_error; | ||
470 | |||
471 | if (bio_integrity_verify(bio)) { | ||
472 | clear_bit(BIO_UPTODATE, &bio->bi_flags); | ||
473 | error = -EIO; | ||
474 | } | ||
475 | |||
476 | /* Restore original bio completion handler */ | ||
477 | bio->bi_end_io = bip->bip_end_io; | ||
478 | |||
479 | if (bio->bi_end_io) | ||
480 | bio->bi_end_io(bio, error); | ||
481 | } | ||
482 | |||
483 | /** | ||
484 | * bio_integrity_endio - Integrity I/O completion function | ||
485 | * @bio: Protected bio | ||
486 | * @error: Pointer to errno | ||
487 | * | ||
488 | * Description: Completion for integrity I/O | ||
489 | * | ||
490 | * Normally I/O completion is done in interrupt context. However, | ||
491 | * verifying I/O integrity is a time-consuming task which must be run | ||
492 | * in process context. This function postpones completion | ||
493 | * accordingly. | ||
494 | */ | ||
495 | void bio_integrity_endio(struct bio *bio, int error) | ||
496 | { | ||
497 | struct bio_integrity_payload *bip = bio->bi_integrity; | ||
498 | |||
499 | BUG_ON(bip->bip_bio != bio); | ||
500 | |||
501 | bip->bip_error = error; | ||
502 | INIT_WORK(&bip->bip_work, bio_integrity_verify_fn); | ||
503 | queue_work(kintegrityd_wq, &bip->bip_work); | ||
504 | } | ||
505 | EXPORT_SYMBOL(bio_integrity_endio); | ||
506 | |||
507 | /** | ||
508 | * bio_integrity_mark_head - Advance bip_vec skip bytes | ||
509 | * @bip: Integrity vector to advance | ||
510 | * @skip: Number of bytes to advance it | ||
511 | */ | ||
512 | void bio_integrity_mark_head(struct bio_integrity_payload *bip, | ||
513 | unsigned int skip) | ||
514 | { | ||
515 | struct bio_vec *iv; | ||
516 | unsigned int i; | ||
517 | |||
518 | bip_for_each_vec(iv, bip, i) { | ||
519 | if (skip == 0) { | ||
520 | bip->bip_idx = i; | ||
521 | return; | ||
522 | } else if (skip >= iv->bv_len) { | ||
523 | skip -= iv->bv_len; | ||
524 | } else { /* skip < iv->bv_len) */ | ||
525 | iv->bv_offset += skip; | ||
526 | iv->bv_len -= skip; | ||
527 | bip->bip_idx = i; | ||
528 | return; | ||
529 | } | ||
530 | } | ||
531 | } | ||
532 | |||
533 | /** | ||
534 | * bio_integrity_mark_tail - Truncate bip_vec to be len bytes long | ||
535 | * @bip: Integrity vector to truncate | ||
536 | * @len: New length of integrity vector | ||
537 | */ | ||
538 | void bio_integrity_mark_tail(struct bio_integrity_payload *bip, | ||
539 | unsigned int len) | ||
540 | { | ||
541 | struct bio_vec *iv; | ||
542 | unsigned int i; | ||
543 | |||
544 | bip_for_each_vec(iv, bip, i) { | ||
545 | if (len == 0) { | ||
546 | bip->bip_vcnt = i; | ||
547 | return; | ||
548 | } else if (len >= iv->bv_len) { | ||
549 | len -= iv->bv_len; | ||
550 | } else { /* len < iv->bv_len) */ | ||
551 | iv->bv_len = len; | ||
552 | len = 0; | ||
553 | } | ||
554 | } | ||
555 | } | ||
556 | |||
557 | /** | ||
558 | * bio_integrity_advance - Advance integrity vector | ||
559 | * @bio: bio whose integrity vector to update | ||
560 | * @bytes_done: number of data bytes that have been completed | ||
561 | * | ||
562 | * Description: This function calculates how many integrity bytes the | ||
563 | * number of completed data bytes correspond to and advances the | ||
564 | * integrity vector accordingly. | ||
565 | */ | ||
566 | void bio_integrity_advance(struct bio *bio, unsigned int bytes_done) | ||
567 | { | ||
568 | struct bio_integrity_payload *bip = bio->bi_integrity; | ||
569 | struct blk_integrity *bi = bdev_get_integrity(bio->bi_bdev); | ||
570 | unsigned int nr_sectors; | ||
571 | |||
572 | BUG_ON(bip == NULL); | ||
573 | BUG_ON(bi == NULL); | ||
574 | |||
575 | nr_sectors = bio_integrity_hw_sectors(bi, bytes_done >> 9); | ||
576 | bio_integrity_mark_head(bip, nr_sectors * bi->tuple_size); | ||
577 | } | ||
578 | EXPORT_SYMBOL(bio_integrity_advance); | ||
579 | |||
580 | /** | ||
581 | * bio_integrity_trim - Trim integrity vector | ||
582 | * @bio: bio whose integrity vector to update | ||
583 | * @offset: offset to first data sector | ||
584 | * @sectors: number of data sectors | ||
585 | * | ||
586 | * Description: Used to trim the integrity vector in a cloned bio. | ||
587 | * The ivec will be advanced corresponding to 'offset' data sectors | ||
588 | * and the length will be truncated corresponding to 'len' data | ||
589 | * sectors. | ||
590 | */ | ||
591 | void bio_integrity_trim(struct bio *bio, unsigned int offset, | ||
592 | unsigned int sectors) | ||
593 | { | ||
594 | struct bio_integrity_payload *bip = bio->bi_integrity; | ||
595 | struct blk_integrity *bi = bdev_get_integrity(bio->bi_bdev); | ||
596 | unsigned int nr_sectors; | ||
597 | |||
598 | BUG_ON(bip == NULL); | ||
599 | BUG_ON(bi == NULL); | ||
600 | BUG_ON(!bio_flagged(bio, BIO_CLONED)); | ||
601 | |||
602 | nr_sectors = bio_integrity_hw_sectors(bi, sectors); | ||
603 | bip->bip_sector = bip->bip_sector + offset; | ||
604 | bio_integrity_mark_head(bip, offset * bi->tuple_size); | ||
605 | bio_integrity_mark_tail(bip, sectors * bi->tuple_size); | ||
606 | } | ||
607 | EXPORT_SYMBOL(bio_integrity_trim); | ||
608 | |||
609 | /** | ||
610 | * bio_integrity_split - Split integrity metadata | ||
611 | * @bio: Protected bio | ||
612 | * @bp: Resulting bio_pair | ||
613 | * @sectors: Offset | ||
614 | * | ||
615 | * Description: Splits an integrity page into a bio_pair. | ||
616 | */ | ||
617 | void bio_integrity_split(struct bio *bio, struct bio_pair *bp, int sectors) | ||
618 | { | ||
619 | struct blk_integrity *bi; | ||
620 | struct bio_integrity_payload *bip = bio->bi_integrity; | ||
621 | unsigned int nr_sectors; | ||
622 | |||
623 | if (bio_integrity(bio) == 0) | ||
624 | return; | ||
625 | |||
626 | bi = bdev_get_integrity(bio->bi_bdev); | ||
627 | BUG_ON(bi == NULL); | ||
628 | BUG_ON(bip->bip_vcnt != 1); | ||
629 | |||
630 | nr_sectors = bio_integrity_hw_sectors(bi, sectors); | ||
631 | |||
632 | bp->bio1.bi_integrity = &bp->bip1; | ||
633 | bp->bio2.bi_integrity = &bp->bip2; | ||
634 | |||
635 | bp->iv1 = bip->bip_vec[0]; | ||
636 | bp->iv2 = bip->bip_vec[0]; | ||
637 | |||
638 | bp->bip1.bip_vec = &bp->iv1; | ||
639 | bp->bip2.bip_vec = &bp->iv2; | ||
640 | |||
641 | bp->iv1.bv_len = sectors * bi->tuple_size; | ||
642 | bp->iv2.bv_offset += sectors * bi->tuple_size; | ||
643 | bp->iv2.bv_len -= sectors * bi->tuple_size; | ||
644 | |||
645 | bp->bip1.bip_sector = bio->bi_integrity->bip_sector; | ||
646 | bp->bip2.bip_sector = bio->bi_integrity->bip_sector + nr_sectors; | ||
647 | |||
648 | bp->bip1.bip_vcnt = bp->bip2.bip_vcnt = 1; | ||
649 | bp->bip1.bip_idx = bp->bip2.bip_idx = 0; | ||
650 | } | ||
651 | EXPORT_SYMBOL(bio_integrity_split); | ||
652 | |||
653 | /** | ||
654 | * bio_integrity_clone - Callback for cloning bios with integrity metadata | ||
655 | * @bio: New bio | ||
656 | * @bio_src: Original bio | ||
657 | * @bs: bio_set to allocate bip from | ||
658 | * | ||
659 | * Description: Called to allocate a bip when cloning a bio | ||
660 | */ | ||
661 | int bio_integrity_clone(struct bio *bio, struct bio *bio_src, | ||
662 | struct bio_set *bs) | ||
663 | { | ||
664 | struct bio_integrity_payload *bip_src = bio_src->bi_integrity; | ||
665 | struct bio_integrity_payload *bip; | ||
666 | |||
667 | BUG_ON(bip_src == NULL); | ||
668 | |||
669 | bip = bio_integrity_alloc_bioset(bio, GFP_NOIO, bip_src->bip_vcnt, bs); | ||
670 | |||
671 | if (bip == NULL) | ||
672 | return -EIO; | ||
673 | |||
674 | memcpy(bip->bip_vec, bip_src->bip_vec, | ||
675 | bip_src->bip_vcnt * sizeof(struct bio_vec)); | ||
676 | |||
677 | bip->bip_sector = bip_src->bip_sector; | ||
678 | bip->bip_vcnt = bip_src->bip_vcnt; | ||
679 | bip->bip_idx = bip_src->bip_idx; | ||
680 | |||
681 | return 0; | ||
682 | } | ||
683 | EXPORT_SYMBOL(bio_integrity_clone); | ||
684 | |||
685 | int bioset_integrity_create(struct bio_set *bs, int pool_size) | ||
686 | { | ||
687 | bs->bio_integrity_pool = mempool_create_slab_pool(pool_size, | ||
688 | bio_integrity_slab); | ||
689 | if (!bs->bio_integrity_pool) | ||
690 | return -1; | ||
691 | |||
692 | return 0; | ||
693 | } | ||
694 | EXPORT_SYMBOL(bioset_integrity_create); | ||
695 | |||
696 | void bioset_integrity_free(struct bio_set *bs) | ||
697 | { | ||
698 | if (bs->bio_integrity_pool) | ||
699 | mempool_destroy(bs->bio_integrity_pool); | ||
700 | } | ||
701 | EXPORT_SYMBOL(bioset_integrity_free); | ||
702 | |||
703 | void __init bio_integrity_init_slab(void) | ||
704 | { | ||
705 | bio_integrity_slab = KMEM_CACHE(bio_integrity_payload, | ||
706 | SLAB_HWCACHE_ALIGN|SLAB_PANIC); | ||
707 | } | ||
708 | EXPORT_SYMBOL(bio_integrity_init_slab); | ||
709 | |||
710 | static int __init integrity_init(void) | ||
711 | { | ||
712 | kintegrityd_wq = create_workqueue("kintegrityd"); | ||
713 | |||
714 | if (!kintegrityd_wq) | ||
715 | panic("Failed to create kintegrityd\n"); | ||
716 | |||
717 | return 0; | ||
718 | } | ||
719 | subsys_initcall(integrity_init); | ||
@@ -28,25 +28,10 @@ | |||
28 | #include <linux/blktrace_api.h> | 28 | #include <linux/blktrace_api.h> |
29 | #include <scsi/sg.h> /* for struct sg_iovec */ | 29 | #include <scsi/sg.h> /* for struct sg_iovec */ |
30 | 30 | ||
31 | #define BIO_POOL_SIZE 2 | ||
32 | |||
33 | static struct kmem_cache *bio_slab __read_mostly; | 31 | static struct kmem_cache *bio_slab __read_mostly; |
34 | 32 | ||
35 | #define BIOVEC_NR_POOLS 6 | ||
36 | |||
37 | /* | ||
38 | * a small number of entries is fine, not going to be performance critical. | ||
39 | * basically we just need to survive | ||
40 | */ | ||
41 | #define BIO_SPLIT_ENTRIES 2 | ||
42 | mempool_t *bio_split_pool __read_mostly; | 33 | mempool_t *bio_split_pool __read_mostly; |
43 | 34 | ||
44 | struct biovec_slab { | ||
45 | int nr_vecs; | ||
46 | char *name; | ||
47 | struct kmem_cache *slab; | ||
48 | }; | ||
49 | |||
50 | /* | 35 | /* |
51 | * if you change this list, also change bvec_alloc or things will | 36 | * if you change this list, also change bvec_alloc or things will |
52 | * break badly! cannot be bigger than what you can fit into an | 37 | * break badly! cannot be bigger than what you can fit into an |
@@ -60,23 +45,17 @@ static struct biovec_slab bvec_slabs[BIOVEC_NR_POOLS] __read_mostly = { | |||
60 | #undef BV | 45 | #undef BV |
61 | 46 | ||
62 | /* | 47 | /* |
63 | * bio_set is used to allow other portions of the IO system to | ||
64 | * allocate their own private memory pools for bio and iovec structures. | ||
65 | * These memory pools in turn all allocate from the bio_slab | ||
66 | * and the bvec_slabs[]. | ||
67 | */ | ||
68 | struct bio_set { | ||
69 | mempool_t *bio_pool; | ||
70 | mempool_t *bvec_pools[BIOVEC_NR_POOLS]; | ||
71 | }; | ||
72 | |||
73 | /* | ||
74 | * fs_bio_set is the bio_set containing bio and iovec memory pools used by | 48 | * fs_bio_set is the bio_set containing bio and iovec memory pools used by |
75 | * IO code that does not need private memory pools. | 49 | * IO code that does not need private memory pools. |
76 | */ | 50 | */ |
77 | static struct bio_set *fs_bio_set; | 51 | struct bio_set *fs_bio_set; |
52 | |||
53 | unsigned int bvec_nr_vecs(unsigned short idx) | ||
54 | { | ||
55 | return bvec_slabs[idx].nr_vecs; | ||
56 | } | ||
78 | 57 | ||
79 | static inline struct bio_vec *bvec_alloc_bs(gfp_t gfp_mask, int nr, unsigned long *idx, struct bio_set *bs) | 58 | struct bio_vec *bvec_alloc_bs(gfp_t gfp_mask, int nr, unsigned long *idx, struct bio_set *bs) |
80 | { | 59 | { |
81 | struct bio_vec *bvl; | 60 | struct bio_vec *bvl; |
82 | 61 | ||
@@ -117,6 +96,9 @@ void bio_free(struct bio *bio, struct bio_set *bio_set) | |||
117 | mempool_free(bio->bi_io_vec, bio_set->bvec_pools[pool_idx]); | 96 | mempool_free(bio->bi_io_vec, bio_set->bvec_pools[pool_idx]); |
118 | } | 97 | } |
119 | 98 | ||
99 | if (bio_integrity(bio)) | ||
100 | bio_integrity_free(bio, bio_set); | ||
101 | |||
120 | mempool_free(bio, bio_set->bio_pool); | 102 | mempool_free(bio, bio_set->bio_pool); |
121 | } | 103 | } |
122 | 104 | ||
@@ -275,9 +257,19 @@ struct bio *bio_clone(struct bio *bio, gfp_t gfp_mask) | |||
275 | { | 257 | { |
276 | struct bio *b = bio_alloc_bioset(gfp_mask, bio->bi_max_vecs, fs_bio_set); | 258 | struct bio *b = bio_alloc_bioset(gfp_mask, bio->bi_max_vecs, fs_bio_set); |
277 | 259 | ||
278 | if (b) { | 260 | if (!b) |
279 | b->bi_destructor = bio_fs_destructor; | 261 | return NULL; |
280 | __bio_clone(b, bio); | 262 | |
263 | b->bi_destructor = bio_fs_destructor; | ||
264 | __bio_clone(b, bio); | ||
265 | |||
266 | if (bio_integrity(bio)) { | ||
267 | int ret; | ||
268 | |||
269 | ret = bio_integrity_clone(b, bio, fs_bio_set); | ||
270 | |||
271 | if (ret < 0) | ||
272 | return NULL; | ||
281 | } | 273 | } |
282 | 274 | ||
283 | return b; | 275 | return b; |
@@ -333,10 +325,19 @@ static int __bio_add_page(struct request_queue *q, struct bio *bio, struct page | |||
333 | if (page == prev->bv_page && | 325 | if (page == prev->bv_page && |
334 | offset == prev->bv_offset + prev->bv_len) { | 326 | offset == prev->bv_offset + prev->bv_len) { |
335 | prev->bv_len += len; | 327 | prev->bv_len += len; |
336 | if (q->merge_bvec_fn && | 328 | |
337 | q->merge_bvec_fn(q, bio, prev) < len) { | 329 | if (q->merge_bvec_fn) { |
338 | prev->bv_len -= len; | 330 | struct bvec_merge_data bvm = { |
339 | return 0; | 331 | .bi_bdev = bio->bi_bdev, |
332 | .bi_sector = bio->bi_sector, | ||
333 | .bi_size = bio->bi_size, | ||
334 | .bi_rw = bio->bi_rw, | ||
335 | }; | ||
336 | |||
337 | if (q->merge_bvec_fn(q, &bvm, prev) < len) { | ||
338 | prev->bv_len -= len; | ||
339 | return 0; | ||
340 | } | ||
340 | } | 341 | } |
341 | 342 | ||
342 | goto done; | 343 | goto done; |
@@ -377,11 +378,18 @@ static int __bio_add_page(struct request_queue *q, struct bio *bio, struct page | |||
377 | * queue to get further control | 378 | * queue to get further control |
378 | */ | 379 | */ |
379 | if (q->merge_bvec_fn) { | 380 | if (q->merge_bvec_fn) { |
381 | struct bvec_merge_data bvm = { | ||
382 | .bi_bdev = bio->bi_bdev, | ||
383 | .bi_sector = bio->bi_sector, | ||
384 | .bi_size = bio->bi_size, | ||
385 | .bi_rw = bio->bi_rw, | ||
386 | }; | ||
387 | |||
380 | /* | 388 | /* |
381 | * merge_bvec_fn() returns number of bytes it can accept | 389 | * merge_bvec_fn() returns number of bytes it can accept |
382 | * at this offset | 390 | * at this offset |
383 | */ | 391 | */ |
384 | if (q->merge_bvec_fn(q, bio, bvec) < len) { | 392 | if (q->merge_bvec_fn(q, &bvm, bvec) < len) { |
385 | bvec->bv_page = NULL; | 393 | bvec->bv_page = NULL; |
386 | bvec->bv_len = 0; | 394 | bvec->bv_len = 0; |
387 | bvec->bv_offset = 0; | 395 | bvec->bv_offset = 0; |
@@ -1249,6 +1257,9 @@ struct bio_pair *bio_split(struct bio *bi, mempool_t *pool, int first_sectors) | |||
1249 | bp->bio1.bi_private = bi; | 1257 | bp->bio1.bi_private = bi; |
1250 | bp->bio2.bi_private = pool; | 1258 | bp->bio2.bi_private = pool; |
1251 | 1259 | ||
1260 | if (bio_integrity(bi)) | ||
1261 | bio_integrity_split(bi, bp, first_sectors); | ||
1262 | |||
1252 | return bp; | 1263 | return bp; |
1253 | } | 1264 | } |
1254 | 1265 | ||
@@ -1290,6 +1301,7 @@ void bioset_free(struct bio_set *bs) | |||
1290 | if (bs->bio_pool) | 1301 | if (bs->bio_pool) |
1291 | mempool_destroy(bs->bio_pool); | 1302 | mempool_destroy(bs->bio_pool); |
1292 | 1303 | ||
1304 | bioset_integrity_free(bs); | ||
1293 | biovec_free_pools(bs); | 1305 | biovec_free_pools(bs); |
1294 | 1306 | ||
1295 | kfree(bs); | 1307 | kfree(bs); |
@@ -1306,6 +1318,9 @@ struct bio_set *bioset_create(int bio_pool_size, int bvec_pool_size) | |||
1306 | if (!bs->bio_pool) | 1318 | if (!bs->bio_pool) |
1307 | goto bad; | 1319 | goto bad; |
1308 | 1320 | ||
1321 | if (bioset_integrity_create(bs, bio_pool_size)) | ||
1322 | goto bad; | ||
1323 | |||
1309 | if (!biovec_create_pools(bs, bvec_pool_size)) | 1324 | if (!biovec_create_pools(bs, bvec_pool_size)) |
1310 | return bs; | 1325 | return bs; |
1311 | 1326 | ||
@@ -1332,6 +1347,7 @@ static int __init init_bio(void) | |||
1332 | { | 1347 | { |
1333 | bio_slab = KMEM_CACHE(bio, SLAB_HWCACHE_ALIGN|SLAB_PANIC); | 1348 | bio_slab = KMEM_CACHE(bio, SLAB_HWCACHE_ALIGN|SLAB_PANIC); |
1334 | 1349 | ||
1350 | bio_integrity_init_slab(); | ||
1335 | biovec_init_slabs(); | 1351 | biovec_init_slabs(); |
1336 | 1352 | ||
1337 | fs_bio_set = bioset_create(BIO_POOL_SIZE, 2); | 1353 | fs_bio_set = bioset_create(BIO_POOL_SIZE, 2); |
diff --git a/fs/ramfs/file-mmu.c b/fs/ramfs/file-mmu.c index 9590b9024300..78f613cb9c76 100644 --- a/fs/ramfs/file-mmu.c +++ b/fs/ramfs/file-mmu.c | |||
@@ -45,6 +45,7 @@ const struct file_operations ramfs_file_operations = { | |||
45 | .mmap = generic_file_mmap, | 45 | .mmap = generic_file_mmap, |
46 | .fsync = simple_sync_file, | 46 | .fsync = simple_sync_file, |
47 | .splice_read = generic_file_splice_read, | 47 | .splice_read = generic_file_splice_read, |
48 | .splice_write = generic_file_splice_write, | ||
48 | .llseek = generic_file_llseek, | 49 | .llseek = generic_file_llseek, |
49 | }; | 50 | }; |
50 | 51 | ||
diff --git a/fs/ramfs/file-nommu.c b/fs/ramfs/file-nommu.c index 0989bc2c2f69..52312ec93ff4 100644 --- a/fs/ramfs/file-nommu.c +++ b/fs/ramfs/file-nommu.c | |||
@@ -43,6 +43,7 @@ const struct file_operations ramfs_file_operations = { | |||
43 | .aio_write = generic_file_aio_write, | 43 | .aio_write = generic_file_aio_write, |
44 | .fsync = simple_sync_file, | 44 | .fsync = simple_sync_file, |
45 | .splice_read = generic_file_splice_read, | 45 | .splice_read = generic_file_splice_read, |
46 | .splice_write = generic_file_splice_write, | ||
46 | .llseek = generic_file_llseek, | 47 | .llseek = generic_file_llseek, |
47 | }; | 48 | }; |
48 | 49 | ||
diff --git a/fs/splice.c b/fs/splice.c index aa5f6f60b305..399442179d89 100644 --- a/fs/splice.c +++ b/fs/splice.c | |||
@@ -379,13 +379,22 @@ __generic_file_splice_read(struct file *in, loff_t *ppos, | |||
379 | lock_page(page); | 379 | lock_page(page); |
380 | 380 | ||
381 | /* | 381 | /* |
382 | * page was truncated, stop here. if this isn't the | 382 | * Page was truncated, or invalidated by the |
383 | * first page, we'll just complete what we already | 383 | * filesystem. Redo the find/create, but this time the |
384 | * added | 384 | * page is kept locked, so there's no chance of another |
385 | * race with truncate/invalidate. | ||
385 | */ | 386 | */ |
386 | if (!page->mapping) { | 387 | if (!page->mapping) { |
387 | unlock_page(page); | 388 | unlock_page(page); |
388 | break; | 389 | page = find_or_create_page(mapping, index, |
390 | mapping_gfp_mask(mapping)); | ||
391 | |||
392 | if (!page) { | ||
393 | error = -ENOMEM; | ||
394 | break; | ||
395 | } | ||
396 | page_cache_release(pages[page_nr]); | ||
397 | pages[page_nr] = page; | ||
389 | } | 398 | } |
390 | /* | 399 | /* |
391 | * page was already under io and is now done, great | 400 | * page was already under io and is now done, great |
diff --git a/include/linux/bio.h b/include/linux/bio.h index 61c15eaf3fb3..0933a14e6414 100644 --- a/include/linux/bio.h +++ b/include/linux/bio.h | |||
@@ -64,6 +64,7 @@ struct bio_vec { | |||
64 | 64 | ||
65 | struct bio_set; | 65 | struct bio_set; |
66 | struct bio; | 66 | struct bio; |
67 | struct bio_integrity_payload; | ||
67 | typedef void (bio_end_io_t) (struct bio *, int); | 68 | typedef void (bio_end_io_t) (struct bio *, int); |
68 | typedef void (bio_destructor_t) (struct bio *); | 69 | typedef void (bio_destructor_t) (struct bio *); |
69 | 70 | ||
@@ -112,6 +113,9 @@ struct bio { | |||
112 | atomic_t bi_cnt; /* pin count */ | 113 | atomic_t bi_cnt; /* pin count */ |
113 | 114 | ||
114 | void *bi_private; | 115 | void *bi_private; |
116 | #if defined(CONFIG_BLK_DEV_INTEGRITY) | ||
117 | struct bio_integrity_payload *bi_integrity; /* data integrity */ | ||
118 | #endif | ||
115 | 119 | ||
116 | bio_destructor_t *bi_destructor; /* destructor */ | 120 | bio_destructor_t *bi_destructor; /* destructor */ |
117 | }; | 121 | }; |
@@ -271,6 +275,29 @@ static inline void *bio_data(struct bio *bio) | |||
271 | */ | 275 | */ |
272 | #define bio_get(bio) atomic_inc(&(bio)->bi_cnt) | 276 | #define bio_get(bio) atomic_inc(&(bio)->bi_cnt) |
273 | 277 | ||
278 | #if defined(CONFIG_BLK_DEV_INTEGRITY) | ||
279 | /* | ||
280 | * bio integrity payload | ||
281 | */ | ||
282 | struct bio_integrity_payload { | ||
283 | struct bio *bip_bio; /* parent bio */ | ||
284 | struct bio_vec *bip_vec; /* integrity data vector */ | ||
285 | |||
286 | sector_t bip_sector; /* virtual start sector */ | ||
287 | |||
288 | void *bip_buf; /* generated integrity data */ | ||
289 | bio_end_io_t *bip_end_io; /* saved I/O completion fn */ | ||
290 | |||
291 | int bip_error; /* saved I/O error */ | ||
292 | unsigned int bip_size; | ||
293 | |||
294 | unsigned short bip_pool; /* pool the ivec came from */ | ||
295 | unsigned short bip_vcnt; /* # of integrity bio_vecs */ | ||
296 | unsigned short bip_idx; /* current bip_vec index */ | ||
297 | |||
298 | struct work_struct bip_work; /* I/O completion */ | ||
299 | }; | ||
300 | #endif /* CONFIG_BLK_DEV_INTEGRITY */ | ||
274 | 301 | ||
275 | /* | 302 | /* |
276 | * A bio_pair is used when we need to split a bio. | 303 | * A bio_pair is used when we need to split a bio. |
@@ -283,10 +310,14 @@ static inline void *bio_data(struct bio *bio) | |||
283 | * in bio2.bi_private | 310 | * in bio2.bi_private |
284 | */ | 311 | */ |
285 | struct bio_pair { | 312 | struct bio_pair { |
286 | struct bio bio1, bio2; | 313 | struct bio bio1, bio2; |
287 | struct bio_vec bv1, bv2; | 314 | struct bio_vec bv1, bv2; |
288 | atomic_t cnt; | 315 | #if defined(CONFIG_BLK_DEV_INTEGRITY) |
289 | int error; | 316 | struct bio_integrity_payload bip1, bip2; |
317 | struct bio_vec iv1, iv2; | ||
318 | #endif | ||
319 | atomic_t cnt; | ||
320 | int error; | ||
290 | }; | 321 | }; |
291 | extern struct bio_pair *bio_split(struct bio *bi, mempool_t *pool, | 322 | extern struct bio_pair *bio_split(struct bio *bi, mempool_t *pool, |
292 | int first_sectors); | 323 | int first_sectors); |
@@ -333,6 +364,39 @@ extern struct bio *bio_copy_user_iov(struct request_queue *, struct sg_iovec *, | |||
333 | int, int); | 364 | int, int); |
334 | extern int bio_uncopy_user(struct bio *); | 365 | extern int bio_uncopy_user(struct bio *); |
335 | void zero_fill_bio(struct bio *bio); | 366 | void zero_fill_bio(struct bio *bio); |
367 | extern struct bio_vec *bvec_alloc_bs(gfp_t, int, unsigned long *, struct bio_set *); | ||
368 | extern unsigned int bvec_nr_vecs(unsigned short idx); | ||
369 | |||
370 | /* | ||
371 | * bio_set is used to allow other portions of the IO system to | ||
372 | * allocate their own private memory pools for bio and iovec structures. | ||
373 | * These memory pools in turn all allocate from the bio_slab | ||
374 | * and the bvec_slabs[]. | ||
375 | */ | ||
376 | #define BIO_POOL_SIZE 2 | ||
377 | #define BIOVEC_NR_POOLS 6 | ||
378 | |||
379 | struct bio_set { | ||
380 | mempool_t *bio_pool; | ||
381 | #if defined(CONFIG_BLK_DEV_INTEGRITY) | ||
382 | mempool_t *bio_integrity_pool; | ||
383 | #endif | ||
384 | mempool_t *bvec_pools[BIOVEC_NR_POOLS]; | ||
385 | }; | ||
386 | |||
387 | struct biovec_slab { | ||
388 | int nr_vecs; | ||
389 | char *name; | ||
390 | struct kmem_cache *slab; | ||
391 | }; | ||
392 | |||
393 | extern struct bio_set *fs_bio_set; | ||
394 | |||
395 | /* | ||
396 | * a small number of entries is fine, not going to be performance critical. | ||
397 | * basically we just need to survive | ||
398 | */ | ||
399 | #define BIO_SPLIT_ENTRIES 2 | ||
336 | 400 | ||
337 | #ifdef CONFIG_HIGHMEM | 401 | #ifdef CONFIG_HIGHMEM |
338 | /* | 402 | /* |
@@ -381,5 +445,63 @@ static inline char *__bio_kmap_irq(struct bio *bio, unsigned short idx, | |||
381 | __bio_kmap_irq((bio), (bio)->bi_idx, (flags)) | 445 | __bio_kmap_irq((bio), (bio)->bi_idx, (flags)) |
382 | #define bio_kunmap_irq(buf,flags) __bio_kunmap_irq(buf, flags) | 446 | #define bio_kunmap_irq(buf,flags) __bio_kunmap_irq(buf, flags) |
383 | 447 | ||
448 | #if defined(CONFIG_BLK_DEV_INTEGRITY) | ||
449 | |||
450 | #define bip_vec_idx(bip, idx) (&(bip->bip_vec[(idx)])) | ||
451 | #define bip_vec(bip) bip_vec_idx(bip, 0) | ||
452 | |||
453 | #define __bip_for_each_vec(bvl, bip, i, start_idx) \ | ||
454 | for (bvl = bip_vec_idx((bip), (start_idx)), i = (start_idx); \ | ||
455 | i < (bip)->bip_vcnt; \ | ||
456 | bvl++, i++) | ||
457 | |||
458 | #define bip_for_each_vec(bvl, bip, i) \ | ||
459 | __bip_for_each_vec(bvl, bip, i, (bip)->bip_idx) | ||
460 | |||
461 | static inline int bio_integrity(struct bio *bio) | ||
462 | { | ||
463 | #if defined(CONFIG_BLK_DEV_INTEGRITY) | ||
464 | return bio->bi_integrity != NULL; | ||
465 | #else | ||
466 | return 0; | ||
467 | #endif | ||
468 | } | ||
469 | |||
470 | extern struct bio_integrity_payload *bio_integrity_alloc_bioset(struct bio *, gfp_t, unsigned int, struct bio_set *); | ||
471 | extern struct bio_integrity_payload *bio_integrity_alloc(struct bio *, gfp_t, unsigned int); | ||
472 | extern void bio_integrity_free(struct bio *, struct bio_set *); | ||
473 | extern int bio_integrity_add_page(struct bio *, struct page *, unsigned int, unsigned int); | ||
474 | extern int bio_integrity_enabled(struct bio *bio); | ||
475 | extern int bio_integrity_set_tag(struct bio *, void *, unsigned int); | ||
476 | extern int bio_integrity_get_tag(struct bio *, void *, unsigned int); | ||
477 | extern int bio_integrity_prep(struct bio *); | ||
478 | extern void bio_integrity_endio(struct bio *, int); | ||
479 | extern void bio_integrity_advance(struct bio *, unsigned int); | ||
480 | extern void bio_integrity_trim(struct bio *, unsigned int, unsigned int); | ||
481 | extern void bio_integrity_split(struct bio *, struct bio_pair *, int); | ||
482 | extern int bio_integrity_clone(struct bio *, struct bio *, struct bio_set *); | ||
483 | extern int bioset_integrity_create(struct bio_set *, int); | ||
484 | extern void bioset_integrity_free(struct bio_set *); | ||
485 | extern void bio_integrity_init_slab(void); | ||
486 | |||
487 | #else /* CONFIG_BLK_DEV_INTEGRITY */ | ||
488 | |||
489 | #define bio_integrity(a) (0) | ||
490 | #define bioset_integrity_create(a, b) (0) | ||
491 | #define bio_integrity_prep(a) (0) | ||
492 | #define bio_integrity_enabled(a) (0) | ||
493 | #define bio_integrity_clone(a, b, c) (0) | ||
494 | #define bioset_integrity_free(a) do { } while (0) | ||
495 | #define bio_integrity_free(a, b) do { } while (0) | ||
496 | #define bio_integrity_endio(a, b) do { } while (0) | ||
497 | #define bio_integrity_advance(a, b) do { } while (0) | ||
498 | #define bio_integrity_trim(a, b, c) do { } while (0) | ||
499 | #define bio_integrity_split(a, b, c) do { } while (0) | ||
500 | #define bio_integrity_set_tag(a, b, c) do { } while (0) | ||
501 | #define bio_integrity_get_tag(a, b, c) do { } while (0) | ||
502 | #define bio_integrity_init_slab(a) do { } while (0) | ||
503 | |||
504 | #endif /* CONFIG_BLK_DEV_INTEGRITY */ | ||
505 | |||
384 | #endif /* CONFIG_BLOCK */ | 506 | #endif /* CONFIG_BLOCK */ |
385 | #endif /* __LINUX_BIO_H */ | 507 | #endif /* __LINUX_BIO_H */ |
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index d2a1b71e93c3..1ffd8bfdc4c9 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h | |||
@@ -23,7 +23,6 @@ | |||
23 | struct scsi_ioctl_command; | 23 | struct scsi_ioctl_command; |
24 | 24 | ||
25 | struct request_queue; | 25 | struct request_queue; |
26 | typedef struct request_queue request_queue_t __deprecated; | ||
27 | struct elevator_queue; | 26 | struct elevator_queue; |
28 | typedef struct elevator_queue elevator_t; | 27 | typedef struct elevator_queue elevator_t; |
29 | struct request_pm_state; | 28 | struct request_pm_state; |
@@ -34,12 +33,6 @@ struct sg_io_hdr; | |||
34 | #define BLKDEV_MIN_RQ 4 | 33 | #define BLKDEV_MIN_RQ 4 |
35 | #define BLKDEV_MAX_RQ 128 /* Default maximum */ | 34 | #define BLKDEV_MAX_RQ 128 /* Default maximum */ |
36 | 35 | ||
37 | int put_io_context(struct io_context *ioc); | ||
38 | void exit_io_context(void); | ||
39 | struct io_context *get_io_context(gfp_t gfp_flags, int node); | ||
40 | struct io_context *alloc_io_context(gfp_t gfp_flags, int node); | ||
41 | void copy_io_context(struct io_context **pdst, struct io_context **psrc); | ||
42 | |||
43 | struct request; | 36 | struct request; |
44 | typedef void (rq_end_io_fn)(struct request *, int); | 37 | typedef void (rq_end_io_fn)(struct request *, int); |
45 | 38 | ||
@@ -113,6 +106,7 @@ enum rq_flag_bits { | |||
113 | __REQ_ALLOCED, /* request came from our alloc pool */ | 106 | __REQ_ALLOCED, /* request came from our alloc pool */ |
114 | __REQ_RW_META, /* metadata io request */ | 107 | __REQ_RW_META, /* metadata io request */ |
115 | __REQ_COPY_USER, /* contains copies of user pages */ | 108 | __REQ_COPY_USER, /* contains copies of user pages */ |
109 | __REQ_INTEGRITY, /* integrity metadata has been remapped */ | ||
116 | __REQ_NR_BITS, /* stops here */ | 110 | __REQ_NR_BITS, /* stops here */ |
117 | }; | 111 | }; |
118 | 112 | ||
@@ -135,6 +129,7 @@ enum rq_flag_bits { | |||
135 | #define REQ_ALLOCED (1 << __REQ_ALLOCED) | 129 | #define REQ_ALLOCED (1 << __REQ_ALLOCED) |
136 | #define REQ_RW_META (1 << __REQ_RW_META) | 130 | #define REQ_RW_META (1 << __REQ_RW_META) |
137 | #define REQ_COPY_USER (1 << __REQ_COPY_USER) | 131 | #define REQ_COPY_USER (1 << __REQ_COPY_USER) |
132 | #define REQ_INTEGRITY (1 << __REQ_INTEGRITY) | ||
138 | 133 | ||
139 | #define BLK_MAX_CDB 16 | 134 | #define BLK_MAX_CDB 16 |
140 | 135 | ||
@@ -259,7 +254,14 @@ typedef int (prep_rq_fn) (struct request_queue *, struct request *); | |||
259 | typedef void (unplug_fn) (struct request_queue *); | 254 | typedef void (unplug_fn) (struct request_queue *); |
260 | 255 | ||
261 | struct bio_vec; | 256 | struct bio_vec; |
262 | typedef int (merge_bvec_fn) (struct request_queue *, struct bio *, struct bio_vec *); | 257 | struct bvec_merge_data { |
258 | struct block_device *bi_bdev; | ||
259 | sector_t bi_sector; | ||
260 | unsigned bi_size; | ||
261 | unsigned long bi_rw; | ||
262 | }; | ||
263 | typedef int (merge_bvec_fn) (struct request_queue *, struct bvec_merge_data *, | ||
264 | struct bio_vec *); | ||
263 | typedef void (prepare_flush_fn) (struct request_queue *, struct request *); | 265 | typedef void (prepare_flush_fn) (struct request_queue *, struct request *); |
264 | typedef void (softirq_done_fn)(struct request *); | 266 | typedef void (softirq_done_fn)(struct request *); |
265 | typedef int (dma_drain_needed_fn)(struct request *); | 267 | typedef int (dma_drain_needed_fn)(struct request *); |
@@ -426,6 +428,32 @@ static inline void queue_flag_set_unlocked(unsigned int flag, | |||
426 | __set_bit(flag, &q->queue_flags); | 428 | __set_bit(flag, &q->queue_flags); |
427 | } | 429 | } |
428 | 430 | ||
431 | static inline int queue_flag_test_and_clear(unsigned int flag, | ||
432 | struct request_queue *q) | ||
433 | { | ||
434 | WARN_ON_ONCE(!queue_is_locked(q)); | ||
435 | |||
436 | if (test_bit(flag, &q->queue_flags)) { | ||
437 | __clear_bit(flag, &q->queue_flags); | ||
438 | return 1; | ||
439 | } | ||
440 | |||
441 | return 0; | ||
442 | } | ||
443 | |||
444 | static inline int queue_flag_test_and_set(unsigned int flag, | ||
445 | struct request_queue *q) | ||
446 | { | ||
447 | WARN_ON_ONCE(!queue_is_locked(q)); | ||
448 | |||
449 | if (!test_bit(flag, &q->queue_flags)) { | ||
450 | __set_bit(flag, &q->queue_flags); | ||
451 | return 0; | ||
452 | } | ||
453 | |||
454 | return 1; | ||
455 | } | ||
456 | |||
429 | static inline void queue_flag_set(unsigned int flag, struct request_queue *q) | 457 | static inline void queue_flag_set(unsigned int flag, struct request_queue *q) |
430 | { | 458 | { |
431 | WARN_ON_ONCE(!queue_is_locked(q)); | 459 | WARN_ON_ONCE(!queue_is_locked(q)); |
@@ -676,7 +704,6 @@ extern int blk_execute_rq(struct request_queue *, struct gendisk *, | |||
676 | struct request *, int); | 704 | struct request *, int); |
677 | extern void blk_execute_rq_nowait(struct request_queue *, struct gendisk *, | 705 | extern void blk_execute_rq_nowait(struct request_queue *, struct gendisk *, |
678 | struct request *, int, rq_end_io_fn *); | 706 | struct request *, int, rq_end_io_fn *); |
679 | extern int blk_verify_command(unsigned char *, int); | ||
680 | extern void blk_unplug(struct request_queue *q); | 707 | extern void blk_unplug(struct request_queue *q); |
681 | 708 | ||
682 | static inline struct request_queue *bdev_get_queue(struct block_device *bdev) | 709 | static inline struct request_queue *bdev_get_queue(struct block_device *bdev) |
@@ -749,6 +776,7 @@ extern void blk_queue_max_segment_size(struct request_queue *, unsigned int); | |||
749 | extern void blk_queue_hardsect_size(struct request_queue *, unsigned short); | 776 | extern void blk_queue_hardsect_size(struct request_queue *, unsigned short); |
750 | extern void blk_queue_stack_limits(struct request_queue *t, struct request_queue *b); | 777 | extern void blk_queue_stack_limits(struct request_queue *t, struct request_queue *b); |
751 | extern void blk_queue_dma_pad(struct request_queue *, unsigned int); | 778 | extern void blk_queue_dma_pad(struct request_queue *, unsigned int); |
779 | extern void blk_queue_update_dma_pad(struct request_queue *, unsigned int); | ||
752 | extern int blk_queue_dma_drain(struct request_queue *q, | 780 | extern int blk_queue_dma_drain(struct request_queue *q, |
753 | dma_drain_needed_fn *dma_drain_needed, | 781 | dma_drain_needed_fn *dma_drain_needed, |
754 | void *buf, unsigned int size); | 782 | void *buf, unsigned int size); |
@@ -802,6 +830,15 @@ static inline struct request *blk_map_queue_find_tag(struct blk_queue_tag *bqt, | |||
802 | 830 | ||
803 | extern int blkdev_issue_flush(struct block_device *, sector_t *); | 831 | extern int blkdev_issue_flush(struct block_device *, sector_t *); |
804 | 832 | ||
833 | /* | ||
834 | * command filter functions | ||
835 | */ | ||
836 | extern int blk_verify_command(struct file *file, unsigned char *cmd); | ||
837 | extern int blk_cmd_filter_verify_command(struct blk_scsi_cmd_filter *filter, | ||
838 | unsigned char *cmd, mode_t *f_mode); | ||
839 | extern int blk_register_filter(struct gendisk *disk); | ||
840 | extern void blk_unregister_filter(struct gendisk *disk); | ||
841 | |||
805 | #define MAX_PHYS_SEGMENTS 128 | 842 | #define MAX_PHYS_SEGMENTS 128 |
806 | #define MAX_HW_SEGMENTS 128 | 843 | #define MAX_HW_SEGMENTS 128 |
807 | #define SAFE_MAX_SECTORS 255 | 844 | #define SAFE_MAX_SECTORS 255 |
@@ -865,28 +902,116 @@ void kblockd_flush_work(struct work_struct *work); | |||
865 | #define MODULE_ALIAS_BLOCKDEV_MAJOR(major) \ | 902 | #define MODULE_ALIAS_BLOCKDEV_MAJOR(major) \ |
866 | MODULE_ALIAS("block-major-" __stringify(major) "-*") | 903 | MODULE_ALIAS("block-major-" __stringify(major) "-*") |
867 | 904 | ||
905 | #if defined(CONFIG_BLK_DEV_INTEGRITY) | ||
868 | 906 | ||
869 | #else /* CONFIG_BLOCK */ | 907 | #define INTEGRITY_FLAG_READ 2 /* verify data integrity on read */ |
870 | /* | 908 | #define INTEGRITY_FLAG_WRITE 4 /* generate data integrity on write */ |
871 | * stubs for when the block layer is configured out | ||
872 | */ | ||
873 | #define buffer_heads_over_limit 0 | ||
874 | 909 | ||
875 | static inline long nr_blockdev_pages(void) | 910 | struct blk_integrity_exchg { |
911 | void *prot_buf; | ||
912 | void *data_buf; | ||
913 | sector_t sector; | ||
914 | unsigned int data_size; | ||
915 | unsigned short sector_size; | ||
916 | const char *disk_name; | ||
917 | }; | ||
918 | |||
919 | typedef void (integrity_gen_fn) (struct blk_integrity_exchg *); | ||
920 | typedef int (integrity_vrfy_fn) (struct blk_integrity_exchg *); | ||
921 | typedef void (integrity_set_tag_fn) (void *, void *, unsigned int); | ||
922 | typedef void (integrity_get_tag_fn) (void *, void *, unsigned int); | ||
923 | |||
924 | struct blk_integrity { | ||
925 | integrity_gen_fn *generate_fn; | ||
926 | integrity_vrfy_fn *verify_fn; | ||
927 | integrity_set_tag_fn *set_tag_fn; | ||
928 | integrity_get_tag_fn *get_tag_fn; | ||
929 | |||
930 | unsigned short flags; | ||
931 | unsigned short tuple_size; | ||
932 | unsigned short sector_size; | ||
933 | unsigned short tag_size; | ||
934 | |||
935 | const char *name; | ||
936 | |||
937 | struct kobject kobj; | ||
938 | }; | ||
939 | |||
940 | extern int blk_integrity_register(struct gendisk *, struct blk_integrity *); | ||
941 | extern void blk_integrity_unregister(struct gendisk *); | ||
942 | extern int blk_integrity_compare(struct block_device *, struct block_device *); | ||
943 | extern int blk_rq_map_integrity_sg(struct request *, struct scatterlist *); | ||
944 | extern int blk_rq_count_integrity_sg(struct request *); | ||
945 | |||
946 | static inline unsigned short blk_integrity_tuple_size(struct blk_integrity *bi) | ||
876 | { | 947 | { |
948 | if (bi) | ||
949 | return bi->tuple_size; | ||
950 | |||
877 | return 0; | 951 | return 0; |
878 | } | 952 | } |
879 | 953 | ||
880 | static inline void exit_io_context(void) | 954 | static inline struct blk_integrity *bdev_get_integrity(struct block_device *bdev) |
881 | { | 955 | { |
956 | return bdev->bd_disk->integrity; | ||
882 | } | 957 | } |
883 | 958 | ||
884 | struct io_context; | 959 | static inline unsigned int bdev_get_tag_size(struct block_device *bdev) |
885 | static inline int put_io_context(struct io_context *ioc) | ||
886 | { | 960 | { |
887 | return 1; | 961 | struct blk_integrity *bi = bdev_get_integrity(bdev); |
962 | |||
963 | if (bi) | ||
964 | return bi->tag_size; | ||
965 | |||
966 | return 0; | ||
967 | } | ||
968 | |||
969 | static inline int bdev_integrity_enabled(struct block_device *bdev, int rw) | ||
970 | { | ||
971 | struct blk_integrity *bi = bdev_get_integrity(bdev); | ||
972 | |||
973 | if (bi == NULL) | ||
974 | return 0; | ||
975 | |||
976 | if (rw == READ && bi->verify_fn != NULL && | ||
977 | (bi->flags & INTEGRITY_FLAG_READ)) | ||
978 | return 1; | ||
979 | |||
980 | if (rw == WRITE && bi->generate_fn != NULL && | ||
981 | (bi->flags & INTEGRITY_FLAG_WRITE)) | ||
982 | return 1; | ||
983 | |||
984 | return 0; | ||
888 | } | 985 | } |
889 | 986 | ||
987 | static inline int blk_integrity_rq(struct request *rq) | ||
988 | { | ||
989 | return bio_integrity(rq->bio); | ||
990 | } | ||
991 | |||
992 | #else /* CONFIG_BLK_DEV_INTEGRITY */ | ||
993 | |||
994 | #define blk_integrity_rq(rq) (0) | ||
995 | #define blk_rq_count_integrity_sg(a) (0) | ||
996 | #define blk_rq_map_integrity_sg(a, b) (0) | ||
997 | #define bdev_get_integrity(a) (0) | ||
998 | #define bdev_get_tag_size(a) (0) | ||
999 | #define blk_integrity_compare(a, b) (0) | ||
1000 | #define blk_integrity_register(a, b) (0) | ||
1001 | #define blk_integrity_unregister(a) do { } while (0); | ||
1002 | |||
1003 | #endif /* CONFIG_BLK_DEV_INTEGRITY */ | ||
1004 | |||
1005 | #else /* CONFIG_BLOCK */ | ||
1006 | /* | ||
1007 | * stubs for when the block layer is configured out | ||
1008 | */ | ||
1009 | #define buffer_heads_over_limit 0 | ||
1010 | |||
1011 | static inline long nr_blockdev_pages(void) | ||
1012 | { | ||
1013 | return 0; | ||
1014 | } | ||
890 | 1015 | ||
891 | #endif /* CONFIG_BLOCK */ | 1016 | #endif /* CONFIG_BLOCK */ |
892 | 1017 | ||
diff --git a/include/linux/blktrace_api.h b/include/linux/blktrace_api.h index e3ef903aae88..d084b8d227a5 100644 --- a/include/linux/blktrace_api.h +++ b/include/linux/blktrace_api.h | |||
@@ -129,6 +129,7 @@ struct blk_trace { | |||
129 | u32 dev; | 129 | u32 dev; |
130 | struct dentry *dir; | 130 | struct dentry *dir; |
131 | struct dentry *dropped_file; | 131 | struct dentry *dropped_file; |
132 | struct dentry *msg_file; | ||
132 | atomic_t dropped; | 133 | atomic_t dropped; |
133 | }; | 134 | }; |
134 | 135 | ||
diff --git a/include/linux/genhd.h b/include/linux/genhd.h index ae7aec3cabee..e8787417f65a 100644 --- a/include/linux/genhd.h +++ b/include/linux/genhd.h | |||
@@ -110,6 +110,14 @@ struct hd_struct { | |||
110 | #define GENHD_FL_SUPPRESS_PARTITION_INFO 32 | 110 | #define GENHD_FL_SUPPRESS_PARTITION_INFO 32 |
111 | #define GENHD_FL_FAIL 64 | 111 | #define GENHD_FL_FAIL 64 |
112 | 112 | ||
113 | #define BLK_SCSI_MAX_CMDS (256) | ||
114 | #define BLK_SCSI_CMD_PER_LONG (BLK_SCSI_MAX_CMDS / (sizeof(long) * 8)) | ||
115 | |||
116 | struct blk_scsi_cmd_filter { | ||
117 | unsigned long read_ok[BLK_SCSI_CMD_PER_LONG]; | ||
118 | unsigned long write_ok[BLK_SCSI_CMD_PER_LONG]; | ||
119 | struct kobject kobj; | ||
120 | }; | ||
113 | 121 | ||
114 | struct gendisk { | 122 | struct gendisk { |
115 | int major; /* major number of driver */ | 123 | int major; /* major number of driver */ |
@@ -120,6 +128,7 @@ struct gendisk { | |||
120 | struct hd_struct **part; /* [indexed by minor] */ | 128 | struct hd_struct **part; /* [indexed by minor] */ |
121 | struct block_device_operations *fops; | 129 | struct block_device_operations *fops; |
122 | struct request_queue *queue; | 130 | struct request_queue *queue; |
131 | struct blk_scsi_cmd_filter cmd_filter; | ||
123 | void *private_data; | 132 | void *private_data; |
124 | sector_t capacity; | 133 | sector_t capacity; |
125 | 134 | ||
@@ -141,6 +150,9 @@ struct gendisk { | |||
141 | struct disk_stats dkstats; | 150 | struct disk_stats dkstats; |
142 | #endif | 151 | #endif |
143 | struct work_struct async_notify; | 152 | struct work_struct async_notify; |
153 | #ifdef CONFIG_BLK_DEV_INTEGRITY | ||
154 | struct blk_integrity *integrity; | ||
155 | #endif | ||
144 | }; | 156 | }; |
145 | 157 | ||
146 | /* | 158 | /* |
diff --git a/include/linux/iocontext.h b/include/linux/iocontext.h index 2b7a1187cb29..08b987bccf89 100644 --- a/include/linux/iocontext.h +++ b/include/linux/iocontext.h | |||
@@ -99,4 +99,22 @@ static inline struct io_context *ioc_task_link(struct io_context *ioc) | |||
99 | return NULL; | 99 | return NULL; |
100 | } | 100 | } |
101 | 101 | ||
102 | #ifdef CONFIG_BLOCK | ||
103 | int put_io_context(struct io_context *ioc); | ||
104 | void exit_io_context(void); | ||
105 | struct io_context *get_io_context(gfp_t gfp_flags, int node); | ||
106 | struct io_context *alloc_io_context(gfp_t gfp_flags, int node); | ||
107 | void copy_io_context(struct io_context **pdst, struct io_context **psrc); | ||
108 | #else | ||
109 | static inline void exit_io_context(void) | ||
110 | { | ||
111 | } | ||
112 | |||
113 | struct io_context; | ||
114 | static inline int put_io_context(struct io_context *ioc) | ||
115 | { | ||
116 | return 1; | ||
117 | } | ||
118 | #endif | ||
119 | |||
102 | #endif | 120 | #endif |
diff --git a/kernel/exit.c b/kernel/exit.c index 8f6185e69b69..ceb258782835 100644 --- a/kernel/exit.c +++ b/kernel/exit.c | |||
@@ -13,6 +13,7 @@ | |||
13 | #include <linux/personality.h> | 13 | #include <linux/personality.h> |
14 | #include <linux/tty.h> | 14 | #include <linux/tty.h> |
15 | #include <linux/mnt_namespace.h> | 15 | #include <linux/mnt_namespace.h> |
16 | #include <linux/iocontext.h> | ||
16 | #include <linux/key.h> | 17 | #include <linux/key.h> |
17 | #include <linux/security.h> | 18 | #include <linux/security.h> |
18 | #include <linux/cpu.h> | 19 | #include <linux/cpu.h> |
diff --git a/kernel/fork.c b/kernel/fork.c index 19908b26cf80..b71ccd09fc8d 100644 --- a/kernel/fork.c +++ b/kernel/fork.c | |||
@@ -23,6 +23,7 @@ | |||
23 | #include <linux/sem.h> | 23 | #include <linux/sem.h> |
24 | #include <linux/file.h> | 24 | #include <linux/file.h> |
25 | #include <linux/fdtable.h> | 25 | #include <linux/fdtable.h> |
26 | #include <linux/iocontext.h> | ||
26 | #include <linux/key.h> | 27 | #include <linux/key.h> |
27 | #include <linux/binfmts.h> | 28 | #include <linux/binfmts.h> |
28 | #include <linux/mman.h> | 29 | #include <linux/mman.h> |