summaryrefslogtreecommitdiff
blob: 72de8e0c97d9ac28cccba9ab2a2abb3bc44715c6 (plain)
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);