Back to home page

LXR

 
 

    


0001 /*
0002  * linux/fs/seq_file.c
0003  *
0004  * helper functions for making synthetic files from sequences of records.
0005  * initial implementation -- AV, Oct 2001.
0006  */
0007 
0008 #include <linux/fs.h>
0009 #include <linux/export.h>
0010 #include <linux/seq_file.h>
0011 #include <linux/vmalloc.h>
0012 #include <linux/slab.h>
0013 #include <linux/cred.h>
0014 #include <linux/mm.h>
0015 #include <linux/printk.h>
0016 #include <linux/string_helpers.h>
0017 
0018 #include <linux/uaccess.h>
0019 #include <asm/page.h>
0020 
0021 static void seq_set_overflow(struct seq_file *m)
0022 {
0023     m->count = m->size;
0024 }
0025 
0026 static void *seq_buf_alloc(unsigned long size)
0027 {
0028     void *buf;
0029     gfp_t gfp = GFP_KERNEL;
0030 
0031     /*
0032      * For high order allocations, use __GFP_NORETRY to avoid oom-killing -
0033      * it's better to fall back to vmalloc() than to kill things.  For small
0034      * allocations, just use GFP_KERNEL which will oom kill, thus no need
0035      * for vmalloc fallback.
0036      */
0037     if (size > PAGE_SIZE)
0038         gfp |= __GFP_NORETRY | __GFP_NOWARN;
0039     buf = kmalloc(size, gfp);
0040     if (!buf && size > PAGE_SIZE)
0041         buf = vmalloc(size);
0042     return buf;
0043 }
0044 
0045 /**
0046  *  seq_open -  initialize sequential file
0047  *  @file: file we initialize
0048  *  @op: method table describing the sequence
0049  *
0050  *  seq_open() sets @file, associating it with a sequence described
0051  *  by @op.  @op->start() sets the iterator up and returns the first
0052  *  element of sequence. @op->stop() shuts it down.  @op->next()
0053  *  returns the next element of sequence.  @op->show() prints element
0054  *  into the buffer.  In case of error ->start() and ->next() return
0055  *  ERR_PTR(error).  In the end of sequence they return %NULL. ->show()
0056  *  returns 0 in case of success and negative number in case of error.
0057  *  Returning SEQ_SKIP means "discard this element and move on".
0058  *  Note: seq_open() will allocate a struct seq_file and store its
0059  *  pointer in @file->private_data. This pointer should not be modified.
0060  */
0061 int seq_open(struct file *file, const struct seq_operations *op)
0062 {
0063     struct seq_file *p;
0064 
0065     WARN_ON(file->private_data);
0066 
0067     p = kzalloc(sizeof(*p), GFP_KERNEL);
0068     if (!p)
0069         return -ENOMEM;
0070 
0071     file->private_data = p;
0072 
0073     mutex_init(&p->lock);
0074     p->op = op;
0075 
0076     // No refcounting: the lifetime of 'p' is constrained
0077     // to the lifetime of the file.
0078     p->file = file;
0079 
0080     /*
0081      * Wrappers around seq_open(e.g. swaps_open) need to be
0082      * aware of this. If they set f_version themselves, they
0083      * should call seq_open first and then set f_version.
0084      */
0085     file->f_version = 0;
0086 
0087     /*
0088      * seq_files support lseek() and pread().  They do not implement
0089      * write() at all, but we clear FMODE_PWRITE here for historical
0090      * reasons.
0091      *
0092      * If a client of seq_files a) implements file.write() and b) wishes to
0093      * support pwrite() then that client will need to implement its own
0094      * file.open() which calls seq_open() and then sets FMODE_PWRITE.
0095      */
0096     file->f_mode &= ~FMODE_PWRITE;
0097     return 0;
0098 }
0099 EXPORT_SYMBOL(seq_open);
0100 
0101 static int traverse(struct seq_file *m, loff_t offset)
0102 {
0103     loff_t pos = 0, index;
0104     int error = 0;
0105     void *p;
0106 
0107     m->version = 0;
0108     index = 0;
0109     m->count = m->from = 0;
0110     if (!offset) {
0111         m->index = index;
0112         return 0;
0113     }
0114     if (!m->buf) {
0115         m->buf = seq_buf_alloc(m->size = PAGE_SIZE);
0116         if (!m->buf)
0117             return -ENOMEM;
0118     }
0119     p = m->op->start(m, &index);
0120     while (p) {
0121         error = PTR_ERR(p);
0122         if (IS_ERR(p))
0123             break;
0124         error = m->op->show(m, p);
0125         if (error < 0)
0126             break;
0127         if (unlikely(error)) {
0128             error = 0;
0129             m->count = 0;
0130         }
0131         if (seq_has_overflowed(m))
0132             goto Eoverflow;
0133         if (pos + m->count > offset) {
0134             m->from = offset - pos;
0135             m->count -= m->from;
0136             m->index = index;
0137             break;
0138         }
0139         pos += m->count;
0140         m->count = 0;
0141         if (pos == offset) {
0142             index++;
0143             m->index = index;
0144             break;
0145         }
0146         p = m->op->next(m, p, &index);
0147     }
0148     m->op->stop(m, p);
0149     m->index = index;
0150     return error;
0151 
0152 Eoverflow:
0153     m->op->stop(m, p);
0154     kvfree(m->buf);
0155     m->count = 0;
0156     m->buf = seq_buf_alloc(m->size <<= 1);
0157     return !m->buf ? -ENOMEM : -EAGAIN;
0158 }
0159 
0160 /**
0161  *  seq_read -  ->read() method for sequential files.
0162  *  @file: the file to read from
0163  *  @buf: the buffer to read to
0164  *  @size: the maximum number of bytes to read
0165  *  @ppos: the current position in the file
0166  *
0167  *  Ready-made ->f_op->read()
0168  */
0169 ssize_t seq_read(struct file *file, char __user *buf, size_t size, loff_t *ppos)
0170 {
0171     struct seq_file *m = file->private_data;
0172     size_t copied = 0;
0173     loff_t pos;
0174     size_t n;
0175     void *p;
0176     int err = 0;
0177 
0178     mutex_lock(&m->lock);
0179 
0180     /*
0181      * seq_file->op->..m_start/m_stop/m_next may do special actions
0182      * or optimisations based on the file->f_version, so we want to
0183      * pass the file->f_version to those methods.
0184      *
0185      * seq_file->version is just copy of f_version, and seq_file
0186      * methods can treat it simply as file version.
0187      * It is copied in first and copied out after all operations.
0188      * It is convenient to have it as  part of structure to avoid the
0189      * need of passing another argument to all the seq_file methods.
0190      */
0191     m->version = file->f_version;
0192 
0193     /*
0194      * if request is to read from zero offset, reset iterator to first
0195      * record as it might have been already advanced by previous requests
0196      */
0197     if (*ppos == 0)
0198         m->index = 0;
0199 
0200     /* Don't assume *ppos is where we left it */
0201     if (unlikely(*ppos != m->read_pos)) {
0202         while ((err = traverse(m, *ppos)) == -EAGAIN)
0203             ;
0204         if (err) {
0205             /* With prejudice... */
0206             m->read_pos = 0;
0207             m->version = 0;
0208             m->index = 0;
0209             m->count = 0;
0210             goto Done;
0211         } else {
0212             m->read_pos = *ppos;
0213         }
0214     }
0215 
0216     /* grab buffer if we didn't have one */
0217     if (!m->buf) {
0218         m->buf = seq_buf_alloc(m->size = PAGE_SIZE);
0219         if (!m->buf)
0220             goto Enomem;
0221     }
0222     /* if not empty - flush it first */
0223     if (m->count) {
0224         n = min(m->count, size);
0225         err = copy_to_user(buf, m->buf + m->from, n);
0226         if (err)
0227             goto Efault;
0228         m->count -= n;
0229         m->from += n;
0230         size -= n;
0231         buf += n;
0232         copied += n;
0233         if (!m->count) {
0234             m->from = 0;
0235             m->index++;
0236         }
0237         if (!size)
0238             goto Done;
0239     }
0240     /* we need at least one record in buffer */
0241     pos = m->index;
0242     p = m->op->start(m, &pos);
0243     while (1) {
0244         err = PTR_ERR(p);
0245         if (!p || IS_ERR(p))
0246             break;
0247         err = m->op->show(m, p);
0248         if (err < 0)
0249             break;
0250         if (unlikely(err))
0251             m->count = 0;
0252         if (unlikely(!m->count)) {
0253             p = m->op->next(m, p, &pos);
0254             m->index = pos;
0255             continue;
0256         }
0257         if (m->count < m->size)
0258             goto Fill;
0259         m->op->stop(m, p);
0260         kvfree(m->buf);
0261         m->count = 0;
0262         m->buf = seq_buf_alloc(m->size <<= 1);
0263         if (!m->buf)
0264             goto Enomem;
0265         m->version = 0;
0266         pos = m->index;
0267         p = m->op->start(m, &pos);
0268     }
0269     m->op->stop(m, p);
0270     m->count = 0;
0271     goto Done;
0272 Fill:
0273     /* they want more? let's try to get some more */
0274     while (m->count < size) {
0275         size_t offs = m->count;
0276         loff_t next = pos;
0277         p = m->op->next(m, p, &next);
0278         if (!p || IS_ERR(p)) {
0279             err = PTR_ERR(p);
0280             break;
0281         }
0282         err = m->op->show(m, p);
0283         if (seq_has_overflowed(m) || err) {
0284             m->count = offs;
0285             if (likely(err <= 0))
0286                 break;
0287         }
0288         pos = next;
0289     }
0290     m->op->stop(m, p);
0291     n = min(m->count, size);
0292     err = copy_to_user(buf, m->buf, n);
0293     if (err)
0294         goto Efault;
0295     copied += n;
0296     m->count -= n;
0297     if (m->count)
0298         m->from = n;
0299     else
0300         pos++;
0301     m->index = pos;
0302 Done:
0303     if (!copied)
0304         copied = err;
0305     else {
0306         *ppos += copied;
0307         m->read_pos += copied;
0308     }
0309     file->f_version = m->version;
0310     mutex_unlock(&m->lock);
0311     return copied;
0312 Enomem:
0313     err = -ENOMEM;
0314     goto Done;
0315 Efault:
0316     err = -EFAULT;
0317     goto Done;
0318 }
0319 EXPORT_SYMBOL(seq_read);
0320 
0321 /**
0322  *  seq_lseek - ->llseek() method for sequential files.
0323  *  @file: the file in question
0324  *  @offset: new position
0325  *  @whence: 0 for absolute, 1 for relative position
0326  *
0327  *  Ready-made ->f_op->llseek()
0328  */
0329 loff_t seq_lseek(struct file *file, loff_t offset, int whence)
0330 {
0331     struct seq_file *m = file->private_data;
0332     loff_t retval = -EINVAL;
0333 
0334     mutex_lock(&m->lock);
0335     m->version = file->f_version;
0336     switch (whence) {
0337     case SEEK_CUR:
0338         offset += file->f_pos;
0339     case SEEK_SET:
0340         if (offset < 0)
0341             break;
0342         retval = offset;
0343         if (offset != m->read_pos) {
0344             while ((retval = traverse(m, offset)) == -EAGAIN)
0345                 ;
0346             if (retval) {
0347                 /* with extreme prejudice... */
0348                 file->f_pos = 0;
0349                 m->read_pos = 0;
0350                 m->version = 0;
0351                 m->index = 0;
0352                 m->count = 0;
0353             } else {
0354                 m->read_pos = offset;
0355                 retval = file->f_pos = offset;
0356             }
0357         } else {
0358             file->f_pos = offset;
0359         }
0360     }
0361     file->f_version = m->version;
0362     mutex_unlock(&m->lock);
0363     return retval;
0364 }
0365 EXPORT_SYMBOL(seq_lseek);
0366 
0367 /**
0368  *  seq_release -   free the structures associated with sequential file.
0369  *  @file: file in question
0370  *  @inode: its inode
0371  *
0372  *  Frees the structures associated with sequential file; can be used
0373  *  as ->f_op->release() if you don't have private data to destroy.
0374  */
0375 int seq_release(struct inode *inode, struct file *file)
0376 {
0377     struct seq_file *m = file->private_data;
0378     kvfree(m->buf);
0379     kfree(m);
0380     return 0;
0381 }
0382 EXPORT_SYMBOL(seq_release);
0383 
0384 /**
0385  *  seq_escape -    print string into buffer, escaping some characters
0386  *  @m: target buffer
0387  *  @s: string
0388  *  @esc:   set of characters that need escaping
0389  *
0390  *  Puts string into buffer, replacing each occurrence of character from
0391  *  @esc with usual octal escape.
0392  *  Use seq_has_overflowed() to check for errors.
0393  */
0394 void seq_escape(struct seq_file *m, const char *s, const char *esc)
0395 {
0396     char *buf;
0397     size_t size = seq_get_buf(m, &buf);
0398     int ret;
0399 
0400     ret = string_escape_str(s, buf, size, ESCAPE_OCTAL, esc);
0401     seq_commit(m, ret < size ? ret : -1);
0402 }
0403 EXPORT_SYMBOL(seq_escape);
0404 
0405 void seq_vprintf(struct seq_file *m, const char *f, va_list args)
0406 {
0407     int len;
0408 
0409     if (m->count < m->size) {
0410         len = vsnprintf(m->buf + m->count, m->size - m->count, f, args);
0411         if (m->count + len < m->size) {
0412             m->count += len;
0413             return;
0414         }
0415     }
0416     seq_set_overflow(m);
0417 }
0418 EXPORT_SYMBOL(seq_vprintf);
0419 
0420 void seq_printf(struct seq_file *m, const char *f, ...)
0421 {
0422     va_list args;
0423 
0424     va_start(args, f);
0425     seq_vprintf(m, f, args);
0426     va_end(args);
0427 }
0428 EXPORT_SYMBOL(seq_printf);
0429 
0430 /**
0431  *  mangle_path -   mangle and copy path to buffer beginning
0432  *  @s: buffer start
0433  *  @p: beginning of path in above buffer
0434  *  @esc: set of characters that need escaping
0435  *
0436  *      Copy the path from @p to @s, replacing each occurrence of character from
0437  *      @esc with usual octal escape.
0438  *      Returns pointer past last written character in @s, or NULL in case of
0439  *      failure.
0440  */
0441 char *mangle_path(char *s, const char *p, const char *esc)
0442 {
0443     while (s <= p) {
0444         char c = *p++;
0445         if (!c) {
0446             return s;
0447         } else if (!strchr(esc, c)) {
0448             *s++ = c;
0449         } else if (s + 4 > p) {
0450             break;
0451         } else {
0452             *s++ = '\\';
0453             *s++ = '0' + ((c & 0300) >> 6);
0454             *s++ = '0' + ((c & 070) >> 3);
0455             *s++ = '0' + (c & 07);
0456         }
0457     }
0458     return NULL;
0459 }
0460 EXPORT_SYMBOL(mangle_path);
0461 
0462 /**
0463  * seq_path - seq_file interface to print a pathname
0464  * @m: the seq_file handle
0465  * @path: the struct path to print
0466  * @esc: set of characters to escape in the output
0467  *
0468  * return the absolute path of 'path', as represented by the
0469  * dentry / mnt pair in the path parameter.
0470  */
0471 int seq_path(struct seq_file *m, const struct path *path, const char *esc)
0472 {
0473     char *buf;
0474     size_t size = seq_get_buf(m, &buf);
0475     int res = -1;
0476 
0477     if (size) {
0478         char *p = d_path(path, buf, size);
0479         if (!IS_ERR(p)) {
0480             char *end = mangle_path(buf, p, esc);
0481             if (end)
0482                 res = end - buf;
0483         }
0484     }
0485     seq_commit(m, res);
0486 
0487     return res;
0488 }
0489 EXPORT_SYMBOL(seq_path);
0490 
0491 /**
0492  * seq_file_path - seq_file interface to print a pathname of a file
0493  * @m: the seq_file handle
0494  * @file: the struct file to print
0495  * @esc: set of characters to escape in the output
0496  *
0497  * return the absolute path to the file.
0498  */
0499 int seq_file_path(struct seq_file *m, struct file *file, const char *esc)
0500 {
0501     return seq_path(m, &file->f_path, esc);
0502 }
0503 EXPORT_SYMBOL(seq_file_path);
0504 
0505 /*
0506  * Same as seq_path, but relative to supplied root.
0507  */
0508 int seq_path_root(struct seq_file *m, const struct path *path,
0509           const struct path *root, const char *esc)
0510 {
0511     char *buf;
0512     size_t size = seq_get_buf(m, &buf);
0513     int res = -ENAMETOOLONG;
0514 
0515     if (size) {
0516         char *p;
0517 
0518         p = __d_path(path, root, buf, size);
0519         if (!p)
0520             return SEQ_SKIP;
0521         res = PTR_ERR(p);
0522         if (!IS_ERR(p)) {
0523             char *end = mangle_path(buf, p, esc);
0524             if (end)
0525                 res = end - buf;
0526             else
0527                 res = -ENAMETOOLONG;
0528         }
0529     }
0530     seq_commit(m, res);
0531 
0532     return res < 0 && res != -ENAMETOOLONG ? res : 0;
0533 }
0534 
0535 /*
0536  * returns the path of the 'dentry' from the root of its filesystem.
0537  */
0538 int seq_dentry(struct seq_file *m, struct dentry *dentry, const char *esc)
0539 {
0540     char *buf;
0541     size_t size = seq_get_buf(m, &buf);
0542     int res = -1;
0543 
0544     if (size) {
0545         char *p = dentry_path(dentry, buf, size);
0546         if (!IS_ERR(p)) {
0547             char *end = mangle_path(buf, p, esc);
0548             if (end)
0549                 res = end - buf;
0550         }
0551     }
0552     seq_commit(m, res);
0553 
0554     return res;
0555 }
0556 EXPORT_SYMBOL(seq_dentry);
0557 
0558 static void *single_start(struct seq_file *p, loff_t *pos)
0559 {
0560     return NULL + (*pos == 0);
0561 }
0562 
0563 static void *single_next(struct seq_file *p, void *v, loff_t *pos)
0564 {
0565     ++*pos;
0566     return NULL;
0567 }
0568 
0569 static void single_stop(struct seq_file *p, void *v)
0570 {
0571 }
0572 
0573 int single_open(struct file *file, int (*show)(struct seq_file *, void *),
0574         void *data)
0575 {
0576     struct seq_operations *op = kmalloc(sizeof(*op), GFP_KERNEL);
0577     int res = -ENOMEM;
0578 
0579     if (op) {
0580         op->start = single_start;
0581         op->next = single_next;
0582         op->stop = single_stop;
0583         op->show = show;
0584         res = seq_open(file, op);
0585         if (!res)
0586             ((struct seq_file *)file->private_data)->private = data;
0587         else
0588             kfree(op);
0589     }
0590     return res;
0591 }
0592 EXPORT_SYMBOL(single_open);
0593 
0594 int single_open_size(struct file *file, int (*show)(struct seq_file *, void *),
0595         void *data, size_t size)
0596 {
0597     char *buf = seq_buf_alloc(size);
0598     int ret;
0599     if (!buf)
0600         return -ENOMEM;
0601     ret = single_open(file, show, data);
0602     if (ret) {
0603         kvfree(buf);
0604         return ret;
0605     }
0606     ((struct seq_file *)file->private_data)->buf = buf;
0607     ((struct seq_file *)file->private_data)->size = size;
0608     return 0;
0609 }
0610 EXPORT_SYMBOL(single_open_size);
0611 
0612 int single_release(struct inode *inode, struct file *file)
0613 {
0614     const struct seq_operations *op = ((struct seq_file *)file->private_data)->op;
0615     int res = seq_release(inode, file);
0616     kfree(op);
0617     return res;
0618 }
0619 EXPORT_SYMBOL(single_release);
0620 
0621 int seq_release_private(struct inode *inode, struct file *file)
0622 {
0623     struct seq_file *seq = file->private_data;
0624 
0625     kfree(seq->private);
0626     seq->private = NULL;
0627     return seq_release(inode, file);
0628 }
0629 EXPORT_SYMBOL(seq_release_private);
0630 
0631 void *__seq_open_private(struct file *f, const struct seq_operations *ops,
0632         int psize)
0633 {
0634     int rc;
0635     void *private;
0636     struct seq_file *seq;
0637 
0638     private = kzalloc(psize, GFP_KERNEL);
0639     if (private == NULL)
0640         goto out;
0641 
0642     rc = seq_open(f, ops);
0643     if (rc < 0)
0644         goto out_free;
0645 
0646     seq = f->private_data;
0647     seq->private = private;
0648     return private;
0649 
0650 out_free:
0651     kfree(private);
0652 out:
0653     return NULL;
0654 }
0655 EXPORT_SYMBOL(__seq_open_private);
0656 
0657 int seq_open_private(struct file *filp, const struct seq_operations *ops,
0658         int psize)
0659 {
0660     return __seq_open_private(filp, ops, psize) ? 0 : -ENOMEM;
0661 }
0662 EXPORT_SYMBOL(seq_open_private);
0663 
0664 void seq_putc(struct seq_file *m, char c)
0665 {
0666     if (m->count >= m->size)
0667         return;
0668 
0669     m->buf[m->count++] = c;
0670 }
0671 EXPORT_SYMBOL(seq_putc);
0672 
0673 void seq_puts(struct seq_file *m, const char *s)
0674 {
0675     int len = strlen(s);
0676 
0677     if (m->count + len >= m->size) {
0678         seq_set_overflow(m);
0679         return;
0680     }
0681     memcpy(m->buf + m->count, s, len);
0682     m->count += len;
0683 }
0684 EXPORT_SYMBOL(seq_puts);
0685 
0686 /*
0687  * A helper routine for putting decimal numbers without rich format of printf().
0688  * only 'unsigned long long' is supported.
0689  * This routine will put strlen(delimiter) + number into seq_file.
0690  * This routine is very quick when you show lots of numbers.
0691  * In usual cases, it will be better to use seq_printf(). It's easier to read.
0692  */
0693 void seq_put_decimal_ull(struct seq_file *m, const char *delimiter,
0694              unsigned long long num)
0695 {
0696     int len;
0697 
0698     if (m->count + 2 >= m->size) /* we'll write 2 bytes at least */
0699         goto overflow;
0700 
0701     len = strlen(delimiter);
0702     if (m->count + len >= m->size)
0703         goto overflow;
0704 
0705     memcpy(m->buf + m->count, delimiter, len);
0706     m->count += len;
0707 
0708     if (m->count + 1 >= m->size)
0709         goto overflow;
0710 
0711     if (num < 10) {
0712         m->buf[m->count++] = num + '0';
0713         return;
0714     }
0715 
0716     len = num_to_str(m->buf + m->count, m->size - m->count, num);
0717     if (!len)
0718         goto overflow;
0719 
0720     m->count += len;
0721     return;
0722 
0723 overflow:
0724     seq_set_overflow(m);
0725 }
0726 EXPORT_SYMBOL(seq_put_decimal_ull);
0727 
0728 void seq_put_decimal_ll(struct seq_file *m, const char *delimiter, long long num)
0729 {
0730     int len;
0731 
0732     if (m->count + 3 >= m->size) /* we'll write 2 bytes at least */
0733         goto overflow;
0734 
0735     len = strlen(delimiter);
0736     if (m->count + len >= m->size)
0737         goto overflow;
0738 
0739     memcpy(m->buf + m->count, delimiter, len);
0740     m->count += len;
0741 
0742     if (m->count + 2 >= m->size)
0743         goto overflow;
0744 
0745     if (num < 0) {
0746         m->buf[m->count++] = '-';
0747         num = -num;
0748     }
0749 
0750     if (num < 10) {
0751         m->buf[m->count++] = num + '0';
0752         return;
0753     }
0754 
0755     len = num_to_str(m->buf + m->count, m->size - m->count, num);
0756     if (!len)
0757         goto overflow;
0758 
0759     m->count += len;
0760     return;
0761 
0762 overflow:
0763     seq_set_overflow(m);
0764 }
0765 EXPORT_SYMBOL(seq_put_decimal_ll);
0766 
0767 /**
0768  * seq_write - write arbitrary data to buffer
0769  * @seq: seq_file identifying the buffer to which data should be written
0770  * @data: data address
0771  * @len: number of bytes
0772  *
0773  * Return 0 on success, non-zero otherwise.
0774  */
0775 int seq_write(struct seq_file *seq, const void *data, size_t len)
0776 {
0777     if (seq->count + len < seq->size) {
0778         memcpy(seq->buf + seq->count, data, len);
0779         seq->count += len;
0780         return 0;
0781     }
0782     seq_set_overflow(seq);
0783     return -1;
0784 }
0785 EXPORT_SYMBOL(seq_write);
0786 
0787 /**
0788  * seq_pad - write padding spaces to buffer
0789  * @m: seq_file identifying the buffer to which data should be written
0790  * @c: the byte to append after padding if non-zero
0791  */
0792 void seq_pad(struct seq_file *m, char c)
0793 {
0794     int size = m->pad_until - m->count;
0795     if (size > 0)
0796         seq_printf(m, "%*s", size, "");
0797     if (c)
0798         seq_putc(m, c);
0799 }
0800 EXPORT_SYMBOL(seq_pad);
0801 
0802 /* A complete analogue of print_hex_dump() */
0803 void seq_hex_dump(struct seq_file *m, const char *prefix_str, int prefix_type,
0804           int rowsize, int groupsize, const void *buf, size_t len,
0805           bool ascii)
0806 {
0807     const u8 *ptr = buf;
0808     int i, linelen, remaining = len;
0809     char *buffer;
0810     size_t size;
0811     int ret;
0812 
0813     if (rowsize != 16 && rowsize != 32)
0814         rowsize = 16;
0815 
0816     for (i = 0; i < len && !seq_has_overflowed(m); i += rowsize) {
0817         linelen = min(remaining, rowsize);
0818         remaining -= rowsize;
0819 
0820         switch (prefix_type) {
0821         case DUMP_PREFIX_ADDRESS:
0822             seq_printf(m, "%s%p: ", prefix_str, ptr + i);
0823             break;
0824         case DUMP_PREFIX_OFFSET:
0825             seq_printf(m, "%s%.8x: ", prefix_str, i);
0826             break;
0827         default:
0828             seq_printf(m, "%s", prefix_str);
0829             break;
0830         }
0831 
0832         size = seq_get_buf(m, &buffer);
0833         ret = hex_dump_to_buffer(ptr + i, linelen, rowsize, groupsize,
0834                      buffer, size, ascii);
0835         seq_commit(m, ret < size ? ret : -1);
0836 
0837         seq_putc(m, '\n');
0838     }
0839 }
0840 EXPORT_SYMBOL(seq_hex_dump);
0841 
0842 struct list_head *seq_list_start(struct list_head *head, loff_t pos)
0843 {
0844     struct list_head *lh;
0845 
0846     list_for_each(lh, head)
0847         if (pos-- == 0)
0848             return lh;
0849 
0850     return NULL;
0851 }
0852 EXPORT_SYMBOL(seq_list_start);
0853 
0854 struct list_head *seq_list_start_head(struct list_head *head, loff_t pos)
0855 {
0856     if (!pos)
0857         return head;
0858 
0859     return seq_list_start(head, pos - 1);
0860 }
0861 EXPORT_SYMBOL(seq_list_start_head);
0862 
0863 struct list_head *seq_list_next(void *v, struct list_head *head, loff_t *ppos)
0864 {
0865     struct list_head *lh;
0866 
0867     lh = ((struct list_head *)v)->next;
0868     ++*ppos;
0869     return lh == head ? NULL : lh;
0870 }
0871 EXPORT_SYMBOL(seq_list_next);
0872 
0873 /**
0874  * seq_hlist_start - start an iteration of a hlist
0875  * @head: the head of the hlist
0876  * @pos:  the start position of the sequence
0877  *
0878  * Called at seq_file->op->start().
0879  */
0880 struct hlist_node *seq_hlist_start(struct hlist_head *head, loff_t pos)
0881 {
0882     struct hlist_node *node;
0883 
0884     hlist_for_each(node, head)
0885         if (pos-- == 0)
0886             return node;
0887     return NULL;
0888 }
0889 EXPORT_SYMBOL(seq_hlist_start);
0890 
0891 /**
0892  * seq_hlist_start_head - start an iteration of a hlist
0893  * @head: the head of the hlist
0894  * @pos:  the start position of the sequence
0895  *
0896  * Called at seq_file->op->start(). Call this function if you want to
0897  * print a header at the top of the output.
0898  */
0899 struct hlist_node *seq_hlist_start_head(struct hlist_head *head, loff_t pos)
0900 {
0901     if (!pos)
0902         return SEQ_START_TOKEN;
0903 
0904     return seq_hlist_start(head, pos - 1);
0905 }
0906 EXPORT_SYMBOL(seq_hlist_start_head);
0907 
0908 /**
0909  * seq_hlist_next - move to the next position of the hlist
0910  * @v:    the current iterator
0911  * @head: the head of the hlist
0912  * @ppos: the current position
0913  *
0914  * Called at seq_file->op->next().
0915  */
0916 struct hlist_node *seq_hlist_next(void *v, struct hlist_head *head,
0917                   loff_t *ppos)
0918 {
0919     struct hlist_node *node = v;
0920 
0921     ++*ppos;
0922     if (v == SEQ_START_TOKEN)
0923         return head->first;
0924     else
0925         return node->next;
0926 }
0927 EXPORT_SYMBOL(seq_hlist_next);
0928 
0929 /**
0930  * seq_hlist_start_rcu - start an iteration of a hlist protected by RCU
0931  * @head: the head of the hlist
0932  * @pos:  the start position of the sequence
0933  *
0934  * Called at seq_file->op->start().
0935  *
0936  * This list-traversal primitive may safely run concurrently with
0937  * the _rcu list-mutation primitives such as hlist_add_head_rcu()
0938  * as long as the traversal is guarded by rcu_read_lock().
0939  */
0940 struct hlist_node *seq_hlist_start_rcu(struct hlist_head *head,
0941                        loff_t pos)
0942 {
0943     struct hlist_node *node;
0944 
0945     __hlist_for_each_rcu(node, head)
0946         if (pos-- == 0)
0947             return node;
0948     return NULL;
0949 }
0950 EXPORT_SYMBOL(seq_hlist_start_rcu);
0951 
0952 /**
0953  * seq_hlist_start_head_rcu - start an iteration of a hlist protected by RCU
0954  * @head: the head of the hlist
0955  * @pos:  the start position of the sequence
0956  *
0957  * Called at seq_file->op->start(). Call this function if you want to
0958  * print a header at the top of the output.
0959  *
0960  * This list-traversal primitive may safely run concurrently with
0961  * the _rcu list-mutation primitives such as hlist_add_head_rcu()
0962  * as long as the traversal is guarded by rcu_read_lock().
0963  */
0964 struct hlist_node *seq_hlist_start_head_rcu(struct hlist_head *head,
0965                         loff_t pos)
0966 {
0967     if (!pos)
0968         return SEQ_START_TOKEN;
0969 
0970     return seq_hlist_start_rcu(head, pos - 1);
0971 }
0972 EXPORT_SYMBOL(seq_hlist_start_head_rcu);
0973 
0974 /**
0975  * seq_hlist_next_rcu - move to the next position of the hlist protected by RCU
0976  * @v:    the current iterator
0977  * @head: the head of the hlist
0978  * @ppos: the current position
0979  *
0980  * Called at seq_file->op->next().
0981  *
0982  * This list-traversal primitive may safely run concurrently with
0983  * the _rcu list-mutation primitives such as hlist_add_head_rcu()
0984  * as long as the traversal is guarded by rcu_read_lock().
0985  */
0986 struct hlist_node *seq_hlist_next_rcu(void *v,
0987                       struct hlist_head *head,
0988                       loff_t *ppos)
0989 {
0990     struct hlist_node *node = v;
0991 
0992     ++*ppos;
0993     if (v == SEQ_START_TOKEN)
0994         return rcu_dereference(head->first);
0995     else
0996         return rcu_dereference(node->next);
0997 }
0998 EXPORT_SYMBOL(seq_hlist_next_rcu);
0999 
1000 /**
1001  * seq_hlist_start_precpu - start an iteration of a percpu hlist array
1002  * @head: pointer to percpu array of struct hlist_heads
1003  * @cpu:  pointer to cpu "cursor"
1004  * @pos:  start position of sequence
1005  *
1006  * Called at seq_file->op->start().
1007  */
1008 struct hlist_node *
1009 seq_hlist_start_percpu(struct hlist_head __percpu *head, int *cpu, loff_t pos)
1010 {
1011     struct hlist_node *node;
1012 
1013     for_each_possible_cpu(*cpu) {
1014         hlist_for_each(node, per_cpu_ptr(head, *cpu)) {
1015             if (pos-- == 0)
1016                 return node;
1017         }
1018     }
1019     return NULL;
1020 }
1021 EXPORT_SYMBOL(seq_hlist_start_percpu);
1022 
1023 /**
1024  * seq_hlist_next_percpu - move to the next position of the percpu hlist array
1025  * @v:    pointer to current hlist_node
1026  * @head: pointer to percpu array of struct hlist_heads
1027  * @cpu:  pointer to cpu "cursor"
1028  * @pos:  start position of sequence
1029  *
1030  * Called at seq_file->op->next().
1031  */
1032 struct hlist_node *
1033 seq_hlist_next_percpu(void *v, struct hlist_head __percpu *head,
1034             int *cpu, loff_t *pos)
1035 {
1036     struct hlist_node *node = v;
1037 
1038     ++*pos;
1039 
1040     if (node->next)
1041         return node->next;
1042 
1043     for (*cpu = cpumask_next(*cpu, cpu_possible_mask); *cpu < nr_cpu_ids;
1044          *cpu = cpumask_next(*cpu, cpu_possible_mask)) {
1045         struct hlist_head *bucket = per_cpu_ptr(head, *cpu);
1046 
1047         if (!hlist_empty(bucket))
1048             return bucket->first;
1049     }
1050     return NULL;
1051 }
1052 EXPORT_SYMBOL(seq_hlist_next_percpu);