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