diff options
author | HATAYAMA Daisuke <d.hatayama@jp.fujitsu.com> | 2013-07-03 18:02:13 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-07-03 19:07:30 -0400 |
commit | b27eb186608c89ef0979ae47c649859ceaa1b2e7 (patch) | |
tree | 02bf3f94555e4c42773af8f544871ef9785a2c15 /fs/proc/vmcore.c | |
parent | 0fa73b86ef0797ca4fde5334117ca0b330f08030 (diff) |
vmcore: clean up read_vmcore()
Rewrite part of read_vmcore() that reads objects in vmcore_list in the
same way as part reading ELF headers, by which some duplicated and
redundant codes are removed.
Signed-off-by: HATAYAMA Daisuke <d.hatayama@jp.fujitsu.com>
Acked-by: Vivek Goyal <vgoyal@redhat.com>
Cc: KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com>
Cc: Atsushi Kumagai <kumagai-atsushi@mxc.nes.nec.co.jp>
Cc: Lisa Mitchell <lisa.mitchell@hp.com>
Cc: Zhang Yanfei <zhangyanfei@cn.fujitsu.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'fs/proc/vmcore.c')
-rw-r--r-- | fs/proc/vmcore.c | 68 |
1 files changed, 20 insertions, 48 deletions
diff --git a/fs/proc/vmcore.c b/fs/proc/vmcore.c index 17f7e080d7ff..ab0c92e64411 100644 --- a/fs/proc/vmcore.c +++ b/fs/proc/vmcore.c | |||
@@ -118,27 +118,6 @@ static ssize_t read_from_oldmem(char *buf, size_t count, | |||
118 | return read; | 118 | return read; |
119 | } | 119 | } |
120 | 120 | ||
121 | /* Maps vmcore file offset to respective physical address in memroy. */ | ||
122 | static u64 map_offset_to_paddr(loff_t offset, struct list_head *vc_list, | ||
123 | struct vmcore **m_ptr) | ||
124 | { | ||
125 | struct vmcore *m; | ||
126 | u64 paddr; | ||
127 | |||
128 | list_for_each_entry(m, vc_list, list) { | ||
129 | u64 start, end; | ||
130 | start = m->offset; | ||
131 | end = m->offset + m->size - 1; | ||
132 | if (offset >= start && offset <= end) { | ||
133 | paddr = m->paddr + offset - start; | ||
134 | *m_ptr = m; | ||
135 | return paddr; | ||
136 | } | ||
137 | } | ||
138 | *m_ptr = NULL; | ||
139 | return 0; | ||
140 | } | ||
141 | |||
142 | /* Read from the ELF header and then the crash dump. On error, negative value is | 121 | /* Read from the ELF header and then the crash dump. On error, negative value is |
143 | * returned otherwise number of bytes read are returned. | 122 | * returned otherwise number of bytes read are returned. |
144 | */ | 123 | */ |
@@ -147,8 +126,8 @@ static ssize_t read_vmcore(struct file *file, char __user *buffer, | |||
147 | { | 126 | { |
148 | ssize_t acc = 0, tmp; | 127 | ssize_t acc = 0, tmp; |
149 | size_t tsz; | 128 | size_t tsz; |
150 | u64 start, nr_bytes; | 129 | u64 start; |
151 | struct vmcore *curr_m = NULL; | 130 | struct vmcore *m = NULL; |
152 | 131 | ||
153 | if (buflen == 0 || *fpos >= vmcore_size) | 132 | if (buflen == 0 || *fpos >= vmcore_size) |
154 | return 0; | 133 | return 0; |
@@ -174,33 +153,26 @@ static ssize_t read_vmcore(struct file *file, char __user *buffer, | |||
174 | return acc; | 153 | return acc; |
175 | } | 154 | } |
176 | 155 | ||
177 | start = map_offset_to_paddr(*fpos, &vmcore_list, &curr_m); | 156 | list_for_each_entry(m, &vmcore_list, list) { |
178 | if (!curr_m) | 157 | if (*fpos < m->offset + m->size) { |
179 | return -EINVAL; | 158 | tsz = m->offset + m->size - *fpos; |
180 | 159 | if (buflen < tsz) | |
181 | while (buflen) { | 160 | tsz = buflen; |
182 | tsz = min_t(size_t, buflen, PAGE_SIZE - (start & ~PAGE_MASK)); | 161 | start = m->paddr + *fpos - m->offset; |
183 | 162 | tmp = read_from_oldmem(buffer, tsz, &start, 1); | |
184 | /* Calculate left bytes in current memory segment. */ | 163 | if (tmp < 0) |
185 | nr_bytes = (curr_m->size - (start - curr_m->paddr)); | 164 | return tmp; |
186 | if (tsz > nr_bytes) | 165 | buflen -= tsz; |
187 | tsz = nr_bytes; | 166 | *fpos += tsz; |
188 | 167 | buffer += tsz; | |
189 | tmp = read_from_oldmem(buffer, tsz, &start, 1); | 168 | acc += tsz; |
190 | if (tmp < 0) | 169 | |
191 | return tmp; | 170 | /* leave now if filled buffer already */ |
192 | buflen -= tsz; | 171 | if (buflen == 0) |
193 | *fpos += tsz; | 172 | return acc; |
194 | buffer += tsz; | ||
195 | acc += tsz; | ||
196 | if (start >= (curr_m->paddr + curr_m->size)) { | ||
197 | if (curr_m->list.next == &vmcore_list) | ||
198 | return acc; /*EOF*/ | ||
199 | curr_m = list_entry(curr_m->list.next, | ||
200 | struct vmcore, list); | ||
201 | start = curr_m->paddr; | ||
202 | } | 173 | } |
203 | } | 174 | } |
175 | |||
204 | return acc; | 176 | return acc; |
205 | } | 177 | } |
206 | 178 | ||