title: Filesystem has been set read-only for clusters badly computed error
body: <p>my sd cart run a long time in embed linux system,but sometime the filesystem set readonly and print bellow msg:
  clusters badly computed (587 != 531)
  FAT: Filesystem panic (dev hda6)</p>
  
  <h1>i see source code from linux kernel as show this: who can explain why this error,tks very much.</h1>
  
  <p>/*
   * fat_chain_add() adds a new cluster to the chain of clusters represented
   * by inode.
   */</p>
  
  <pre><code>int fat_chain_add(struct inode *inode, int new_dclus, int nr_cluster)
  {
      struct super_block *sb = inode-&gt;i_sb;
      struct msdos_sb_info *sbi = MSDOS_SB(sb);
      int ret, new_fclus, last;
  
      /*
       * We must locate the last cluster of the file to add this new
       * one (new_dclus) to the end of the link list (the FAT).
       */
      last = new_fclus = 0;
      if (MSDOS_I(inode)-&gt;i_start) {
          int fclus, dclus;
  
          ret = fat_get_cluster(inode, FAT_ENT_EOF, &amp;fclus, &amp;dclus);
          if (ret &lt; 0)
              return ret;
          new_fclus = fclus + 1;
          last = dclus;
      }
  
      /* add new one to the last of the cluster chain */
      if (last) {
          struct fat_entry fatent;
  
          fatent_init(&amp;fatent);
          ret = fat_ent_read(inode, &amp;fatent, last);
          if (ret &gt;= 0) {
              int wait = inode_needs_sync(inode);
              ret = fat_ent_write(inode, &amp;fatent, new_dclus, wait);
              fatent_brelse(&amp;fatent);
          }
          if (ret &lt; 0)
              return ret;
          /*
           * FIXME:Although we can add this cache, fat_cache_add() is
           * assuming to be called after linear search with fat_cache_id.
           */
  //      fat_cache_add(inode, new_fclus, new_dclus);
      } else {
          MSDOS_I(inode)-&gt;i_start = new_dclus;
          MSDOS_I(inode)-&gt;i_logstart = new_dclus;
          /*
           * Since generic_write_sync() synchronizes regular files later,
           * we sync here only directories.
           */
          if (S_ISDIR(inode-&gt;i_mode) &amp;&amp; IS_DIRSYNC(inode)) {
              ret = fat_sync_inode(inode);
              if (ret)
                  return ret;
          } else
              mark_inode_dirty(inode);
      }
      if (new_fclus != (inode-&gt;i_blocks &gt;&gt; (sbi-&gt;cluster_bits - 9))) {
          fat_fs_error(sb, "clusters badly computed (%d != %llu)",
                   new_fclus,
                   (llu)(inode-&gt;i_blocks &gt;&gt; (sbi-&gt;cluster_bits - 9)));
          fat_cache_inval_inode(inode);
      }
      inode-&gt;i_blocks += nr_cluster &lt;&lt; (sbi-&gt;cluster_bits - 9);
  
      return 0;
  }
  </code></pre>