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
443443 return -1;
444444 }
445445
446+int 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+
446460 static void *single_start(struct seq_file *p, loff_t *pos)
447461 {
448462 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
110110
111111 extern int bitmap_scnprintf(char *buf, unsigned int len,
112112 const unsigned long *src, int nbits);
113+extern int bitmap_scnprintf_len(unsigned int nr_bits);
113114 extern int __bitmap_parse(const char *buf, unsigned int buflen, int is_user,
114115 unsigned long *dst, int nbits);
115116 extern 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
44 #include <linux/types.h>
55 #include <linux/string.h>
66 #include <linux/mutex.h>
7+#include <linux/cpumask.h>
8+#include <linux/nodemask.h>
79
810 struct seq_operations;
911 struct file;
@@ -47,6 +49,16 @@ int seq_path(struct seq_file *, struct path *, char *); · 37 unmodified lines
4749 int seq_dentry(struct seq_file *, struct dentry *, char *);
4850 int seq_path_root(struct seq_file *m, struct path *path, struct path *root,
4951 char *esc);
52+int seq_bitmap(struct seq_file *m, unsigned long *bits, unsigned int nr_bits);
53+static inline int seq_cpumask(struct seq_file *m, cpumask_t *mask)
54+{
55+ return seq_bitmap(m, mask->bits, NR_CPUS);
56+}
57+
58+static inline int seq_nodemask(struct seq_file *m, nodemask_t *mask)
59+{
60+ return seq_bitmap(m, mask->bits, MAX_NUMNODES);
61+}
5062
5163 int single_open(struct file *, int (*)(struct seq_file *, void *), void *);
5264 int 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
315315 }
316316 EXPORT_SYMBOL(bitmap_scnprintf);
317317
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+ */
323+int 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+
318329 /**
319330 * __bitmap_parse - convert an ASCII hex string into a bitmap.
320331 * @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