History

seq_file: add seq_cpumask(), seq_nodemask()

Short enough reads from /proc/irq/*/smp_affinity return -EINVAL for no good reason. This became noticed with NR_CPUS=4096 patches, when length of printed representation of cpumask becase 1152, but cat(1) continued to read with 1024-byte chunks. bitmap_scnprintf() in good faith fills buffer, returns 1023, check returns -EINVAL. Fix it by switching to seq_file, so handler will just fill buffer and doesn't care about offsets, length, filling EOF and all this crap. For that add seq_bitmap(), and wrappers around it -- seq_cpumask() and seq_nodemask().

Alexey Dobriyan committed 18 years ago

Commit 50ac2d61 parent dd763464 files · +38 −0Browse files

Unified · Split

4 files
  1. fs/seq_file.c +14 −0
  2. include/linux/bitmap.h +1 −0
  3. include/linux/seq_file.h +12 −0
  4. lib/bitmap.c +11 −0
fs/seq_file.c+14−0
@@ -443,6 +443,20 @@ int seq_dentry(struct seq_file *m, struct dentry *dentry, char *esc) · 442 unmodified lines
443 return -1;443 return -1;
444}444}
445 445
446int seq_bitmap(struct seq_file *m, unsigned long *bits, unsigned int nr_bits)
447{
448 size_t len = bitmap_scnprintf_len(nr_bits);
449
450 if (m->count + len < m->size) {
451 bitmap_scnprintf(m->buf + m->count, m->size - m->count,
452 bits, nr_bits);
453 m->count += len;
454 return 0;
455 }
456 m->count = m->size;
457 return -1;
458}
459
446static void *single_start(struct seq_file *p, loff_t *pos)460static void *single_start(struct seq_file *p, loff_t *pos)
447{461{
448 return NULL + (*pos == 0);462 return NULL + (*pos == 0);
include/linux/bitmap.h+1−0
@@ -110,6 +110,7 @@ extern int __bitmap_weight(const unsigned long *bitmap, int bits); · 109 unmodified lines
110 110
111extern int bitmap_scnprintf(char *buf, unsigned int len,111extern int bitmap_scnprintf(char *buf, unsigned int len,
112 const unsigned long *src, int nbits);112 const unsigned long *src, int nbits);
113extern int bitmap_scnprintf_len(unsigned int nr_bits);
113extern int __bitmap_parse(const char *buf, unsigned int buflen, int is_user,114extern int __bitmap_parse(const char *buf, unsigned int buflen, int is_user,
114 unsigned long *dst, int nbits);115 unsigned long *dst, int nbits);
115extern int bitmap_parse_user(const char __user *ubuf, unsigned int ulen,116extern int bitmap_parse_user(const char __user *ubuf, unsigned int ulen,
include/linux/seq_file.h+12−0
@@ -4,6 +4,8 @@ · 3 unmodified lines
4#include <linux/types.h>4#include <linux/types.h>
5#include <linux/string.h>5#include <linux/string.h>
6#include <linux/mutex.h>6#include <linux/mutex.h>
7#include <linux/cpumask.h>
8#include <linux/nodemask.h>
7 9
8struct seq_operations;10struct seq_operations;
9struct file;11struct file;
@@ -47,6 +49,16 @@ int seq_path(struct seq_file *, struct path *, char *); · 37 unmodified lines
47int seq_dentry(struct seq_file *, struct dentry *, char *);49int seq_dentry(struct seq_file *, struct dentry *, char *);
48int seq_path_root(struct seq_file *m, struct path *path, struct path *root,50int seq_path_root(struct seq_file *m, struct path *path, struct path *root,
49 char *esc);51 char *esc);
52int seq_bitmap(struct seq_file *m, unsigned long *bits, unsigned int nr_bits);
53static inline int seq_cpumask(struct seq_file *m, cpumask_t *mask)
54{
55 return seq_bitmap(m, mask->bits, NR_CPUS);
56}
57
58static inline int seq_nodemask(struct seq_file *m, nodemask_t *mask)
59{
60 return seq_bitmap(m, mask->bits, MAX_NUMNODES);
61}
50 62
51int single_open(struct file *, int (*)(struct seq_file *, void *), void *);63int single_open(struct file *, int (*)(struct seq_file *, void *), void *);
52int single_release(struct inode *, struct file *);64int single_release(struct inode *, struct file *);
lib/bitmap.c+11−0
@@ -315,6 +315,17 @@ int bitmap_scnprintf(char *buf, unsigned int buflen, · 314 unmodified lines
315}315}
316EXPORT_SYMBOL(bitmap_scnprintf);316EXPORT_SYMBOL(bitmap_scnprintf);
317 317
318/**
319 * bitmap_scnprintf_len - return buffer length needed to convert
320 * bitmap to an ASCII hex string
321 * @nr_bits: number of bits to be converted
322 */
323int bitmap_scnprintf_len(unsigned int nr_bits)
324{
325 unsigned int nr_nibbles = ALIGN(nr_bits, 4) / 4;
326 return nr_nibbles + ALIGN(nr_nibbles, CHUNKSZ / 4) / (CHUNKSZ / 4) - 1;
327}
328
318/**329/**
319 * __bitmap_parse - convert an ASCII hex string into a bitmap.330 * __bitmap_parse - convert an ASCII hex string into a bitmap.
320 * @buf: pointer to buffer containing string.331 * @buf: pointer to buffer containing string.

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t