1#define S_SIZE (1024 - (sizeof(unsigned int) + 1)) 2 3struct sbuff { 4 unsigned int count; 5 char buf[S_SIZE + 1]; 6}; 7static struct sbuff emergency, *emergency_ptr = &emergency; 8 9static __printf(2, 3) 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 28static 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 42static 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 emergency_ptr = m; 51 local_bh_enable(); 52 } 53} 54 55