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