title: write method for /proc/ entry always called with count bytes set to zero
body: <p>I am trying to understand the seq file interface of procfs. I have created a small kernel module to read/write from/to the proc entry. The module I wrote is:</p>
  
  <pre><code>#define PROC_DIR_NAME "driver/kernel_test_dir2"
  #define KERNEL_DATA "This is kernel test"
  
  static struct proc_dir_entry *proc_entry_file = 0;
  static struct proc_dir_entry *proc_dir = 0;
  
  #define PROC_ENTRY_BUFFER_SIZE 64
  
  struct proc_entry
  {
      ssize_t buffer_length;
      char buffer[PROC_ENTRY_BUFFER_SIZE];
  };
  
  static int proc_entry_seq_show(struct seq_file *s, void *v)
  {
      printk(KERN_INFO "kernel_test:proc_entry_seq_show\n");
      struct proc_entry* kmem = s-&gt;private;
  
      if(kmem)
      {
          printk(KERN_INFO "kernel_test:proc_entry_seq_show:s-&gt;private=%x\n",s-&gt;private);
          seq_printf(s, "%s\n",&amp;(kmem-&gt;buffer[0]));
      }
      return 0;
  }
  
  static int proc_entry_open(struct inode *inode, struct file *file)
  {
      struct proc_entry* kmem = kmalloc(sizeof(struct proc_entry),GFP_KERNEL);
      return single_open(file,&amp;proc_entry_seq_show,(void*)kmem);
  };
  
  static int proc_entry_close(struct inode *inode, struct file *file)
  {
      struct seq_file *s =  file-&gt;private_data;
      struct proc_entry* kmem = (struct proc_entry*)(s-&gt;private);
      kfree(kmem);
      return single_release(inode,file);
  };
  
  static ssize_t proc_entry_write(struct file *file, const char *buf,
  size_t count, loff_t *ppos)
  {
      ssize_t len=0;
      loff_t pos;
      struct seq_file* seqfile = (struct seq_file*)(file-&gt;private_data);
  
      printk(KERN_INFO "kernel_test:proc_entry_write\n");
      printk(KERN_INFO "kernel_test:proc_entry_write:offset = %d, count=%d\n",*ppos,count);
  
      if(seqfile)
      {
          printk(KERN_INFO "kernel_test:proc_entry_write:seqfile\n");
          struct proc_entry* kmem = (struct proc_entry*)(seqfile-&gt;private);
          if(kmem)
          {
              printk(KERN_INFO "kernel_test:proc_entry_write:kmem\n");
              pos = *ppos;
              if(pos&lt;0)
                  return -EINVAL;
              if(count &gt; PROC_ENTRY_BUFFER_SIZE)
                  count = PROC_ENTRY_BUFFER_SIZE;
  
              if(copy_from_user(&amp;(kmem-&gt;buffer[0]), buf, count))
                  return -EFAULT;
              (*ppos) = pos + count;
  
              kmem-&gt;buffer_length = count;
              return count;
          }
          printk(KERN_INFO "kernel_test:proc_entry_write:kmem does not exist!\n");
      }
      printk(KERN_INFO "kernel_test:proc_entry_write:seqfile does not exist!\n");
      return -EFAULT;
  }
  
  static struct file_operations fops_proc_entry = {
      .open       = proc_entry_open,
      .read       = seq_read,
      .release    = proc_entry_close,
      .write      = proc_entry_write,
  };
  
  static int __init init_test_kernel(void) {
      int rv;
      proc_dir = proc_mkdir(PROC_DIR_NAME, NULL);
      if(proc_dir == NULL) {
          rv = -ENOMEM;
      }
      proc_entry_file = proc_create ("kernel_test_file", S_IRUSR | S_IWUSR, proc_dir,&amp;fops_proc_entry);
      if(!proc_entry_file) {
          rv = -ENOMEM;
      }
  
      printk(KERN_INFO "kernel_test: Kernel Test module started\n");
      return 0;
  }
  
  
  // Cleanup module
  static void __exit cleanup_test_kernel(void) {
      remove_proc_entry("kernel_test_file", proc_dir);
      remove_proc_entry(PROC_DIR_NAME,NULL);
      printk(KERN_INFO "kernel_test: Kernel Test module stopped\n");
  }
  
  module_init(init_test_kernel);
  module_exit(cleanup_test_kernel);
  </code></pre>
  
  <p>I wrote a small program to test my kernel module, and the source code for the sample program is:</p>
  
  <pre><code>#define BUFFER_DATA "This is test kernel data by me"
  #define MAX_BUFFER_SIZE 64
  
  static char write_buffer[MAX_BUFFER_SIZE];
  static char read_buffer[MAX_BUFFER_SIZE];
  
  int main()
  {
      int fd;
      int count=0;
  
      fd = open("/proc/driver/kernel_test_dir2/kernel_test_file",O_RDWR);
      if(fd&lt;0)
      {
          std::cout &lt;&lt;"Could not open file /proc/driver/kernel_test_dir2/kernel_test_file !"&lt;&lt;
          strerror(errno)&lt;&lt;std::endl;
          return -1;
      }
  
      sprintf(write_buffer,"%s",BUFFER_DATA);
      std::cout &lt;&lt; "Write Buffer to be written is - "&lt;&lt;write_buffer&lt;&lt;std::endl;
      count = write(fd,write_buffer,strlen(write_buffer));
      std::cout &lt;&lt; "The bytes requested to be written are - "&lt;&lt;strlen(write_buffer) &lt;&lt;std::endl;
      if(count&lt;0)
      {
          std::cout&lt;&lt;"write error : " &lt;&lt; strerror(errno)&lt;&lt;std::endl;
          return -1;
      }
      else if(count!=strlen(write_buffer))
      {
          std::cout&lt;&lt;"Wrote only "&lt;&lt;count&lt;&lt;" bytes, but was asked to write "&lt;&lt;strlen(write_buffer)&lt;&lt;" bytes"&lt;&lt;std::endl;
          return -1;
      }
  
      count = read(fd,read_buffer,MAX_BUFFER_SIZE);
      if(count &lt; 0)
      {
          std::cout&lt;&lt;"read error : " &lt;&lt; strerror(errno)&lt;&lt;std::endl;
          return -1;
      }
  
      std::cout &lt;&lt; "buffer read as - "&lt;&lt;read_buffer&lt;&lt;std::endl;
  
      close(fd);
      return 0;
  }
  </code></pre>
  
  <p>The problem I am facing is that write calls to the module somehow set the 'count' bytes in "proc_entry_write()" to 0 (zero).</p>
  
  <p>The syslog messages for my sample application execution are:</p>
  
  <pre><code>Jun 20 16:03:51 kernel: [356787.943092] kernel_test:proc_entry_write
  Jun 20 16:03:51 kernel: [356787.943554] kernel_test:proc_entry_write:offset = 0, count=0
  Jun 20 16:03:51 kernel: [356787.943944] kernel_test:proc_entry_write:seqfile
  Jun 20 16:03:51 kernel: [356787.944344] kernel_test:proc_entry_write:kmem
  Jun 20 16:03:51 kernel: [356787.944978] kernel_test:proc_entry_seq_show
  Jun 20 16:03:51 kernel: [356787.945408] kernel_test:proc_entry_seq_show:s-&gt;private=ee600600
  </code></pre>