linux/fs/seq_file.c
<<
>>
Prefs
   1/*
   2 * linux/fs/seq_file.c
   3 *
   4 * helper functions for making synthetic files from sequences of records.
   5 * initial implementation -- AV, Oct 2001.
   6 */
   7
   8#include <linux/fs.h>
   9#include <linux/export.h>
  10#include <linux/seq_file.h>
  11#include <linux/vmalloc.h>
  12#include <linux/slab.h>
  13#include <linux/cred.h>
  14#ifndef __GENKSYMS__
  15#include <linux/mm.h>
  16#endif
  17#include <linux/printk.h>
  18
  19#include <asm/uaccess.h>
  20#include <asm/page.h>
  21
  22static void seq_set_overflow(struct seq_file *m)
  23{
  24        m->count = m->size;
  25}
  26
  27static void *seq_buf_alloc(unsigned long size)
  28{
  29        return kvmalloc(size, GFP_KERNEL);
  30}
  31
  32static void seq_buf_free(const void *buf)
  33{
  34        if (unlikely(is_vmalloc_addr(buf)))
  35                vfree(buf);
  36        else
  37                kfree(buf);
  38}
  39
  40/**
  41 *      seq_open -      initialize sequential file
  42 *      @file: file we initialize
  43 *      @op: method table describing the sequence
  44 *
  45 *      seq_open() sets @file, associating it with a sequence described
  46 *      by @op.  @op->start() sets the iterator up and returns the first
  47 *      element of sequence. @op->stop() shuts it down.  @op->next()
  48 *      returns the next element of sequence.  @op->show() prints element
  49 *      into the buffer.  In case of error ->start() and ->next() return
  50 *      ERR_PTR(error).  In the end of sequence they return %NULL. ->show()
  51 *      returns 0 in case of success and negative number in case of error.
  52 *      Returning SEQ_SKIP means "discard this element and move on".
  53 */
  54int seq_open(struct file *file, const struct seq_operations *op)
  55{
  56        struct seq_file *p = file->private_data;
  57
  58        if (!p) {
  59                p = kmalloc(sizeof(*p), GFP_KERNEL);
  60                if (!p)
  61                        return -ENOMEM;
  62                file->private_data = p;
  63        }
  64        memset(p, 0, sizeof(*p));
  65        mutex_init(&p->lock);
  66        p->op = op;
  67#ifdef CONFIG_USER_NS
  68        p->user_ns = file->f_cred->user_ns;
  69#endif
  70
  71        // No refcounting: the lifetime of 'p' is constrained
  72        // to the lifetime of the file.
  73        p->file = file;
  74
  75        /*
  76         * Wrappers around seq_open(e.g. swaps_open) need to be
  77         * aware of this. If they set f_version themselves, they
  78         * should call seq_open first and then set f_version.
  79         */
  80        file->f_version = 0;
  81
  82        /*
  83         * seq_files support lseek() and pread().  They do not implement
  84         * write() at all, but we clear FMODE_PWRITE here for historical
  85         * reasons.
  86         *
  87         * If a client of seq_files a) implements file.write() and b) wishes to
  88         * support pwrite() then that client will need to implement its own
  89         * file.open() which calls seq_open() and then sets FMODE_PWRITE.
  90         */
  91        file->f_mode &= ~FMODE_PWRITE;
  92        return 0;
  93}
  94EXPORT_SYMBOL(seq_open);
  95
  96static int traverse(struct seq_file *m, loff_t offset)
  97{
  98        loff_t pos = 0, index;
  99        int error = 0;
 100        void *p;
 101
 102        m->version = 0;
 103        index = 0;
 104        m->count = m->from = 0;
 105        if (!offset) {
 106                m->index = index;
 107                return 0;
 108        }
 109        if (!m->buf) {
 110                m->buf = seq_buf_alloc(m->size = PAGE_SIZE);
 111                if (!m->buf)
 112                        return -ENOMEM;
 113        }
 114        p = m->op->start(m, &index);
 115        while (p) {
 116                error = PTR_ERR(p);
 117                if (IS_ERR(p))
 118                        break;
 119                error = m->op->show(m, p);
 120                if (error < 0)
 121                        break;
 122                if (unlikely(error)) {
 123                        error = 0;
 124                        m->count = 0;
 125                }
 126                if (seq_has_overflowed(m))
 127                        goto Eoverflow;
 128                if (pos + m->count > offset) {
 129                        m->from = offset - pos;
 130                        m->count -= m->from;
 131                        m->index = index;
 132                        break;
 133                }
 134                pos += m->count;
 135                m->count = 0;
 136                if (pos == offset) {
 137                        index++;
 138                        m->index = index;
 139                        break;
 140                }
 141                p = m->op->next(m, p, &index);
 142        }
 143        m->op->stop(m, p);
 144        m->index = index;
 145        return error;
 146
 147Eoverflow:
 148        m->op->stop(m, p);
 149        seq_buf_free(m->buf);
 150        m->count = 0;
 151        m->buf = seq_buf_alloc(m->size <<= 1);
 152        return !m->buf ? -ENOMEM : -EAGAIN;
 153}
 154
 155/**
 156 *      seq_read -      ->read() method for sequential files.
 157 *      @file: the file to read from
 158 *      @buf: the buffer to read to
 159 *      @size: the maximum number of bytes to read
 160 *      @ppos: the current position in the file
 161 *
 162 *      Ready-made ->f_op->read()
 163 */
 164ssize_t seq_read(struct file *file, char __user *buf, size_t size, loff_t *ppos)
 165{
 166        struct seq_file *m = file->private_data;
 167        size_t copied = 0;
 168        loff_t pos;
 169        size_t n;
 170        void *p;
 171        int err = 0;
 172
 173        mutex_lock(&m->lock);
 174
 175        /*
 176         * seq_file->op->..m_start/m_stop/m_next may do special actions
 177         * or optimisations based on the file->f_version, so we want to
 178         * pass the file->f_version to those methods.
 179         *
 180         * seq_file->version is just copy of f_version, and seq_file
 181         * methods can treat it simply as file version.
 182         * It is copied in first and copied out after all operations.
 183         * It is convenient to have it as  part of structure to avoid the
 184         * need of passing another argument to all the seq_file methods.
 185         */
 186        m->version = file->f_version;
 187
 188        /*
 189         * if request is to read from zero offset, reset iterator to first
 190         * record as it might have been already advanced by previous requests
 191         */
 192        if (*ppos == 0)
 193                m->index = 0;
 194
 195        /* Don't assume *ppos is where we left it */
 196        if (unlikely(*ppos != m->read_pos)) {
 197                while ((err = traverse(m, *ppos)) == -EAGAIN)
 198                        ;
 199                if (err) {
 200                        /* With prejudice... */
 201                        m->read_pos = 0;
 202                        m->version = 0;
 203                        m->index = 0;
 204                        m->count = 0;
 205                        goto Done;
 206                } else {
 207                        m->read_pos = *ppos;
 208                }
 209        }
 210
 211        /* grab buffer if we didn't have one */
 212        if (!m->buf) {
 213                m->buf = seq_buf_alloc(m->size = PAGE_SIZE);
 214                if (!m->buf)
 215                        goto Enomem;
 216        }
 217        /* if not empty - flush it first */
 218        if (m->count) {
 219                n = min(m->count, size);
 220                err = copy_to_user(buf, m->buf + m->from, n);
 221                if (err)
 222                        goto Efault;
 223                m->count -= n;
 224                m->from += n;
 225                size -= n;
 226                buf += n;
 227                copied += n;
 228                if (!m->count) {
 229                        m->from = 0;
 230                        m->index++;
 231                }
 232                if (!size)
 233                        goto Done;
 234        }
 235        /* we need at least one record in buffer */
 236        pos = m->index;
 237        p = m->op->start(m, &pos);
 238        while (1) {
 239                err = PTR_ERR(p);
 240                if (!p || IS_ERR(p))
 241                        break;
 242                err = m->op->show(m, p);
 243                if (err < 0)
 244                        break;
 245                if (unlikely(err))
 246                        m->count = 0;
 247                if (unlikely(!m->count)) {
 248                        p = m->op->next(m, p, &pos);
 249                        m->index = pos;
 250                        continue;
 251                }
 252                if (m->count < m->size)
 253                        goto Fill;
 254                m->op->stop(m, p);
 255                seq_buf_free(m->buf);
 256                m->count = 0;
 257                m->buf = seq_buf_alloc(m->size <<= 1);
 258                if (!m->buf)
 259                        goto Enomem;
 260                m->version = 0;
 261                pos = m->index;
 262                p = m->op->start(m, &pos);
 263        }
 264        m->op->stop(m, p);
 265        m->count = 0;
 266        goto Done;
 267Fill:
 268        /* they want more? let's try to get some more */
 269        while (m->count < size) {
 270                size_t offs = m->count;
 271                loff_t next = pos;
 272                p = m->op->next(m, p, &next);
 273                if (!p || IS_ERR(p)) {
 274                        err = PTR_ERR(p);
 275                        break;
 276                }
 277                err = m->op->show(m, p);
 278                if (seq_has_overflowed(m) || err) {
 279                        m->count = offs;
 280                        if (likely(err <= 0))
 281                                break;
 282                }
 283                pos = next;
 284        }
 285        m->op->stop(m, p);
 286        n = min(m->count, size);
 287        err = copy_to_user(buf, m->buf, n);
 288        if (err)
 289                goto Efault;
 290        copied += n;
 291        m->count -= n;
 292        if (m->count)
 293                m->from = n;
 294        else
 295                pos++;
 296        m->index = pos;
 297Done:
 298        if (!copied)
 299                copied = err;
 300        else {
 301                *ppos += copied;
 302                m->read_pos += copied;
 303        }
 304        file->f_version = m->version;
 305        mutex_unlock(&m->lock);
 306        return copied;
 307Enomem:
 308        err = -ENOMEM;
 309        goto Done;
 310Efault:
 311        err = -EFAULT;
 312        goto Done;
 313}
 314EXPORT_SYMBOL(seq_read);
 315
 316/**
 317 *      seq_lseek -     ->llseek() method for sequential files.
 318 *      @file: the file in question
 319 *      @offset: new position
 320 *      @whence: 0 for absolute, 1 for relative position
 321 *
 322 *      Ready-made ->f_op->llseek()
 323 */
 324loff_t seq_lseek(struct file *file, loff_t offset, int whence)
 325{
 326        struct seq_file *m = file->private_data;
 327        loff_t retval = -EINVAL;
 328
 329        mutex_lock(&m->lock);
 330        m->version = file->f_version;
 331        switch (whence) {
 332        case SEEK_CUR:
 333                offset += file->f_pos;
 334        case SEEK_SET:
 335                if (offset < 0)
 336                        break;
 337                retval = offset;
 338                if (offset != m->read_pos) {
 339                        while ((retval = traverse(m, offset)) == -EAGAIN)
 340                                ;
 341                        if (retval) {
 342                                /* with extreme prejudice... */
 343                                file->f_pos = 0;
 344                                m->read_pos = 0;
 345                                m->version = 0;
 346                                m->index = 0;
 347                                m->count = 0;
 348                        } else {
 349                                m->read_pos = offset;
 350                                retval = file->f_pos = offset;
 351                        }
 352                } else {
 353                        file->f_pos = offset;
 354                }
 355        }
 356        file->f_version = m->version;
 357        mutex_unlock(&m->lock);
 358        return retval;
 359}
 360EXPORT_SYMBOL(seq_lseek);
 361
 362/**
 363 *      seq_release -   free the structures associated with sequential file.
 364 *      @file: file in question
 365 *      @inode: its inode
 366 *
 367 *      Frees the structures associated with sequential file; can be used
 368 *      as ->f_op->release() if you don't have private data to destroy.
 369 */
 370int seq_release(struct inode *inode, struct file *file)
 371{
 372        struct seq_file *m = file->private_data;
 373        seq_buf_free(m->buf);
 374        kfree(m);
 375        return 0;
 376}
 377EXPORT_SYMBOL(seq_release);
 378
 379/**
 380 *      seq_escape -    print string into buffer, escaping some characters
 381 *      @m:     target buffer
 382 *      @s:     string
 383 *      @esc:   set of characters that need escaping
 384 *
 385 *      Puts string into buffer, replacing each occurrence of character from
 386 *      @esc with usual octal escape.  Returns 0 in case of success, -1 - in
 387 *      case of overflow.
 388 */
 389int seq_escape(struct seq_file *m, const char *s, const char *esc)
 390{
 391        char *end = m->buf + m->size;
 392        char *p;
 393        char c;
 394
 395        for (p = m->buf + m->count; (c = *s) != '\0' && p < end; s++) {
 396                if (!strchr(esc, c)) {
 397                        *p++ = c;
 398                        continue;
 399                }
 400                if (p + 3 < end) {
 401                        *p++ = '\\';
 402                        *p++ = '0' + ((c & 0300) >> 6);
 403                        *p++ = '0' + ((c & 070) >> 3);
 404                        *p++ = '0' + (c & 07);
 405                        continue;
 406                }
 407                seq_set_overflow(m);
 408                return -1;
 409        }
 410        m->count = p - m->buf;
 411        return 0;
 412}
 413EXPORT_SYMBOL(seq_escape);
 414
 415int seq_vprintf(struct seq_file *m, const char *f, va_list args)
 416{
 417        int len;
 418
 419        if (m->count < m->size) {
 420                len = vsnprintf(m->buf + m->count, m->size - m->count, f, args);
 421                if (m->count + len < m->size) {
 422                        m->count += len;
 423                        return 0;
 424                }
 425        }
 426        seq_set_overflow(m);
 427        return -1;
 428}
 429EXPORT_SYMBOL(seq_vprintf);
 430
 431int seq_printf(struct seq_file *m, const char *f, ...)
 432{
 433        int ret;
 434        va_list args;
 435
 436        va_start(args, f);
 437        ret = seq_vprintf(m, f, args);
 438        va_end(args);
 439
 440        return ret;
 441}
 442EXPORT_SYMBOL(seq_printf);
 443
 444/**
 445 *      mangle_path -   mangle and copy path to buffer beginning
 446 *      @s: buffer start
 447 *      @p: beginning of path in above buffer
 448 *      @esc: set of characters that need escaping
 449 *
 450 *      Copy the path from @p to @s, replacing each occurrence of character from
 451 *      @esc with usual octal escape.
 452 *      Returns pointer past last written character in @s, or NULL in case of
 453 *      failure.
 454 */
 455char *mangle_path(char *s, const char *p, const char *esc)
 456{
 457        while (s <= p) {
 458                char c = *p++;
 459                if (!c) {
 460                        return s;
 461                } else if (!strchr(esc, c)) {
 462                        *s++ = c;
 463                } else if (s + 4 > p) {
 464                        break;
 465                } else {
 466                        *s++ = '\\';
 467                        *s++ = '0' + ((c & 0300) >> 6);
 468                        *s++ = '0' + ((c & 070) >> 3);
 469                        *s++ = '0' + (c & 07);
 470                }
 471        }
 472        return NULL;
 473}
 474EXPORT_SYMBOL(mangle_path);
 475
 476/**
 477 * seq_path - seq_file interface to print a pathname
 478 * @m: the seq_file handle
 479 * @path: the struct path to print
 480 * @esc: set of characters to escape in the output
 481 *
 482 * return the absolute path of 'path', as represented by the
 483 * dentry / mnt pair in the path parameter.
 484 */
 485int seq_path(struct seq_file *m, const struct path *path, const char *esc)
 486{
 487        char *buf;
 488        size_t size = seq_get_buf(m, &buf);
 489        int res = -1;
 490
 491        if (size) {
 492                char *p = d_path(path, buf, size);
 493                if (!IS_ERR(p)) {
 494                        char *end = mangle_path(buf, p, esc);
 495                        if (end)
 496                                res = end - buf;
 497                }
 498        }
 499        seq_commit(m, res);
 500
 501        return res;
 502}
 503EXPORT_SYMBOL(seq_path);
 504
 505/*
 506 * Same as seq_path, but relative to supplied root.
 507 */
 508int seq_path_root(struct seq_file *m, const struct path *path,
 509                  const struct path *root, const char *esc)
 510{
 511        char *buf;
 512        size_t size = seq_get_buf(m, &buf);
 513        int res = -ENAMETOOLONG;
 514
 515        if (size) {
 516                char *p;
 517
 518                p = __d_path(path, root, buf, size);
 519                if (!p)
 520                        return SEQ_SKIP;
 521                res = PTR_ERR(p);
 522                if (!IS_ERR(p)) {
 523                        char *end = mangle_path(buf, p, esc);
 524                        if (end)
 525                                res = end - buf;
 526                        else
 527                                res = -ENAMETOOLONG;
 528                }
 529        }
 530        seq_commit(m, res);
 531
 532        return res < 0 && res != -ENAMETOOLONG ? res : 0;
 533}
 534
 535/*
 536 * returns the path of the 'dentry' from the root of its filesystem.
 537 */
 538int seq_dentry(struct seq_file *m, struct dentry *dentry, const char *esc)
 539{
 540        char *buf;
 541        size_t size = seq_get_buf(m, &buf);
 542        int res = -1;
 543
 544        if (size) {
 545                char *p = dentry_path(dentry, buf, size);
 546                if (!IS_ERR(p)) {
 547                        char *end = mangle_path(buf, p, esc);
 548                        if (end)
 549                                res = end - buf;
 550                }
 551        }
 552        seq_commit(m, res);
 553
 554        return res;
 555}
 556EXPORT_SYMBOL(seq_dentry);
 557
 558int seq_bitmap(struct seq_file *m, const unsigned long *bits,
 559                                   unsigned int nr_bits)
 560{
 561        if (m->count < m->size) {
 562                int len = bitmap_scnprintf(m->buf + m->count,
 563                                m->size - m->count, bits, nr_bits);
 564                if (m->count + len < m->size) {
 565                        m->count += len;
 566                        return 0;
 567                }
 568        }
 569        seq_set_overflow(m);
 570        return -1;
 571}
 572EXPORT_SYMBOL(seq_bitmap);
 573
 574int seq_bitmap_list(struct seq_file *m, const unsigned long *bits,
 575                unsigned int nr_bits)
 576{
 577        if (m->count < m->size) {
 578                int len = bitmap_scnlistprintf(m->buf + m->count,
 579                                m->size - m->count, bits, nr_bits);
 580                if (m->count + len < m->size) {
 581                        m->count += len;
 582                        return 0;
 583                }
 584        }
 585        seq_set_overflow(m);
 586        return -1;
 587}
 588EXPORT_SYMBOL(seq_bitmap_list);
 589
 590static void *single_start(struct seq_file *p, loff_t *pos)
 591{
 592        return NULL + (*pos == 0);
 593}
 594
 595static void *single_next(struct seq_file *p, void *v, loff_t *pos)
 596{
 597        ++*pos;
 598        return NULL;
 599}
 600
 601static void single_stop(struct seq_file *p, void *v)
 602{
 603}
 604
 605int single_open(struct file *file, int (*show)(struct seq_file *, void *),
 606                void *data)
 607{
 608        struct seq_operations *op = kmalloc(sizeof(*op), GFP_KERNEL);
 609        int res = -ENOMEM;
 610
 611        if (op) {
 612                op->start = single_start;
 613                op->next = single_next;
 614                op->stop = single_stop;
 615                op->show = show;
 616                res = seq_open(file, op);
 617                if (!res)
 618                        ((struct seq_file *)file->private_data)->private = data;
 619                else
 620                        kfree(op);
 621        }
 622        return res;
 623}
 624EXPORT_SYMBOL(single_open);
 625
 626int single_open_size(struct file *file, int (*show)(struct seq_file *, void *),
 627                void *data, size_t size)
 628{
 629        char *buf = seq_buf_alloc(size);
 630        int ret;
 631        if (!buf)
 632                return -ENOMEM;
 633        ret = single_open(file, show, data);
 634        if (ret) {
 635                seq_buf_free(buf);
 636                return ret;
 637        }
 638        ((struct seq_file *)file->private_data)->buf = buf;
 639        ((struct seq_file *)file->private_data)->size = size;
 640        return 0;
 641}
 642EXPORT_SYMBOL(single_open_size);
 643
 644int single_release(struct inode *inode, struct file *file)
 645{
 646        const struct seq_operations *op = ((struct seq_file *)file->private_data)->op;
 647        int res = seq_release(inode, file);
 648        kfree(op);
 649        return res;
 650}
 651EXPORT_SYMBOL(single_release);
 652
 653int seq_release_private(struct inode *inode, struct file *file)
 654{
 655        struct seq_file *seq = file->private_data;
 656
 657        kfree(seq->private);
 658        seq->private = NULL;
 659        return seq_release(inode, file);
 660}
 661EXPORT_SYMBOL(seq_release_private);
 662
 663void *__seq_open_private(struct file *f, const struct seq_operations *ops,
 664                int psize)
 665{
 666        int rc;
 667        void *private;
 668        struct seq_file *seq;
 669
 670        private = kzalloc(psize, GFP_KERNEL);
 671        if (private == NULL)
 672                goto out;
 673
 674        rc = seq_open(f, ops);
 675        if (rc < 0)
 676                goto out_free;
 677
 678        seq = f->private_data;
 679        seq->private = private;
 680        return private;
 681
 682out_free:
 683        kfree(private);
 684out:
 685        return NULL;
 686}
 687EXPORT_SYMBOL(__seq_open_private);
 688
 689int seq_open_private(struct file *filp, const struct seq_operations *ops,
 690                int psize)
 691{
 692        return __seq_open_private(filp, ops, psize) ? 0 : -ENOMEM;
 693}
 694EXPORT_SYMBOL(seq_open_private);
 695
 696int seq_putc(struct seq_file *m, char c)
 697{
 698        if (m->count < m->size) {
 699                m->buf[m->count++] = c;
 700                return 0;
 701        }
 702        return -1;
 703}
 704EXPORT_SYMBOL(seq_putc);
 705
 706int seq_puts(struct seq_file *m, const char *s)
 707{
 708        int len = strlen(s);
 709        if (m->count + len < m->size) {
 710                memcpy(m->buf + m->count, s, len);
 711                m->count += len;
 712                return 0;
 713        }
 714        seq_set_overflow(m);
 715        return -1;
 716}
 717EXPORT_SYMBOL(seq_puts);
 718
 719/*
 720 * A helper routine for putting decimal numbers without rich format of printf().
 721 * only 'unsigned long long' is supported.
 722 * This routine will put one byte delimiter + number into seq_file.
 723 * This routine is very quick when you show lots of numbers.
 724 * In usual cases, it will be better to use seq_printf(). It's easier to read.
 725 */
 726int seq_put_decimal_ull(struct seq_file *m, char delimiter,
 727                        unsigned long long num)
 728{
 729        int len;
 730
 731        if (m->count + 2 >= m->size) /* we'll write 2 bytes at least */
 732                goto overflow;
 733
 734        if (delimiter)
 735                m->buf[m->count++] = delimiter;
 736
 737        if (num < 10) {
 738                m->buf[m->count++] = num + '0';
 739                return 0;
 740        }
 741
 742        len = num_to_str(m->buf + m->count, m->size - m->count, num);
 743        if (!len)
 744                goto overflow;
 745        m->count += len;
 746        return 0;
 747overflow:
 748        seq_set_overflow(m);
 749        return -1;
 750}
 751EXPORT_SYMBOL(seq_put_decimal_ull);
 752
 753int seq_put_decimal_ll(struct seq_file *m, char delimiter,
 754                        long long num)
 755{
 756        if (num < 0) {
 757                if (m->count + 3 >= m->size) {
 758                        seq_set_overflow(m);
 759                        return -1;
 760                }
 761                if (delimiter)
 762                        m->buf[m->count++] = delimiter;
 763                num = -num;
 764                delimiter = '-';
 765        }
 766        return seq_put_decimal_ull(m, delimiter, num);
 767
 768}
 769EXPORT_SYMBOL(seq_put_decimal_ll);
 770
 771/**
 772 * seq_write - write arbitrary data to buffer
 773 * @seq: seq_file identifying the buffer to which data should be written
 774 * @data: data address
 775 * @len: number of bytes
 776 *
 777 * Return 0 on success, non-zero otherwise.
 778 */
 779int seq_write(struct seq_file *seq, const void *data, size_t len)
 780{
 781        if (seq->count + len < seq->size) {
 782                memcpy(seq->buf + seq->count, data, len);
 783                seq->count += len;
 784                return 0;
 785        }
 786        seq_set_overflow(seq);
 787        return -1;
 788}
 789EXPORT_SYMBOL(seq_write);
 790
 791/* A complete analogue of print_hex_dump() */
 792void seq_hex_dump(struct seq_file *m, const char *prefix_str, int prefix_type,
 793                  int rowsize, int groupsize, const void *buf, size_t len,
 794                  bool ascii)
 795{
 796        const u8 *ptr = buf;
 797        int i, linelen, remaining = len;
 798        int ret;
 799
 800        if (rowsize != 16 && rowsize != 32)
 801                rowsize = 16;
 802
 803        for (i = 0; i < len && !seq_has_overflowed(m); i += rowsize) {
 804                linelen = min(remaining, rowsize);
 805                remaining -= rowsize;
 806
 807                switch (prefix_type) {
 808                case DUMP_PREFIX_ADDRESS:
 809                        seq_printf(m, "%s%p: ", prefix_str, ptr + i);
 810                        break;
 811                case DUMP_PREFIX_OFFSET:
 812                        seq_printf(m, "%s%.8x: ", prefix_str, i);
 813                        break;
 814                default:
 815                        seq_printf(m, "%s", prefix_str);
 816                        break;
 817                }
 818
 819                ret = hex_dump_to_buffer(ptr + i, linelen, rowsize, groupsize,
 820                                         m->buf + m->count, m->size - m->count,
 821                                         ascii);
 822                if (ret >= m->size - m->count) {
 823                        seq_set_overflow(m);
 824                } else {
 825                        m->count += ret;
 826                        seq_putc(m, '\n');
 827                }
 828        }
 829}
 830EXPORT_SYMBOL(seq_hex_dump);
 831
 832struct list_head *seq_list_start(struct list_head *head, loff_t pos)
 833{
 834        struct list_head *lh;
 835
 836        list_for_each(lh, head)
 837                if (pos-- == 0)
 838                        return lh;
 839
 840        return NULL;
 841}
 842EXPORT_SYMBOL(seq_list_start);
 843
 844struct list_head *seq_list_start_head(struct list_head *head, loff_t pos)
 845{
 846        if (!pos)
 847                return head;
 848
 849        return seq_list_start(head, pos - 1);
 850}
 851EXPORT_SYMBOL(seq_list_start_head);
 852
 853struct list_head *seq_list_next(void *v, struct list_head *head, loff_t *ppos)
 854{
 855        struct list_head *lh;
 856
 857        lh = ((struct list_head *)v)->next;
 858        ++*ppos;
 859        return lh == head ? NULL : lh;
 860}
 861EXPORT_SYMBOL(seq_list_next);
 862
 863/**
 864 * seq_hlist_start - start an iteration of a hlist
 865 * @head: the head of the hlist
 866 * @pos:  the start position of the sequence
 867 *
 868 * Called at seq_file->op->start().
 869 */
 870struct hlist_node *seq_hlist_start(struct hlist_head *head, loff_t pos)
 871{
 872        struct hlist_node *node;
 873
 874        hlist_for_each(node, head)
 875                if (pos-- == 0)
 876                        return node;
 877        return NULL;
 878}
 879EXPORT_SYMBOL(seq_hlist_start);
 880
 881/**
 882 * seq_hlist_start_head - start an iteration of a hlist
 883 * @head: the head of the hlist
 884 * @pos:  the start position of the sequence
 885 *
 886 * Called at seq_file->op->start(). Call this function if you want to
 887 * print a header at the top of the output.
 888 */
 889struct hlist_node *seq_hlist_start_head(struct hlist_head *head, loff_t pos)
 890{
 891        if (!pos)
 892                return SEQ_START_TOKEN;
 893
 894        return seq_hlist_start(head, pos - 1);
 895}
 896EXPORT_SYMBOL(seq_hlist_start_head);
 897
 898/**
 899 * seq_hlist_next - move to the next position of the hlist
 900 * @v:    the current iterator
 901 * @head: the head of the hlist
 902 * @ppos: the current position
 903 *
 904 * Called at seq_file->op->next().
 905 */
 906struct hlist_node *seq_hlist_next(void *v, struct hlist_head *head,
 907                                  loff_t *ppos)
 908{
 909        struct hlist_node *node = v;
 910
 911        ++*ppos;
 912        if (v == SEQ_START_TOKEN)
 913                return head->first;
 914        else
 915                return node->next;
 916}
 917EXPORT_SYMBOL(seq_hlist_next);
 918
 919/**
 920 * seq_hlist_start_rcu - start an iteration of a hlist protected by RCU
 921 * @head: the head of the hlist
 922 * @pos:  the start position of the sequence
 923 *
 924 * Called at seq_file->op->start().
 925 *
 926 * This list-traversal primitive may safely run concurrently with
 927 * the _rcu list-mutation primitives such as hlist_add_head_rcu()
 928 * as long as the traversal is guarded by rcu_read_lock().
 929 */
 930struct hlist_node *seq_hlist_start_rcu(struct hlist_head *head,
 931                                       loff_t pos)
 932{
 933        struct hlist_node *node;
 934
 935        __hlist_for_each_rcu(node, head)
 936                if (pos-- == 0)
 937                        return node;
 938        return NULL;
 939}
 940EXPORT_SYMBOL(seq_hlist_start_rcu);
 941
 942/**
 943 * seq_hlist_start_head_rcu - start an iteration of a hlist protected by RCU
 944 * @head: the head of the hlist
 945 * @pos:  the start position of the sequence
 946 *
 947 * Called at seq_file->op->start(). Call this function if you want to
 948 * print a header at the top of the output.
 949 *
 950 * This list-traversal primitive may safely run concurrently with
 951 * the _rcu list-mutation primitives such as hlist_add_head_rcu()
 952 * as long as the traversal is guarded by rcu_read_lock().
 953 */
 954struct hlist_node *seq_hlist_start_head_rcu(struct hlist_head *head,
 955                                            loff_t pos)
 956{
 957        if (!pos)
 958                return SEQ_START_TOKEN;
 959
 960        return seq_hlist_start_rcu(head, pos - 1);
 961}
 962EXPORT_SYMBOL(seq_hlist_start_head_rcu);
 963
 964/**
 965 * seq_hlist_next_rcu - move to the next position of the hlist protected by RCU
 966 * @v:    the current iterator
 967 * @head: the head of the hlist
 968 * @ppos: the current position
 969 *
 970 * Called at seq_file->op->next().
 971 *
 972 * This list-traversal primitive may safely run concurrently with
 973 * the _rcu list-mutation primitives such as hlist_add_head_rcu()
 974 * as long as the traversal is guarded by rcu_read_lock().
 975 */
 976struct hlist_node *seq_hlist_next_rcu(void *v,
 977                                      struct hlist_head *head,
 978                                      loff_t *ppos)
 979{
 980        struct hlist_node *node = v;
 981
 982        ++*ppos;
 983        if (v == SEQ_START_TOKEN)
 984                return rcu_dereference(head->first);
 985        else
 986                return rcu_dereference(node->next);
 987}
 988EXPORT_SYMBOL(seq_hlist_next_rcu);
 989
 990/**
 991 * seq_hlist_start_precpu - start an iteration of a percpu hlist array
 992 * @head: pointer to percpu array of struct hlist_heads
 993 * @cpu:  pointer to cpu "cursor"
 994 * @pos:  start position of sequence
 995 *
 996 * Called at seq_file->op->start().
 997 */
 998struct hlist_node *
 999seq_hlist_start_percpu(struct hlist_head __percpu *head, int *cpu, loff_t pos)
