Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f8439806 authored by Miklos Szeredi's avatar Miklos Szeredi Committed by Al Viro
Browse files

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: default avatarMiklos Szeredi <mszeredi@suse.cz>
Acked-by: default avatarHugh Dickins <hugh.dickins@tiscali.co.uk>
Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent f9098980
Loading
Loading
Loading
Loading
+39 −36
Original line number Original line Diff line number Diff line
@@ -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;
		}
		}
	}
	}
	}
	seq_commit(m, res);
	m->count = m->size;

	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,
+38 −0
Original line number Original line Diff line number Diff line
@@ -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 *);