]> git.proxmox.com Git - pve-kernel-jessie.git/blame - 0001-Revert-block-loop-switch-to-VFS-ITER_BVEC.patch
fix typo
[pve-kernel-jessie.git] / 0001-Revert-block-loop-switch-to-VFS-ITER_BVEC.patch
CommitLineData
924f98e8
DM
1From a265a27f75e6ab35d0289f11337eaab8cb80906c Mon Sep 17 00:00:00 2001
2From: Dietmar Maurer <dietmar@proxmox.com>
3Date: Sun, 9 Aug 2015 17:19:35 +0200
4Subject: [PATCH] Revert "block: loop: switch to VFS ITER_BVEC"
5
6This reverts commit aa4d86163e4e91a1ac560954a554bab417e338f4.
7
8Conflicts:
9 drivers/block/loop.c
10---
11 drivers/block/loop.c | 293 ++++++++++++++++++++++++++++++---------------------
12 1 file changed, 173 insertions(+), 120 deletions(-)
13
14diff --git a/drivers/block/loop.c b/drivers/block/loop.c
15index 866f8e2..7fad961 100644
16--- a/drivers/block/loop.c
17+++ b/drivers/block/loop.c
18@@ -88,6 +88,28 @@ static int part_shift;
19
20 static struct workqueue_struct *loop_wq;
21
22+/*
23+ * Transfer functions
24+ */
25+static int transfer_none(struct loop_device *lo, int cmd,
26+ struct page *raw_page, unsigned raw_off,
27+ struct page *loop_page, unsigned loop_off,
28+ int size, sector_t real_block)
29+{
30+ char *raw_buf = kmap_atomic(raw_page) + raw_off;
31+ char *loop_buf = kmap_atomic(loop_page) + loop_off;
32+
33+ if (cmd == READ)
34+ memcpy(loop_buf, raw_buf, size);
35+ else
36+ memcpy(raw_buf, loop_buf, size);
37+
38+ kunmap_atomic(loop_buf);
39+ kunmap_atomic(raw_buf);
40+ cond_resched();
41+ return 0;
42+}
43+
44 static int transfer_xor(struct loop_device *lo, int cmd,
45 struct page *raw_page, unsigned raw_off,
46 struct page *loop_page, unsigned loop_off,
47@@ -126,13 +148,14 @@ static int xor_init(struct loop_device *lo, const struct loop_info64 *info)
48
49 static struct loop_func_table none_funcs = {
50 .number = LO_CRYPT_NONE,
51-};
52+ .transfer = transfer_none,
53+};
54
55 static struct loop_func_table xor_funcs = {
56 .number = LO_CRYPT_XOR,
57 .transfer = transfer_xor,
58 .init = xor_init
59-};
60+};
61
62 /* xfer_funcs[0] is special - its release function is never called */
63 static struct loop_func_table *xfer_funcs[MAX_LO_CRYPT] = {
64@@ -192,169 +215,207 @@ lo_do_transfer(struct loop_device *lo, int cmd,
65 struct page *lpage, unsigned loffs,
66 int size, sector_t rblock)
67 {
68- int ret;
69-
70- ret = lo->transfer(lo, cmd, rpage, roffs, lpage, loffs, size, rblock);
71- if (likely(!ret))
72+ if (unlikely(!lo->transfer))
73 return 0;
74
75- printk_ratelimited(KERN_ERR
76- "loop: Transfer error at byte offset %llu, length %i.\n",
77- (unsigned long long)rblock << 9, size);
78- return ret;
79+ return lo->transfer(lo, cmd, rpage, roffs, lpage, loffs, size, rblock);
80 }
81
82-static int lo_write_bvec(struct file *file, struct bio_vec *bvec, loff_t *ppos)
83+/**
84+ * __do_lo_send_write - helper for writing data to a loop device
85+ *
86+ * This helper just factors out common code between do_lo_send_direct_write()
87+ * and do_lo_send_write().
88+ */
89+static int __do_lo_send_write(struct file *file,
90+ u8 *buf, const int len, loff_t pos)
91 {
92- struct iov_iter i;
93+ struct kvec kvec = {.iov_base = buf, .iov_len = len};
94+ struct iov_iter from;
95 ssize_t bw;
96
97- iov_iter_bvec(&i, ITER_BVEC, bvec, 1, bvec->bv_len);
98+ iov_iter_kvec(&from, ITER_KVEC | WRITE, &kvec, 1, len);
99
100 file_start_write(file);
101- bw = vfs_iter_write(file, &i, ppos);
102+ bw = vfs_iter_write(file, &from, &pos);
103 file_end_write(file);
104-
105- if (likely(bw == bvec->bv_len))
106+ if (likely(bw == len))
107 return 0;
108-
109- printk_ratelimited(KERN_ERR
110- "loop: Write error at byte offset %llu, length %i.\n",
111- (unsigned long long)*ppos, bvec->bv_len);
112+ printk_ratelimited(KERN_ERR "loop: Write error at byte offset %llu, length %i.\n",
113+ (unsigned long long)pos, len);
114 if (bw >= 0)
115 bw = -EIO;
116 return bw;
117 }
118
119-static int lo_write_simple(struct loop_device *lo, struct request *rq,
120- loff_t pos)
121+/**
122+ * do_lo_send_direct_write - helper for writing data to a loop device
123+ *
124+ * This is the fast, non-transforming version that does not need double
125+ * buffering.
126+ */
127+static int do_lo_send_direct_write(struct loop_device *lo,
128+ struct bio_vec *bvec, loff_t pos, struct page *page)
129 {
130- struct bio_vec bvec;
131- struct req_iterator iter;
132- int ret = 0;
133-
134- rq_for_each_segment(bvec, rq, iter) {
135- ret = lo_write_bvec(lo->lo_backing_file, &bvec, &pos);
136- if (ret < 0)
137- break;
138- cond_resched();
139- }
140-
141- return ret;
142+ ssize_t bw = __do_lo_send_write(lo->lo_backing_file,
143+ kmap(bvec->bv_page) + bvec->bv_offset,
144+ bvec->bv_len, pos);
145+ kunmap(bvec->bv_page);
146+ cond_resched();
147+ return bw;
148 }
149
150-/*
151+/**
152+ * do_lo_send_write - helper for writing data to a loop device
153+ *
154 * This is the slow, transforming version that needs to double buffer the
155 * data as it cannot do the transformations in place without having direct
156 * access to the destination pages of the backing file.
157 */
158-static int lo_write_transfer(struct loop_device *lo, struct request *rq,
159- loff_t pos)
160+static int do_lo_send_write(struct loop_device *lo, struct bio_vec *bvec,
161+ loff_t pos, struct page *page)
162 {
163- struct bio_vec bvec, b;
164+ int ret = lo_do_transfer(lo, WRITE, page, 0, bvec->bv_page,
165+ bvec->bv_offset, bvec->bv_len, pos >> 9);
166+ if (likely(!ret))
167+ return __do_lo_send_write(lo->lo_backing_file,
168+ page_address(page), bvec->bv_len,
169+ pos);
170+ printk_ratelimited(KERN_ERR "loop: Transfer error at byte offset %llu, "
171+ "length %i.\n", (unsigned long long)pos, bvec->bv_len);
172+ if (ret > 0)
173+ ret = -EIO;
174+ return ret;
175+}
176+
177+static int lo_send(struct loop_device *lo, struct request *rq, loff_t pos)
178+{
179+ int (*do_lo_send)(struct loop_device *, struct bio_vec *, loff_t,
180+ struct page *page);
181+ struct bio_vec bvec;
182 struct req_iterator iter;
183- struct page *page;
184+ struct page *page = NULL;
185 int ret = 0;
186
187- page = alloc_page(GFP_NOIO);
188- if (unlikely(!page))
189- return -ENOMEM;
190+ if (lo->transfer != transfer_none) {
191+ page = alloc_page(GFP_NOIO | __GFP_HIGHMEM);
192+ if (unlikely(!page))
193+ goto fail;
194+ kmap(page);
195+ do_lo_send = do_lo_send_write;
196+ } else {
197+ do_lo_send = do_lo_send_direct_write;
198+ }
199
200 rq_for_each_segment(bvec, rq, iter) {
201- ret = lo_do_transfer(lo, WRITE, page, 0, bvec.bv_page,
202- bvec.bv_offset, bvec.bv_len, pos >> 9);
203- if (unlikely(ret))
204- break;
205-
206- b.bv_page = page;
207- b.bv_offset = 0;
208- b.bv_len = bvec.bv_len;
209- ret = lo_write_bvec(lo->lo_backing_file, &b, &pos);
210+ ret = do_lo_send(lo, &bvec, pos, page);
211 if (ret < 0)
212 break;
213+ pos += bvec.bv_len;
214 }
215-
216- __free_page(page);
217+ if (page) {
218+ kunmap(page);
219+ __free_page(page);
220+ }
221+out:
222 return ret;
223+fail:
224+ printk_ratelimited(KERN_ERR "loop: Failed to allocate temporary page for write.\n");
225+ ret = -ENOMEM;
226+ goto out;
227 }
228
229-static int lo_read_simple(struct loop_device *lo, struct request *rq,
230- loff_t pos)
231-{
232- struct bio_vec bvec;
233- struct req_iterator iter;
234- struct iov_iter i;
235- ssize_t len;
236+struct lo_read_data {
237+ struct loop_device *lo;
238+ struct page *page;
239+ unsigned offset;
240+ int bsize;
241+};
242
243- rq_for_each_segment(bvec, rq, iter) {
244- iov_iter_bvec(&i, ITER_BVEC, &bvec, 1, bvec.bv_len);
245- len = vfs_iter_read(lo->lo_backing_file, &i, &pos);
246- if (len < 0)
247- return len;
248+static int
249+lo_splice_actor(struct pipe_inode_info *pipe, struct pipe_buffer *buf,
250+ struct splice_desc *sd)
251+{
252+ struct lo_read_data *p = sd->u.data;
253+ struct loop_device *lo = p->lo;
254+ struct page *page = buf->page;
255+ sector_t IV;
256+ int size;
257+
258+ IV = ((sector_t) page->index << (PAGE_CACHE_SHIFT - 9)) +
259+ (buf->offset >> 9);
260+ size = sd->len;
261+ if (size > p->bsize)
262+ size = p->bsize;
263+
264+ if (lo_do_transfer(lo, READ, page, buf->offset, p->page, p->offset, size, IV)) {
265+ printk_ratelimited(KERN_ERR "loop: transfer error block %ld\n",
266+ page->index);
267+ size = -EINVAL;
268+ }
269
270- flush_dcache_page(bvec.bv_page);
271+ flush_dcache_page(p->page);
272
273- if (len != bvec.bv_len) {
274- struct bio *bio;
275+ if (size > 0)
276+ p->offset += size;
277
278- __rq_for_each_bio(bio, rq)
279- zero_fill_bio(bio);
280- break;
281- }
282- cond_resched();
283- }
284+ return size;
285+}
286
287- return 0;
288+static int
289+lo_direct_splice_actor(struct pipe_inode_info *pipe, struct splice_desc *sd)
290+{
291+ return __splice_from_pipe(pipe, sd, lo_splice_actor);
292 }
293
294-static int lo_read_transfer(struct loop_device *lo, struct request *rq,
295- loff_t pos)
296+static ssize_t
297+do_lo_receive(struct loop_device *lo,
298+ struct bio_vec *bvec, int bsize, loff_t pos)
299 {
300- struct bio_vec bvec, b;
301- struct req_iterator iter;
302- struct iov_iter i;
303- struct page *page;
304- ssize_t len;
305- int ret = 0;
306+ struct lo_read_data cookie;
307+ struct splice_desc sd;
308+ struct file *file;
309+ ssize_t retval;
310
311- page = alloc_page(GFP_NOIO);
312- if (unlikely(!page))
313- return -ENOMEM;
314+ cookie.lo = lo;
315+ cookie.page = bvec->bv_page;
316+ cookie.offset = bvec->bv_offset;
317+ cookie.bsize = bsize;
318
319- rq_for_each_segment(bvec, rq, iter) {
320- loff_t offset = pos;
321+ sd.len = 0;
322+ sd.total_len = bvec->bv_len;
323+ sd.flags = 0;
324+ sd.pos = pos;
325+ sd.u.data = &cookie;
326
327- b.bv_page = page;
328- b.bv_offset = 0;
329- b.bv_len = bvec.bv_len;
330+ file = lo->lo_backing_file;
331+ retval = splice_direct_to_actor(file, &sd, lo_direct_splice_actor);
332
333- iov_iter_bvec(&i, ITER_BVEC, &b, 1, b.bv_len);
334- len = vfs_iter_read(lo->lo_backing_file, &i, &pos);
335- if (len < 0) {
336- ret = len;
337- goto out_free_page;
338- }
339+ return retval;
340+}
341
342- ret = lo_do_transfer(lo, READ, page, 0, bvec.bv_page,
343- bvec.bv_offset, len, offset >> 9);
344- if (ret)
345- goto out_free_page;
346+static int
347+lo_receive(struct loop_device *lo, struct request *rq, int bsize, loff_t pos)
348+{
349+ struct bio_vec bvec;
350+ struct req_iterator iter;
351+ ssize_t s;
352
353- flush_dcache_page(bvec.bv_page);
354+ rq_for_each_segment(bvec, rq, iter) {
355+ s = do_lo_receive(lo, &bvec, bsize, pos);
356+ if (s < 0)
357+ return s;
358
359- if (len != bvec.bv_len) {
360+ if (s != bvec.bv_len) {
361 struct bio *bio;
362
363 __rq_for_each_bio(bio, rq)
364 zero_fill_bio(bio);
365 break;
366 }
367+ pos += bvec.bv_len;
368 }
369-
370- ret = 0;
371-out_free_page:
372- __free_page(page);
373- return ret;
374+ return 0;
375 }
376
377 static int lo_discard(struct loop_device *lo, struct request *rq, loff_t pos)
378@@ -403,17 +464,10 @@ static int do_req_filebacked(struct loop_device *lo, struct request *rq)
379 ret = lo_req_flush(lo, rq);
380 else if (rq->cmd_flags & REQ_DISCARD)
381 ret = lo_discard(lo, rq, pos);
382- else if (lo->transfer)
383- ret = lo_write_transfer(lo, rq, pos);
384 else
385- ret = lo_write_simple(lo, rq, pos);
386-
387- } else {
388- if (lo->transfer)
389- ret = lo_read_transfer(lo, rq, pos);
390- else
391- ret = lo_read_simple(lo, rq, pos);
392- }
393+ ret = lo_send(lo, rq, pos);
394+ } else
395+ ret = lo_receive(lo, rq, lo->lo_blocksize, pos);
396
397 return ret;
398 }
399@@ -783,7 +837,6 @@ static int loop_set_fd(struct loop_device *lo, fmode_t mode,
400 lo->lo_flags = lo_flags;
401 lo->lo_backing_file = file;
402 lo->lo_backing_virt_file = virt_file;
403- lo->transfer = NULL;
404 lo->ioctl = NULL;
405 lo->lo_sizelimit = 0;
406 lo->old_gfp_mask = mapping_gfp_mask(mapping);
407@@ -1008,7 +1061,7 @@ loop_set_status(struct loop_device *lo, const struct loop_info64 *info)
408 memcpy(lo->lo_encrypt_key, info->lo_encrypt_key,
409 info->lo_encrypt_key_size);
410 lo->lo_key_owner = uid;
411- }
412+ }
413
414 return 0;
415 }
416--
4172.1.4
418