1000{
1001        struct hlist_node *node;
1002
1003        for_each_possible_cpu(*cpu) {
1004                hlist_for_each(node, per_cpu_ptr(head, *cpu)) {
1005                        if (pos-- == 0)
1006                                return node;
1007                }
1008        }
1009        return NULL;
1010}
1011EXPORT_SYMBOL(seq_hlist_start_percpu);
1012
1013/**
1014 * seq_hlist_next_percpu - move to the next position of the percpu hlist array
1015 * @v:    pointer to current hlist_node
1016 * @head: pointer to percpu array of struct hlist_heads
1017 * @cpu:  pointer to cpu "cursor"
1018 * @pos:  start position of sequence
1019 *
1020 * Called at seq_file->op->next().
1021 */
1022struct hlist_node *
1023seq_hlist_next_percpu(void *v, struct hlist_head __percpu *head,
1024                        int *cpu, loff_t *pos)
1025{
1026        struct hlist_node *node = v;
1027
1028        ++*pos;
1029
1030        if (node->next)
1031                return node->next;
1032
1033        for (*cpu = cpumask_next(*cpu, cpu_possible_mask); *cpu < nr_cpu_ids;
1034             *cpu = cpumask_next(*cpu, cpu_possible_mask)) {
1035                struct hlist_head *bucket = per_cpu_ptr(head, *cpu);
1036
1037                if (!hlist_empty(bucket))
1038                        return bucket->first;
1039        }
1040        return NULL;
1041}
1042EXPORT_SYMBOL(seq_hlist_next_percpu);
1043