+ if (count > PROC_BLOCK_SIZE)
+ count = PROC_BLOCK_SIZE;
+
+ /* fade that out as soon as stable */
+ WARN_ON(!nid);
+ nxi = lookup_nx_info(nid);
+ if (!nxi)
+ goto out;
+
+ length = -ENOMEM;
+ if (!(page = __get_free_page(GFP_KERNEL)))
+ goto out_put;
+
+ BUG_ON(!PROC_I(inode)->op.proc_nxi_read);
+ length = PROC_I(inode)->op.proc_nxi_read(nxi, (char*)page);
+
+ if (length >= 0)
+ length = simple_read_from_buffer(buf, count, ppos,
+ (char *)page, length);
+
+ free_page(page);
+out_put:
+ put_nx_info(nxi);
+out:
+ return length;
+}
+
+
+
+/* here comes the lower level */
+
+
+#define NOD(NAME, MODE, IOP, FOP, OP) { \
+ .len = sizeof(NAME) - 1, \
+ .name = (NAME), \
+ .mode = MODE, \
+ .iop = IOP, \
+ .fop = FOP, \
+ .op = OP, \
+}
+
+
+#define DIR(NAME, MODE, OTYPE) \
+ NOD(NAME, (S_IFDIR|(MODE)), \
+ &proc_##OTYPE##_inode_operations, \
+ &proc_##OTYPE##_file_operations, { } )
+
+#define INF(NAME, MODE, OTYPE) \
+ NOD(NAME, (S_IFREG|(MODE)), NULL, \
+ &proc_vs_info_file_operations, \
+ { .proc_vs_read = &proc_##OTYPE } )
+
+#define VINF(NAME, MODE, OTYPE) \
+ NOD(NAME, (S_IFREG|(MODE)), NULL, \
+ &proc_vx_info_file_operations, \
+ { .proc_vxi_read = &proc_##OTYPE } )
+
+#define NINF(NAME, MODE, OTYPE) \
+ NOD(NAME, (S_IFREG|(MODE)), NULL, \
+ &proc_nx_info_file_operations, \
+ { .proc_nxi_read = &proc_##OTYPE } )
+
+
+static struct file_operations proc_vs_info_file_operations = {
+ .read = proc_vs_info_read,