aboutsummaryrefslogtreecommitdiffstats
path: root/fs/seq_file.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/seq_file.c')
-rw-r--r--fs/seq_file.c52
1 files changed, 45 insertions, 7 deletions
diff --git a/fs/seq_file.c b/fs/seq_file.c
index 0ac22af7afe5..bbb19be260ce 100644
--- a/fs/seq_file.c
+++ b/fs/seq_file.c
@@ -177,21 +177,23 @@ EXPORT_SYMBOL(seq_read);
177 177
178static int traverse(struct seq_file *m, loff_t offset) 178static int traverse(struct seq_file *m, loff_t offset)
179{ 179{
180 loff_t pos = 0; 180 loff_t pos = 0, index;
181 int error = 0; 181 int error = 0;
182 void *p; 182 void *p;
183 183
184 m->version = 0; 184 m->version = 0;
185 m->index = 0; 185 index = 0;
186 m->count = m->from = 0; 186 m->count = m->from = 0;
187 if (!offset) 187 if (!offset) {
188 m->index = index;
188 return 0; 189 return 0;
190 }
189 if (!m->buf) { 191 if (!m->buf) {
190 m->buf = kmalloc(m->size = PAGE_SIZE, GFP_KERNEL); 192 m->buf = kmalloc(m->size = PAGE_SIZE, GFP_KERNEL);
191 if (!m->buf) 193 if (!m->buf)
192 return -ENOMEM; 194 return -ENOMEM;
193 } 195 }
194 p = m->op->start(m, &m->index); 196 p = m->op->start(m, &index);
195 while (p) { 197 while (p) {
196 error = PTR_ERR(p); 198 error = PTR_ERR(p);
197 if (IS_ERR(p)) 199 if (IS_ERR(p))
@@ -204,15 +206,17 @@ static int traverse(struct seq_file *m, loff_t offset)
204 if (pos + m->count > offset) { 206 if (pos + m->count > offset) {
205 m->from = offset - pos; 207 m->from = offset - pos;
206 m->count -= m->from; 208 m->count -= m->from;
209 m->index = index;
207 break; 210 break;
208 } 211 }
209 pos += m->count; 212 pos += m->count;
210 m->count = 0; 213 m->count = 0;
211 if (pos == offset) { 214 if (pos == offset) {
212 m->index++; 215 index++;
216 m->index = index;
213 break; 217 break;
214 } 218 }
215 p = m->op->next(m, p, &m->index); 219 p = m->op->next(m, p, &index);
216 } 220 }
217 m->op->stop(m, p); 221 m->op->stop(m, p);
218 return error; 222 return error;
@@ -260,8 +264,8 @@ loff_t seq_lseek(struct file *file, loff_t offset, int origin)
260 } 264 }
261 } 265 }
262 } 266 }
263 mutex_unlock(&m->lock);
264 file->f_version = m->version; 267 file->f_version = m->version;
268 mutex_unlock(&m->lock);
265 return retval; 269 return retval;
266} 270}
267EXPORT_SYMBOL(seq_lseek); 271EXPORT_SYMBOL(seq_lseek);
@@ -447,3 +451,37 @@ int seq_puts(struct seq_file *m, const char *s)
447 return -1; 451 return -1;
448} 452}
449EXPORT_SYMBOL(seq_puts); 453EXPORT_SYMBOL(seq_puts);
454
455struct list_head *seq_list_start(struct list_head *head, loff_t pos)
456{
457 struct list_head *lh;
458
459 list_for_each(lh, head)
460 if (pos-- == 0)
461 return lh;
462
463 return NULL;
464}
465
466EXPORT_SYMBOL(seq_list_start);
467
468struct list_head *seq_list_start_head(struct list_head *head, loff_t pos)
469{
470 if (!pos)
471 return head;
472
473 return seq_list_start(head, pos - 1);
474}
475
476EXPORT_SYMBOL(seq_list_start_head);
477
478struct list_head *seq_list_next(void *v, struct list_head *head, loff_t *ppos)
479{
480 struct list_head *lh;
481
482 lh = ((struct list_head *)v)->next;
483 ++*ppos;
484 return lh == head ? NULL : lh;
485}
486
487EXPORT_SYMBOL(seq_list_next);