1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
|
Index: vserver-sources-2.6.16_2.1.1/mm/filemap.c
===================================================================
--- vserver-sources-2.6.16_2.1.1.orig/mm/filemap.c
+++ vserver-sources-2.6.16_2.1.1/mm/filemap.c
@@ -2172,6 +2172,26 @@ out:
}
EXPORT_SYMBOL(generic_file_aio_write_nolock);
+static inline void
+filemap_set_next_kvec(const struct kvec **iovp, size_t *basep, size_t bytes)
+{
+ const struct kvec *iov = *iovp;
+ size_t base = *basep;
+
+ while (bytes) {
+ int copy = min(bytes, iov->iov_len - base);
+
+ bytes -= copy;
+ base += copy;
+ if (iov->iov_len == base) {
+ iov++;
+ base = 0;
+ }
+ }
+ *iovp = iov;
+ *basep = base;
+}
+
/*
* TODO:
* This largely tries to copy generic_file_aio_write_nolock(), although it
@@ -2180,7 +2200,7 @@ EXPORT_SYMBOL(generic_file_aio_write_nol
* and remove as much code as possible.
*/
static ssize_t
-generic_kernel_file_aio_write_nolock(struct kiocb *iocb, const struct iovec*iov,
+generic_kernel_file_aio_write_nolock(struct kiocb *iocb, const struct kvec*iov,
unsigned long nr_segs, loff_t *ppos)
{
struct file *file = iocb->ki_filp;
@@ -2198,14 +2218,14 @@ generic_kernel_file_aio_write_nolock(str
ssize_t err;
size_t bytes;
struct pagevec lru_pvec;
- const struct iovec *cur_iov = iov; /* current iovec */
- size_t iov_base = 0; /* offset in the current iovec */
+ const struct kvec *cur_iov = iov; /* current kvec */
+ size_t iov_base = 0; /* offset in the current kvec */
unsigned long seg;
char *buf;
ocount = 0;
for (seg = 0; seg < nr_segs; seg++) {
- const struct iovec *iv = &iov[seg];
+ const struct kvec *iv = &iov[seg];
/*
* If any segment has a negative length, or the cumulative
@@ -2238,7 +2258,7 @@ generic_kernel_file_aio_write_nolock(str
/* There is no sane reason to use O_DIRECT */
BUG_ON(file->f_flags & O_DIRECT);
- buf = (char *)iov->iov_base;
+ buf = iov->iov_base;
do {
unsigned long index;
unsigned long offset;
@@ -2285,7 +2305,7 @@ generic_kernel_file_aio_write_nolock(str
pos += status;
buf += status;
if (unlikely(nr_segs > 1))
- filemap_set_next_iovec(&cur_iov,
+ filemap_set_next_kvec(&cur_iov,
&iov_base, status);
}
}
@@ -2372,7 +2392,7 @@ generic_file_write_nolock(struct file *f
}
static ssize_t
-generic_kernel_file_write_nolock(struct file *file, const struct iovec *iov,
+generic_kernel_file_write_nolock(struct file *file, const struct kvec *iov,
unsigned long nr_segs, loff_t *ppos)
{
struct kiocb kiocb;
@@ -2444,7 +2464,7 @@ static ssize_t generic_kernel_file_write
{
struct inode *inode = file->f_mapping->host;
ssize_t err;
- struct iovec local_iov = {.iov_base = (void __user *)buf,
+ struct kvec local_iov = { .iov_base = (char *) buf,
.iov_len = count };
mutex_lock(&inode->i_mutex);
|