mirror of
https://github.com/adulau/aha.git
synced 2024-12-27 11:16:11 +00:00
vfs: seq_file: add helpers for data filling
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 <mszeredi@suse.cz> Acked-by: Hugh Dickins <hugh.dickins@tiscali.co.uk> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
This commit is contained in:
parent
f9098980ff
commit
f84398068d
2 changed files with 77 additions and 36 deletions
|
@ -429,20 +429,21 @@ EXPORT_SYMBOL(mangle_path);
|
||||||
*/
|
*/
|
||||||
int seq_path(struct seq_file *m, struct path *path, char *esc)
|
int seq_path(struct seq_file *m, struct path *path, char *esc)
|
||||||
{
|
{
|
||||||
if (m->count < m->size) {
|
char *buf;
|
||||||
char *s = m->buf + m->count;
|
size_t size = seq_get_buf(m, &buf);
|
||||||
char *p = d_path(path, s, m->size - m->count);
|
int res = -1;
|
||||||
|
|
||||||
|
if (size) {
|
||||||
|
char *p = d_path(path, buf, size);
|
||||||
if (!IS_ERR(p)) {
|
if (!IS_ERR(p)) {
|
||||||
s = mangle_path(s, p, esc);
|
char *end = mangle_path(buf, p, esc);
|
||||||
if (s) {
|
if (end)
|
||||||
p = m->buf + m->count;
|
res = end - buf;
|
||||||
m->count = s - m->buf;
|
|
||||||
return s - p;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
m->count = m->size;
|
seq_commit(m, res);
|
||||||
return -1;
|
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(seq_path);
|
EXPORT_SYMBOL(seq_path);
|
||||||
|
|
||||||
|
@ -454,27 +455,28 @@ EXPORT_SYMBOL(seq_path);
|
||||||
int seq_path_root(struct seq_file *m, struct path *path, struct path *root,
|
int seq_path_root(struct seq_file *m, struct path *path, struct path *root,
|
||||||
char *esc)
|
char *esc)
|
||||||
{
|
{
|
||||||
int err = -ENAMETOOLONG;
|
char *buf;
|
||||||
if (m->count < m->size) {
|
size_t size = seq_get_buf(m, &buf);
|
||||||
char *s = m->buf + m->count;
|
int res = -ENAMETOOLONG;
|
||||||
|
|
||||||
|
if (size) {
|
||||||
char *p;
|
char *p;
|
||||||
|
|
||||||
spin_lock(&dcache_lock);
|
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);
|
spin_unlock(&dcache_lock);
|
||||||
err = PTR_ERR(p);
|
res = PTR_ERR(p);
|
||||||
if (!IS_ERR(p)) {
|
if (!IS_ERR(p)) {
|
||||||
s = mangle_path(s, p, esc);
|
char *end = mangle_path(buf, p, esc);
|
||||||
if (s) {
|
if (end)
|
||||||
p = m->buf + m->count;
|
res = end - buf;
|
||||||
m->count = s - m->buf;
|
else
|
||||||
return 0;
|
res = -ENAMETOOLONG;
|
||||||
}
|
|
||||||
err = -ENAMETOOLONG;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
m->count = m->size;
|
seq_commit(m, res);
|
||||||
return err;
|
|
||||||
|
return res < 0 ? res : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -482,20 +484,21 @@ int seq_path_root(struct seq_file *m, struct path *path, struct path *root,
|
||||||
*/
|
*/
|
||||||
int seq_dentry(struct seq_file *m, struct dentry *dentry, char *esc)
|
int seq_dentry(struct seq_file *m, struct dentry *dentry, char *esc)
|
||||||
{
|
{
|
||||||
if (m->count < m->size) {
|
char *buf;
|
||||||
char *s = m->buf + m->count;
|
size_t size = seq_get_buf(m, &buf);
|
||||||
char *p = dentry_path(dentry, s, m->size - m->count);
|
int res = -1;
|
||||||
|
|
||||||
|
if (size) {
|
||||||
|
char *p = dentry_path(dentry, buf, size);
|
||||||
if (!IS_ERR(p)) {
|
if (!IS_ERR(p)) {
|
||||||
s = mangle_path(s, p, esc);
|
char *end = mangle_path(buf, p, esc);
|
||||||
if (s) {
|
if (end)
|
||||||
p = m->buf + m->count;
|
res = end - buf;
|
||||||
m->count = s - m->buf;
|
|
||||||
return s - p;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
m->count = m->size;
|
seq_commit(m, res);
|
||||||
return -1;
|
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
int seq_bitmap(struct seq_file *m, const unsigned long *bits,
|
int seq_bitmap(struct seq_file *m, const unsigned long *bits,
|
||||||
|
|
|
@ -35,6 +35,44 @@ struct seq_operations {
|
||||||
|
|
||||||
#define SEQ_SKIP 1
|
#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);
|
char *mangle_path(char *s, char *p, char *esc);
|
||||||
int seq_open(struct file *, const struct seq_operations *);
|
int seq_open(struct file *, const struct seq_operations *);
|
||||||
ssize_t seq_read(struct file *, char __user *, size_t, loff_t *);
|
ssize_t seq_read(struct file *, char __user *, size_t, loff_t *);
|
||||||
|
|
Loading…
Reference in a new issue