Skip to content

Commit

Permalink
vfs: seq_file: add helpers for data filling
Browse files Browse the repository at this point in the history
Add two helpers that allow access to the seq_file's own buffer, but
hide the internal details of seq_files.

This allows easier implementation of special purpose filling
functions.  It also cleans up some existing functions which duplicated
the seq_file logic.

Make these inline functions in seq_file.h, as suggested by Al.

Signed-off-by: Miklos Szeredi <[email protected]>
Acked-by: Hugh Dickins <[email protected]>
Signed-off-by: Al Viro <[email protected]>
  • Loading branch information
Miklos Szeredi authored and Al Viro committed Sep 24, 2009
1 parent f909898 commit f843980
Show file tree
Hide file tree
Showing 2 changed files with 77 additions and 36 deletions.
75 changes: 39 additions & 36 deletions fs/seq_file.c
Original file line number Diff line number Diff line change
Expand Up @@ -429,20 +429,21 @@ EXPORT_SYMBOL(mangle_path);
*/
int seq_path(struct seq_file *m, struct path *path, char *esc)
{
if (m->count < m->size) {
char *s = m->buf + m->count;
char *p = d_path(path, s, m->size - m->count);
char *buf;
size_t size = seq_get_buf(m, &buf);
int res = -1;

if (size) {
char *p = d_path(path, buf, size);
if (!IS_ERR(p)) {
s = mangle_path(s, p, esc);
if (s) {
p = m->buf + m->count;
m->count = s - m->buf;
return s - p;
}
char *end = mangle_path(buf, p, esc);
if (end)
res = end - buf;
}
}
m->count = m->size;
return -1;
seq_commit(m, res);

return res;
}
EXPORT_SYMBOL(seq_path);

Expand All @@ -454,48 +455,50 @@ EXPORT_SYMBOL(seq_path);
int seq_path_root(struct seq_file *m, struct path *path, struct path *root,
char *esc)
{
int err = -ENAMETOOLONG;
if (m->count < m->size) {
char *s = m->buf + m->count;
char *buf;
size_t size = seq_get_buf(m, &buf);
int res = -ENAMETOOLONG;

if (size) {
char *p;

spin_lock(&dcache_lock);
p = __d_path(path, root, s, m->size - m->count);
p = __d_path(path, root, buf, size);
spin_unlock(&dcache_lock);
err = PTR_ERR(p);
res = PTR_ERR(p);
if (!IS_ERR(p)) {
s = mangle_path(s, p, esc);
if (s) {
p = m->buf + m->count;
m->count = s - m->buf;
return 0;
}
err = -ENAMETOOLONG;
char *end = mangle_path(buf, p, esc);
if (end)
res = end - buf;
else
res = -ENAMETOOLONG;
}
}
m->count = m->size;
return err;
seq_commit(m, res);

return res < 0 ? res : 0;
}

/*
* returns the path of the 'dentry' from the root of its filesystem.
*/
int seq_dentry(struct seq_file *m, struct dentry *dentry, char *esc)
{
if (m->count < m->size) {
char *s = m->buf + m->count;
char *p = dentry_path(dentry, s, m->size - m->count);
char *buf;
size_t size = seq_get_buf(m, &buf);
int res = -1;

if (size) {
char *p = dentry_path(dentry, buf, size);
if (!IS_ERR(p)) {
s = mangle_path(s, p, esc);
if (s) {
p = m->buf + m->count;
m->count = s - m->buf;
return s - p;
}
char *end = mangle_path(buf, p, esc);
if (end)
res = end - buf;
}
}
m->count = m->size;
return -1;
seq_commit(m, res);

return res;
}

int seq_bitmap(struct seq_file *m, const unsigned long *bits,
Expand Down
38 changes: 38 additions & 0 deletions include/linux/seq_file.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,44 @@ struct seq_operations {

#define SEQ_SKIP 1

/**
* seq_get_buf - get buffer to write arbitrary data to
* @m: the seq_file handle
* @bufp: the beginning of the buffer is stored here
*
* Return the number of bytes available in the buffer, or zero if
* there's no space.
*/
static inline size_t seq_get_buf(struct seq_file *m, char **bufp)
{
BUG_ON(m->count > m->size);
if (m->count < m->size)
*bufp = m->buf + m->count;
else
*bufp = NULL;

return m->size - m->count;
}

/**
* seq_commit - commit data to the buffer
* @m: the seq_file handle
* @num: the number of bytes to commit
*
* Commit @num bytes of data written to a buffer previously acquired
* by seq_buf_get. To signal an error condition, or that the data
* didn't fit in the available space, pass a negative @num value.
*/
static inline void seq_commit(struct seq_file *m, int num)
{
if (num < 0) {
m->count = m->size;
} else {
BUG_ON(m->count + num > m->size);
m->count += num;
}
}

char *mangle_path(char *s, char *p, char *esc);
int seq_open(struct file *, const struct seq_operations *);
ssize_t seq_read(struct file *, char __user *, size_t, loff_t *);
Expand Down

0 comments on commit f843980

Please sign in to comment.