#ifndef __BACKPORT_SEQ_FILE_H
#define __BACKPORT_SEQ_FILE_H
#include_next <linux/seq_file.h>
#include <linux/version.h>

#if LINUX_VERSION_IS_LESS(3,7,0)
#include <linux/user_namespace.h>
#include <linux/file.h>
#include <linux/fs.h>
#ifdef CONFIG_USER_NS
static inline struct user_namespace *seq_user_ns(struct seq_file *seq)
{
	struct file *f = container_of((void *) seq, struct file, private_data);

	return f->f_cred->user_ns;
}
#else
static inline struct user_namespace *seq_user_ns(struct seq_file *seq)
{
	extern struct user_namespace init_user_ns;
	return &init_user_ns;
}
#endif /* CONFIG_USER_NS */
#endif /* < 3.7 */

#if LINUX_VERSION_IS_LESS(3,19,0)
#define seq_has_overflowed LINUX_BACKPORT(seq_has_overflowed)
/**
 * seq_has_overflowed - check if the buffer has overflowed
 * @m: the seq_file handle
 *
 * seq_files have a buffer which may overflow. When this happens a larger
 * buffer is reallocated and all the data will be printed again.
 * The overflow state is true when m->count == m->size.
 *
 * Returns true if the buffer received more than it can hold.
 */
static inline bool seq_has_overflowed(struct seq_file *m)
{
	return m->count == m->size;
}
#endif

#if LINUX_VERSION_IS_LESS(4,3,0)
#define seq_hex_dump LINUX_BACKPORT(seq_hex_dump)
void seq_hex_dump(struct seq_file *m, const char *prefix_str, int prefix_type,
		  int rowsize, int groupsize, const void *buf, size_t len,
		  bool ascii);
#endif

#ifndef DEFINE_SHOW_ATTRIBUTE
#define DEFINE_SHOW_ATTRIBUTE(__name)					\
static int __name ## _open(struct inode *inode, struct file *file)	\
{									\
	return single_open(file, __name ## _show, inode->i_private);	\
}									\
									\
static const struct file_operations __name ## _fops = {			\
	.owner		= THIS_MODULE,					\
	.open		= __name ## _open,				\
	.read		= seq_read,					\
	.llseek		= seq_lseek,					\
	.release	= single_release,				\
}
#endif /* DEFINE_SHOW_ATTRIBUTE */

#endif /* __BACKPORT_SEQ_FILE_H */
