1 #define S_SIZE (1024 - (sizeof(unsigned int) + 1))
2 
3 struct sbuff {
4 	unsigned int	count;
5 	char		buf[S_SIZE + 1];
6 };
7 static struct sbuff emergency, *emergency_ptr = &emergency;
8 
sb_add(struct sbuff * m,const char * f,...)9 static int sb_add(struct sbuff *m, const char *f, ...)
10 {
11 	va_list args;
12 	int len;
13 
14 	if (likely(m->count < S_SIZE)) {
15 		va_start(args, f);
16 		len = vsnprintf(m->buf + m->count, S_SIZE - m->count, f, args);
17 		va_end(args);
18 		if (likely(m->count + len < S_SIZE)) {
19 			m->count += len;
20 			return 0;
21 		}
22 	}
23 	m->count = S_SIZE;
24 	printk_once(KERN_ERR KBUILD_MODNAME " please increase S_SIZE\n");
25 	return -1;
26 }
27 
sb_open(void)28 static struct sbuff *sb_open(void)
29 {
30 	struct sbuff *m = kmalloc(sizeof(*m), GFP_ATOMIC);
31 
32 	if (unlikely(!m)) {
33 		local_bh_disable();
34 		do {
35 			m = xchg(&emergency_ptr, NULL);
36 		} while (!m);
37 	}
38 	m->count = 0;
39 	return m;
40 }
41 
sb_close(struct sbuff * m)42 static void sb_close(struct sbuff *m)
43 {
44 	m->buf[m->count] = 0;
45 	printk("%s\n", m->buf);
46 
47 	if (likely(m != &emergency))
48 		kfree(m);
49 	else {
50 		xchg(&emergency_ptr, m);
51 		local_bh_enable();
52 	}
53 }
54 
55