diff options
author | Maciej Sosnowski <maciej.sosnowski@intel.com> | 2008-11-06 20:46:33 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-11-10 18:00:56 -0500 |
commit | c2c0b4c5434c0a25f7f7796b29155d53805909f5 (patch) | |
tree | ea3fb7e114e06c346d95c94ed288fe8b1a8ac95e | |
parent | c3d4f44f50b65b0b0290e357f8739cfb3f4bcaca (diff) |
[2/4] I/OAT: fix dma_pin_iovec_pages() error handling
Error handling needs to be modified in dma_pin_iovec_pages().
It should return NULL instead of ERR_PTR
(pinned_list is checked for NULL in tcp_recvmsg() to determine
if iovec pages have been successfully pinned down).
In case of error for the first iovec,
local_list->nr_iovecs needs to be initialized.
Cc: <stable@kernel.org>
Signed-off-by: Maciej Sosnowski <maciej.sosnowski@intel.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/dma/iovlock.c | 17 |
1 files changed, 6 insertions, 11 deletions
diff --git a/drivers/dma/iovlock.c b/drivers/dma/iovlock.c index e763d723e4cf..9f6fe46a9b87 100644 --- a/drivers/dma/iovlock.c +++ b/drivers/dma/iovlock.c | |||
@@ -55,7 +55,6 @@ struct dma_pinned_list *dma_pin_iovec_pages(struct iovec *iov, size_t len) | |||
55 | int nr_iovecs = 0; | 55 | int nr_iovecs = 0; |
56 | int iovec_len_used = 0; | 56 | int iovec_len_used = 0; |
57 | int iovec_pages_used = 0; | 57 | int iovec_pages_used = 0; |
58 | long err; | ||
59 | 58 | ||
60 | /* don't pin down non-user-based iovecs */ | 59 | /* don't pin down non-user-based iovecs */ |
61 | if (segment_eq(get_fs(), KERNEL_DS)) | 60 | if (segment_eq(get_fs(), KERNEL_DS)) |
@@ -72,23 +71,21 @@ struct dma_pinned_list *dma_pin_iovec_pages(struct iovec *iov, size_t len) | |||
72 | local_list = kmalloc(sizeof(*local_list) | 71 | local_list = kmalloc(sizeof(*local_list) |
73 | + (nr_iovecs * sizeof (struct dma_page_list)) | 72 | + (nr_iovecs * sizeof (struct dma_page_list)) |
74 | + (iovec_pages_used * sizeof (struct page*)), GFP_KERNEL); | 73 | + (iovec_pages_used * sizeof (struct page*)), GFP_KERNEL); |
75 | if (!local_list) { | 74 | if (!local_list) |
76 | err = -ENOMEM; | ||
77 | goto out; | 75 | goto out; |
78 | } | ||
79 | 76 | ||
80 | /* list of pages starts right after the page list array */ | 77 | /* list of pages starts right after the page list array */ |
81 | pages = (struct page **) &local_list->page_list[nr_iovecs]; | 78 | pages = (struct page **) &local_list->page_list[nr_iovecs]; |
82 | 79 | ||
80 | local_list->nr_iovecs = 0; | ||
81 | |||
83 | for (i = 0; i < nr_iovecs; i++) { | 82 | for (i = 0; i < nr_iovecs; i++) { |
84 | struct dma_page_list *page_list = &local_list->page_list[i]; | 83 | struct dma_page_list *page_list = &local_list->page_list[i]; |
85 | 84 | ||
86 | len -= iov[i].iov_len; | 85 | len -= iov[i].iov_len; |
87 | 86 | ||
88 | if (!access_ok(VERIFY_WRITE, iov[i].iov_base, iov[i].iov_len)) { | 87 | if (!access_ok(VERIFY_WRITE, iov[i].iov_base, iov[i].iov_len)) |
89 | err = -EFAULT; | ||
90 | goto unpin; | 88 | goto unpin; |
91 | } | ||
92 | 89 | ||
93 | page_list->nr_pages = num_pages_spanned(&iov[i]); | 90 | page_list->nr_pages = num_pages_spanned(&iov[i]); |
94 | page_list->base_address = iov[i].iov_base; | 91 | page_list->base_address = iov[i].iov_base; |
@@ -109,10 +106,8 @@ struct dma_pinned_list *dma_pin_iovec_pages(struct iovec *iov, size_t len) | |||
109 | NULL); | 106 | NULL); |
110 | up_read(¤t->mm->mmap_sem); | 107 | up_read(¤t->mm->mmap_sem); |
111 | 108 | ||
112 | if (ret != page_list->nr_pages) { | 109 | if (ret != page_list->nr_pages) |
113 | err = -ENOMEM; | ||
114 | goto unpin; | 110 | goto unpin; |
115 | } | ||
116 | 111 | ||
117 | local_list->nr_iovecs = i + 1; | 112 | local_list->nr_iovecs = i + 1; |
118 | } | 113 | } |
@@ -122,7 +117,7 @@ struct dma_pinned_list *dma_pin_iovec_pages(struct iovec *iov, size_t len) | |||
122 | unpin: | 117 | unpin: |
123 | dma_unpin_iovec_pages(local_list); | 118 | dma_unpin_iovec_pages(local_list); |
124 | out: | 119 | out: |
125 | return ERR_PTR(err); | 120 | return NULL; |
126 | } | 121 | } |
127 | 122 | ||
128 | void dma_unpin_iovec_pages(struct dma_pinned_list *pinned_list) | 123 | void dma_unpin_iovec_pages(struct dma_pinned_list *pinned_list) |